Browse Source

refactor: Button component with full typing

master
npmrun 3 weeks ago
parent
commit
b88d7535fe
  1. 294
      src/components/Button.ts

294
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<IOpts>) {
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
export default Button;
Loading…
Cancel
Save