diff --git a/src/components/Button.ts b/src/components/Button.ts index 05d3ef8..e7db33c 100644 --- a/src/components/Button.ts +++ b/src/components/Button.ts @@ -1,159 +1,165 @@ -import { Text, Graphics, Container, TextStyle, NineSlicePlane, Texture, NineSliceSprite, Ticker } from "pixi.js"; - -interface IOpts { - text: string; - autoUpdate: Boolean; - bg: Texture; - pressBg: Texture; - position: null | any; - click(): void; -} +import { + Container, + Text, + Graphics, + TextStyle, + NineSliceSprite, + Ticker, + Texture, +} from "pixi.js"; -const defaultOpts: IOpts = { - autoUpdate: true, - text: "", - bg: null, - position: null, - pressBg: null, - click() { }, -}; - -function getConfig() { - return Object.assign({}, defaultOpts) +export interface ButtonOptions { + text: string; + bg?: Texture; + pressBg?: Texture; + position?: () => { x: number; y: number }; + onClick: () => void; + autoUpdate?: boolean; + padding?: { x: number; y: number }; + fontSize?: number; } export class Button { - config: IOpts - _comp: Container - textObj: Text - bgRect: Graphics - bgNine: NineSliceSprite - padding = { x: 60, y: 40 } - getComp(){ - return this._comp - } - constructor(opts: Partial) { - this.config = getConfig(); - ; (Object.keys(defaultOpts) as (keyof IOpts)[]).forEach((key) => { - if (opts[key] != undefined) { - this.config[key] = opts[key] as any; - } - }); - - this._comp = new Container(); - this._comp.cursor = 'pointer'; - this._comp.interactive = true; - - if (!this.config.bg) { - this.createRect() - this._comp.addChild(this.bgRect) - } 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); + private config: ButtonOptions; + private _container: Container; + private textObj: Text; + private bgRect?: Graphics; + private bgNine?: NineSliceSprite; + private padding: { x: number; y: number }; + + constructor(opts: ButtonOptions) { + this.config = { + autoUpdate: true, + padding: { x: 60, y: 40 }, + fontSize: 30, + ...opts, + }; + this.padding = this.config.padding!; + + this._container = new Container(); + this._container.cursor = "pointer"; + this._container.interactive = true; + + if (!this.config.bg) { + this.createRectBackground(); + } else { + this.createNineSliceBackground(); } - updateView() { - if(this._comp.destroyed) return - let width = this.textObj.width + this.padding.x; - let height = this.textObj.height + this.padding.y; - this._comp.pivot.set(width / 2, height / 2) - this.textObj.x = this.padding.x / 2; - this.textObj.y = this.padding.y / 2 - 2; - - if (this.bgRect) { - this.bgRect.rect(0, 0, width, height); - 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() - } + this.createText(); + this._container.addChild(this.textObj); + + this.setupEvents(); + + if (this.config.autoUpdate) { + const update = () => this.updateView(); + Ticker.shared.add(update); + this._container.on("destroyed", () => { + Ticker.shared.remove(update); + }); } - createNine() { - this.bgNine = new NineSliceSprite({ - texture: this.config.bg, - leftWidth: 10, - topHeight: 10, - rightWidth: 10, - bottomHeight: 10, - }); - this.bgNine.cursor = 'pointer'; - this.bgNine.label = "nine-pic" - this.bgNine.interactive = true; - // plane9.buttonMode = true; + this.updateView(); + } + + get container(): Container { + return this._container; + } + + updateView(): void { + if (this._container.destroyed) return; + + const width = this.textObj.width + this.padding.x; + 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() { - this.bgRect = new Graphics(); - this.bgRect.label = "rect"; - this.bgRect.interactive = true; - this.bgRect.cursor = 'pointer'; - // rect.buttonMode = true; + if (this.bgNine) { + this.bgNine.width = width; + this.bgNine.height = height; } - createText() { - let textStyle = new TextStyle({ - 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" + if (this.config.position) { + this._container.position = this.config.position(); } + } + + 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 \ No newline at end of file +export default Button; \ No newline at end of file