改为点选,增加顶部框,支持缩放
This commit is contained in:
parent
34c16e8a36
commit
4cedc0bf63
226
painter.js
226
painter.js
@ -13,6 +13,9 @@ Component({
|
|||||||
paintCount: 0,
|
paintCount: 0,
|
||||||
currentPalette: {},
|
currentPalette: {},
|
||||||
globalContext: {},
|
globalContext: {},
|
||||||
|
frontContext: {},
|
||||||
|
bottomContext: {},
|
||||||
|
topContext: {},
|
||||||
hasIdViews: [],
|
hasIdViews: [],
|
||||||
/**
|
/**
|
||||||
* 组件的属性列表
|
* 组件的属性列表
|
||||||
@ -23,7 +26,7 @@ Component({
|
|||||||
},
|
},
|
||||||
palette: {
|
palette: {
|
||||||
type: Object,
|
type: Object,
|
||||||
observer: function (newVal, oldVal) {
|
observer: function(newVal, oldVal) {
|
||||||
if (this.isNeedRefresh(newVal, oldVal)) {
|
if (this.isNeedRefresh(newVal, oldVal)) {
|
||||||
this.paintCount = 0;
|
this.paintCount = 0;
|
||||||
this.startPaint();
|
this.startPaint();
|
||||||
@ -41,7 +44,7 @@ Component({
|
|||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
type: Object,
|
type: Object,
|
||||||
observer: function (newVal, oldVal) {
|
observer: function(newVal, oldVal) {
|
||||||
this.doAction(newVal)
|
this.doAction(newVal)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -87,43 +90,111 @@ Component({
|
|||||||
}
|
}
|
||||||
const pen = new Pen(this.globalContext, draw);
|
const pen = new Pen(this.globalContext, draw);
|
||||||
pen.paint();
|
pen.paint();
|
||||||
|
const { rect } = this.touchedView
|
||||||
|
const block = {
|
||||||
|
width: this.currentPalette.width,
|
||||||
|
height: this.currentPalette.height,
|
||||||
|
views: [{
|
||||||
|
type: 'rect',
|
||||||
|
css: {
|
||||||
|
height: `${rect.bottom - rect.top}px`,
|
||||||
|
width: `${rect.right - rect.left}px`,
|
||||||
|
left: `${rect.left}px`,
|
||||||
|
top: `${rect.top}px`,
|
||||||
|
borderWidth: '2rpx',
|
||||||
|
borderColor: '#0000ff',
|
||||||
|
color: 'transparent'
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
type: 'rect',
|
||||||
|
css: {
|
||||||
|
height: '20px',
|
||||||
|
width: '20px',
|
||||||
|
borderRadius: '10px',
|
||||||
|
color: '#0000ff',
|
||||||
|
left: `${rect.right - 10}px`,
|
||||||
|
top: `${rect.bottom - 10}px`
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
const topBlock = new Pen(this.topContext, block)
|
||||||
|
topBlock.paint();
|
||||||
|
},
|
||||||
|
|
||||||
|
inArea(x, y, rect, hasTouchedView) {
|
||||||
|
return (hasTouchedView &&
|
||||||
|
((x > rect.left &&
|
||||||
|
y > rect.top &&
|
||||||
|
x < rect.right &&
|
||||||
|
y < rect.bottom) ||
|
||||||
|
(x > rect.right - 10 &&
|
||||||
|
y > rect.bottom - 10 &&
|
||||||
|
x < rect.right + 10 &&
|
||||||
|
y < rect.bottom + 10))
|
||||||
|
) ||
|
||||||
|
(x > rect.left &&
|
||||||
|
y > rect.top &&
|
||||||
|
x < rect.right &&
|
||||||
|
y < rect.bottom
|
||||||
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
startX: 0,
|
|
||||||
startY: 0,
|
|
||||||
touchedView: {},
|
touchedView: {},
|
||||||
onTouchStart(event) {
|
findedIndex: -1,
|
||||||
const {
|
onClick(event) {
|
||||||
x,
|
const x = this.startX
|
||||||
y
|
const y = this.startY
|
||||||
} = event.touches[0]
|
|
||||||
this.startX = x
|
|
||||||
this.startY = y
|
|
||||||
const totalLayerCount = this.currentPalette.views.length
|
const totalLayerCount = this.currentPalette.views.length
|
||||||
let findedIndex = -1;
|
const hasTouchedView = this.findedIndex !== -1
|
||||||
this.touchedView = {}
|
this.touchedView = {}
|
||||||
|
const canBeTouched = []
|
||||||
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]
|
||||||
if (x > view.rect.left && y > view.rect.top && x < view.rect.right && y < view.rect.bottom) {
|
const { rect, id } = view
|
||||||
if (view.id) {
|
if (this.inArea(x, y, rect, hasTouchedView) && id) {
|
||||||
this.touchedView = view
|
canBeTouched.push({
|
||||||
this.triggerEvent('touchStart', {
|
view,
|
||||||
id: view.id,
|
index: i
|
||||||
css: view.css,
|
})
|
||||||
rect: view.rect
|
|
||||||
})
|
|
||||||
}
|
|
||||||
findedIndex = i;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (canBeTouched.length === 0) {
|
||||||
if (findedIndex < 0) {
|
this.findedIndex = -1
|
||||||
// 证明点击了背景
|
} else {
|
||||||
|
let i = 0
|
||||||
|
for (i = 0; i < canBeTouched.length; i++) {
|
||||||
|
if (this.findedIndex === canBeTouched[i].index) {
|
||||||
|
i++
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i === canBeTouched.length) {
|
||||||
|
i = 0
|
||||||
|
}
|
||||||
|
this.touchedView = canBeTouched[i].view
|
||||||
|
this.findedIndex = canBeTouched[i].index
|
||||||
|
const { rect, id, css } = this.touchedView
|
||||||
|
this.triggerEvent('touchStart', {
|
||||||
|
id: id,
|
||||||
|
css: css,
|
||||||
|
rect: rect
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (this.findedIndex < 0 || (this.touchedView && !this.touchedView.id)) {
|
||||||
|
// 证明点击了背景 或无法移动的view
|
||||||
|
this.touchedView = {}
|
||||||
|
this.findedIndex = -1
|
||||||
|
const block = {
|
||||||
|
width: this.currentPalette.width,
|
||||||
|
height: this.currentPalette.height,
|
||||||
|
views: []
|
||||||
|
}
|
||||||
|
const topBlock = new Pen(this.topContext, block)
|
||||||
|
topBlock.paint();
|
||||||
this.triggerEvent('touchStart', {})
|
this.triggerEvent('touchStart', {})
|
||||||
} else if (this.touchedView.id) {
|
} else if (this.touchedView && this.touchedView.id) {
|
||||||
const bottomLayers = this.currentPalette.views.slice(0, findedIndex)
|
const bottomLayers = this.currentPalette.views.slice(0, this.findedIndex)
|
||||||
const topLayers = this.currentPalette.views.slice(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,
|
||||||
@ -135,31 +206,62 @@ Component({
|
|||||||
height: this.currentPalette.height,
|
height: this.currentPalette.height,
|
||||||
views: topLayers
|
views: topLayers
|
||||||
}
|
}
|
||||||
if (this.prevFindedIndex < findedIndex) {
|
if (this.prevFindedIndex < this.findedIndex) {
|
||||||
new Pen(wx.createCanvasContext('bottom', this), bottomDraw).paint();
|
new Pen(this.bottomContext, bottomDraw).paint();
|
||||||
new Pen(wx.createCanvasContext('top', this), topDraw).paint();
|
this.doAction()
|
||||||
|
new Pen(this.frontContext, topDraw).paint();
|
||||||
} else {
|
} else {
|
||||||
new Pen(wx.createCanvasContext('top', this), topDraw).paint();
|
new Pen(this.frontContext, topDraw).paint();
|
||||||
new Pen(wx.createCanvasContext('bottom', this), bottomDraw).paint();
|
this.doAction()
|
||||||
|
new Pen(this.bottomContext, bottomDraw).paint();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.doAction()
|
|
||||||
}
|
}
|
||||||
this.prevFindedIndex = findedIndex
|
this.prevFindedIndex = this.findedIndex
|
||||||
},
|
},
|
||||||
|
|
||||||
onTouchEnd() {
|
startX: 0,
|
||||||
this.touchedView = {}
|
startY: 0,
|
||||||
|
startH: 0,
|
||||||
|
startW: 0,
|
||||||
|
isScale: false,
|
||||||
|
startTimeStamp: 0,
|
||||||
|
onTouchStart(event) {
|
||||||
|
const {
|
||||||
|
x,
|
||||||
|
y
|
||||||
|
} = event.touches[0]
|
||||||
|
this.startX = x
|
||||||
|
this.startY = y
|
||||||
|
this.startTimeStamp = new Date().getTime()
|
||||||
|
if (this.touchedView && JSON.stringify(this.touchedView) !== JSON.stringify({})) {
|
||||||
|
const { rect } = this.touchedView
|
||||||
|
if (rect.right - 10 < x && x < rect.right + 10 && rect.bottom - 10 < y && y < rect.bottom + 10) {
|
||||||
|
this.isScale = true
|
||||||
|
this.startH = rect.bottom - rect.top
|
||||||
|
this.startW = rect.right - rect.left
|
||||||
|
} else {
|
||||||
|
this.isScale = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onTouchEnd(e) {
|
||||||
|
const current = new Date().getTime()
|
||||||
|
if ((current - this.startTimeStamp) <= 100 && !this.hasMove) {
|
||||||
|
this.onClick(e)
|
||||||
|
}
|
||||||
|
this.hasMove = false
|
||||||
this.triggerEvent('touchEnd')
|
this.triggerEvent('touchEnd')
|
||||||
},
|
},
|
||||||
|
|
||||||
onTouchCancel() {
|
onTouchCancel() {
|
||||||
this.touchedView = {}
|
|
||||||
this.triggerEvent('touchCancel')
|
this.triggerEvent('touchCancel')
|
||||||
},
|
},
|
||||||
|
|
||||||
|
hasMove: false,
|
||||||
onTouchMove(event) {
|
onTouchMove(event) {
|
||||||
if (!this.touchedView.id) {
|
this.hasMove = true
|
||||||
|
if (!this.touchedView || (this.touchedView && !this.touchedView.id)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const {
|
const {
|
||||||
@ -168,19 +270,36 @@ Component({
|
|||||||
} = event.touches[0]
|
} = event.touches[0]
|
||||||
const offsetX = x - this.startX
|
const offsetX = x - this.startX
|
||||||
const offsetY = y - this.startY
|
const offsetY = y - this.startY
|
||||||
this.startX = x
|
const { rect, type } = this.touchedView
|
||||||
this.startY = y
|
let css = {}
|
||||||
const css = {
|
if (this.isScale) {
|
||||||
left: `${this.touchedView.rect.x + offsetX}px`,
|
const newW = this.startW + offsetX > 1 ? this.startW + offsetX : 1
|
||||||
top: `${this.touchedView.rect.y + offsetY}px`,
|
const newH = this.startH + offsetY > 1 ? this.startH + offsetY : 1
|
||||||
right: undefined,
|
css = {
|
||||||
bottom: undefined
|
width: `${newW}px`,
|
||||||
|
}
|
||||||
|
if (type !== 'text') {
|
||||||
|
if (type === 'image') {
|
||||||
|
css.height = `${(newW) * this.startH / this.startW }px`
|
||||||
|
} else {
|
||||||
|
css.height = `${newH}px`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.startX = x
|
||||||
|
this.startY = y
|
||||||
|
css = {
|
||||||
|
left: `${rect.x + offsetX}px`,
|
||||||
|
top: `${rect.y + offsetY}px`,
|
||||||
|
right: undefined,
|
||||||
|
bottom: undefined
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.doAction({
|
this.doAction({
|
||||||
id: this.touchedView.id,
|
id: this.touchedView.id,
|
||||||
css
|
css
|
||||||
})
|
})
|
||||||
this.triggerEvent('touchMove',{
|
this.triggerEvent('touchMove', {
|
||||||
id: this.touchedView.id,
|
id: this.touchedView.id,
|
||||||
css
|
css
|
||||||
})
|
})
|
||||||
@ -239,6 +358,9 @@ Component({
|
|||||||
pen.paint(() => {
|
pen.paint(() => {
|
||||||
this.saveImgToLocal();
|
this.saveImgToLocal();
|
||||||
});
|
});
|
||||||
|
this.frontContext = wx.createCanvasContext('front', this);
|
||||||
|
this.bottomContext = wx.createCanvasContext('bottom', this);
|
||||||
|
this.topContext = wx.createCanvasContext('top', this)
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -308,10 +430,10 @@ Component({
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
wx.canvasToTempFilePath({
|
wx.canvasToTempFilePath({
|
||||||
canvasId: 'k-canvas',
|
canvasId: 'k-canvas',
|
||||||
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
|
||||||
@ -381,7 +503,7 @@ function setStringPrototype(screenK, scale) {
|
|||||||
if (unit === 'rpx') {
|
if (unit === 'rpx') {
|
||||||
res = Math.round(value * screenK * (scale || 1));
|
res = Math.round(value * screenK * (scale || 1));
|
||||||
} else if (unit === 'px') {
|
} else if (unit === 'px') {
|
||||||
res = Math.round(value * (scale || 1));
|
res = value * (scale || 1);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
<view style='position: relative;{{painterStyle}}{{customStyle}}'>
|
<view style='position: relative;{{painterStyle}}{{customStyle}}'>
|
||||||
<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="front" style="{{painterStyle}};position: absolute;" />
|
||||||
<canvas
|
<canvas
|
||||||
canvas-id="top"
|
canvas-id="top"
|
||||||
style="{{painterStyle}};position: absolute;"
|
style="{{painterStyle}};position: absolute;"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user