1 changed files with 150 additions and 144 deletions
@ -1,159 +1,165 @@ |
|||||
import { Text, Graphics, Container, TextStyle, NineSlicePlane, Texture, NineSliceSprite, Ticker } from "pixi.js"; |
import { |
||||
|
Container, |
||||
interface IOpts { |
Text, |
||||
text: string; |
Graphics, |
||||
autoUpdate: Boolean; |
TextStyle, |
||||
bg: Texture; |
NineSliceSprite, |
||||
pressBg: Texture; |
Ticker, |
||||
position: null | any; |
Texture, |
||||
click(): void; |
} from "pixi.js"; |
||||
} |
|
||||
|
|
||||
const defaultOpts: IOpts = { |
export interface ButtonOptions { |
||||
autoUpdate: true, |
text: string; |
||||
text: "", |
bg?: Texture; |
||||
bg: null, |
pressBg?: Texture; |
||||
position: null, |
position?: () => { x: number; y: number }; |
||||
pressBg: null, |
onClick: () => void; |
||||
click() { }, |
autoUpdate?: boolean; |
||||
}; |
padding?: { x: number; y: number }; |
||||
|
fontSize?: number; |
||||
function getConfig() { |
|
||||
return Object.assign({}, defaultOpts) |
|
||||
} |
} |
||||
|
|
||||
export class Button { |
export class Button { |
||||
config: IOpts |
private config: ButtonOptions; |
||||
_comp: Container |
private _container: Container; |
||||
textObj: Text |
private textObj: Text; |
||||
bgRect: Graphics |
private bgRect?: Graphics; |
||||
bgNine: NineSliceSprite |
private bgNine?: NineSliceSprite; |
||||
padding = { x: 60, y: 40 } |
private padding: { x: number; y: number }; |
||||
getComp(){ |
|
||||
return this._comp |
constructor(opts: ButtonOptions) { |
||||
} |
this.config = { |
||||
constructor(opts: Partial<IOpts>) { |
autoUpdate: true, |
||||
this.config = getConfig(); |
padding: { x: 60, y: 40 }, |
||||
; (Object.keys(defaultOpts) as (keyof IOpts)[]).forEach((key) => { |
fontSize: 30, |
||||
if (opts[key] != undefined) { |
...opts, |
||||
this.config[key] = opts[key] as any; |
}; |
||||
} |
this.padding = this.config.padding!; |
||||
}); |
|
||||
|
this._container = new Container(); |
||||
this._comp = new Container(); |
this._container.cursor = "pointer"; |
||||
this._comp.cursor = 'pointer'; |
this._container.interactive = true; |
||||
this._comp.interactive = true; |
|
||||
|
if (!this.config.bg) { |
||||
if (!this.config.bg) { |
this.createRectBackground(); |
||||
this.createRect() |
} else { |
||||
this._comp.addChild(this.bgRect) |
this.createNineSliceBackground(); |
||||
} else { |
|
||||
this.createNine() |
|
||||
this._comp.addChild(this.bgNine) |
|
||||
} |
|
||||
this.createText() |
|
||||
this._comp.addChild(this.textObj) |
|
||||
if (this.config.autoUpdate) { |
|
||||
const update = () => { |
|
||||
this.updateView() |
|
||||
} |
|
||||
Ticker.shared.add(update) |
|
||||
this._comp.on("destroyed", ()=>{ |
|
||||
console.log("销毁了"); |
|
||||
Ticker.shared.remove(update, this) |
|
||||
}) |
|
||||
} |
|
||||
const downFN = () => { |
|
||||
if (this.config.pressBg && this.bgNine) { |
|
||||
this.bgNine.texture = this.config.pressBg |
|
||||
} else { |
|
||||
this._comp.alpha = 0.8; |
|
||||
this._comp.scale = { x: .8, y: .8 } |
|
||||
} |
|
||||
} |
|
||||
this._comp.on("mousedown", downFN); |
|
||||
this._comp.on("touchstart", downFN); |
|
||||
const upFN = () => { |
|
||||
if (this.config.pressBg && this.bgNine) { |
|
||||
this.bgNine.texture = this.config.bg |
|
||||
} else { |
|
||||
this._comp.alpha = 1; |
|
||||
this._comp.scale = { x: 1, y: 1 } |
|
||||
} |
|
||||
this.config.click(); |
|
||||
} |
|
||||
this._comp.on('mouseup', upFN); |
|
||||
this._comp.on('touchend', upFN); |
|
||||
const upOutsideFN = () => { |
|
||||
if (this.config.pressBg) { |
|
||||
this.bgNine.texture = this.config.bg |
|
||||
} else { |
|
||||
this._comp.alpha = 1; |
|
||||
this._comp.scale = { x: 1, y: 1 } |
|
||||
} |
|
||||
} |
|
||||
this._comp.on("mouseupoutside", upOutsideFN); |
|
||||
this._comp.on("touchendoutside", upOutsideFN); |
|
||||
} |
} |
||||
|
|
||||
updateView() { |
this.createText(); |
||||
if(this._comp.destroyed) return |
this._container.addChild(this.textObj); |
||||
let width = this.textObj.width + this.padding.x; |
|
||||
let height = this.textObj.height + this.padding.y; |
this.setupEvents(); |
||||
this._comp.pivot.set(width / 2, height / 2) |
|
||||
this.textObj.x = this.padding.x / 2; |
if (this.config.autoUpdate) { |
||||
this.textObj.y = this.padding.y / 2 - 2; |
const update = () => this.updateView(); |
||||
|
Ticker.shared.add(update); |
||||
if (this.bgRect) { |
this._container.on("destroyed", () => { |
||||
this.bgRect.rect(0, 0, width, height); |
Ticker.shared.remove(update); |
||||
this.bgRect.fill(0xff0000); |
}); |
||||
} |
|
||||
if (this.bgNine) { |
|
||||
this.bgNine.width = width |
|
||||
this.bgNine.height = height |
|
||||
} |
|
||||
|
|
||||
if (this.config.position) { |
|
||||
this._comp.position = this.config.position() |
|
||||
} |
|
||||
} |
} |
||||
|
|
||||
createNine() { |
this.updateView(); |
||||
this.bgNine = new NineSliceSprite({ |
} |
||||
texture: this.config.bg, |
|
||||
leftWidth: 10, |
get container(): Container { |
||||
topHeight: 10, |
return this._container; |
||||
rightWidth: 10, |
} |
||||
bottomHeight: 10, |
|
||||
}); |
updateView(): void { |
||||
this.bgNine.cursor = 'pointer'; |
if (this._container.destroyed) return; |
||||
this.bgNine.label = "nine-pic" |
|
||||
this.bgNine.interactive = true; |
const width = this.textObj.width + this.padding.x; |
||||
// plane9.buttonMode = true;
|
const height = this.textObj.height + this.padding.y; |
||||
|
|
||||
|
this._container.pivot.set(width / 2, height / 2); |
||||
|
this.textObj.position.set(this.padding.x / 2, this.padding.y / 2 - 2); |
||||
|
|
||||
|
if (this.bgRect) { |
||||
|
this.bgRect.clear(); |
||||
|
this.bgRect.rect(0, 0, width, height); |
||||
|
this.bgRect.fill(0xff0000); |
||||
} |
} |
||||
|
|
||||
createRect() { |
if (this.bgNine) { |
||||
this.bgRect = new Graphics(); |
this.bgNine.width = width; |
||||
this.bgRect.label = "rect"; |
this.bgNine.height = height; |
||||
this.bgRect.interactive = true; |
|
||||
this.bgRect.cursor = 'pointer'; |
|
||||
// rect.buttonMode = true;
|
|
||||
} |
} |
||||
|
|
||||
createText() { |
if (this.config.position) { |
||||
let textStyle = new TextStyle({ |
this._container.position = this.config.position(); |
||||
fontFamily: "Arial", |
|
||||
fontSize: 30, |
|
||||
fill: 0xffffff, |
|
||||
align: "center", |
|
||||
}); |
|
||||
this.textObj = new Text({ |
|
||||
text: this.config.text, |
|
||||
style: textStyle |
|
||||
}); |
|
||||
this.textObj.cursor = 'pointer'; |
|
||||
this.textObj.label = "text" |
|
||||
} |
} |
||||
|
} |
||||
|
|
||||
|
private createRectBackground(): void { |
||||
|
this.bgRect = new Graphics(); |
||||
|
this.bgRect.label = "button-bg-rect"; |
||||
|
this._container.addChild(this.bgRect); |
||||
|
} |
||||
|
|
||||
|
private createNineSliceBackground(): void { |
||||
|
if (!this.config.bg) return; |
||||
|
this.bgNine = new NineSliceSprite({ |
||||
|
texture: this.config.bg, |
||||
|
leftWidth: 10, |
||||
|
topHeight: 10, |
||||
|
rightWidth: 10, |
||||
|
bottomHeight: 10, |
||||
|
}); |
||||
|
this.bgNine.label = "button-bg-nine"; |
||||
|
this._container.addChild(this.bgNine); |
||||
|
} |
||||
|
|
||||
|
private createText(): void { |
||||
|
const style = new TextStyle({ |
||||
|
fontFamily: "Arial", |
||||
|
fontSize: this.config.fontSize!, |
||||
|
fill: 0xffffff, |
||||
|
align: "center", |
||||
|
}); |
||||
|
this.textObj = new Text({ |
||||
|
text: this.config.text, |
||||
|
style, |
||||
|
}); |
||||
|
this.textObj.label = "button-text"; |
||||
|
} |
||||
|
|
||||
|
private setupEvents(): void { |
||||
|
const onPointerDown = () => { |
||||
|
if (this.config.pressBg && this.bgNine && this.config.bg) { |
||||
|
this.bgNine.texture = this.config.pressBg; |
||||
|
} else { |
||||
|
this._container.alpha = 0.8; |
||||
|
this._container.scale.set(0.8, 0.8); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const onPointerUp = () => { |
||||
|
if (this.config.pressBg && this.bgNine && this.config.bg) { |
||||
|
this.bgNine.texture = this.config.bg; |
||||
|
} else { |
||||
|
this._container.alpha = 1; |
||||
|
this._container.scale.set(1, 1); |
||||
|
} |
||||
|
this.config.onClick(); |
||||
|
}; |
||||
|
|
||||
|
const onPointerUpOutside = () => { |
||||
|
if (this.config.pressBg && this.bgNine && this.config.bg) { |
||||
|
this.bgNine.texture = this.config.bg; |
||||
|
} else { |
||||
|
this._container.alpha = 1; |
||||
|
this._container.scale.set(1, 1); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
this._container.on("mousedown", onPointerDown); |
||||
|
this._container.on("touchstart", onPointerDown); |
||||
|
this._container.on("mouseup", onPointerUp); |
||||
|
this._container.on("touchend", onPointerUp); |
||||
|
this._container.on("mouseupoutside", onPointerUpOutside); |
||||
|
this._container.on("touchendoutside", onPointerUpOutside); |
||||
|
} |
||||
} |
} |
||||
|
|
||||
export default Button |
export default Button; |
||||
Loading…
Reference in new issue