fix: calc 引起的 dancePalette 问题
This commit is contained in:
parent
5c155bf66f
commit
cdea1f2ba6
@ -1,4 +1,4 @@
|
|||||||
var calculate = function (s) {
|
module.exports = function (s) {
|
||||||
s = s.trim();
|
s = s.trim();
|
||||||
const stack = new Array();
|
const stack = new Array();
|
||||||
let preSign = '+';
|
let preSign = '+';
|
||||||
@ -46,5 +46,3 @@ var calculate = function (s) {
|
|||||||
}
|
}
|
||||||
return ans;
|
return ans;
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = calculate;
|
|
||||||
|
|||||||
81
lib/pen.js
81
lib/pen.js
@ -1,33 +1,38 @@
|
|||||||
const QR = require('./qrcode.js');
|
const QR = require('./qrcode.js');
|
||||||
const GD = require('./gradient.js');
|
const GD = require('./gradient.js');
|
||||||
|
|
||||||
|
export const penCache = {
|
||||||
|
// 用于存储带 id 的 view 的 rect 信息
|
||||||
|
viewRect: {},
|
||||||
|
textLines: {},
|
||||||
|
};
|
||||||
|
export const clearPenCache = id => {
|
||||||
|
if (id) {
|
||||||
|
penCache.viewRect[id] = null;
|
||||||
|
penCache.textLines[id] = null;
|
||||||
|
} else {
|
||||||
|
penCache.viewRect = {};
|
||||||
|
penCache.textLines = {};
|
||||||
|
}
|
||||||
|
};
|
||||||
export default class Painter {
|
export default class Painter {
|
||||||
constructor(ctx, data) {
|
constructor(ctx, data) {
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
this.data = data;
|
this.data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
isMoving = false;
|
paint(callback) {
|
||||||
// 动态模板时的缓存,加速渲染
|
|
||||||
movingCache = {};
|
|
||||||
callbackInfo = {};
|
|
||||||
// 用于存储带 id 的 view 的 rect 信息
|
|
||||||
viewRect = {};
|
|
||||||
paint(callback, isMoving, movingCache) {
|
|
||||||
this.style = {
|
this.style = {
|
||||||
width: this.data.width.toPx(),
|
width: this.data.width.toPx(),
|
||||||
height: this.data.height.toPx(),
|
height: this.data.height.toPx(),
|
||||||
};
|
};
|
||||||
if (isMoving) {
|
|
||||||
this.isMoving = true;
|
|
||||||
this.movingCache = movingCache;
|
|
||||||
}
|
|
||||||
this._background();
|
this._background();
|
||||||
for (const view of this.data.views) {
|
for (const view of this.data.views) {
|
||||||
this._drawAbsolute(view);
|
this._drawAbsolute(view);
|
||||||
}
|
}
|
||||||
this.ctx.draw(false, () => {
|
this.ctx.draw(false, () => {
|
||||||
callback && callback(this.callbackInfo);
|
callback && callback();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,14 +267,14 @@ export default class Painter {
|
|||||||
width = Math.round(view.sWidth / ratio);
|
width = Math.round(view.sWidth / ratio);
|
||||||
height = Math.round(view.sHeight / ratio);
|
height = Math.round(view.sHeight / ratio);
|
||||||
} else if (view.css.width === 'auto') {
|
} else if (view.css.width === 'auto') {
|
||||||
height = view.css.height.toPx(false, this.style.height, this.viewRect);
|
height = view.css.height.toPx(false, this.style.height);
|
||||||
width = (view.sWidth / view.sHeight) * height;
|
width = (view.sWidth / view.sHeight) * height;
|
||||||
} else if (view.css.height === 'auto') {
|
} else if (view.css.height === 'auto') {
|
||||||
width = view.css.width.toPx(false, this.style.width, this.viewRect);
|
width = view.css.width.toPx(false, this.style.width);
|
||||||
height = (view.sHeight / view.sWidth) * width;
|
height = (view.sHeight / view.sWidth) * width;
|
||||||
} else {
|
} else {
|
||||||
width = view.css.width.toPx(false, this.style.width, this.viewRect);
|
width = view.css.width.toPx(false, this.style.width);
|
||||||
height = view.css.height.toPx(false, this.style.height, this.viewRect);
|
height = view.css.height.toPx(false, this.style.height);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -278,26 +283,29 @@ export default class Painter {
|
|||||||
console.error('You should set width and height');
|
console.error('You should set width and height');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
width = view.css.width.toPx(false, this.style.width, this.viewRect);
|
width = view.css.width.toPx(false, this.style.width);
|
||||||
height = view.css.height.toPx(false, this.style.height, this.viewRect);
|
height = view.css.height.toPx(false, this.style.height);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let x;
|
let x;
|
||||||
if (view.css && view.css.right) {
|
if (view.css && view.css.right) {
|
||||||
if (typeof view.css.right === 'string') {
|
if (typeof view.css.right === 'string') {
|
||||||
x = this.style.width - view.css.right.toPx(true, this.style.width, this.viewRect);
|
x = this.style.width - view.css.right.toPx(true, this.style.width);
|
||||||
} else {
|
} else {
|
||||||
// 可以用数组方式,把文字长度计算进去
|
// 可以用数组方式,把文字长度计算进去
|
||||||
// [right, 文字id, 乘数(默认 1)]
|
// [right, 文字id, 乘数(默认 1)]
|
||||||
const rights = view.css.right;
|
const rights = view.css.right;
|
||||||
x = this.style.width - rights[0].toPx(true, this.style.width) - this.viewRect[rights[1]].width * (rights[2] || 1);
|
x =
|
||||||
|
this.style.width -
|
||||||
|
rights[0].toPx(true, this.style.width) -
|
||||||
|
penCache.viewRect[rights[1]].width * (rights[2] || 1);
|
||||||
}
|
}
|
||||||
} else if (view.css && view.css.left) {
|
} else if (view.css && view.css.left) {
|
||||||
if (typeof view.css.left === 'string') {
|
if (typeof view.css.left === 'string') {
|
||||||
x = view.css.left.toPx(true, this.style.width, this.viewRect);
|
x = view.css.left.toPx(true, this.style.width);
|
||||||
} else {
|
} else {
|
||||||
const lefts = view.css.left;
|
const lefts = view.css.left;
|
||||||
x = lefts[0].toPx(true, this.style.width) + this.viewRect[lefts[1]].width * (lefts[2] || 1);
|
x = lefts[0].toPx(true, this.style.width) + penCache.viewRect[lefts[1]].width * (lefts[2] || 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
x = 0;
|
x = 0;
|
||||||
@ -305,14 +313,14 @@ export default class Painter {
|
|||||||
//const y = view.css && view.css.bottom ? this.style.height - height - view.css.bottom.toPx(true) : (view.css && view.css.top ? view.css.top.toPx(true) : 0);
|
//const y = view.css && view.css.bottom ? this.style.height - height - view.css.bottom.toPx(true) : (view.css && view.css.top ? view.css.top.toPx(true) : 0);
|
||||||
let y;
|
let y;
|
||||||
if (view.css && view.css.bottom) {
|
if (view.css && view.css.bottom) {
|
||||||
y = this.style.height - height - view.css.bottom.toPx(true, this.style.height, this.viewRect);
|
y = this.style.height - height - view.css.bottom.toPx(true, this.style.height);
|
||||||
} else {
|
} else {
|
||||||
if (view.css && view.css.top) {
|
if (view.css && view.css.top) {
|
||||||
if (typeof view.css.top === 'string') {
|
if (typeof view.css.top === 'string') {
|
||||||
y = view.css.top.toPx(true, this.style.height, this.viewRect);
|
y = view.css.top.toPx(true, this.style.height);
|
||||||
} else {
|
} else {
|
||||||
const tops = view.css.top;
|
const tops = view.css.top;
|
||||||
y = tops[0].toPx(true, this.style.height) + this.viewRect[tops[1]].height * (tops[2] || 1);
|
y = tops[0].toPx(true, this.style.height) + penCache.viewRect[tops[1]].height * (tops[2] || 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
y = 0;
|
y = 0;
|
||||||
@ -396,7 +404,7 @@ export default class Painter {
|
|||||||
}
|
}
|
||||||
this._doShadow(view);
|
this._doShadow(view);
|
||||||
if (view.id) {
|
if (view.id) {
|
||||||
this.viewRect[view.id] = {
|
penCache.viewRect[view.id] = {
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
left: x,
|
left: x,
|
||||||
@ -520,10 +528,9 @@ export default class Painter {
|
|||||||
this.ctx.save();
|
this.ctx.save();
|
||||||
const { width, height, extra } = this._preProcess(view, view.css.background && view.css.borderRadius);
|
const { width, height, extra } = this._preProcess(view, view.css.background && view.css.borderRadius);
|
||||||
this.ctx.fillStyle = view.css.color || 'black';
|
this.ctx.fillStyle = view.css.color || 'black';
|
||||||
if (this.isMoving && JSON.stringify(this.movingCache) !== JSON.stringify({})) {
|
if (view.id && penCache.textLines[view.id]) {
|
||||||
this.viewRect[view.id] = this.movingCache.viewRect;
|
|
||||||
this.ctx.textAlign = view.css.textAlign ? view.css.textAlign : 'left';
|
this.ctx.textAlign = view.css.textAlign ? view.css.textAlign : 'left';
|
||||||
for (const i of this.movingCache.lineArray) {
|
for (const i of penCache.textLines[view.id]) {
|
||||||
const { measuredWith, text, x, y, textDecoration } = i;
|
const { measuredWith, text, x, y, textDecoration } = i;
|
||||||
if (view.css.textStyle === 'stroke') {
|
if (view.css.textStyle === 'stroke') {
|
||||||
this.ctx.strokeText(text, x, y, measuredWith);
|
this.ctx.strokeText(text, x, y, measuredWith);
|
||||||
@ -550,12 +557,7 @@ export default class Painter {
|
|||||||
const _w = this.ctx.measureText(textArray[i]).width;
|
const _w = this.ctx.measureText(textArray[i]).width;
|
||||||
textWidth = _w > textWidth ? _w : textWidth;
|
textWidth = _w > textWidth ? _w : textWidth;
|
||||||
}
|
}
|
||||||
this.viewRect[view.id].width = width ? (textWidth < width ? textWidth : width) : textWidth;
|
penCache.viewRect[view.id].width = width ? (textWidth < width ? textWidth : width) : textWidth;
|
||||||
if (!this.isMoving) {
|
|
||||||
Object.assign(this.callbackInfo, {
|
|
||||||
viewRect: this.viewRect[view.id],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
let lineIndex = 0;
|
let lineIndex = 0;
|
||||||
for (let j = 0; j < textArray.length; ++j) {
|
for (let j = 0; j < textArray.length; ++j) {
|
||||||
@ -619,6 +621,7 @@ export default class Painter {
|
|||||||
lineX = x;
|
lineX = x;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const y =
|
const y =
|
||||||
-(height / 2) +
|
-(height / 2) +
|
||||||
(lineIndex === 0 ? view.css.fontSize.toPx() : view.css.fontSize.toPx() + lineIndex * lineHeight);
|
(lineIndex === 0 ? view.css.fontSize.toPx() : view.css.fontSize.toPx() + lineIndex * lineHeight);
|
||||||
@ -661,16 +664,16 @@ export default class Painter {
|
|||||||
this.ctx.strokeStyle = view.css.color;
|
this.ctx.strokeStyle = view.css.color;
|
||||||
this.ctx.stroke();
|
this.ctx.stroke();
|
||||||
}
|
}
|
||||||
if (!this.isMoving) {
|
if (view.id) {
|
||||||
this.callbackInfo.lineArray
|
penCache.textLines[view.id]
|
||||||
? this.callbackInfo.lineArray.push({
|
? penCache.textLines[view.id].push({
|
||||||
text,
|
text,
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
measuredWith,
|
measuredWith,
|
||||||
textDecoration,
|
textDecoration,
|
||||||
})
|
})
|
||||||
: (this.callbackInfo.lineArray = [
|
: (penCache.textLines[view.id] = [
|
||||||
{
|
{
|
||||||
text,
|
text,
|
||||||
x,
|
x,
|
||||||
|
|||||||
508
painter.js
508
painter.js
@ -1,4 +1,4 @@
|
|||||||
import Pen from './lib/pen';
|
import Pen, { penCache, clearPenCache } from './lib/pen';
|
||||||
import Downloader from './lib/downloader';
|
import Downloader from './lib/downloader';
|
||||||
import WxCanvas from './lib/wx-canvas';
|
import WxCanvas from './lib/wx-canvas';
|
||||||
|
|
||||||
@ -17,7 +17,6 @@ Component({
|
|||||||
canvasNode: null,
|
canvasNode: null,
|
||||||
paintCount: 0,
|
paintCount: 0,
|
||||||
currentPalette: {},
|
currentPalette: {},
|
||||||
movingCache: {},
|
|
||||||
outterDisabled: false,
|
outterDisabled: false,
|
||||||
isDisabled: false,
|
isDisabled: false,
|
||||||
needClear: false,
|
needClear: false,
|
||||||
@ -40,6 +39,7 @@ Component({
|
|||||||
observer: function (newVal, oldVal) {
|
observer: function (newVal, oldVal) {
|
||||||
if (this.isNeedRefresh(newVal, oldVal)) {
|
if (this.isNeedRefresh(newVal, oldVal)) {
|
||||||
this.paintCount = 0;
|
this.paintCount = 0;
|
||||||
|
clearPenCache();
|
||||||
this.startPaint();
|
this.startPaint();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -48,6 +48,7 @@ Component({
|
|||||||
type: Object,
|
type: Object,
|
||||||
observer: function (newVal, oldVal) {
|
observer: function (newVal, oldVal) {
|
||||||
if (!this.isEmpty(newVal) && !this.properties.use2D) {
|
if (!this.isEmpty(newVal) && !this.properties.use2D) {
|
||||||
|
clearPenCache();
|
||||||
this.initDancePalette(newVal);
|
this.initDancePalette(newVal);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -55,11 +56,11 @@ Component({
|
|||||||
// 缩放比,会在传入的 palette 中统一乘以该缩放比
|
// 缩放比,会在传入的 palette 中统一乘以该缩放比
|
||||||
scaleRatio: {
|
scaleRatio: {
|
||||||
type: Number,
|
type: Number,
|
||||||
value: 1
|
value: 1,
|
||||||
},
|
},
|
||||||
widthPixels: {
|
widthPixels: {
|
||||||
type: Number,
|
type: Number,
|
||||||
value: 0
|
value: 0,
|
||||||
},
|
},
|
||||||
// 启用脏检查,默认 false
|
// 启用脏检查,默认 false
|
||||||
dirty: {
|
dirty: {
|
||||||
@ -74,18 +75,16 @@ Component({
|
|||||||
type: Object,
|
type: Object,
|
||||||
observer: function (newVal, oldVal) {
|
observer: function (newVal, oldVal) {
|
||||||
if (newVal && !this.isEmpty(newVal) && !this.properties.use2D) {
|
if (newVal && !this.isEmpty(newVal) && !this.properties.use2D) {
|
||||||
this.doAction(newVal, (callbackInfo) => {
|
this.doAction(newVal, null, false, true);
|
||||||
this.movingCache = callbackInfo
|
|
||||||
}, false, true)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
disableAction: {
|
disableAction: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
observer: function (isDisabled) {
|
observer: function (isDisabled) {
|
||||||
this.outterDisabled = isDisabled
|
this.outterDisabled = isDisabled;
|
||||||
this.isDisabled = isDisabled
|
this.isDisabled = isDisabled;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
clearActionBox: {
|
clearActionBox: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@ -96,12 +95,12 @@ Component({
|
|||||||
this.frontContext.draw();
|
this.frontContext.draw();
|
||||||
}, 100);
|
}, 100);
|
||||||
this.touchedView = {};
|
this.touchedView = {};
|
||||||
this.prevFindedIndex = this.findedIndex
|
this.prevFindedIndex = this.findedIndex;
|
||||||
this.findedIndex = -1;
|
this.findedIndex = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.needClear = needClear
|
this.needClear = needClear;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -112,7 +111,6 @@ Component({
|
|||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断一个 object 是否为 空
|
* 判断一个 object 是否为 空
|
||||||
* @param {object} object
|
* @param {object} object
|
||||||
@ -141,28 +139,26 @@ Component({
|
|||||||
top: `${rect.top}px`,
|
top: `${rect.top}px`,
|
||||||
borderWidth: '4rpx',
|
borderWidth: '4rpx',
|
||||||
borderColor: '#1A7AF8',
|
borderColor: '#1A7AF8',
|
||||||
color: 'transparent'
|
color: 'transparent',
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
if (type === 'text') {
|
if (type === 'text') {
|
||||||
boxArea.css = Object.assign({}, boxArea.css, {
|
boxArea.css = Object.assign({}, boxArea.css, {
|
||||||
borderStyle: 'dashed'
|
borderStyle: 'dashed',
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
if (this.properties.customActionStyle && this.properties.customActionStyle.border) {
|
if (this.properties.customActionStyle && this.properties.customActionStyle.border) {
|
||||||
boxArea.css = Object.assign({}, boxArea.css, this.properties.customActionStyle.border)
|
boxArea.css = Object.assign({}, boxArea.css, this.properties.customActionStyle.border);
|
||||||
}
|
}
|
||||||
Object.assign(boxArea, {
|
Object.assign(boxArea, {
|
||||||
id: 'box'
|
id: 'box',
|
||||||
})
|
});
|
||||||
return boxArea
|
return boxArea;
|
||||||
},
|
},
|
||||||
|
|
||||||
getScaleIcon(rect, type) {
|
getScaleIcon(rect, type) {
|
||||||
let scaleArea = {}
|
let scaleArea = {};
|
||||||
const {
|
const { customActionStyle } = this.properties;
|
||||||
customActionStyle
|
|
||||||
} = this.properties
|
|
||||||
if (customActionStyle && customActionStyle.scale) {
|
if (customActionStyle && customActionStyle.scale) {
|
||||||
scaleArea = {
|
scaleArea = {
|
||||||
type: 'image',
|
type: 'image',
|
||||||
@ -171,8 +167,8 @@ Component({
|
|||||||
height: `${2 * ACTION_DEFAULT_SIZE}rpx`,
|
height: `${2 * ACTION_DEFAULT_SIZE}rpx`,
|
||||||
width: `${2 * ACTION_DEFAULT_SIZE}rpx`,
|
width: `${2 * ACTION_DEFAULT_SIZE}rpx`,
|
||||||
borderRadius: `${ACTION_DEFAULT_SIZE}rpx`,
|
borderRadius: `${ACTION_DEFAULT_SIZE}rpx`,
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
} else {
|
} else {
|
||||||
scaleArea = {
|
scaleArea = {
|
||||||
type: 'rect',
|
type: 'rect',
|
||||||
@ -181,25 +177,26 @@ Component({
|
|||||||
width: `${2 * ACTION_DEFAULT_SIZE}rpx`,
|
width: `${2 * ACTION_DEFAULT_SIZE}rpx`,
|
||||||
borderRadius: `${ACTION_DEFAULT_SIZE}rpx`,
|
borderRadius: `${ACTION_DEFAULT_SIZE}rpx`,
|
||||||
color: '#0000ff',
|
color: '#0000ff',
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
scaleArea.css = Object.assign({}, scaleArea.css, {
|
scaleArea.css = Object.assign({}, scaleArea.css, {
|
||||||
align: 'center',
|
align: 'center',
|
||||||
left: `${rect.right + ACTION_OFFSET.toPx()}px`,
|
left: `${rect.right + ACTION_OFFSET.toPx()}px`,
|
||||||
top: type === 'text' ? `${rect.top - ACTION_OFFSET.toPx() - scaleArea.css.height.toPx() / 2}px` : `${rect.bottom - ACTION_OFFSET.toPx() - scaleArea.css.height.toPx() / 2}px`
|
top:
|
||||||
})
|
type === 'text'
|
||||||
|
? `${rect.top - ACTION_OFFSET.toPx() - scaleArea.css.height.toPx() / 2}px`
|
||||||
|
: `${rect.bottom - ACTION_OFFSET.toPx() - scaleArea.css.height.toPx() / 2}px`,
|
||||||
|
});
|
||||||
Object.assign(scaleArea, {
|
Object.assign(scaleArea, {
|
||||||
id: 'scale'
|
id: 'scale',
|
||||||
})
|
});
|
||||||
return scaleArea
|
return scaleArea;
|
||||||
},
|
},
|
||||||
|
|
||||||
getDeleteIcon(rect) {
|
getDeleteIcon(rect) {
|
||||||
let deleteArea = {}
|
let deleteArea = {};
|
||||||
const {
|
const { customActionStyle } = this.properties;
|
||||||
customActionStyle
|
|
||||||
} = this.properties
|
|
||||||
if (customActionStyle && customActionStyle.scale) {
|
if (customActionStyle && customActionStyle.scale) {
|
||||||
deleteArea = {
|
deleteArea = {
|
||||||
type: 'image',
|
type: 'image',
|
||||||
@ -208,8 +205,8 @@ Component({
|
|||||||
height: `${2 * ACTION_DEFAULT_SIZE}rpx`,
|
height: `${2 * ACTION_DEFAULT_SIZE}rpx`,
|
||||||
width: `${2 * ACTION_DEFAULT_SIZE}rpx`,
|
width: `${2 * ACTION_DEFAULT_SIZE}rpx`,
|
||||||
borderRadius: `${ACTION_DEFAULT_SIZE}rpx`,
|
borderRadius: `${ACTION_DEFAULT_SIZE}rpx`,
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
} else {
|
} else {
|
||||||
deleteArea = {
|
deleteArea = {
|
||||||
type: 'rect',
|
type: 'rect',
|
||||||
@ -218,91 +215,96 @@ Component({
|
|||||||
width: `${2 * ACTION_DEFAULT_SIZE}rpx`,
|
width: `${2 * ACTION_DEFAULT_SIZE}rpx`,
|
||||||
borderRadius: `${ACTION_DEFAULT_SIZE}rpx`,
|
borderRadius: `${ACTION_DEFAULT_SIZE}rpx`,
|
||||||
color: '#0000ff',
|
color: '#0000ff',
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
deleteArea.css = Object.assign({}, deleteArea.css, {
|
deleteArea.css = Object.assign({}, deleteArea.css, {
|
||||||
align: 'center',
|
align: 'center',
|
||||||
left: `${rect.left - ACTION_OFFSET.toPx()}px`,
|
left: `${rect.left - ACTION_OFFSET.toPx()}px`,
|
||||||
top: `${rect.top - ACTION_OFFSET.toPx() - deleteArea.css.height.toPx() / 2}px`
|
top: `${rect.top - ACTION_OFFSET.toPx() - deleteArea.css.height.toPx() / 2}px`,
|
||||||
})
|
});
|
||||||
Object.assign(deleteArea, {
|
Object.assign(deleteArea, {
|
||||||
id: 'delete'
|
id: 'delete',
|
||||||
})
|
});
|
||||||
return deleteArea
|
return deleteArea;
|
||||||
},
|
},
|
||||||
|
|
||||||
doAction(action, callback, isMoving, overwrite) {
|
doAction(action, callback, isMoving, overwrite) {
|
||||||
if (this.properties.use2D) {
|
if (this.properties.use2D) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let newVal = null
|
let newVal = null;
|
||||||
if (action) {
|
if (action) {
|
||||||
newVal = action.view
|
newVal = action.view;
|
||||||
}
|
}
|
||||||
if (newVal && newVal.id && this.touchedView.id !== newVal.id) {
|
if (newVal && newVal.id && this.touchedView.id !== newVal.id) {
|
||||||
// 带 id 的动作给撤回时使用,不带 id,表示对当前选中对象进行操作
|
// 带 id 的动作给撤回时使用,不带 id,表示对当前选中对象进行操作
|
||||||
const {
|
const { views } = this.currentPalette;
|
||||||
views
|
|
||||||
} = this.currentPalette;
|
|
||||||
for (let i = 0; i < views.length; i++) {
|
for (let i = 0; i < views.length; i++) {
|
||||||
if (views[i].id === newVal.id) {
|
if (views[i].id === newVal.id) {
|
||||||
// 跨层回撤,需要重新构建三层关系
|
// 跨层回撤,需要重新构建三层关系
|
||||||
this.touchedView = views[i];
|
this.touchedView = views[i];
|
||||||
this.findedIndex = i;
|
this.findedIndex = i;
|
||||||
this.sliceLayers();
|
this.sliceLayers();
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const doView = this.touchedView
|
const doView = this.touchedView;
|
||||||
|
|
||||||
if (!doView || this.isEmpty(doView)) {
|
if (!doView || this.isEmpty(doView)) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
if (newVal && newVal.css) {
|
if (newVal && newVal.css) {
|
||||||
if (overwrite) {
|
if (overwrite) {
|
||||||
doView.css = newVal.css
|
doView.css = newVal.css;
|
||||||
} else if (Array.isArray(doView.css) && Array.isArray(newVal.css)) {
|
} else if (Array.isArray(doView.css) && Array.isArray(newVal.css)) {
|
||||||
doView.css = Object.assign({}, ...doView.css, ...newVal.css)
|
doView.css = Object.assign({}, ...doView.css, ...newVal.css);
|
||||||
} else if (Array.isArray(doView.css)) {
|
} else if (Array.isArray(doView.css)) {
|
||||||
doView.css = Object.assign({}, ...doView.css, newVal.css)
|
doView.css = Object.assign({}, ...doView.css, newVal.css);
|
||||||
} else if (Array.isArray(newVal.css)) {
|
} else if (Array.isArray(newVal.css)) {
|
||||||
doView.css = Object.assign({}, doView.css, ...newVal.css)
|
doView.css = Object.assign({}, doView.css, ...newVal.css);
|
||||||
} else {
|
} else {
|
||||||
doView.css = Object.assign({}, doView.css, newVal.css)
|
doView.css = Object.assign({}, doView.css, newVal.css);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (newVal && newVal.rect) {
|
if (newVal && newVal.rect) {
|
||||||
doView.rect = newVal.rect;
|
doView.rect = newVal.rect;
|
||||||
}
|
}
|
||||||
if (newVal && newVal.url && doView.url && newVal.url !== doView.url) {
|
if (newVal && newVal.url && doView.url && newVal.url !== doView.url) {
|
||||||
downloader.download(newVal.url, this.properties.LRU).then((path) => {
|
downloader
|
||||||
|
.download(newVal.url, this.properties.LRU)
|
||||||
|
.then(path => {
|
||||||
if (newVal.url.startsWith('https')) {
|
if (newVal.url.startsWith('https')) {
|
||||||
doView.originUrl = newVal.url
|
doView.originUrl = newVal.url;
|
||||||
}
|
}
|
||||||
doView.url = path;
|
doView.url = path;
|
||||||
wx.getImageInfo({
|
wx.getImageInfo({
|
||||||
src: path,
|
src: path,
|
||||||
success: (res) => {
|
success: res => {
|
||||||
doView.sHeight = res.height
|
doView.sHeight = res.height;
|
||||||
doView.sWidth = res.width
|
doView.sWidth = res.width;
|
||||||
this.reDraw(doView, callback, isMoving)
|
this.reDraw(doView, callback, isMoving);
|
||||||
},
|
},
|
||||||
fail: () => {
|
fail: () => {
|
||||||
this.reDraw(doView, callback, isMoving)
|
this.reDraw(doView, callback, isMoving);
|
||||||
}
|
},
|
||||||
|
});
|
||||||
})
|
})
|
||||||
}).catch((error) => {
|
.catch(error => {
|
||||||
// 未下载成功,直接绘制
|
// 未下载成功,直接绘制
|
||||||
console.error(error)
|
console.error(error);
|
||||||
this.reDraw(doView, callback, isMoving)
|
this.reDraw(doView, callback, isMoving);
|
||||||
})
|
});
|
||||||
} else {
|
} else {
|
||||||
(newVal && newVal.text && doView.text && newVal.text !== doView.text) && (doView.text = newVal.text);
|
newVal && newVal.text && doView.text && newVal.text !== doView.text && (doView.text = newVal.text);
|
||||||
(newVal && newVal.content && doView.content && newVal.content !== doView.content) && (doView.content = newVal.content);
|
newVal &&
|
||||||
this.reDraw(doView, callback, isMoving)
|
newVal.content &&
|
||||||
|
doView.content &&
|
||||||
|
newVal.content !== doView.content &&
|
||||||
|
(doView.content = newVal.content);
|
||||||
|
this.reDraw(doView, callback, isMoving);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -310,133 +312,104 @@ Component({
|
|||||||
const draw = {
|
const draw = {
|
||||||
width: this.currentPalette.width,
|
width: this.currentPalette.width,
|
||||||
height: this.currentPalette.height,
|
height: this.currentPalette.height,
|
||||||
views: this.isEmpty(doView) ? [] : [doView]
|
views: this.isEmpty(doView) ? [] : [doView],
|
||||||
}
|
};
|
||||||
const pen = new Pen(this.globalContext, draw);
|
const pen = new Pen(this.globalContext, draw);
|
||||||
|
|
||||||
if (isMoving && doView.type === 'text') {
|
pen.paint(callbackInfo => {
|
||||||
pen.paint((callbackInfo) => {
|
|
||||||
callback && callback(callbackInfo);
|
callback && callback(callbackInfo);
|
||||||
this.triggerEvent('viewUpdate', {
|
this.triggerEvent('viewUpdate', {
|
||||||
view: this.touchedView
|
view: this.touchedView,
|
||||||
});
|
});
|
||||||
}, true, this.movingCache);
|
|
||||||
} else {
|
|
||||||
// 某些机型(华为 P20)非移动和缩放场景下,只绘制一遍会偶然性图片绘制失败
|
|
||||||
// if (!isMoving && !this.isScale) {
|
|
||||||
// pen.paint()
|
|
||||||
// }
|
|
||||||
pen.paint((callbackInfo) => {
|
|
||||||
callback && callback(callbackInfo);
|
|
||||||
this.triggerEvent('viewUpdate', {
|
|
||||||
view: this.touchedView
|
|
||||||
});
|
});
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const {
|
const { rect, css, type } = doView;
|
||||||
rect,
|
|
||||||
css,
|
|
||||||
type
|
|
||||||
} = doView
|
|
||||||
|
|
||||||
this.block = {
|
this.block = {
|
||||||
width: this.currentPalette.width,
|
width: this.currentPalette.width,
|
||||||
height: this.currentPalette.height,
|
height: this.currentPalette.height,
|
||||||
views: this.isEmpty(doView) ? [] : [this.getBox(rect, doView.type)]
|
views: this.isEmpty(doView) ? [] : [this.getBox(rect, doView.type)],
|
||||||
}
|
};
|
||||||
if (css && css.scalable) {
|
if (css && css.scalable) {
|
||||||
this.block.views.push(this.getScaleIcon(rect, type))
|
this.block.views.push(this.getScaleIcon(rect, type));
|
||||||
}
|
}
|
||||||
if (css && css.deletable) {
|
if (css && css.deletable) {
|
||||||
this.block.views.push(this.getDeleteIcon(rect))
|
this.block.views.push(this.getDeleteIcon(rect));
|
||||||
}
|
}
|
||||||
const topBlock = new Pen(this.frontContext, this.block)
|
const topBlock = new Pen(this.frontContext, this.block);
|
||||||
topBlock.paint();
|
topBlock.paint();
|
||||||
},
|
},
|
||||||
|
|
||||||
isInView(x, y, rect) {
|
isInView(x, y, rect) {
|
||||||
return (x > rect.left &&
|
return x > rect.left && y > rect.top && x < rect.right && y < rect.bottom;
|
||||||
y > rect.top &&
|
|
||||||
x < rect.right &&
|
|
||||||
y < rect.bottom
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
|
|
||||||
isInDelete(x, y) {
|
isInDelete(x, y) {
|
||||||
for (const view of this.block.views) {
|
for (const view of this.block.views) {
|
||||||
if (view.id === 'delete') {
|
if (view.id === 'delete') {
|
||||||
return (x > view.rect.left &&
|
return x > view.rect.left && y > view.rect.top && x < view.rect.right && y < view.rect.bottom;
|
||||||
y > view.rect.top &&
|
|
||||||
x < view.rect.right &&
|
|
||||||
y < view.rect.bottom)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
isInScale(x, y) {
|
isInScale(x, y) {
|
||||||
for (const view of this.block.views) {
|
for (const view of this.block.views) {
|
||||||
if (view.id === 'scale') {
|
if (view.id === 'scale') {
|
||||||
return (x > view.rect.left &&
|
return x > view.rect.left && y > view.rect.top && x < view.rect.right && y < view.rect.bottom;
|
||||||
y > view.rect.top &&
|
|
||||||
x < view.rect.right &&
|
|
||||||
y < view.rect.bottom)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
touchedView: {},
|
touchedView: {},
|
||||||
findedIndex: -1,
|
findedIndex: -1,
|
||||||
onClick() {
|
onClick() {
|
||||||
const x = this.startX
|
const x = this.startX;
|
||||||
const y = this.startY
|
const y = this.startY;
|
||||||
const totalLayerCount = this.currentPalette.views.length
|
const totalLayerCount = this.currentPalette.views.length;
|
||||||
let canBeTouched = []
|
let canBeTouched = [];
|
||||||
let isDelete = false
|
let isDelete = false;
|
||||||
let deleteIndex = -1
|
let deleteIndex = -1;
|
||||||
for (let i = totalLayerCount - 1; i >= 0; i--) {
|
for (let i = totalLayerCount - 1; i >= 0; i--) {
|
||||||
const view = this.currentPalette.views[i]
|
const view = this.currentPalette.views[i];
|
||||||
const {
|
const { rect } = view;
|
||||||
rect
|
|
||||||
} = view
|
|
||||||
if (this.touchedView && this.touchedView.id && this.touchedView.id === view.id && this.isInDelete(x, y, rect)) {
|
if (this.touchedView && this.touchedView.id && this.touchedView.id === view.id && this.isInDelete(x, y, rect)) {
|
||||||
canBeTouched.length = 0
|
canBeTouched.length = 0;
|
||||||
deleteIndex = i
|
deleteIndex = i;
|
||||||
isDelete = true
|
isDelete = true;
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
if (this.isInView(x, y, rect)) {
|
if (this.isInView(x, y, rect)) {
|
||||||
canBeTouched.push({
|
canBeTouched.push({
|
||||||
view,
|
view,
|
||||||
index: i
|
index: i,
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.touchedView = {}
|
this.touchedView = {};
|
||||||
if (canBeTouched.length === 0) {
|
if (canBeTouched.length === 0) {
|
||||||
this.findedIndex = -1
|
this.findedIndex = -1;
|
||||||
} else {
|
} else {
|
||||||
let i = 0
|
let i = 0;
|
||||||
const touchAble = canBeTouched.filter(item => Boolean(item.view.id))
|
const touchAble = canBeTouched.filter(item => Boolean(item.view.id));
|
||||||
if (touchAble.length === 0) {
|
if (touchAble.length === 0) {
|
||||||
this.findedIndex = canBeTouched[0].index
|
this.findedIndex = canBeTouched[0].index;
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < touchAble.length; i++) {
|
for (i = 0; i < touchAble.length; i++) {
|
||||||
if (this.findedIndex === touchAble[i].index) {
|
if (this.findedIndex === touchAble[i].index) {
|
||||||
i++
|
i++;
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i === touchAble.length) {
|
if (i === touchAble.length) {
|
||||||
i = 0
|
i = 0;
|
||||||
}
|
}
|
||||||
this.touchedView = touchAble[i].view
|
this.touchedView = touchAble[i].view;
|
||||||
this.findedIndex = touchAble[i].index
|
this.findedIndex = touchAble[i].index;
|
||||||
this.triggerEvent('viewClicked', {
|
this.triggerEvent('viewClicked', {
|
||||||
view: this.touchedView
|
view: this.touchedView,
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.findedIndex < 0 || (this.touchedView && !this.touchedView.id)) {
|
if (this.findedIndex < 0 || (this.touchedView && !this.touchedView.id)) {
|
||||||
@ -446,47 +419,43 @@ Component({
|
|||||||
this.triggerEvent('touchEnd', {
|
this.triggerEvent('touchEnd', {
|
||||||
view: this.currentPalette.views[deleteIndex],
|
view: this.currentPalette.views[deleteIndex],
|
||||||
index: deleteIndex,
|
index: deleteIndex,
|
||||||
type: 'delete'
|
type: 'delete',
|
||||||
})
|
});
|
||||||
this.doAction()
|
this.doAction();
|
||||||
} else if (this.findedIndex < 0) {
|
} else if (this.findedIndex < 0) {
|
||||||
this.triggerEvent('viewClicked', {})
|
this.triggerEvent('viewClicked', {});
|
||||||
}
|
}
|
||||||
this.findedIndex = -1
|
this.findedIndex = -1;
|
||||||
this.prevFindedIndex = -1
|
this.prevFindedIndex = -1;
|
||||||
} else if (this.touchedView && this.touchedView.id) {
|
} else if (this.touchedView && this.touchedView.id) {
|
||||||
this.sliceLayers();
|
this.sliceLayers();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
sliceLayers() {
|
sliceLayers() {
|
||||||
const bottomLayers = this.currentPalette.views.slice(0, this.findedIndex)
|
const bottomLayers = this.currentPalette.views.slice(0, this.findedIndex);
|
||||||
const topLayers = this.currentPalette.views.slice(this.findedIndex + 1)
|
const topLayers = this.currentPalette.views.slice(this.findedIndex + 1);
|
||||||
const bottomDraw = {
|
const bottomDraw = {
|
||||||
width: this.currentPalette.width,
|
width: this.currentPalette.width,
|
||||||
height: this.currentPalette.height,
|
height: this.currentPalette.height,
|
||||||
background: this.currentPalette.background,
|
background: this.currentPalette.background,
|
||||||
views: bottomLayers
|
views: bottomLayers,
|
||||||
}
|
};
|
||||||
const topDraw = {
|
const topDraw = {
|
||||||
width: this.currentPalette.width,
|
width: this.currentPalette.width,
|
||||||
height: this.currentPalette.height,
|
height: this.currentPalette.height,
|
||||||
views: topLayers
|
views: topLayers,
|
||||||
}
|
};
|
||||||
if (this.prevFindedIndex < this.findedIndex) {
|
if (this.prevFindedIndex < this.findedIndex) {
|
||||||
new Pen(this.bottomContext, bottomDraw).paint();
|
new Pen(this.bottomContext, bottomDraw).paint();
|
||||||
this.doAction(null, (callbackInfo) => {
|
this.doAction();
|
||||||
this.movingCache = callbackInfo
|
|
||||||
})
|
|
||||||
new Pen(this.topContext, topDraw).paint();
|
new Pen(this.topContext, topDraw).paint();
|
||||||
} else {
|
} else {
|
||||||
new Pen(this.topContext, topDraw).paint();
|
new Pen(this.topContext, topDraw).paint();
|
||||||
this.doAction(null, (callbackInfo) => {
|
this.doAction();
|
||||||
this.movingCache = callbackInfo
|
|
||||||
})
|
|
||||||
new Pen(this.bottomContext, bottomDraw).paint();
|
new Pen(this.bottomContext, bottomDraw).paint();
|
||||||
}
|
}
|
||||||
this.prevFindedIndex = this.findedIndex
|
this.prevFindedIndex = this.findedIndex;
|
||||||
},
|
},
|
||||||
|
|
||||||
startX: 0,
|
startX: 0,
|
||||||
@ -497,116 +466,105 @@ Component({
|
|||||||
startTimeStamp: 0,
|
startTimeStamp: 0,
|
||||||
onTouchStart(event) {
|
onTouchStart(event) {
|
||||||
if (this.isDisabled) {
|
if (this.isDisabled) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
const {
|
const { x, y } = event.touches[0];
|
||||||
x,
|
this.startX = x;
|
||||||
y
|
this.startY = y;
|
||||||
} = event.touches[0]
|
this.startTimeStamp = new Date().getTime();
|
||||||
this.startX = x
|
|
||||||
this.startY = y
|
|
||||||
this.startTimeStamp = new Date().getTime()
|
|
||||||
if (this.touchedView && !this.isEmpty(this.touchedView)) {
|
if (this.touchedView && !this.isEmpty(this.touchedView)) {
|
||||||
const {
|
const { rect } = this.touchedView;
|
||||||
rect
|
|
||||||
} = this.touchedView
|
|
||||||
if (this.isInScale(x, y, rect)) {
|
if (this.isInScale(x, y, rect)) {
|
||||||
this.isScale = true
|
this.isScale = true;
|
||||||
this.movingCache = {}
|
this.startH = rect.bottom - rect.top;
|
||||||
this.startH = rect.bottom - rect.top
|
this.startW = rect.right - rect.left;
|
||||||
this.startW = rect.right - rect.left
|
|
||||||
} else {
|
} else {
|
||||||
this.isScale = false
|
this.isScale = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.isScale = false
|
this.isScale = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onTouchEnd(e) {
|
onTouchEnd(e) {
|
||||||
if (this.isDisabled) {
|
if (this.isDisabled) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
const current = new Date().getTime()
|
const current = new Date().getTime();
|
||||||
if ((current - this.startTimeStamp) <= 500 && !this.hasMove) {
|
if (current - this.startTimeStamp <= 500 && !this.hasMove) {
|
||||||
!this.isScale && this.onClick(e)
|
!this.isScale && this.onClick(e);
|
||||||
} else if (this.touchedView && !this.isEmpty(this.touchedView)) {
|
} else if (this.touchedView && !this.isEmpty(this.touchedView)) {
|
||||||
this.triggerEvent('touchEnd', {
|
this.triggerEvent('touchEnd', {
|
||||||
view: this.touchedView,
|
view: this.touchedView,
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
this.hasMove = false
|
this.hasMove = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
onTouchCancel(e) {
|
onTouchCancel(e) {
|
||||||
if (this.isDisabled) {
|
if (this.isDisabled) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
this.onTouchEnd(e)
|
this.onTouchEnd(e);
|
||||||
},
|
},
|
||||||
|
|
||||||
hasMove: false,
|
hasMove: false,
|
||||||
onTouchMove(event) {
|
onTouchMove(event) {
|
||||||
if (this.isDisabled) {
|
if (this.isDisabled) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
this.hasMove = true
|
this.hasMove = true;
|
||||||
if (!this.touchedView || (this.touchedView && !this.touchedView.id)) {
|
if (!this.touchedView || (this.touchedView && !this.touchedView.id)) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
const {
|
const { x, y } = event.touches[0];
|
||||||
x,
|
const offsetX = x - this.startX;
|
||||||
y
|
const offsetY = y - this.startY;
|
||||||
} = event.touches[0]
|
const { rect, type } = this.touchedView;
|
||||||
const offsetX = x - this.startX
|
let css = {};
|
||||||
const offsetY = y - this.startY
|
|
||||||
const {
|
|
||||||
rect,
|
|
||||||
type
|
|
||||||
} = this.touchedView
|
|
||||||
let css = {}
|
|
||||||
if (this.isScale) {
|
if (this.isScale) {
|
||||||
const newW = this.startW + offsetX > 1 ? this.startW + offsetX : 1
|
clearPenCache(this.touchedView.id);
|
||||||
|
const newW = this.startW + offsetX > 1 ? this.startW + offsetX : 1;
|
||||||
if (this.touchedView.css && this.touchedView.css.minWidth) {
|
if (this.touchedView.css && this.touchedView.css.minWidth) {
|
||||||
if (newW < this.touchedView.css.minWidth.toPx()) {
|
if (newW < this.touchedView.css.minWidth.toPx()) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.touchedView.rect && this.touchedView.rect.minWidth) {
|
if (this.touchedView.rect && this.touchedView.rect.minWidth) {
|
||||||
if (newW < this.touchedView.rect.minWidth) {
|
if (newW < this.touchedView.rect.minWidth) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const newH = this.startH + offsetY > 1 ? this.startH + offsetY : 1
|
const newH = this.startH + offsetY > 1 ? this.startH + offsetY : 1;
|
||||||
css = {
|
css = {
|
||||||
width: `${newW}px`,
|
width: `${newW}px`,
|
||||||
}
|
};
|
||||||
if (type !== 'text') {
|
if (type !== 'text') {
|
||||||
if (type === 'image') {
|
if (type === 'image') {
|
||||||
css.height = `${(newW) * this.startH / this.startW }px`
|
css.height = `${(newW * this.startH) / this.startW}px`;
|
||||||
} else {
|
} else {
|
||||||
css.height = `${newH}px`
|
css.height = `${newH}px`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.startX = x
|
this.startX = x;
|
||||||
this.startY = y
|
this.startY = y;
|
||||||
css = {
|
css = {
|
||||||
left: `${rect.x + offsetX}px`,
|
left: `${rect.x + offsetX}px`,
|
||||||
top: `${rect.y + offsetY}px`,
|
top: `${rect.y + offsetY}px`,
|
||||||
right: undefined,
|
right: undefined,
|
||||||
bottom: undefined
|
bottom: undefined,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
this.doAction(
|
||||||
this.doAction({
|
{
|
||||||
view: {
|
view: {
|
||||||
css
|
css,
|
||||||
}
|
},
|
||||||
}, (callbackInfo) => {
|
},
|
||||||
if (this.isScale) {
|
null,
|
||||||
this.movingCache = callbackInfo
|
!this.isScale,
|
||||||
}
|
);
|
||||||
}, !this.isScale)
|
|
||||||
},
|
},
|
||||||
|
|
||||||
initScreenK() {
|
initScreenK() {
|
||||||
@ -631,12 +589,9 @@ Component({
|
|||||||
}
|
}
|
||||||
this.isDisabled = true;
|
this.isDisabled = true;
|
||||||
this.initScreenK();
|
this.initScreenK();
|
||||||
this.downloadImages(this.properties.dancePalette).then(async (palette) => {
|
this.downloadImages(this.properties.dancePalette).then(async palette => {
|
||||||
this.currentPalette = palette
|
this.currentPalette = palette;
|
||||||
const {
|
const { width, height } = palette;
|
||||||
width,
|
|
||||||
height
|
|
||||||
} = palette;
|
|
||||||
|
|
||||||
if (!width || !height) {
|
if (!width || !height) {
|
||||||
console.error(`You should set width and height correctly for painter, width: ${width}, height: ${height}`);
|
console.error(`You should set width and height correctly for painter, width: ${width}, height: ${height}`);
|
||||||
@ -663,10 +618,7 @@ Component({
|
|||||||
|
|
||||||
startPaint() {
|
startPaint() {
|
||||||
this.initScreenK();
|
this.initScreenK();
|
||||||
const {
|
const { width, height } = this.properties.palette;
|
||||||
width,
|
|
||||||
height
|
|
||||||
} = this.properties.palette;
|
|
||||||
|
|
||||||
if (!width || !height) {
|
if (!width || !height) {
|
||||||
console.error(`You should set width and height correctly for painter, width: ${width}, height: ${height}`);
|
console.error(`You should set width and height correctly for painter, width: ${width}, height: ${height}`);
|
||||||
@ -680,17 +632,19 @@ Component({
|
|||||||
needScale = this.properties.use2D;
|
needScale = this.properties.use2D;
|
||||||
}
|
}
|
||||||
if (this.properties.widthPixels) {
|
if (this.properties.widthPixels) {
|
||||||
setStringPrototype(this.screenK, this.properties.widthPixels / this.canvasWidthInPx)
|
setStringPrototype(this.screenK, this.properties.widthPixels / this.canvasWidthInPx);
|
||||||
this.canvasWidthInPx = this.properties.widthPixels
|
this.canvasWidthInPx = this.properties.widthPixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.canvasHeightInPx !== height.toPx()) {
|
if (this.canvasHeightInPx !== height.toPx()) {
|
||||||
this.canvasHeightInPx = height.toPx();
|
this.canvasHeightInPx = height.toPx();
|
||||||
needScale = needScale || this.properties.use2D;
|
needScale = needScale || this.properties.use2D;
|
||||||
}
|
}
|
||||||
this.setData({
|
this.setData(
|
||||||
|
{
|
||||||
photoStyle: `width:${this.canvasWidthInPx}px;height:${this.canvasHeightInPx}px;`,
|
photoStyle: `width:${this.canvasWidthInPx}px;height:${this.canvasHeightInPx}px;`,
|
||||||
}, function () {
|
},
|
||||||
|
function () {
|
||||||
this.downloadImages(this.properties.palette).then(async palette => {
|
this.downloadImages(this.properties.palette).then(async palette => {
|
||||||
if (!this.photoContext) {
|
if (!this.photoContext) {
|
||||||
this.photoContext = await this.getCanvasContext(this.properties.use2D, 'photo');
|
this.photoContext = await this.getCanvasContext(this.properties.use2D, 'photo');
|
||||||
@ -706,7 +660,8 @@ Component({
|
|||||||
});
|
});
|
||||||
setStringPrototype(this.screenK, this.properties.scaleRatio);
|
setStringPrototype(this.screenK, this.properties.scaleRatio);
|
||||||
});
|
});
|
||||||
});
|
},
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
downloadImages(palette) {
|
downloadImages(palette) {
|
||||||
@ -716,38 +671,42 @@ Component({
|
|||||||
const paletteCopy = JSON.parse(JSON.stringify(palette));
|
const paletteCopy = JSON.parse(JSON.stringify(palette));
|
||||||
if (paletteCopy.background) {
|
if (paletteCopy.background) {
|
||||||
preCount++;
|
preCount++;
|
||||||
downloader.download(paletteCopy.background, this.properties.LRU).then((path) => {
|
downloader.download(paletteCopy.background, this.properties.LRU).then(
|
||||||
|
path => {
|
||||||
paletteCopy.background = path;
|
paletteCopy.background = path;
|
||||||
completeCount++;
|
completeCount++;
|
||||||
if (preCount === completeCount) {
|
if (preCount === completeCount) {
|
||||||
resolve(paletteCopy);
|
resolve(paletteCopy);
|
||||||
}
|
}
|
||||||
}, () => {
|
},
|
||||||
|
() => {
|
||||||
completeCount++;
|
completeCount++;
|
||||||
if (preCount === completeCount) {
|
if (preCount === completeCount) {
|
||||||
resolve(paletteCopy);
|
resolve(paletteCopy);
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (paletteCopy.views) {
|
if (paletteCopy.views) {
|
||||||
for (const view of paletteCopy.views) {
|
for (const view of paletteCopy.views) {
|
||||||
if (view && view.type === 'image' && view.url) {
|
if (view && view.type === 'image' && view.url) {
|
||||||
preCount++;
|
preCount++;
|
||||||
/* eslint-disable no-loop-func */
|
/* eslint-disable no-loop-func */
|
||||||
downloader.download(view.url, this.properties.LRU).then((path) => {
|
downloader.download(view.url, this.properties.LRU).then(
|
||||||
|
path => {
|
||||||
view.originUrl = view.url;
|
view.originUrl = view.url;
|
||||||
view.url = path;
|
view.url = path;
|
||||||
wx.getImageInfo({
|
wx.getImageInfo({
|
||||||
src: path,
|
src: path,
|
||||||
success: (res) => {
|
success: res => {
|
||||||
// 获得一下图片信息,供后续裁减使用
|
// 获得一下图片信息,供后续裁减使用
|
||||||
view.sWidth = res.width;
|
view.sWidth = res.width;
|
||||||
view.sHeight = res.height;
|
view.sHeight = res.height;
|
||||||
},
|
},
|
||||||
fail: (error) => {
|
fail: error => {
|
||||||
// 如果图片坏了,则直接置空,防止坑爹的 canvas 画崩溃了
|
// 如果图片坏了,则直接置空,防止坑爹的 canvas 画崩溃了
|
||||||
console.warn(`getImageInfo ${view.originUrl} failed, ${JSON.stringify(error)}`);
|
console.warn(`getImageInfo ${view.originUrl} failed, ${JSON.stringify(error)}`);
|
||||||
view.url = "";
|
view.url = '';
|
||||||
},
|
},
|
||||||
complete: () => {
|
complete: () => {
|
||||||
completeCount++;
|
completeCount++;
|
||||||
@ -756,12 +715,14 @@ Component({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}, () => {
|
},
|
||||||
|
() => {
|
||||||
completeCount++;
|
completeCount++;
|
||||||
if (preCount === completeCount) {
|
if (preCount === completeCount) {
|
||||||
resolve(paletteCopy);
|
resolve(paletteCopy);
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -774,34 +735,37 @@ Component({
|
|||||||
saveImgToLocal() {
|
saveImgToLocal() {
|
||||||
const that = this;
|
const that = this;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
wx.canvasToTempFilePath({
|
wx.canvasToTempFilePath(
|
||||||
|
{
|
||||||
canvasId: 'photo',
|
canvasId: 'photo',
|
||||||
canvas: that.properties.use2D ? that.canvasNode : null,
|
canvas: that.properties.use2D ? that.canvasNode : null,
|
||||||
destWidth: that.canvasWidthInPx * getApp().systemInfo.pixelRatio,
|
destWidth: that.canvasWidthInPx,
|
||||||
destHeight: that.canvasHeightInPx * getApp().systemInfo.pixelRatio,
|
destHeight: that.canvasHeightInPx,
|
||||||
success: function (res) {
|
success: function (res) {
|
||||||
that.getImageInfo(res.tempFilePath);
|
that.getImageInfo(res.tempFilePath);
|
||||||
},
|
},
|
||||||
fail: function (error) {
|
fail: function (error) {
|
||||||
console.error(`canvasToTempFilePath failed, ${JSON.stringify(error)}`);
|
console.error(`canvasToTempFilePath failed, ${JSON.stringify(error)}`);
|
||||||
that.triggerEvent('imgErr', {
|
that.triggerEvent('imgErr', {
|
||||||
error: error
|
error: error,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
}, this);
|
},
|
||||||
|
this,
|
||||||
|
);
|
||||||
}, 300);
|
}, 300);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
getCanvasContext(use2D, id) {
|
getCanvasContext(use2D, id) {
|
||||||
const that = this;
|
const that = this;
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
if (use2D) {
|
if (use2D) {
|
||||||
const query = wx.createSelectorQuery().in(that);
|
const query = wx.createSelectorQuery().in(that);
|
||||||
const selectId = `#${id}`;
|
const selectId = `#${id}`;
|
||||||
query.select(selectId)
|
query
|
||||||
|
.select(selectId)
|
||||||
.fields({ node: true, size: true })
|
.fields({ node: true, size: true })
|
||||||
.exec((res) => {
|
.exec(res => {
|
||||||
that.canvasNode = res[0].node;
|
that.canvasNode = res[0].node;
|
||||||
const ctx = that.canvasNode.getContext('2d');
|
const ctx = that.canvasNode.getContext('2d');
|
||||||
const wxCanvas = new WxCanvas('2d', ctx, id, true, that.canvasNode);
|
const wxCanvas = new WxCanvas('2d', ctx, id, true, that.canvasNode);
|
||||||
@ -811,36 +775,41 @@ Component({
|
|||||||
const temp = wx.createCanvasContext(id, that);
|
const temp = wx.createCanvasContext(id, that);
|
||||||
resolve(new WxCanvas('mina', temp, id, true));
|
resolve(new WxCanvas('mina', temp, id, true));
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
getImageInfo(filePath) {
|
getImageInfo(filePath) {
|
||||||
const that = this;
|
const that = this;
|
||||||
wx.getImageInfo({
|
wx.getImageInfo({
|
||||||
src: filePath,
|
src: filePath,
|
||||||
success: (infoRes) => {
|
success: infoRes => {
|
||||||
if (that.paintCount > MAX_PAINT_COUNT) {
|
if (that.paintCount > MAX_PAINT_COUNT) {
|
||||||
const error = `The result is always fault, even we tried ${MAX_PAINT_COUNT} times`;
|
const error = `The result is always fault, even we tried ${MAX_PAINT_COUNT} times`;
|
||||||
console.error(error);
|
console.error(error);
|
||||||
that.triggerEvent('imgErr', {
|
that.triggerEvent('imgErr', {
|
||||||
error: error
|
error: error,
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 比例相符时才证明绘制成功,否则进行强制重绘制
|
// 比例相符时才证明绘制成功,否则进行强制重绘制
|
||||||
if (Math.abs((infoRes.width * that.canvasHeightInPx - that.canvasWidthInPx * infoRes.height) / (infoRes.height * that.canvasHeightInPx)) < 0.01) {
|
if (
|
||||||
|
Math.abs(
|
||||||
|
(infoRes.width * that.canvasHeightInPx - that.canvasWidthInPx * infoRes.height) /
|
||||||
|
(infoRes.height * that.canvasHeightInPx),
|
||||||
|
) < 0.01
|
||||||
|
) {
|
||||||
that.triggerEvent('imgOK', {
|
that.triggerEvent('imgOK', {
|
||||||
path: filePath
|
path: filePath,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
that.startPaint();
|
that.startPaint();
|
||||||
}
|
}
|
||||||
that.paintCount++;
|
that.paintCount++;
|
||||||
},
|
},
|
||||||
fail: (error) => {
|
fail: error => {
|
||||||
console.error(`getImageInfo failed, ${JSON.stringify(error)}`);
|
console.error(`getImageInfo failed, ${JSON.stringify(error)}`);
|
||||||
that.triggerEvent('imgErr', {
|
that.triggerEvent('imgErr', {
|
||||||
error: error
|
error: error,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -848,15 +817,13 @@ Component({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
function setStringPrototype(screenK, scale) {
|
function setStringPrototype(screenK, scale) {
|
||||||
/* eslint-disable no-extend-native */
|
/* eslint-disable no-extend-native */
|
||||||
/**
|
/**
|
||||||
* string 到对应的 px
|
* string 到对应的 px
|
||||||
* @param {Number} baseSize 当设置了 % 号时,设置的基准值
|
* @param {Number} baseSize 当设置了 % 号时,设置的基准值
|
||||||
* @param {Object} relativeViewRect 所相对的 view 的信息
|
|
||||||
*/
|
*/
|
||||||
String.prototype.toPx = function toPx(_, baseSize, relativeViewRect) {
|
String.prototype.toPx = function toPx(_, baseSize) {
|
||||||
if (this === '0') {
|
if (this === '0') {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -881,14 +848,13 @@ function setStringPrototype(screenK, scale) {
|
|||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
const formula = /^calc\((.+)\)$/.exec(this)
|
const formula = /^calc\((.+)\)$/.exec(this);
|
||||||
if (formula && formula[1]) {
|
if (formula && formula[1]) {
|
||||||
// 进行 calc 计算
|
// 进行 calc 计算
|
||||||
const afterOne = formula[1].replace(/([^\s]+)\.(left|right|bottom|top|width|height)/g, (word) => {
|
const afterOne = formula[1].replace(/([^\s]+)\.(left|right|bottom|top|width|height)/g, word => {
|
||||||
const [id, attr] = word.split('.');
|
const [id, attr] = word.split('.');
|
||||||
return relativeViewRect[id][attr]
|
return penCache.viewRect[id][attr];
|
||||||
}
|
});
|
||||||
);
|
|
||||||
const afterTwo = afterOne.replace(new RegExp(REG, 'g'), parsePx);
|
const afterTwo = afterOne.replace(new RegExp(REG, 'g'), parsePx);
|
||||||
return calc(afterTwo);
|
return calc(afterTwo);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
14
painter.wxml
14
painter.wxml
@ -1,6 +1,7 @@
|
|||||||
<view style='position: relative;{{customStyle}};{{painterStyle}}'>
|
<view style='position: relative;{{customStyle}};{{painterStyle}}'>
|
||||||
<block wx:if="{{!use2D}}">
|
<block wx:if="{{!use2D}}">
|
||||||
<canvas canvas-id="photo" style="{{photoStyle}};position: absolute; left: -9999px; top: -9999rpx;" />
|
<canvas canvas-id="photo" style="{{photoStyle}};position: absolute; left: -9999px; top: -9999rpx;" />
|
||||||
|
<block wx:if="{{dancePalette}}">
|
||||||
<canvas canvas-id="bottom" style="{{painterStyle}};position: absolute;" />
|
<canvas canvas-id="bottom" style="{{painterStyle}};position: absolute;" />
|
||||||
<canvas canvas-id="k-canvas" style="{{painterStyle}};position: absolute;" />
|
<canvas canvas-id="k-canvas" style="{{painterStyle}};position: absolute;" />
|
||||||
<canvas canvas-id="top" style="{{painterStyle}};position: absolute;" />
|
<canvas canvas-id="top" style="{{painterStyle}};position: absolute;" />
|
||||||
@ -13,19 +14,8 @@
|
|||||||
bindtouchcancel="onTouchCancel"
|
bindtouchcancel="onTouchCancel"
|
||||||
disable-scroll="{{true}}" />
|
disable-scroll="{{true}}" />
|
||||||
</block>
|
</block>
|
||||||
|
</block>
|
||||||
<block wx:if="{{use2D}}">
|
<block wx:if="{{use2D}}">
|
||||||
<canvas type="2d" id="photo" style="{{photoStyle}};" />
|
<canvas type="2d" id="photo" style="{{photoStyle}};" />
|
||||||
<!-- <canvas type="2d" id="bottom" style="{{painterStyle}};position: absolute;" />
|
|
||||||
<canvas type="2d" id="k-canvas" style="{{painterStyle}};position: absolute;" />
|
|
||||||
<canvas type="2d" id="top" style="{{painterStyle}};position: absolute;" />
|
|
||||||
<canvas
|
|
||||||
type="2d"
|
|
||||||
id="front"
|
|
||||||
style="{{painterStyle}};position: absolute;"
|
|
||||||
bindtouchstart="onTouchStart"
|
|
||||||
bindtouchmove="onTouchMove"
|
|
||||||
bindtouchend="onTouchEnd"
|
|
||||||
bindtouchcancel="onTouchCancel"
|
|
||||||
disable-scroll="{{true}}" /> -->
|
|
||||||
</block>
|
</block>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user