620 lines
11 KiB
JavaScript
620 lines
11 KiB
JavaScript
|
// @ts-check
|
|||
|
export default class WxCanvas {
|
|||
|
ctx;
|
|||
|
type;
|
|||
|
canvasId;
|
|||
|
canvasNode;
|
|||
|
stepList = [];
|
|||
|
canvasPrototype = {};
|
|||
|
|
|||
|
constructor(type, ctx, canvasId, isNew, canvasNode) {
|
|||
|
this.ctx = ctx;
|
|||
|
this.canvasId = canvasId;
|
|||
|
this.type = type;
|
|||
|
if (isNew) {
|
|||
|
this.canvasNode = canvasNode || {};
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
set width(w) {
|
|||
|
if (this.canvasNode) {
|
|||
|
this.canvasNode.width = w;
|
|||
|
// 经测试,在 2d 接口中如果不设置这个值,IOS 端有一定几率会出现图片显示不全的情况。
|
|||
|
this.canvasNode._width = w;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
get width() {
|
|||
|
if (this.canvasNode) return this.canvasNode.width;
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
set height(h) {
|
|||
|
if (this.canvasNode) {
|
|||
|
this.canvasNode.height = h;
|
|||
|
// 经测试,在 2d 接口中如果不设置这个值,IOS 端有一定几率会出现图片显示不全的情况。
|
|||
|
this.canvasNode._height = h;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
get height() {
|
|||
|
if (this.canvasNode) return this.canvasNode.height;
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
set lineWidth(args) {
|
|||
|
this.canvasPrototype.lineWidth = args;
|
|||
|
this.stepList.push({
|
|||
|
action: "lineWidth",
|
|||
|
args,
|
|||
|
actionType: "set",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
get lineWidth() {
|
|||
|
return this.canvasPrototype.lineWidth;
|
|||
|
}
|
|||
|
|
|||
|
set lineCap(args) {
|
|||
|
this.canvasPrototype.lineCap = args;
|
|||
|
this.stepList.push({
|
|||
|
action: "lineCap",
|
|||
|
args,
|
|||
|
actionType: "set",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
get lineCap() {
|
|||
|
return this.canvasPrototype.lineCap;
|
|||
|
}
|
|||
|
|
|||
|
set lineJoin(args) {
|
|||
|
this.canvasPrototype.lineJoin = args;
|
|||
|
this.stepList.push({
|
|||
|
action: "lineJoin",
|
|||
|
args,
|
|||
|
actionType: "set",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
get lineJoin() {
|
|||
|
return this.canvasPrototype.lineJoin;
|
|||
|
}
|
|||
|
|
|||
|
set miterLimit(args) {
|
|||
|
this.canvasPrototype.miterLimit = args;
|
|||
|
this.stepList.push({
|
|||
|
action: "miterLimit",
|
|||
|
args,
|
|||
|
actionType: "set",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
get miterLimit() {
|
|||
|
return this.canvasPrototype.miterLimit;
|
|||
|
}
|
|||
|
|
|||
|
set lineDashOffset(args) {
|
|||
|
this.canvasPrototype.lineDashOffset = args;
|
|||
|
this.stepList.push({
|
|||
|
action: "lineDashOffset",
|
|||
|
args,
|
|||
|
actionType: "set",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
get lineDashOffset() {
|
|||
|
return this.canvasPrototype.lineDashOffset;
|
|||
|
}
|
|||
|
|
|||
|
set font(args) {
|
|||
|
this.canvasPrototype.font = args;
|
|||
|
this.ctx.font = args;
|
|||
|
this.stepList.push({
|
|||
|
action: "font",
|
|||
|
args,
|
|||
|
actionType: "set",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
get font() {
|
|||
|
return this.canvasPrototype.font;
|
|||
|
}
|
|||
|
|
|||
|
set textAlign(args) {
|
|||
|
this.canvasPrototype.textAlign = args;
|
|||
|
this.stepList.push({
|
|||
|
action: "textAlign",
|
|||
|
args,
|
|||
|
actionType: "set",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
get textAlign() {
|
|||
|
return this.canvasPrototype.textAlign;
|
|||
|
}
|
|||
|
|
|||
|
set textBaseline(args) {
|
|||
|
this.canvasPrototype.textBaseline = args;
|
|||
|
this.stepList.push({
|
|||
|
action: "textBaseline",
|
|||
|
args,
|
|||
|
actionType: "set",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
get textBaseline() {
|
|||
|
return this.canvasPrototype.textBaseline;
|
|||
|
}
|
|||
|
|
|||
|
set fillStyle(args) {
|
|||
|
this.canvasPrototype.fillStyle = args;
|
|||
|
this.stepList.push({
|
|||
|
action: "fillStyle",
|
|||
|
args,
|
|||
|
actionType: "set",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
get fillStyle() {
|
|||
|
return this.canvasPrototype.fillStyle;
|
|||
|
}
|
|||
|
|
|||
|
set strokeStyle(args) {
|
|||
|
this.canvasPrototype.strokeStyle = args;
|
|||
|
this.stepList.push({
|
|||
|
action: "strokeStyle",
|
|||
|
args,
|
|||
|
actionType: "set",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
get strokeStyle() {
|
|||
|
return this.canvasPrototype.strokeStyle;
|
|||
|
}
|
|||
|
|
|||
|
set globalAlpha(args) {
|
|||
|
this.canvasPrototype.globalAlpha = args;
|
|||
|
this.stepList.push({
|
|||
|
action: "globalAlpha",
|
|||
|
args,
|
|||
|
actionType: "set",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
get globalAlpha() {
|
|||
|
return this.canvasPrototype.globalAlpha;
|
|||
|
}
|
|||
|
|
|||
|
set globalCompositeOperation(args) {
|
|||
|
this.canvasPrototype.globalCompositeOperation = args;
|
|||
|
this.stepList.push({
|
|||
|
action: "globalCompositeOperation",
|
|||
|
args,
|
|||
|
actionType: "set",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
get globalCompositeOperation() {
|
|||
|
return this.canvasPrototype.globalCompositeOperation;
|
|||
|
}
|
|||
|
|
|||
|
set shadowColor(args) {
|
|||
|
this.canvasPrototype.shadowColor = args;
|
|||
|
this.stepList.push({
|
|||
|
action: "shadowColor",
|
|||
|
args,
|
|||
|
actionType: "set",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
get shadowColor() {
|
|||
|
return this.canvasPrototype.shadowColor;
|
|||
|
}
|
|||
|
|
|||
|
set shadowOffsetX(args) {
|
|||
|
this.canvasPrototype.shadowOffsetX = args;
|
|||
|
this.stepList.push({
|
|||
|
action: "shadowOffsetX",
|
|||
|
args,
|
|||
|
actionType: "set",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
get shadowOffsetX() {
|
|||
|
return this.canvasPrototype.shadowOffsetX;
|
|||
|
}
|
|||
|
|
|||
|
set shadowOffsetY(args) {
|
|||
|
this.canvasPrototype.shadowOffsetY = args;
|
|||
|
this.stepList.push({
|
|||
|
action: "shadowOffsetY",
|
|||
|
args,
|
|||
|
actionType: "set",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
get shadowOffsetY() {
|
|||
|
return this.canvasPrototype.shadowOffsetY;
|
|||
|
}
|
|||
|
|
|||
|
set shadowBlur(args) {
|
|||
|
this.canvasPrototype.shadowBlur = args;
|
|||
|
this.stepList.push({
|
|||
|
action: "shadowBlur",
|
|||
|
args,
|
|||
|
actionType: "set",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
get shadowBlur() {
|
|||
|
return this.canvasPrototype.shadowBlur;
|
|||
|
}
|
|||
|
|
|||
|
save() {
|
|||
|
this.stepList.push({
|
|||
|
action: "save",
|
|||
|
args: null,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
restore() {
|
|||
|
this.stepList.push({
|
|||
|
action: "restore",
|
|||
|
args: null,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
setLineDash(...args) {
|
|||
|
this.canvasPrototype.lineDash = args;
|
|||
|
this.stepList.push({
|
|||
|
action: "setLineDash",
|
|||
|
args,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
moveTo(...args) {
|
|||
|
this.stepList.push({
|
|||
|
action: "moveTo",
|
|||
|
args,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
closePath() {
|
|||
|
this.stepList.push({
|
|||
|
action: "closePath",
|
|||
|
args: null,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
lineTo(...args) {
|
|||
|
this.stepList.push({
|
|||
|
action: "lineTo",
|
|||
|
args,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
quadraticCurveTo(...args) {
|
|||
|
this.stepList.push({
|
|||
|
action: "quadraticCurveTo",
|
|||
|
args,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
bezierCurveTo(...args) {
|
|||
|
this.stepList.push({
|
|||
|
action: "bezierCurveTo",
|
|||
|
args,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
arcTo(...args) {
|
|||
|
this.stepList.push({
|
|||
|
action: "arcTo",
|
|||
|
args,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
arc(...args) {
|
|||
|
this.stepList.push({
|
|||
|
action: "arc",
|
|||
|
args,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
rect(...args) {
|
|||
|
this.stepList.push({
|
|||
|
action: "rect",
|
|||
|
args,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
scale(...args) {
|
|||
|
this.stepList.push({
|
|||
|
action: "scale",
|
|||
|
args,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
rotate(...args) {
|
|||
|
this.stepList.push({
|
|||
|
action: "rotate",
|
|||
|
args,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
translate(...args) {
|
|||
|
this.stepList.push({
|
|||
|
action: "translate",
|
|||
|
args,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
transform(...args) {
|
|||
|
this.stepList.push({
|
|||
|
action: "transform",
|
|||
|
args,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
setTransform(...args) {
|
|||
|
this.stepList.push({
|
|||
|
action: "setTransform",
|
|||
|
args,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
clearRect(...args) {
|
|||
|
this.stepList.push({
|
|||
|
action: "clearRect",
|
|||
|
args,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
fillRect(...args) {
|
|||
|
this.stepList.push({
|
|||
|
action: "fillRect",
|
|||
|
args,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
strokeRect(...args) {
|
|||
|
this.stepList.push({
|
|||
|
action: "strokeRect",
|
|||
|
args,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
fillText(...args) {
|
|||
|
this.stepList.push({
|
|||
|
action: "fillText",
|
|||
|
args,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
strokeText(...args) {
|
|||
|
this.stepList.push({
|
|||
|
action: "strokeText",
|
|||
|
args,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
beginPath() {
|
|||
|
this.stepList.push({
|
|||
|
action: "beginPath",
|
|||
|
args: null,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
fill() {
|
|||
|
this.stepList.push({
|
|||
|
action: "fill",
|
|||
|
args: null,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
stroke() {
|
|||
|
this.stepList.push({
|
|||
|
action: "stroke",
|
|||
|
args: null,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
drawFocusIfNeeded(...args) {
|
|||
|
this.stepList.push({
|
|||
|
action: "drawFocusIfNeeded",
|
|||
|
args,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
clip() {
|
|||
|
this.stepList.push({
|
|||
|
action: "clip",
|
|||
|
args: null,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
isPointInPath(...args) {
|
|||
|
this.stepList.push({
|
|||
|
action: "isPointInPath",
|
|||
|
args,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
drawImage(...args) {
|
|||
|
this.stepList.push({
|
|||
|
action: "drawImage",
|
|||
|
args,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
addHitRegion(...args) {
|
|||
|
this.stepList.push({
|
|||
|
action: "addHitRegion",
|
|||
|
args,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
removeHitRegion(...args) {
|
|||
|
this.stepList.push({
|
|||
|
action: "removeHitRegion",
|
|||
|
args,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
clearHitRegions(...args) {
|
|||
|
this.stepList.push({
|
|||
|
action: "clearHitRegions",
|
|||
|
args,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
putImageData(...args) {
|
|||
|
this.stepList.push({
|
|||
|
action: "putImageData",
|
|||
|
args,
|
|||
|
actionType: "func",
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
getLineDash() {
|
|||
|
return this.canvasPrototype.lineDash;
|
|||
|
}
|
|||
|
|
|||
|
createLinearGradient(...args) {
|
|||
|
return this.ctx.createLinearGradient(...args);
|
|||
|
}
|
|||
|
|
|||
|
createRadialGradient(...args) {
|
|||
|
if (this.type === "2d") {
|
|||
|
return this.ctx.createRadialGradient(...args);
|
|||
|
} else {
|
|||
|
return this.ctx.createCircularGradient(...args.slice(3, 6));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
createPattern(...args) {
|
|||
|
return this.ctx.createPattern(...args);
|
|||
|
}
|
|||
|
|
|||
|
measureText(...args) {
|
|||
|
return this.ctx.measureText(...args);
|
|||
|
}
|
|||
|
|
|||
|
createImageData(...args) {
|
|||
|
return this.ctx.createImageData(...args);
|
|||
|
}
|
|||
|
|
|||
|
getImageData(...args) {
|
|||
|
return this.ctx.getImageData(...args);
|
|||
|
}
|
|||
|
|
|||
|
async draw(reserve, func) {
|
|||
|
const realstepList = this.stepList.slice();
|
|||
|
this.stepList.length = 0;
|
|||
|
if (this.type === "mina") {
|
|||
|
if (realstepList.length > 0) {
|
|||
|
for (const step of realstepList) {
|
|||
|
this.implementMinaStep(step);
|
|||
|
}
|
|||
|
realstepList.length = 0;
|
|||
|
}
|
|||
|
this.ctx.draw(reserve, func);
|
|||
|
} else if (this.type === "2d") {
|
|||
|
if (!reserve) {
|
|||
|
this.ctx.clearRect(0, 0, this.canvasNode.width, this.canvasNode.height);
|
|||
|
}
|
|||
|
if (realstepList.length > 0) {
|
|||
|
for (const step of realstepList) {
|
|||
|
await this.implement2DStep(step);
|
|||
|
}
|
|||
|
realstepList.length = 0;
|
|||
|
}
|
|||
|
if (func) {
|
|||
|
func();
|
|||
|
}
|
|||
|
}
|
|||
|
realstepList.length = 0;
|
|||
|
}
|
|||
|
|
|||
|
implementMinaStep(step) {
|
|||
|
switch (step.action) {
|
|||
|
case "textAlign": {
|
|||
|
this.ctx.setTextAlign(step.args);
|
|||
|
break;
|
|||
|
}
|
|||
|
case "textBaseline": {
|
|||
|
this.ctx.setTextBaseline(step.args);
|
|||
|
break;
|
|||
|
}
|
|||
|
default: {
|
|||
|
if (step.actionType === "set") {
|
|||
|
this.ctx[step.action] = step.args;
|
|||
|
} else if (step.actionType === "func") {
|
|||
|
if (step.args) {
|
|||
|
this.ctx[step.action](...step.args);
|
|||
|
} else {
|
|||
|
this.ctx[step.action]();
|
|||
|
}
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
implement2DStep(step) {
|
|||
|
return new Promise((resolve) => {
|
|||
|
if (step.action === "drawImage") {
|
|||
|
const img = this.canvasNode.createImage();
|
|||
|
img.src = step.args[0];
|
|||
|
img.onload = () => {
|
|||
|
this.ctx.drawImage(img, ...step.args.slice(1));
|
|||
|
resolve();
|
|||
|
};
|
|||
|
} else {
|
|||
|
if (step.actionType === "set") {
|
|||
|
this.ctx[step.action] = step.args;
|
|||
|
} else if (step.actionType === "func") {
|
|||
|
if (step.args) {
|
|||
|
this.ctx[step.action](...step.args);
|
|||
|
} else {
|
|||
|
this.ctx[step.action]();
|
|||
|
}
|
|||
|
}
|
|||
|
resolve();
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
}
|