Commit fc45a3c4 authored by limingzhe's avatar limingzhe

feat: Unit 增加图片遮照 图片圆角 图片切圆 视频类

parent 8a51c964
......@@ -4,6 +4,7 @@ import TWEEN from '@tweenjs/tween.js';
interface AirWindow extends Window {
air: any;
curCtx: any;
curImages: any;
}
declare let window: AirWindow;
......@@ -36,7 +37,6 @@ class Sprite {
export class MySprite extends Sprite {
_width = 0;
......@@ -69,6 +69,16 @@ export class MySprite extends Sprite {
img;
_z = 0;
_showRect;
_bitmapFlag = false;
_offCanvas;
_offCtx;
isCircleStyle = false; // 切成圆形
parent;
_maskSpr;
init(imgObj = null, anchorX: number = 0.5, anchorY: number = 0.5) {
......@@ -79,7 +89,6 @@ export class MySprite extends Sprite {
this.width = this.img.width;
this.height = this.img.height;
}
this.anchorX = anchorX;
......@@ -87,8 +96,11 @@ export class MySprite extends Sprite {
}
setShadow(offX, offY, blur, color = 'rgba(0, 0, 0, 0.3)') {
setShowRect(rect) {
this._showRect = rect;
}
setShadow(offX, offY, blur, color = 'rgba(0, 0, 0, 0.3)') {
this._shadowFlag = true;
this._shadowColor = color;
......@@ -102,6 +114,19 @@ export class MySprite extends Sprite {
this._radius = r;
}
setMaskSpr(spr) {
this._maskSpr = spr;
this._createOffCtx();
}
_createOffCtx() {
if (!this._offCtx) {
this._offCanvas = document.createElement('canvas'); // 创建一个新的canvas
this.width = this._offCanvas.width = this.width; // 创建一个正好包裹住一个粒子canvas
this.height = this._offCanvas.height = this.height;
this._offCtx = this._offCanvas.getContext('2d');
}
}
update($event = null) {
if (!this.visible && this.childDepandVisible) {
......@@ -137,7 +162,22 @@ export class MySprite extends Sprite {
this.ctx.transform(1, this.skewX, this.skewY, 1, 0, 0);
}
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) {
......@@ -146,45 +186,68 @@ export class MySprite extends Sprite {
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.beginPath()
this._roundRect(-w / 2, - h / 2, w, h, r * 1 || 0);
this.ctx.clip();
}
if (this.isCircleStyle) {
this.ctx.beginPath()
this.ctx.arc(0, 0, Math.max(this.width, this.height) / 2, 0, Math.PI * 2, false); // 圆形
this.ctx.clip();
}
}
drawSelf() {
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 + rect.x, this._offY + rect.y, rect.width, rect.height);
} else {
if (this._offCtx) {
this._offScreenRender();
} else {
this.ctx.drawImage(this.img, this._offX, this._offY);
}
}
}
}
if (this._shadowFlag) {
_offScreenRender() {
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;
}
this._offCtx.save();
this._offCtx.clearRect(0, 0, this.width, this.height);
if (this.img) {
this.ctx.drawImage(this.img, this._offX, this._offY);
this._offCtx.drawImage(this.img, 0, 0);
if (this._maskSpr) {
this._offCtx.globalCompositeOperation = 'destination-in';
this._offCtx.drawImage(this._maskSpr.img, this._maskSpr.x + this._maskSpr._offX - this._offX , this._maskSpr.y + this._maskSpr._offY - this._offY);
}
this.ctx.drawImage(this._offCanvas, this._offX, this._offY);
this._offCtx.restore();
}
_roundRect(x, y, w, h, r) {
const min_size = Math.min(w, h);
if (r > min_size / 2) r = min_size / 2;
// 开始绘制
const ctx = this.ctx;
ctx.beginPath();
ctx.moveTo(x + r, y);
ctx.arcTo(x + w, y, x + w, y + h, r);
ctx.arcTo(x + w, y + h, x, y + h, r);
ctx.arcTo(x, y + h, x, y, r);
ctx.arcTo(x, y, x + w, y, r);
ctx.closePath();
}
updateChildren() {
updateChildren() {
if (this.children.length <= 0) { return; }
......@@ -257,6 +320,13 @@ export class MySprite extends Sprite {
}
}
set bitmapFlag(v) {
this._bitmapFlag = v;
}
get bitmapFlag() {
return this._bitmapFlag;
}
set alpha(v) {
this._alpha = v;
if (this.childDepandAlpha) {
......@@ -305,7 +375,6 @@ export class MySprite extends Sprite {
getBoundingBox() {
const getParentData = (item) => {
let px = item.x;
......@@ -343,11 +412,6 @@ export class MySprite extends Sprite {
const width = this.width * Math.abs(data.sx);
const height = this.height * Math.abs(data.sy);
// const x = this.x + this._offX * Math.abs(this.scaleX);
// const y = this.y + this._offY * Math.abs(this.scaleY);
// const width = this.width * Math.abs(this.scaleX);
// const height = this.height * Math.abs(this.scaleY);
return {x, y, width, height};
}
......@@ -758,7 +822,8 @@ export class RichTextOld extends Label {
export class RichText extends Label {
disH = 30;
disH = 30;
offW = 10;
constructor(ctx?: any) {
super(ctx);
......@@ -788,7 +853,7 @@ export class RichText extends Label {
const chr = this.text.split(' ');
let temp = '';
const row = [];
const w = selfW - 80;
const w = selfW - this.offW * 2;
const disH = (this.fontSize + this.disH) * this.scaleY;
......@@ -964,28 +1029,28 @@ export class ShapeRectNew extends MySprite {
ctx.save();
ctx.beginPath(0);
// 从右下角顺时针绘制,弧度从0到1/2PI
ctx.arc(width - radius, height - radius, radius, 0, Math.PI / 2);
ctx.arc(width - radius + this._offX, height - radius + this._offY, radius, 0, Math.PI / 2);
// 矩形下边线
ctx.lineTo(radius, height);
ctx.lineTo(radius + this._offX, height + this._offY);
// 左下角圆弧,弧度从1/2PI到PI
ctx.arc(radius, height - radius, radius, Math.PI / 2, Math.PI);
ctx.arc(radius + this._offX, height - radius + this._offY, radius, Math.PI / 2, Math.PI);
// 矩形左边线
ctx.lineTo(0, radius);
ctx.lineTo(0 + this._offX, radius + this._offY);
// 左上角圆弧,弧度从PI到3/2PI
ctx.arc(radius, radius, radius, Math.PI, Math.PI * 3 / 2);
ctx.arc(radius + this._offX, radius + this._offY, radius, Math.PI, Math.PI * 3 / 2);
// 上边线
ctx.lineTo(width - radius, 0);
ctx.lineTo(width - radius + this._offX, 0 + this._offY);
// 右上角圆弧
ctx.arc(width - radius, radius, radius, Math.PI * 3 / 2, Math.PI * 2);
ctx.arc(width - radius + this._offX, radius + this._offY, radius, Math.PI * 3 / 2, Math.PI * 2);
// 右边线
ctx.lineTo(width, height - radius);
ctx.lineTo(width + this._offX, height - radius + this._offY);
ctx.closePath();
if (this.fill) {
......@@ -1020,7 +1085,7 @@ export class MyAnimation extends MySprite {
loop = false;
playEndFunc;
delayPerUnit = 1;
delayPerUnit = 0.07;
restartFlag = false;
reverseFlag = false;
......@@ -1109,8 +1174,9 @@ export class MyAnimation extends MySprite {
this.frameArr[this.frameIndex].visible = true;
if (this.playEndFunc) {
this.playEndFunc();
const func = this.playEndFunc;
this.playEndFunc = null;
func();
}
}
......@@ -1177,6 +1243,14 @@ export class MyAnimation extends MySprite {
export function tweenChange(item, obj, time = 0.8, callBack = null, easing = null, update = null) {
const tween = createTween(item, obj, time, callBack, easing, update)
tween.start();
return tween;
}
export function createTween(item, obj, time = 0.8, callBack = null, easing = null, update = null) {
const tween = new TWEEN.Tween(item).to(obj, time * 1000);
if (callBack) {
......@@ -1192,15 +1266,28 @@ export function tweenChange(item, obj, time = 0.8, callBack = null, easing = nul
update(a, b);
});
}
tween.start();
return tween;
}
export function tweenQueue(arr) {
const showOneTween = () => {
const tween = arr.shift();
if (arr.length > 0) {
tween.onComplete( () => {
showOneTween();
});
}
tween.start();
};
showOneTween();
}
export function rotateItem(item, rotation, time = 0.8, callBack = null, easing = null) {
export function rotateItem(item, rotation, time = 0.8, callBack = null, easing = null, loop = false) {
const tween = new TWEEN.Tween(item).to({ rotation }, time * 1000);
......@@ -1208,7 +1295,14 @@ export function rotateItem(item, rotation, time = 0.8, callBack = null, easing =
tween.onComplete(() => {
callBack();
});
} else if (loop) {
const speed = (rotation - item.rotation) / time;
tween.onComplete(() => {
item.rotation %= 360;
rotateItem(item, item.rotation + speed * time, time, null, easing, true);
});
}
if (easing) {
tween.easing(easing);
}
......@@ -1491,7 +1585,7 @@ export function getPosDistance(sx, sy, ex, ey) {
return len;
}
export function delayCall(callback, second) {
export function delayCall(second, callback) {
const tween = new TWEEN.Tween(this)
.delay(second * 1000)
.onComplete(() => {
......@@ -1525,10 +1619,15 @@ export function formatTime(fmt, date) {
return fmt;
}
export function getMinScale(item, maxLen) {
const sx = maxLen / item.width;
const sy = maxLen / item.height;
export function getMinScale(item, maxW, maxH = null) {
if (!maxH) {
maxH = maxW;
}
const sx = maxW / item.width;
const sy = maxH / item.height;
const minS = Math.min(sx, sy);
return minS;
}
......@@ -1571,6 +1670,46 @@ export function jelly(item, time = 0.7) {
run();
}
export function jellyPop(item, time) {
if (item.jellyTween) {
TWEEN.remove(item.jellyTween);
}
const t = time / 6;
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.3, baseSY * 1.3, t],
[baseSX * 0.85, baseSY * 0.85, t * 1],
[baseSX * 1.1, baseSY * 1.1, t * 1],
[baseSX * 0.95, baseSY * 0.95, t * 1],
[baseSX * 1.02, baseSY * 1.02, t * 1],
[baseSX * 1, baseSY * 1, t * 1],
];
item.setScaleXY(0);
run();
}
export function showPopParticle(img, pos, parent, num = 20, minLen = 40, maxLen = 80, showTime = 0.4) {
......@@ -1672,5 +1811,41 @@ export function shake(item, time = 0.5, callback = null, rate = 1) {
}
export function getMaxScale(item, maxW, maxH) {
const sx = maxW / item.width;
const sy = maxH / item.height;
const maxS = Math.max(sx, sy);
return maxS;
}
export function createSprite(key) {
const image = window.curImages;
const spr = new MySprite();
spr.init(image.get(key));
return spr;
}
export class MyVideo extends MySprite {
element;
initVideoElement(videoElement) {
this.element = videoElement;
this.width = this.element.videoWidth;
this.height = this.element.videoHeight;
this.element.currentTime = 0.01;
}
drawSelf() {
super.drawSelf();
this.ctx.drawImage(this.element, 0, 0, this.width, this.height);
}
}
// --------------- custom class --------------------
......@@ -108,6 +108,16 @@ export class PlayComponent implements OnInit, OnDestroy {
ngOnDestroy() {
window['curCtx'] = null;
window.cancelAnimationFrame(this.animationId);
this.cleanAudio();
}
cleanAudio() {
if (this.audioObj) {
for (const key in this.audioObj) {
this.audioObj[key].pause();
}
}
}
......@@ -141,6 +151,7 @@ export class PlayComponent implements OnInit, OnDestroy {
this.canvas.nativeElement.height = this.canvasHeight;
window['curCtx'] = this.ctx;
window['curImages'] = this.images;
}
......
......@@ -92,7 +92,8 @@
"variable-name": false,
"no-unused-expression": false,
"align": false
"align": false,
"no-string-literal": false
},
"rulesDirectory": [
"codelyzer"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment