import TWEEN from '@tweenjs/tween.js';
interface AirWindow extends Window {
air: any;
curCtx: any;
}
declare let window: AirWindow;
class Sprite {
x = 0;
y = 0;
color = '';
radius = 0;
alive = false;
margin = 0;
angle = 0;
ctx;
constructor(ctx = null) {
if (!ctx) {
this.ctx = window.curCtx;
} else {
this.ctx = ctx;
}
}
update($event) {
this.draw();
}
draw() {
}
}
export class MySprite extends Sprite {
_width = 0;
_height = 0;
_anchorX = 0;
_anchorY = 0;
_offX = 0;
_offY = 0;
scaleX = 1;
scaleY = 1;
_alpha = 1;
rotation = 0;
visible = true;
skewX = 0;
skewY = 0;
_shadowFlag = false;
_shadowColor;
_shadowOffsetX = 0;
_shadowOffsetY = 0;
_shadowBlur = 5;
_radius = 0;
children = [this];
childDepandVisible = true;
childDepandAlpha = false;
img;
_z = 0;
_showRect;
_bitmapFlag = false;
_offCanvas;
_offCtx;
init(imgObj = null, anchorX: number = 0.5, anchorY: number = 0.5) {
if (imgObj) {
this.img = imgObj;
this.width = this.img.width;
this.height = this.img.height;
}
this.anchorX = anchorX;
this.anchorY = anchorY;
}
setShowRect(rect) {
this._showRect = rect;
}
setShadow(offX, offY, blur, color = 'rgba(0, 0, 0, 0.3)') {
this._shadowFlag = true;
this._shadowColor = color;
this._shadowOffsetX = offX;
this._shadowOffsetY = offY;
this._shadowBlur = blur;
}
setRadius(r) {
this._radius = r;
}
update($event = null) {
if (!this.visible && this.childDepandVisible) {
return;
}
this.draw();
}
draw() {
this.ctx.save();
this.drawInit();
this.updateChildren();
this.ctx.restore();
}
drawInit() {
this.ctx.translate(this.x, this.y);
this.ctx.rotate(this.rotation * Math.PI / 180);
this.ctx.scale(this.scaleX, this.scaleY);
this.ctx.globalAlpha = this.alpha;
this.ctx.transform(1, this.skewX, this.skewY, 1, 0, 0);
//
// if (this._radius) {
//
// const r = this._radius;
// const w = this.width;
// const h = this.height;
//
// this.ctx.lineTo(-w / 2, h / 2); // 创建水平线
// this.ctx.arcTo(-w / 2, -h / 2, -w / 2 + r, -h / 2, r);
// this.ctx.arcTo(w / 2, -h / 2, w / 2, -h / 2 + r, r);
// this.ctx.arcTo(w / 2, h / 2, w / 2 - r, h / 2, r);
// this.ctx.arcTo(-w / 2, h / 2, -w / 2, h / 2 - r, r);
//
// this.ctx.clip();
// }
}
drawSelf() {
if (this._shadowFlag) {
this.ctx.shadowOffsetX = this._shadowOffsetX;
this.ctx.shadowOffsetY = this._shadowOffsetY;
this.ctx.shadowBlur = this._shadowBlur;
this.ctx.shadowColor = this._shadowColor;
} else {
this.ctx.shadowOffsetX = 0;
this.ctx.shadowOffsetY = 0;
this.ctx.shadowBlur = null;
this.ctx.shadowColor = null;
}
if (this.img) {
if (this._showRect) {
const rect = this._showRect;
this.ctx.drawImage(this.img, rect.x, rect.y, rect.width, rect.height, this._offX, this._offY + rect.y, this.width, rect.height);
} else {
this.ctx.drawImage(this.img, this._offX, this._offY);
}
}
}
updateChildren() {
if (this.children.length <= 0) { return; }
for (const child of this.children) {
if (child === this) {
if (this.visible) {
this.drawSelf();
}
} else {
child.update();
}
}
}
load(url, anchorX = 0.5, anchorY = 0.5) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => resolve(img);
img.onerror = reject;
img.src = url;
}).then(img => {
this.init(img, anchorX, anchorY);
return img;
});
}
addChild(child, z = 1) {
if (this.children.indexOf(child) === -1) {
this.children.push(child);
child._z = z;
child.parent = this;
}
this.children.sort((a, b) => {
return a._z - b._z;
});
if (this.childDepandAlpha) {
child.alpha = this.alpha;
}
}
removeChild(child) {
const index = this.children.indexOf(child);
if (index !== -1) {
this.children.splice(index, 1);
}
}
removeChildren() {
for (let i = 0; i < this.children.length; i++) {
if (this.children[i]) {
if (this.children[i] !== this) {
this.children.splice(i, 1);
i --;
}
}
}
}
_changeChildAlpha(alpha) {
for (const child of this.children) {
if (child !== this) {
child.alpha = alpha;
}
}
}
set btimapFlag(v) {
this._bitmapFlag = v;
}
get btimapFlag() {
return this._bitmapFlag;
}
set alpha(v) {
this._alpha = v;
if (this.childDepandAlpha) {
this._changeChildAlpha(v);
}
}
get alpha() {
return this._alpha;
}
set width(v) {
this._width = v;
this.refreshAnchorOff();
}
get width() {
return this._width;
}
set height(v) {
this._height = v;
this.refreshAnchorOff();
}
get height() {
return this._height;
}
set anchorX(value) {
this._anchorX = value;
this.refreshAnchorOff();
}
get anchorX() {
return this._anchorX;
}
set anchorY(value) {
this._anchorY = value;
this.refreshAnchorOff();
}
get anchorY() {
return this._anchorY;
}
refreshAnchorOff() {
this._offX = -this._width * this.anchorX;
this._offY = -this._height * this.anchorY;
}
setScaleXY(value) {
this.scaleX = this.scaleY = value;
}
getBoundingBox() {
const getParentData = (item) => {
let px = item.x;
let py = item.y;
let sx = item.scaleX;
let sy = item.scaleY;
const parent = item.parent;
if (parent) {
const obj = getParentData(parent);
const _x = obj.px;
const _y = obj.py;
const _sx = obj.sx;
const _sy = obj.sy;
px = _x + item.x * _sx;
py = _y + item.y * _sy;
sx *= _sx;
sy *= _sy;
}
return {px, py, sx, sy};
};
const data = getParentData(this);
const x = data.px + this._offX * Math.abs(data.sx);
const y = data.py + this._offY * Math.abs(data.sy);
const width = this.width * Math.abs(data.sx);
const height = this.height * Math.abs(data.sy);
return {x, y, width, height};
}
}
export class RoundSprite extends MySprite {
_newCtx;
init(imgObj = null, anchorX: number = 0.5, anchorY: number = 0.5) {
if (imgObj) {
this.img = imgObj;
this.width = this.img.width;
this.height = this.img.height;
}
this.anchorX = anchorX;
this.anchorY = anchorY;
const canvas = window['curCanvas'];
const w = canvas.nativeElement.width;
const h = canvas.nativeElement.height;
this._offCanvas = document.createElement('canvas');
this._offCanvas.width = w;
this._offCanvas.height = h;
this._offCtx = this._offCanvas.getContext('2d');
// this._newCtx = this.ctx;
// this.ctx = this._offCtx;
}
drawSelf() {
//
// if (this._shadowFlag) {
//
// this.ctx.shadowOffsetX = this._shadowOffsetX;
// this.ctx.shadowOffsetY = this._shadowOffsetY;
// this.ctx.shadowBlur = this._shadowBlur;
// this.ctx.shadowColor = this._shadowColor;
// } else {
// this.ctx.shadowOffsetX = 0;
// this.ctx.shadowOffsetY = 0;
// this.ctx.shadowBlur = null;
// this.ctx.shadowColor = null;
// }
if (this._radius) {
const r = this._radius;
const w = this.width;
const h = this.height;
const x = -this._offX;
const y = -this._offY;
this._offCtx.lineTo(x - w / 2, y + h / 2); // 创建水平线
this._offCtx.arcTo(x - w / 2, y - h / 2, x - w / 2 + r, y - h / 2, r);
this._offCtx.arcTo(x + w / 2, y - h / 2, x + w / 2, y - h / 2 + r, r);
this._offCtx.arcTo(x + w / 2, y + h / 2, x + w / 2 - r, y + h / 2, r);
this._offCtx.arcTo(x - w / 2, y + h / 2, x - w / 2, y + h / 2 - r, r);
this._offCtx.clip();
}
if (this.img) {
this._offCtx.drawImage(this.img, 0, 0);
this.ctx.drawImage(this._offCanvas,this._offX, this._offX);
}
}
}
export class ColorSpr extends MySprite {
r = 0;
g = 0;
b = 0;
createGSCanvas() {
if (!this.img) {
return;
}
const rect = this.getBoundingBox();
if (rect.width <= 1 || rect.height <= 1) {
return;
}
const c = this.ctx.getImageData(rect.x, rect.y, rect.width, rect.height);
for ( let i = 0; i < c.height; i++) {
for ( let j = 0; j < c.width; j++) {
const x = (i * 4) * c.width + ( j * 4 );
const r = c.data[x];
const g = c.data[x + 1];
const b = c.data[x + 2];
c.data[x] = this.r;
c.data[x + 1] = this.g;
c.data[x + 2] = this.b;
// c.data[x] = c.data[x + 1] = c.data[x + 2] = (r + g + b) / 3 ;
// // c.data[x + 3] = 255;
}
}
this.ctx.putImageData(c, rect.x, rect.y, 0, 0, rect.width, rect.height);
}
drawSelf() {
super.drawSelf();
this.createGSCanvas();
}
}
export class GrayscaleSpr extends MySprite {
grayScale = 120;
createGSCanvas() {
if (!this.img) {
return;
}
const rect = this.getBoundingBox();
const c = this.ctx.getImageData(rect.x, rect.y, rect.width, rect.height);
for ( let i = 0; i < c.height; i++) {
for ( let j = 0; j < c.width; j++) {
const x = (i * 4) * c.width + ( j * 4 );
const r = c.data[x];
const g = c.data[x + 1];
const b = c.data[x + 2];
// const a = c.data[x + 3];
c.data[x] = c.data[x + 1] = c.data[x + 2] = this.grayScale; // (r + g + b) / 3;
// c.data[x + 3] = 255;
}
}
this.ctx.putImageData(c, rect.x, rect.y, 0, 0, rect.width, rect.height);
}
drawSelf() {
super.drawSelf();
this.createGSCanvas();
}
}
export class BitMapLabel extends MySprite {
labelArr;
baseUrl;
setText(data, text) {
this.labelArr = [];
const labelArr = [];
const tmpArr = text.split('');
let totalW = 0;
let h = 0;
for (const tmp of tmpArr) {
const label = new MySprite(this.ctx);
label.init(data[tmp], 0);
this.addChild(label);
labelArr.push(label);
totalW += label.width;
h = label.height;
}
this.width = totalW;
this.height = h;
let offX = -totalW / 2;
for (const label of labelArr) {
label.x = offX;
offX += label.width;
}
this.labelArr = labelArr;
}
}
export class Label extends MySprite {
private _text: string;
// fontSize:String = '40px';
fontName = 'Verdana';
textAlign = 'left';
fontSize = 40;
fontColor = '#000000';
fontWeight = 900;
_maxWidth;
outline = 0;
outlineColor = '#ffffff';
// _shadowFlag = false;
// _shadowColor;
// _shadowOffsetX;
// _shadowOffsetY;
// _shadowBlur;
_outlineFlag = false;
_outLineWidth;
_outLineColor;
constructor(ctx = null) {
super(ctx);
this.init();
}
get text(): string {
return this._text;
}
set text(value: string) {
this._text = value;
this.refreshSize();
}
refreshSize() {
this.ctx.save();
this.ctx.font = `${this.fontSize * this.scaleX}px ${this.fontName}`;
this.ctx.textAlign = this.textAlign;
this.ctx.textBaseline = 'middle';
this.ctx.fontWeight = this.fontWeight;
this._width = this.ctx.measureText(this.text).width;
this._height = this.fontSize;
this.refreshAnchorOff();
this.ctx.restore();
}
setMaxSize(w) {
this._maxWidth = w;
this.refreshSize();
if (this.width >= w) {
this.scaleX *= w / this.width;
this.scaleY *= w / this.width;
}
}
show(callBack = null) {
this.visible = true;
if (this.alpha >= 1) {
return;
}
const tween = new TWEEN.Tween(this)
.to({ alpha: 1 }, 800)
// .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.
.onComplete(() => {
if (callBack) {
callBack();
}
})
.start(); // Start the tween immediately.
}
setOutline(width = 5, color = '#ffffff') {
this._outlineFlag = true;
this._outLineWidth = width;
this._outLineColor = color;
}
drawText() {
if (!this.text) { return; }
this.ctx.font = `${this.fontSize}px ${this.fontName}`;
this.ctx.textAlign = this.textAlign;
this.ctx.textBaseline = 'middle';
this.ctx.fontWeight = this.fontWeight;
if (this._outlineFlag) {
this.ctx.lineWidth = this._outLineWidth;
this.ctx.strokeStyle = this._outLineColor;
this.ctx.strokeText(this.text, 0, 0);
}
this.ctx.fillStyle = this.fontColor;
if (this.outline > 0) {
this.ctx.lineWidth = this.outline;
this.ctx.strokeStyle = this.outlineColor;
this.ctx.strokeText(this.text, 0, 0);
}
this.ctx.fillText(this.text, 0, 0);
}
drawSelf() {
super.drawSelf();
this.drawText();
}
}
export class RichTextOld extends Label {
textArr = [];
fontSize = 40;
setText(text: string, words) {
let newText = text;
for (const word of words) {
const re = new RegExp(word, 'g');
newText = newText.replace( re, `#${word}#`);
// newText = newText.replace(word, `#${word}#`);
}
this.textArr = newText.split('#');
this.text = newText;
// this.setSize();
}
refreshSize() {
this.ctx.save();
this.ctx.font = `${this.fontSize}px ${this.fontName}`;
this.ctx.textAlign = this.textAlign;
this.ctx.textBaseline = 'middle';
this.ctx.fontWeight = this.fontWeight;
let curX = 0;
for (const text of this.textArr) {
const w = this.ctx.measureText(text).width;
curX += w;
}
this.width = curX;
this.height = this.fontSize;
this.refreshAnchorOff();
this.ctx.restore();
}
show(callBack = null) {
// console.log(' in show ');
this.visible = true;
// this.alpha = 0;
const tween = new TWEEN.Tween(this)
.to({ alpha: 1 }, 800)
// .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.
.onComplete(() => {
if (callBack) {
callBack();
}
})
.start(); // Start the tween immediately.
}
drawText() {
// console.log('in drawText', this.text);
if (!this.text) { return; }
this.ctx.font = `${this.fontSize}px ${this.fontName}`;
this.ctx.textAlign = this.textAlign;
this.ctx.textBaseline = 'middle';
this.ctx.fontWeight = 900;
this.ctx.lineWidth = 5;
this.ctx.strokeStyle = '#ffffff';
// this.ctx.strokeText(this.text, 0, 0);
this.ctx.fillStyle = '#000000';
// this.ctx.fillText(this.text, 0, 0);
let curX = 0;
for (let i = 0; i < this.textArr.length; i++) {
const w = this.ctx.measureText(this.textArr[i]).width;
if ((i + 1) % 2 === 0) {
this.ctx.fillStyle = '#c8171e';
} else {
this.ctx.fillStyle = '#000000';
}
this.ctx.fillText(this.textArr[i], curX, 0);
curX += w;
}
}
}
export class RichText extends Label {
disH = 30;
constructor(ctx?: any) {
super(ctx);
// this.dataArr = dataArr;
}
drawText() {
if (!this.text) {
return;
}
this.ctx.font = `${this.fontSize}px ${this.fontName}`;
this.ctx.textAlign = this.textAlign;
this.ctx.textBaseline = 'middle';
this.ctx.fontWeight = this.fontWeight;
this.ctx.fillStyle = this.fontColor;
const selfW = this.width * this.scaleX;
const chr = this.text.split(' ');
let temp = '';
const row = [];
const w = selfW - 80;
const disH = (this.fontSize + this.disH) * this.scaleY;
for (const c of chr) {
if (this.ctx.measureText(temp).width < w && this.ctx.measureText(temp + (c)).width <= w) {
temp += ' ' + c;
} else {
row.push(temp);
temp = ' ' + c;
}
}
row.push(temp);
const x = 0;
const y = -row.length * disH / 2;
// for (let b = 0 ; b < row.length; b++) {
// this.ctx.strokeText(row[b], x, y + ( b + 1 ) * disH ); // 每行字体y坐标间隔20
// }
if (this._outlineFlag) {
this.ctx.lineWidth = this._outLineWidth;
this.ctx.strokeStyle = this._outLineColor;
for (let b = 0 ; b < row.length; b++) {
this.ctx.strokeText(row[b], x, y + ( b + 1 ) * disH ); // 每行字体y坐标间隔20
}
// this.ctx.strokeText(this.text, 0, 0);
}
// this.ctx.fillStyle = '#ff7600';
for (let b = 0 ; b < row.length; b++) {
this.ctx.fillText(row[b], x, y + ( b + 1 ) * disH ); // 每行字体y坐标间隔20
}
}
drawSelf() {
super.drawSelf();
this.drawText();
}
}
export class LineRect extends MySprite {
lineColor = '#ffffff';
lineWidth = 10;
setSize(w, h) {
this.width = w;
this.height = h;
}
drawLine() {
this.ctx.beginPath();
this.ctx.moveTo(this._offX, this._offY);
this.ctx.lineTo(this._offX + this.width, this._offY);
this.ctx.lineTo(this._offX + this.width, this._offY + this.height);
this.ctx.lineTo(this._offX, this._offY + this.height);
this.ctx.closePath();
this.ctx.lineWidth = this.lineWidth;
// this.ctx.fillStyle = "rgb(2,33,42)"; //指定填充颜色
// this.ctx.fill(); //对多边形进行填充
this.ctx.strokeStyle = this.lineColor; // "#ffffff";
this.ctx.stroke();
}
drawSelf() {
super.drawSelf();
this.drawLine();
}
}
export class ShapeRect extends MySprite {
fillColor = '#FF0000';
setSize(w, h) {
this.width = w;
this.height = h;
// console.log('w:', w);
// console.log('h:', h);
}
drawShape() {
this.ctx.fillStyle = this.fillColor;
this.ctx.fillRect(this._offX, this._offY, this.width, this.height);
}
drawSelf() {
super.drawSelf();
this.drawShape();
}
}
export class Line extends MySprite {
lineWidth = 5;
lineColor = '#000000';
_pointArr = [];
roundFlag = true;
_pointS = 1;
imgObj;
bitMap;
_offCtx;
_offCanvas;
lastPointIndex = 0;
init() {
const canvas = window['curCanvas'];
const w = canvas.nativeElement.width;
const h = canvas.nativeElement.height;
console.log('w: ', w);
console.log('h: ', h);
this._offCanvas = document.createElement('canvas');
this._offCanvas.width = w;
this._offCanvas.height = h;
// this._offCanvas = _offCanvas;
// this._offCtx = this._offCanvas.getContext('2d');
// this._offCanvas = new OffscreenCanvas(w, h);
this._offCtx = this._offCanvas.getContext('2d');
}
addPoint(x, y) {
this._pointArr.push([x, y]);
if (this._pointArr.length < 2) {
return;
}
//
// const lastP = this._pointArr[this._pointArr.length - 1];
//
//
// const context = this._offCtx;
// context.moveTo (lastP[0], lastP[1]); // 设置起点状态
// context.lineTo (x, y); // 设置末端状态
//
// context.lineWidth = this.lineWidth; //设置线宽状态
// context.strokeStyle = this.lineColor;
// context.stroke();
//
//
// this.bitMap = this._offCanvas.transferToImageBitmap();
// const tmpLine = new MySprite(this._offCtx);
// tmpLine.init(this.imgObj);
// tmpLine.anchorY = 1;
// tmpLine.anchorX = 0.5;
// tmpLine.x = lastP[0];
// tmpLine.y = lastP[1];
//
// const disH = getPosDistance(lastP[0], lastP[1], x, y);
// tmpLine.scaleX = this.lineWidth / tmpLine.width;
// tmpLine.scaleY = disH / tmpLine.height * 1.1;
//
// const angle = getAngleByPos(lastP[0], lastP[1], x, y);
// tmpLine.rotation = angle;
//
// this.addChild(tmpLine);
}
setPointArr(arr, imgObj) {
this.removeChildren();
if (arr.length < 2) {
return;
}
let p1 = arr[0];
let p2;
for (let i = 1; i < arr.length; i++) {
p2 = arr[i];
const tmpLine = new MySprite();
tmpLine.init(imgObj);
tmpLine.anchorY = 1;
tmpLine.anchorX = 0.5;
tmpLine.x = p1[0];
tmpLine.y = p1[1];
const disH = getPosDistance(p1[0], p1[1], p2[0], p2[1]);
tmpLine.scaleX = this.lineWidth / tmpLine.width;
tmpLine.scaleY = disH / tmpLine.height * 1.1;
const angle = getAngleByPos(p1[0], p1[1], p2[0], p2[1]);
tmpLine.rotation = angle;
this.addChild(tmpLine);
p1 = p2;
}
}
drawLine() {
if (this._pointArr.length < 2) {
return;
}
const curMaxPointIndex = this._pointArr.length - 1;
if (curMaxPointIndex > this.lastPointIndex) {
const arr = this._pointArr;
const context = this._offCtx;
context.moveTo (arr[this.lastPointIndex][0] * this._pointS, arr[this.lastPointIndex][1] * this._pointS); // 设置起点状态
for (let i = this.lastPointIndex + 1; i < arr.length; i++) {
context.lineTo (arr[i][0] * this._pointS, arr[i][1] * this._pointS); // 设置末端状态
}
if (this.roundFlag) {
context.lineCap = "round";
}
context.lineWidth = this.lineWidth; //设置线宽状态
context.strokeStyle = this.lineColor;
context.stroke();
this.lastPointIndex = curMaxPointIndex;
// this.bitMap = this._offCanvas.transferToImageBitmap();
}
// this.ctx.drawImage(this.bitMap, this._offX, this._offY);
this.ctx.drawImage(this._offCanvas, this._offX, this._offY);
}
drawSelf() {
super.drawSelf();
this.drawLine();
// if (this.img) {
// this.ctx.drawImage(this._offCanvas, 0, 0, this.width, this.height);
// }
// if (this.bitMap) {
// this.bitMap = this._offCanvas.transferToImageBitmap();
// this.ctx.drawImage(this.bitMap, 0, 0, this.width, this.height);
// }
}
}
export class ShapeCircle extends MySprite {
fillColor = '#FF0000';
radius = 0;
setRadius(r) {
this.anchorX = this.anchorY = 0.5;
this.radius = r;
this.width = r * 2;
this.height = r * 2;
}
drawShape() {
this.ctx.beginPath();
this.ctx.fillStyle = this.fillColor;
this.ctx.arc(0, 0, this.radius, 0, angleToRadian(360));
this.ctx.fill();
}
drawSelf() {
super.drawSelf();
this.drawShape();
}
}
export class ShapeRectNew extends MySprite {
radius = 0;
fillColor = '#ffffff';
strokeColor = '#000000';
fill = true;
stroke = false;
lineWidth = 1;
setSize(w, h, r) {
this.width = w;
this.height = h;
this.radius = r;
}
setOutLine(color, lineWidth) {
this.stroke = true;
this.strokeColor = color;
this.lineWidth = lineWidth;
}
drawShape() {
const ctx = this.ctx;
const width = this.width;
const height = this.height;
const radius = this.radius;
ctx.save();
ctx.beginPath(0);
// 从右下角顺时针绘制,弧度从0到1/2PI
ctx.arc(width - radius, height - radius, radius, 0, Math.PI / 2);
// 矩形下边线
ctx.lineTo(radius, height);
// 左下角圆弧,弧度从1/2PI到PI
ctx.arc(radius, height - radius, radius, Math.PI / 2, Math.PI);
// 矩形左边线
ctx.lineTo(0, radius);
// 左上角圆弧,弧度从PI到3/2PI
ctx.arc(radius, radius, radius, Math.PI, Math.PI * 3 / 2);
// 上边线
ctx.lineTo(width - radius, 0);
// 右上角圆弧
ctx.arc(width - radius, radius, radius, Math.PI * 3 / 2, Math.PI * 2);
// 右边线
ctx.lineTo(width, height - radius);
ctx.closePath();
if (this.fill) {
ctx.fillStyle = this.fillColor;
ctx.fill();
}
if (this.stroke) {
ctx.lineWidth = this.lineWidth;
ctx.strokeStyle = this.strokeColor;
ctx.stroke();
}
ctx.restore();
}
drawSelf() {
super.drawSelf();
this.drawShape();
}
}
export class MyAnimation extends MySprite {
frameArr = [];
frameIndex = 0;
playFlag = false;
lastDateTime;
curDelay = 0;
loop = false;
playEndFunc;
delayPerUnit = 1;
restartFlag = false;
reverseFlag = false;
addFrameByImg(img) {
const spr = new MySprite(this.ctx);
spr.init(img);
this._refreshSize(img);
spr.visible = false;
this.addChild(spr);
this.frameArr.push(spr);
this.frameArr[this.frameIndex].visible = true;
}
addFrameByUrl(url) {
const spr = new MySprite(this.ctx);
spr.load(url).then(img => {
this._refreshSize(img);
});
spr.visible = false;
this.addChild(spr);
this.frameArr.push(spr);
this.frameArr[this.frameIndex].visible = true;
}
_refreshSize(img: any) {
if (this.width < img.width) {
this.width = img.width;
}
if (this.height < img.height) {
this.height = img.height;
}
}
play() {
this.playFlag = true;
this.lastDateTime = new Date().getTime();
}
stop() {
this.playFlag = false;
}
replay() {
this.restartFlag = true;
this.play();
}
reverse() {
this.reverseFlag = !this.reverseFlag;
this.frameArr.reverse();
this.frameIndex = 0;
}
showAllFrame() {
for (const frame of this.frameArr ) {
frame.alpha = 1;
}
}
hideAllFrame() {
for (const frame of this.frameArr) {
frame.alpha = 0;
}
}
playEnd() {
this.playFlag = false;
this.curDelay = 0;
this.frameArr[this.frameIndex].visible = true;
if (this.playEndFunc) {
this.playEndFunc();
this.playEndFunc = null;
}
}
updateFrame() {
if (this.frameArr[this.frameIndex]) {
this.frameArr[this.frameIndex].visible = false;
}
this.frameIndex ++;
if (this.frameIndex >= this.frameArr.length) {
if (this.loop) {
this.frameIndex = 0;
} else if (this.restartFlag) {
this.restartFlag = false;
this.frameIndex = 0;
} else {
this.frameIndex -- ;
this.playEnd();
return;
}
}
this.frameArr[this.frameIndex].visible = true;
}
_updateDelay(delay) {
this.curDelay += delay;
if (this.curDelay < this.delayPerUnit) {
return;
}
this.curDelay -= this.delayPerUnit;
this.updateFrame();
}
_updateLastDate() {
if (!this.playFlag) { return; }
let delay = 0;
if (this.lastDateTime) {
delay = (new Date().getTime() - this.lastDateTime) / 1000;
}
this.lastDateTime = new Date().getTime();
this._updateDelay(delay);
}
update($event: any = null) {
super.update($event);
this._updateLastDate();
}
}
// --------=========== util func =============-------------
export function tweenChange(item, obj, time = 0.8, callBack = null, easing = null, update = null) {
const tween = new TWEEN.Tween(item).to(obj, time * 1000);
if (callBack) {
tween.onComplete(() => {
callBack();
});
}
if (easing) {
tween.easing(easing);
}
if (update) {
tween.onUpdate( (a, b) => {
update(a, b);
});
}
tween.start();
return tween;
}
export function rotateItem(item, rotation, time = 0.8, callBack = null, easing = null) {
const tween = new TWEEN.Tween(item).to({ rotation }, time * 1000);
if (callBack) {
tween.onComplete(() => {
callBack();
});
}
if (easing) {
tween.easing(easing);
}
tween.start();
}
export function scaleItem(item, scale, time = 0.8, callBack = null, easing = null) {
const tween = new TWEEN.Tween(item).to({ scaleX: scale, scaleY: scale}, time * 1000);
if (callBack) {
tween.onComplete(() => {
callBack();
});
}
if (easing) {
tween.easing(easing);
}
tween.start();
return tween;
}
export function moveItem(item, x, y, time = 0.8, callBack = null, easing = null) {
const tween = new TWEEN.Tween(item).to({ x, y}, time * 1000);
if (callBack) {
tween.onComplete(() => {
callBack();
});
}
if (easing) {
tween.easing(easing);
}
tween.start();
return tween;
}
export function endShow(item, s = 1) {
item.scaleX = item.scaleY = 0;
item.alpha = 0;
const tween = new TWEEN.Tween(item)
.to({ alpha: 1, scaleX: s, scaleY: s }, 800)
.easing(TWEEN.Easing.Elastic.Out) // Use an easing function to make the animation smooth.
.onComplete(() => {
})
.start();
}
export function hideItem(item, time = 0.8, callBack = null, easing = null) {
if (item.alpha === 0) {
return;
}
const tween = new TWEEN.Tween(item)
.to({alpha: 0}, time * 1000)
// .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.
.onComplete(() => {
if (callBack) {
callBack();
}
});
if (easing) {
tween.easing(easing);
}
tween.start();
}
export function showItem(item, time = 0.8, callBack = null, easing = null) {
if (item.alpha === 1) {
if (callBack) {
callBack();
}
return;
}
item.visible = true;
const tween = new TWEEN.Tween(item)
.to({alpha: 1}, time * 1000)
// .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.
.onComplete(() => {
if (callBack) {
callBack();
}
});
if (easing) {
tween.easing(easing);
}
tween.start();
}
export function alphaItem(item, alpha, time = 0.8, callBack = null, easing = null) {
const tween = new TWEEN.Tween(item)
.to({alpha}, time * 1000)
// .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.
.onComplete(() => {
if (callBack) {
callBack();
}
});
if (easing) {
tween.easing(easing);
}
tween.start();
}
export function showStar(item, time = 0.8, callBack = null, easing = null) {
const tween = new TWEEN.Tween(item)
.to({alpha: 1, scale: 1}, time * 1000)
// .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.
.onComplete(() => {
if (callBack) {
callBack();
}
});
if (easing) {
tween.easing(easing);
}
tween.start();
}
export function randomSortByArr(arr) {
if (!arr) {
return;
}
const newArr = [];
const tmpArr = arr.concat();
while (tmpArr.length > 0) {
const randomIndex = Math.floor( tmpArr.length * Math.random() );
newArr.push(tmpArr[randomIndex]);
tmpArr.splice(randomIndex, 1);
}
return newArr;
}
export function radianToAngle(radian) {
return radian * 180 / Math.PI;
// 角度 = 弧度 * 180 / Math.PI;
}
export function angleToRadian(angle) {
return angle * Math.PI / 180;
// 弧度= 角度 * Math.PI / 180;
}
export function getPosByAngle(angle, len) {
const radian = angle * Math.PI / 180;
const x = Math.sin(radian) * len;
const y = Math.cos(radian) * len;
return {x, y};
}
export function getAngleByPos(px, py, mx, my) {
const x = Math.abs(px - mx);
const y = Math.abs(py - my);
const z = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
const cos = y / z;
const radina = Math.acos(cos); // 用反三角函数求弧度
let angle = Math.floor(180 / (Math.PI / radina) * 100) / 100; // 将弧度转换成角度
if (mx > px && my > py) {// 鼠标在第四象限
angle = 180 - angle;
}
if (mx === px && my > py) {// 鼠标在y轴负方向上
angle = 180;
}
if (mx > px && my === py) {// 鼠标在x轴正方向上
angle = 90;
}
if (mx < px && my > py) {// 鼠标在第三象限
angle = 180 + angle;
}
if (mx < px && my === py) {// 鼠标在x轴负方向
angle = 270;
}
if (mx < px && my < py) {// 鼠标在第二象限
angle = 360 - angle;
}
// console.log('angle: ', angle);
return angle;
}
export function removeItemFromArr(arr, item) {
const index = arr.indexOf(item);
if (index !== -1) {
arr.splice(index, 1);
}
}
export function circleMove(item, x0, y0, time = 2, addR = 360, xPer = 1, yPer = 1, callBack = null, easing = null) {
const r = getPosDistance(item.x, item.y, x0, y0);
let a = getAngleByPos(item.x, item.y, x0, y0);
a += 90;
const obj = {r, a};
item._circleAngle = a;
const targetA = a + addR;
const tween = new TWEEN.Tween(item).to({_circleAngle: targetA}, time * 1000);
if (callBack) {
tween.onComplete(() => {
callBack();
});
}
if (easing) {
tween.easing(easing);
}
tween.onUpdate( (item, progress) => {
// console.log(item._circleAngle);
const r = obj.r;
const a = item._circleAngle;
const x = x0 + r * xPer * Math.cos(a * Math.PI / 180);
const y = y0 + r * yPer * Math.sin(a * Math.PI / 180);
item.x = x;
item.y = y;
// obj.a ++;
});
tween.start();
}
export function getPosDistance(sx, sy, ex, ey) {
const _x = ex - sx;
const _y = ey - sy;
const len = Math.sqrt( Math.pow(_x, 2) + Math.pow(_y, 2) );
return len;
}
export function delayCall(callback, second) {
const tween = new TWEEN.Tween(this)
.delay(second * 1000)
.onComplete(() => {
if (callback) {
callback();
}
})
.start();
}
export function formatTime(fmt, date) {
// "yyyy-MM-dd HH:mm:ss";
const o = {
'M+': date.getMonth() + 1, // 月份
'd+': date.getDate(), // 日
'h+': date.getHours(), // 小时
'm+': date.getMinutes(), // 分
's+': date.getSeconds(), // 秒
'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
S: date.getMilliseconds() // 毫秒
};
if (/(y+)/.test(fmt)) { fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length)); }
for (const k in o) {
if (new RegExp('(' + k + ')').test(fmt)) { fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1)
? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)));
}
}
return fmt;
}
export function getMinScale(item, maxLen) {
const sx = maxLen / item.width;
const sy = maxLen / item.height;
const minS = Math.min(sx, sy);
return minS;
}
export function jelly(item, time = 0.7) {
if (item.jellyTween) {
TWEEN.remove(item.jellyTween);
}
const t = time / 9;
const baseSX = item.scaleX;
const baseSY = item.scaleY;
let index = 0;
const run = () => {
if (index >= arr.length) {
item.jellyTween = null;
return;
}
const data = arr[index];
const t = tweenChange(item, {scaleX: data[0], scaleY: data[1]}, data[2], () => {
index ++;
run();
}, TWEEN.Easing.Sinusoidal.InOut);
item.jellyTween = t;
};
const arr = [
[baseSX * 1.1, baseSY * 0.9, t],
[baseSX * 0.98, baseSY * 1.02, t * 2],
[baseSX * 1.02, baseSY * 0.98, t * 2],
[baseSX * 0.99, baseSY * 1.01, t * 2],
[baseSX * 1.0, baseSY * 1.0, t * 2],
];
run();
}
export function showPopParticle(img, pos, parent, num = 20, minLen = 40, maxLen = 80, showTime = 0.4) {
for (let i = 0; i < num; i ++) {
const particle = new MySprite();
particle.init(img);
particle.x = pos.x;
particle.y = pos.y;
parent.addChild(particle);
const randomR = 360 * Math.random();
particle.rotation = randomR;
const randomS = 0.3 + Math.random() * 0.7;
particle.setScaleXY(randomS * 0.3);
const randomX = Math.random() * 20 - 10;
particle.x += randomX;
const randomY = Math.random() * 20 - 10;
particle.y += randomY;
const randomL = minLen + Math.random() * (maxLen - minLen);
const randomA = 360 * Math.random();
const randomT = getPosByAngle(randomA, randomL);
moveItem(particle, particle.x + randomT.x, particle.y + randomT.y, showTime, () => {
}, TWEEN.Easing.Exponential.Out);
// scaleItem(particle, 0, 0.6, () => {
//
// });
scaleItem(particle, randomS, 0.6, () => {
}, TWEEN.Easing.Exponential.Out);
setTimeout(() => {
hideItem(particle, 0.4, () => {
}, TWEEN.Easing.Cubic.In);
}, showTime * 0.5 * 1000);
}
}
export function shake(item, time = 0.5, callback = null, rate = 1) {
if (item.shakeTween) {
return;
}
item.shakeTween = true;
const offX = 15 * item.scaleX * rate;
const offY = 15 * item.scaleX * rate;
const baseX = item.x;
const baseY = item.y;
const easing = TWEEN.Easing.Sinusoidal.InOut;
const move4 = () => {
moveItem(item, baseX, baseY, time / 4, () => {
item.shakeTween = false;
if (callback) {
callback();
}
}, easing);
};
const move3 = () => {
moveItem(item, baseX + offX / 4, baseY + offY / 4, time / 4, () => {
move4();
}, easing);
};
const move2 = () => {
moveItem(item, baseX - offX / 4 * 3, baseY - offY / 4 * 3, time / 4, () => {
move3();
}, easing);
};
const move1 = () => {
moveItem(item, baseX + offX, baseY + offY, time / 7.5, () => {
move2();
}, easing);
};
move1();
}
// --------------- custom class --------------------
export class HotZoneItem extends MySprite {
lineDashFlag = false;
arrow: MySprite;
label: Label;
title;
arrowTop;
arrowRight;
audio_url;
pic_url;
text;
private _itemType;
private shapeRect: ShapeRect;
get itemType() {
return this._itemType;
}
set itemType(value) {
this._itemType = value;
}
setSize(w, h) {
this.width = w;
this.height = h;
const rect = new ShapeRect(this.ctx);
rect.x = -w / 2;
rect.y = -h / 2;
rect.setSize(w, h);
rect.fillColor = '#ffffff';
rect.alpha = 0.2;
this.addChild(rect);
}
showLabel(text = null) {
if (!this.label) {
this.label = new Label(this.ctx);
this.label.anchorY = 0;
this.label.fontSize = 40;
this.label.textAlign = 'center';
this.addChild(this.label);
// this.label.scaleX = 1 / this.scaleX;
// this.label.scaleY = 1 / this.scaleY;
this.refreshLabelScale();
}
if (text) {
this.label.text = text;
} else if (this.title) {
this.label.text = this.title;
}
this.label.visible = true;
}
hideLabel() {
if (!this.label) { return; }
this.label.visible = false;
}
refreshLabelScale() {
if (this.scaleX == this.scaleY) {
this.label.setScaleXY(1);
}
if (this.scaleX > this.scaleY) {
this.label.scaleX = this.scaleY / this.scaleX;
} else {
this.label.scaleY = this.scaleX / this.scaleY;
}
}
showLineDash() {
this.lineDashFlag = true;
if (this.arrow) {
this.arrow.visible = true;
} else {
this.arrow = new MySprite(this.ctx);
this.arrow.load('assets/common/arrow.png', 1, 0);
this.arrow.setScaleXY(0.06);
this.arrowTop = new MySprite(this.ctx);
this.arrowTop.load('assets/common/arrow_top.png', 0.5, 0);
this.arrowTop.setScaleXY(0.06);
this.arrowRight = new MySprite(this.ctx);
this.arrowRight.load('assets/common/arrow_right.png', 1, 0.5);
this.arrowRight.setScaleXY(0.06);
}
this.showLabel();
}
hideLineDash() {
this.lineDashFlag = false;
if (this.arrow) {
this.arrow.visible = false;
}
this.hideLabel();
}
drawArrow() {
if (!this.arrow) { return; }
const rect = this.getBoundingBox();
this.arrow.x = rect.x + rect.width;
this.arrow.y = rect.y;
this.arrow.update();
this.arrowTop.x = rect.x + rect.width / 2;
this.arrowTop.y = rect.y;
this.arrowTop.update();
this.arrowRight.x = rect.x + rect.width;
this.arrowRight.y = rect.y + rect.height / 2;
this.arrowRight.update();
}
drawFrame() {
this.ctx.save();
const rect = this.getBoundingBox();
const w = rect.width;
const h = rect.height;
const x = rect.x + w / 2;
const y = rect.y + h / 2;
this.ctx.setLineDash([5, 5]);
this.ctx.lineWidth = 2;
this.ctx.strokeStyle = '#1bfff7';
// this.ctx.fillStyle = '#ffffff';
this.ctx.beginPath();
this.ctx.moveTo( x - w / 2, y - h / 2);
this.ctx.lineTo(x + w / 2, y - h / 2);
this.ctx.lineTo(x + w / 2, y + h / 2);
this.ctx.lineTo(x - w / 2, y + h / 2);
this.ctx.lineTo(x - w / 2, y - h / 2);
// this.ctx.fill();
this.ctx.stroke();
this.ctx.restore();
}
draw() {
super.draw();
if (this.lineDashFlag) {
this.drawFrame();
this.drawArrow();
}
}
}
export class HotZoneImg extends MySprite {
drawFrame() {
this.ctx.save();
const rect = this.getBoundingBox();
const w = rect.width;
const h = rect.height;
const x = rect.x + w / 2;
const y = rect.y + h / 2;
this.ctx.setLineDash([5, 5]);
this.ctx.lineWidth = 2;
this.ctx.strokeStyle = '#1bfff7';
this.ctx.beginPath();
this.ctx.moveTo( x - w / 2, y - h / 2);
this.ctx.lineTo(x + w / 2, y - h / 2);
this.ctx.lineTo(x + w / 2, y + h / 2);
this.ctx.lineTo(x - w / 2, y + h / 2);
this.ctx.lineTo(x - w / 2, y - h / 2);
// this.ctx.fill();
this.ctx.stroke();
this.ctx.restore();
}
draw() {
super.draw();
this.drawFrame();
}
}
export class HotZoneLabel extends Label {
drawFrame() {
this.ctx.save();
const rect = this.getBoundingBox();
const w = rect.width / this.scaleX;
const h = this.height * this.scaleY;
const x = this.x;
const y = this.y;
this.ctx.setLineDash([5, 5]);
this.ctx.lineWidth = 2;
this.ctx.strokeStyle = '#1bfff7';
this.ctx.beginPath();
this.ctx.moveTo( x - w / 2, y - h / 2);
this.ctx.lineTo(x + w / 2, y - h / 2);
this.ctx.lineTo(x + w / 2, y + h / 2);
this.ctx.lineTo(x - w / 2, y + h / 2);
this.ctx.lineTo(x - w / 2, y - h / 2);
// this.ctx.fill();
this.ctx.stroke();
this.ctx.restore();
}
draw() {
super.draw();
this.drawFrame();
}
}
export class EditorItem extends MySprite {
lineDashFlag = false;
arrow: MySprite;
label: Label;
text;
showLabel(text = null) {
if (!this.label) {
this.label = new Label(this.ctx);
this.label.anchorY = 0;
this.label.fontSize = 50;
this.label.textAlign = 'center';
this.addChild(this.label);
this.label.setScaleXY(1 / this.scaleX);
}
if (text) {
this.label.text = text;
} else if (this.text) {
this.label.text = this.text;
}
this.label.visible = true;
}
hideLabel() {
if (!this.label) { return; }
this.label.visible = false;
}
showLineDash() {
this.lineDashFlag = true;
if (this.arrow) {
this.arrow.visible = true;
} else {
this.arrow = new MySprite(this.ctx);
this.arrow.load('assets/common/arrow.png', 1, 0);
this.arrow.setScaleXY(0.06);
}
this.showLabel();
}
hideLineDash() {
this.lineDashFlag = false;
if (this.arrow) {
this.arrow.visible = false;
}
this.hideLabel();
}
drawArrow() {
if (!this.arrow) { return; }
const rect = this.getBoundingBox();
this.arrow.x = rect.x + rect.width;
this.arrow.y = rect.y;
this.arrow.update();
}
drawFrame() {
this.ctx.save();
const rect = this.getBoundingBox();
const w = rect.width;
const h = rect.height;
const x = rect.x + w / 2;
const y = rect.y + h / 2;
this.ctx.setLineDash([5, 5]);
this.ctx.lineWidth = 2;
this.ctx.strokeStyle = '#1bfff7';
// this.ctx.fillStyle = '#ffffff';
this.ctx.beginPath();
this.ctx.moveTo( x - w / 2, y - h / 2);
this.ctx.lineTo(x + w / 2, y - h / 2);
this.ctx.lineTo(x + w / 2, y + h / 2);
this.ctx.lineTo(x - w / 2, y + h / 2);
this.ctx.lineTo(x - w / 2, y - h / 2);
// this.ctx.fill();
this.ctx.stroke();
this.ctx.restore();
}
draw() {
super.draw();
if (this.lineDashFlag) {
this.drawFrame();
this.drawArrow();
}
}
}
//
//
// import TWEEN from '@tweenjs/tween.js';
//
//
// class Sprite {
// x = 0;
// y = 0;
// color = '';
// radius = 0;
// alive = false;
// margin = 0;
// angle = 0;
// ctx;
//
// constructor(ctx) {
// this.ctx = ctx;
// }
// update($event) {
// this.draw();
// }
// draw() {
//
// }
//
// }
//
//
//
//
//
// export class MySprite extends Sprite {
//
// width = 0;
// height = 0;
// _anchorX = 0;
// _anchorY = 0;
// _offX = 0;
// _offY = 0;
// scaleX = 1;
// scaleY = 1;
// alpha = 1;
// rotation = 0;
// visible = true;
//
// children = [this];
//
// img;
// _z = 0;
//
//
// init(imgObj = null, anchorX:number = 0.5, anchorY:number = 0.5) {
//
// if (imgObj) {
//
// this.img = imgObj;
//
// this.width = this.img.width;
// this.height = this.img.height;
// }
//
// this.anchorX = anchorX;
// this.anchorY = anchorY;
// }
//
//
//
// update($event = null) {
// if (this.visible) {
// this.draw();
// }
// }
// draw() {
//
// this.ctx.save();
//
// this.drawInit();
//
// this.updateChildren();
//
// this.ctx.restore();
// }
//
// drawInit() {
//
// this.ctx.translate(this.x, this.y);
//
// this.ctx.rotate(this.rotation * Math.PI / 180);
//
// this.ctx.scale(this.scaleX, this.scaleY);
//
// this.ctx.globalAlpha = this.alpha;
//
// }
//
// drawSelf() {
// if (this.img) {
// this.ctx.drawImage(this.img, this._offX, this._offY);
// }
// }
//
// updateChildren() {
//
// if (this.children.length <= 0) { return; }
//
// for (let i = 0; i < this.children.length; i++) {
//
// if (this.children[i] === this) {
//
// this.drawSelf();
// } else {
//
// this.children[i].update();
// }
// }
// }
//
//
// load(url, anchorX = 0.5, anchorY = 0.5) {
//
// return new Promise((resolve, reject) => {
// const img = new Image();
// img.onload = () => resolve(img);
// img.onerror = reject;
// img.src = url;
// }).then(img => {
//
// this.init(img, anchorX, anchorY);
// return img;
// });
// }
//
// addChild(child, z = 1) {
// if (this.children.indexOf(child) === -1) {
// this.children.push(child);
// child._z = z;
// child.parent = this;
// }
//
// this.children.sort((a, b) => {
// return a._z - b._z;
// });
//
// }
// removeChild(child) {
// const index = this.children.indexOf(child);
// if (index !== -1) {
// this.children.splice(index, 1);
// }
// }
//
// set anchorX(value) {
// this._anchorX = value;
// this.refreshAnchorOff();
// }
// get anchorX() {
// return this._anchorX;
// }
// set anchorY(value) {
// this._anchorY = value;
// this.refreshAnchorOff();
// }
// get anchorY() {
// return this._anchorY;
// }
// refreshAnchorOff() {
// this._offX = -this.width * this.anchorX;
// this._offY = -this.height * this.anchorY;
// }
//
// setScaleXY(value) {
// this.scaleX = this.scaleY = value;
// }
//
// getBoundingBox() {
//
// const x = this.x + this._offX * this.scaleX;
// const y = this.y + this._offY * this.scaleY;
// const width = this.width * this.scaleX;
// const height = this.height * this.scaleY;
//
// return {x, y, width, height};
// }
//
// }
//
//
//
//
//
// export class Item extends MySprite {
//
// baseX;
//
// move(targetY, callBack) {
//
// const self = this;
//
// const tween = new TWEEN.Tween(this)
// .to({ y: targetY }, 2500)
// .easing(TWEEN.Easing.Quintic.Out)
// .onComplete(function() {
//
// self.hide(callBack);
// // if (callBack) {
// // callBack();
// // }
// })
// .start();
//
// }
//
// show(callBack = null) {
//
// const tween = new TWEEN.Tween(this)
// .to({ alpha: 1 }, 800)
// // .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.
// .onComplete(function() {
// if (callBack) {
// callBack();
// }
// })
// .start(); // Start the tween immediately.
//
// }
//
// hide(callBack = null) {
//
// const tween = new TWEEN.Tween(this)
// .to({ alpha: 0 }, 800)
// // .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.
// .onComplete(function() {
// if (callBack) {
// callBack();
// }
// })
// .start(); // Start the tween immediately.
// }
//
//
// shake(id) {
//
//
// if (!this.baseX) {
// this.baseX = this.x;
// }
//
// const baseX = this.baseX;
// const baseTime = 50;
// const sequence = [
// {target: {x: baseX + 40 * id}, time: baseTime - 25},
// {target: {x: baseX - 20 * id}, time: baseTime},
// {target: {x: baseX + 10 * id}, time: baseTime},
// {target: {x: baseX - 5 * id}, time: baseTime},
// {target: {x: baseX + 2 * id}, time: baseTime},
// {target: {x: baseX - 1 * id}, time: baseTime},
// {target: {x: baseX}, time: baseTime},
//
// ];
//
//
// const self = this;
//
// function runSequence() {
//
// if (self['shakeTween']) {
// self['shakeTween'].stop();
// }
//
// const tween = new TWEEN.Tween(self);
//
// if (sequence.length > 0) {
// // console.log('sequence.length: ', sequence.length);
// const action = sequence.shift();
// tween.to(action['target'], action['time']);
// tween.onComplete( () => {
// runSequence();
// });
// tween.start();
//
// self['shakeTween'] = tween;
// }
// }
//
// runSequence();
//
// }
//
//
//
// drop(targetY, callBack = null) {
//
// const self = this;
//
// const time = Math.abs(targetY - this.y) * 2.4;
//
// this.alpha = 1;
//
// const tween = new TWEEN.Tween(this)
// .to({ y: targetY }, time)
// .easing(TWEEN.Easing.Cubic.In)
// .onComplete(function() {
//
// // self.hideItem(callBack);
// if (callBack) {
// callBack();
// }
// })
// .start();
//
//
// }
//
//
// }
//
//
// export class EndSpr extends MySprite {
//
// show(s) {
//
// this.scaleX = this.scaleY = 0;
// this.alpha = 0;
//
// const tween = new TWEEN.Tween(this)
// .to({ alpha: 1, scaleX: s, scaleY: s }, 800)
// .easing(TWEEN.Easing.Elastic.Out) // Use an easing function to make the animation smooth.
// .onComplete(function() {
//
// })
// .start(); // Start the tween immediately.
//
// }
// }
//
//
//
// export class ShapeRect extends MySprite {
//
// fillColor = '#FF0000';
//
// setSize(w, h) {
// this.width = w;
// this.height = h;
//
// console.log('w:', w);
// console.log('h:', h);
// }
//
// drawShape() {
//
// this.ctx.fillStyle = this.fillColor;
// this.ctx.fillRect(this._offX, this._offY, this.width, this.height);
//
// }
//
//
// drawSelf() {
// super.drawSelf();
// this.drawShape();
// }
// }
//
//
// export class HotZoneItem extends MySprite {
//
//
// lineDashFlag = false;
// arrow: MySprite;
// label: Label;
// title;
//
// arrowTop;
// arrowRight;
//
// audio_url;
// pic_url;
// text;
// private _itemType;
// private shapeRect: ShapeRect;
//
// get itemType() {
// return this._itemType;
// }
// set itemType(value) {
// this._itemType = value;
// }
//
// setSize(w, h) {
// this.width = w;
// this.height = h;
//
//
// const rect = new ShapeRect(this.ctx);
// rect.x = -w / 2;
// rect.y = -h / 2;
// rect.setSize(w, h);
// rect.fillColor = '#ffffff';
// rect.alpha = 0.2;
// this.addChild(rect);
// }
//
// showLabel(text = null) {
//
//
// if (!this.label) {
// this.label = new Label(this.ctx);
// this.label.anchorY = 0;
// this.label.fontSize = '40px';
// this.label.textAlign = 'center';
// this.addChild(this.label);
// // this.label.scaleX = 1 / this.scaleX;
// // this.label.scaleY = 1 / this.scaleY;
//
// this.refreshLabelScale();
//
// }
//
// if (text) {
// this.label.text = text;
// } else if (this.title) {
// this.label.text = this.title;
// }
// this.label.visible = true;
//
// }
//
// hideLabel() {
// if (!this.label) { return; }
//
// this.label.visible = false;
// }
//
// refreshLabelScale() {
// if (this.scaleX == this.scaleY) {
// this.label.setScaleXY(1);
// }
//
// if (this.scaleX > this.scaleY) {
// this.label.scaleX = this.scaleY / this.scaleX;
// } else {
// this.label.scaleY = this.scaleX / this.scaleY;
// }
// }
//
// showLineDash() {
// this.lineDashFlag = true;
//
// if (this.arrow) {
// this.arrow.visible = true;
// } else {
// this.arrow = new MySprite(this.ctx);
// this.arrow.load('assets/common/arrow.png', 1, 0);
// this.arrow.setScaleXY(0.06);
//
// this.arrowTop = new MySprite(this.ctx);
// this.arrowTop.load('assets/common/arrow_top.png', 0.5, 0);
// this.arrowTop.setScaleXY(0.06);
//
// this.arrowRight = new MySprite(this.ctx);
// this.arrowRight.load('assets/common/arrow_right.png', 1, 0.5);
// this.arrowRight.setScaleXY(0.06);
// }
//
// this.showLabel();
// }
//
// hideLineDash() {
//
// this.lineDashFlag = false;
//
// if (this.arrow) {
// this.arrow.visible = false;
// }
//
// this.hideLabel();
// }
//
//
//
// drawArrow() {
// if (!this.arrow) { return; }
//
// const rect = this.getBoundingBox();
// this.arrow.x = rect.x + rect.width;
// this.arrow.y = rect.y;
//
// this.arrow.update();
//
//
// this.arrowTop.x = rect.x + rect.width / 2;
// this.arrowTop.y = rect.y;
// this.arrowTop.update();
//
// this.arrowRight.x = rect.x + rect.width;
// this.arrowRight.y = rect.y + rect.height / 2;
// this.arrowRight.update();
// }
//
// drawFrame() {
//
//
// this.ctx.save();
//
//
// const rect = this.getBoundingBox();
//
// const w = rect.width;
// const h = rect.height;
// const x = rect.x + w / 2;
// const y = rect.y + h / 2;
//
// this.ctx.setLineDash([5, 5]);
// this.ctx.lineWidth = 2;
// this.ctx.strokeStyle = '#1bfff7';
// // this.ctx.fillStyle = '#ffffff';
//
// this.ctx.beginPath();
//
// this.ctx.moveTo( x - w / 2, y - h / 2);
//
// this.ctx.lineTo(x + w / 2, y - h / 2);
//
// this.ctx.lineTo(x + w / 2, y + h / 2);
//
// this.ctx.lineTo(x - w / 2, y + h / 2);
//
// this.ctx.lineTo(x - w / 2, y - h / 2);
//
// // this.ctx.fill();
// this.ctx.stroke();
//
//
//
//
// this.ctx.restore();
//
// }
//
// draw() {
// super.draw();
//
// if (this.lineDashFlag) {
// this.drawFrame();
// this.drawArrow();
// }
// }
// }
//
//
// export class EditorItem extends MySprite {
//
// lineDashFlag = false;
// arrow: MySprite;
// label:Label;
// text;
//
// showLabel(text = null) {
//
//
// if (!this.label) {
// this.label = new Label(this.ctx);
// this.label.anchorY = 0;
// this.label.fontSize = '50px';
// this.label.textAlign = 'center';
// this.addChild(this.label);
// this.label.setScaleXY(1 / this.scaleX);
// }
//
// if (text) {
// this.label.text = text;
// } else if (this.text) {
// this.label.text = this.text;
// }
// this.label.visible = true;
//
// }
//
// hideLabel() {
// if (!this.label) { return; }
//
// this.label.visible = false;
// }
//
// showLineDash() {
// this.lineDashFlag = true;
//
// if (this.arrow) {
// this.arrow.visible = true;
// } else {
// this.arrow = new MySprite(this.ctx);
// this.arrow.load('assets/common/arrow.png', 1, 0);
// this.arrow.setScaleXY(0.06);
//
// }
//
// this.showLabel();
// }
//
// hideLineDash() {
//
// this.lineDashFlag = false;
//
// if (this.arrow) {
// this.arrow.visible = false;
// }
//
// this.hideLabel();
// }
//
//
//
// drawArrow() {
// if (!this.arrow) { return; }
//
// const rect = this.getBoundingBox();
// this.arrow.x = rect.x + rect.width;
// this.arrow.y = rect.y;
//
// this.arrow.update();
// }
//
// drawFrame() {
//
//
// this.ctx.save();
//
//
// const rect = this.getBoundingBox();
//
// const w = rect.width;
// const h = rect.height;
// const x = rect.x + w / 2;
// const y = rect.y + h / 2;
//
// this.ctx.setLineDash([5, 5]);
// this.ctx.lineWidth = 2;
// this.ctx.strokeStyle = '#1bfff7';
// // this.ctx.fillStyle = '#ffffff';
//
// this.ctx.beginPath();
//
// this.ctx.moveTo( x - w / 2, y - h / 2);
//
// this.ctx.lineTo(x + w / 2, y - h / 2);
//
// this.ctx.lineTo(x + w / 2, y + h / 2);
//
// this.ctx.lineTo(x - w / 2, y + h / 2);
//
// this.ctx.lineTo(x - w / 2, y - h / 2);
//
// // this.ctx.fill();
// this.ctx.stroke();
//
//
//
//
// this.ctx.restore();
//
// }
//
// draw() {
// super.draw();
//
// if (this.lineDashFlag) {
// this.drawFrame();
// this.drawArrow();
// }
// }
// }
//
//
//
// export class Label extends MySprite {
//
// text:String;
// fontSize:String = '40px';
// fontName:String = 'Verdana';
// textAlign:String = 'left';
//
//
// constructor(ctx) {
// super(ctx);
// this.init();
// }
//
// drawText() {
//
// // console.log('in drawText', this.text);
//
// if (!this.text) { return; }
//
// this.ctx.font = `${this.fontSize} ${this.fontName}`;
// this.ctx.textAlign = this.textAlign;
// this.ctx.textBaseline = 'middle';
// this.ctx.fontWeight = 900;
//
// this.ctx.lineWidth = 5;
// this.ctx.strokeStyle = '#ffffff';
// this.ctx.strokeText(this.text, 0, 0);
//
// this.ctx.fillStyle = '#000000';
// this.ctx.fillText(this.text, 0, 0);
//
//
// }
//
//
// drawSelf() {
// super.drawSelf();
// this.drawText();
// }
//
// }
//
//
//
// export function getPosByAngle(angle, len) {
//
// const radian = angle * Math.PI / 180;
// const x = Math.sin(radian) * len;
// const y = Math.cos(radian) * len;
//
// return {x, y};
//
// }
//
// export function getAngleByPos(px, py, mx, my) {
//
// // const _x = p2x - p1x;
// // const _y = p2y - p1y;
// // const tan = _y / _x;
// //
// // const radina = Math.atan(tan); // 用反三角函数求弧度
// // const angle = Math.floor(180 / (Math.PI / radina)); //
// //
// // console.log('r: ' , angle);
// // return angle;
// //
//
//
//
// const x = Math.abs(px - mx);
// const y = Math.abs(py - my);
// // const x = Math.abs(mx - px);
// // const y = Math.abs(my - py);
// const z = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
// const cos = y / z;
// const radina = Math.acos(cos); // 用反三角函数求弧度
// let angle = Math.floor(180 / (Math.PI / radina) * 100) / 100; // 将弧度转换成角度
//
// if(mx > px && my > py) {// 鼠标在第四象限
// angle = 180 - angle;
// }
//
// if(mx === px && my > py) {// 鼠标在y轴负方向上
// angle = 180;
// }
//
// if(mx > px && my === py) {// 鼠标在x轴正方向上
// angle = 90;
// }
//
// if(mx < px && my > py) {// 鼠标在第三象限
// angle = 180 + angle;
// }
//
// if(mx < px && my === py) {// 鼠标在x轴负方向
// angle = 270;
// }
//
// if(mx < px && my < py) {// 鼠标在第二象限
// angle = 360 - angle;
// }
//
// // console.log('angle: ', angle);
// return angle;
//
// }