You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
454 lines
13 KiB
454 lines
13 KiB
// subpages/index/checkOutConfirm/sign/sign.js
|
|
|
|
|
|
Page({
|
|
data: {
|
|
canvasName: 'signCanvas',
|
|
ctx: '',
|
|
canvas: '',
|
|
canvasWidth: 0,
|
|
canvasHeight: 0,
|
|
transparent: 1,
|
|
selectColor: 'black',
|
|
lineColor: '#1A1A1A',
|
|
lineSize: 1.5,
|
|
lineMin: 0.5,
|
|
lineMax: 4,
|
|
pressure: 1,
|
|
smoothness: 60,
|
|
currentPoint: {},
|
|
currentLine: [],
|
|
firstTouch: true,
|
|
radius: 1,
|
|
cutArea: { top: 0, right: 0, bottom: 0, left: 0 },
|
|
bethelPoint: [],
|
|
lastPoint: 0,
|
|
chirography: [],
|
|
currentChirography: {},
|
|
linePrack: [],
|
|
isDraw: false,
|
|
upPageNumber: 0,
|
|
offCanvas: '',
|
|
offCtx: '',
|
|
dpr: ''
|
|
},
|
|
|
|
onLoad: function (options) {
|
|
this.data.dpr = wx.getSystemInfoSync().pixelRatio
|
|
const query = wx.createSelectorQuery()
|
|
query
|
|
.select('.handCenter')
|
|
.boundingClientRect(rect => {
|
|
this.data.canvasWidth = rect.width * this.data.dpr
|
|
this.data.canvasHeight = rect.height * this.data.dpr
|
|
})
|
|
.exec()
|
|
const query1 = wx.createSelectorQuery()
|
|
query1
|
|
.select('#signCanvas')
|
|
.fields({ node: true, size: true })
|
|
.exec(res => {
|
|
const canvas = res[0].node
|
|
this.data.ctx = canvas.getContext('2d')
|
|
canvas.width = this.data.canvasWidth
|
|
canvas.height = this.data.canvasHeight
|
|
|
|
this.data.canvas = canvas
|
|
|
|
this.data.ctx.scale(this.data.dpr, this.data.dpr)
|
|
this.setCanvasBg('#fff')
|
|
})
|
|
const query2 = wx.createSelectorQuery()
|
|
query2
|
|
.select('#offCanvas')
|
|
.fields({ node: true, size: true })
|
|
.exec(res => {
|
|
const canvas = res[0].node
|
|
const ctx = canvas.getContext('2d')
|
|
canvas.width = this.data.canvasHeight
|
|
canvas.height = this.data.canvasWidth
|
|
this.data.offCanvas = canvas
|
|
this.data.offCtx = ctx
|
|
this.data.offCtx.scale(this.data.dpr, this.data.dpr)
|
|
})
|
|
},
|
|
|
|
retDraw() {
|
|
this.data.ctx.clearRect(0, 0, 700, 730)
|
|
this.setCanvasBg('#fff')
|
|
this.data.isDraw = false
|
|
this.data.currentPoint = {}
|
|
},
|
|
|
|
pointToLine(line) {
|
|
this.calcBethelLine(line)
|
|
return
|
|
},
|
|
|
|
uploadScaleStart(e) {
|
|
if (e.type != 'touchstart') return false
|
|
let ctx = this.data.ctx
|
|
ctx.fillStyle = this.data.lineColor
|
|
ctx.globalAlpha = this.data.transparent
|
|
let currentPoint = {
|
|
x: e.touches[0].x,
|
|
y: e.touches[0].y
|
|
}
|
|
let currentLine = this.data.currentLine
|
|
currentLine.unshift({
|
|
time: new Date().getTime(),
|
|
dis: 0,
|
|
x: currentPoint.x,
|
|
y: currentPoint.y
|
|
})
|
|
this.setData({
|
|
currentPoint
|
|
})
|
|
if (this.data.firstTouch) {
|
|
this.setData({
|
|
cutArea: {
|
|
top: currentPoint.y,
|
|
right: currentPoint.x,
|
|
bottom: currentPoint.y,
|
|
left: currentPoint.x
|
|
},
|
|
firstTouch: false
|
|
})
|
|
}
|
|
this.pointToLine(currentLine)
|
|
},
|
|
|
|
uploadScaleMove(e) {
|
|
if (e.type != 'touchmove') return false
|
|
if (e.cancelable) {
|
|
|
|
if (!e.defaultPrevented) {
|
|
e.preventDefault()
|
|
}
|
|
}
|
|
let point = {
|
|
x: e.touches[0].x,
|
|
y: e.touches[0].y
|
|
}
|
|
|
|
if (point.y < this.data.cutArea.top) {
|
|
this.data.cutArea.top = point.y
|
|
}
|
|
if (point.y < 0) this.data.cutArea.top = 0
|
|
|
|
if (point.x > this.data.cutArea.right) {
|
|
this.data.cutArea.right = point.x
|
|
}
|
|
if (this.data.canvasWidth - point.x <= 0) {
|
|
this.data.cutArea.right = this.data.canvasWidth
|
|
}
|
|
if (point.y > this.data.cutArea.bottom) {
|
|
this.data.cutArea.bottom = point.y
|
|
}
|
|
if (this.data.canvasHeight - point.y <= 0) {
|
|
this.data.cutArea.bottom = this.data.canvasHeight
|
|
}
|
|
if (point.x < this.data.cutArea.left) {
|
|
this.data.cutArea.left = point.x
|
|
}
|
|
if (point.x < 0) this.data.cutArea.left = 0
|
|
|
|
this.setData({
|
|
lastPoint: this.data.currentPoint,
|
|
currentPoint: point
|
|
})
|
|
let currentLine = this.data.currentLine
|
|
currentLine.unshift({
|
|
time: new Date().getTime(),
|
|
dis: this.distance(this.data.currentPoint, this.data.lastPoint),
|
|
x: point.x,
|
|
y: point.y
|
|
})
|
|
// this.setData({
|
|
// currentLine
|
|
// })
|
|
this.pointToLine(currentLine)
|
|
},
|
|
|
|
uploadScaleEnd(e) {
|
|
if (e.type != 'touchend') return 0
|
|
let point = {
|
|
x: e.changedTouches[0].x,
|
|
y: e.changedTouches[0].y
|
|
}
|
|
this.setData({
|
|
lastPoint: this.data.currentPoint,
|
|
currentPoint: point
|
|
})
|
|
let currentLine = this.data.currentLine
|
|
currentLine.unshift({
|
|
time: new Date().getTime(),
|
|
dis: this.distance(this.data.currentPoint, this.data.lastPoint),
|
|
x: point.x,
|
|
y: point.y
|
|
})
|
|
// this.setData({
|
|
// currentLine
|
|
// })
|
|
if (currentLine.length > 2) {
|
|
var info =
|
|
(currentLine[0].time - currentLine[currentLine.length - 1].time) / currentLine.length
|
|
}
|
|
|
|
this.pointToLine(currentLine)
|
|
var currentChirography = {
|
|
lineSize: this.data.lineSize,
|
|
lineColor: this.data.lineColor
|
|
}
|
|
var chirography = this.data.chirography
|
|
chirography.unshift(currentChirography)
|
|
this.setData({
|
|
chirography
|
|
})
|
|
var linePrack = this.data.linePrack
|
|
linePrack.unshift(this.data.currentLine)
|
|
this.setData({
|
|
linePrack,
|
|
currentLine: []
|
|
})
|
|
this.data.isDraw = true
|
|
},
|
|
|
|
calcBethelLine(line) {
|
|
if (line.length <= 1) {
|
|
line[0].r = this.data.radius
|
|
return
|
|
}
|
|
let x0,
|
|
x1,
|
|
x2,
|
|
y0,
|
|
y1,
|
|
y2,
|
|
r0,
|
|
r1,
|
|
r2,
|
|
len,
|
|
lastRadius,
|
|
dis = 0,
|
|
time = 0,
|
|
curveValue = 0.5
|
|
if (line.length <= 2) {
|
|
x0 = line[1].x
|
|
y0 = line[1].y
|
|
x2 = line[1].x + (line[0].x - line[1].x) * curveValue
|
|
y2 = line[1].y + (line[0].y - line[1].y) * curveValue
|
|
x1 = x0 + (x2 - x0) * curveValue
|
|
y1 = y0 + (y2 - y0) * curveValue
|
|
} else {
|
|
x0 = line[2].x + (line[1].x - line[2].x) * curveValue
|
|
y0 = line[2].y + (line[1].y - line[2].y) * curveValue
|
|
x1 = line[1].x
|
|
y1 = line[1].y
|
|
x2 = x1 + (line[0].x - x1) * curveValue
|
|
y2 = y1 + (line[0].y - y1) * curveValue
|
|
}
|
|
|
|
len = this.distance({ x: x2, y: y2 }, { x: x0, y: y0 })
|
|
lastRadius = this.data.radius
|
|
for (let n = 0; n < line.length - 1; n++) {
|
|
dis += line[n].dis
|
|
time += line[n].time - line[n + 1].time
|
|
if (dis > this.data.smoothness) break
|
|
}
|
|
this.setData({
|
|
radius:
|
|
Math.min((time / len) * this.data.pressure + this.data.lineMin, this.data.lineMax) *
|
|
this.data.lineSize
|
|
})
|
|
line[0].r = this.data.radius
|
|
|
|
if (line.length <= 2) {
|
|
r0 = (lastRadius + this.data.radius) / 2
|
|
r1 = r0
|
|
r2 = r1
|
|
} else {
|
|
r0 = (line[2].r + line[1].r) / 2
|
|
r1 = line[1].r
|
|
r2 = (line[1].r + line[0].r) / 2
|
|
}
|
|
let n = 5
|
|
let point = []
|
|
for (let i = 0; i < n; i++) {
|
|
let t = i / (n - 1)
|
|
let x = (1 - t) * (1 - t) * x0 + 2 * t * (1 - t) * x1 + t * t * x2
|
|
let y = (1 - t) * (1 - t) * y0 + 2 * t * (1 - t) * y1 + t * t * y2
|
|
let r = lastRadius + ((this.data.radius - lastRadius) / n) * i
|
|
point.push({ x: x, y: y, r: r })
|
|
if (point.length == 3) {
|
|
let a = this.ctaCalc(
|
|
point[0].x,
|
|
point[0].y,
|
|
point[0].r,
|
|
point[1].x,
|
|
point[1].y,
|
|
point[1].r,
|
|
point[2].x,
|
|
point[2].y,
|
|
point[2].r
|
|
)
|
|
a[0].color = this.data.lineColor
|
|
this.bethelDraw(a, 1)
|
|
point = [{ x: x, y: y, r: r }]
|
|
}
|
|
}
|
|
this.setData({
|
|
currentLine: line
|
|
})
|
|
},
|
|
|
|
distance(a, b) {
|
|
let x = b.x - a.x
|
|
let y = b.y - a.y
|
|
return Math.sqrt(x * x + y * y)
|
|
},
|
|
|
|
ctaCalc(x0, y0, r0, x1, y1, r1, x2, y2, r2) {
|
|
let a = [],
|
|
vx01,
|
|
vy01,
|
|
norm,
|
|
n_x0,
|
|
n_y0,
|
|
vx21,
|
|
vy21,
|
|
n_x2,
|
|
n_y2
|
|
vx01 = x1 - x0
|
|
vy01 = y1 - y0
|
|
norm = Math.sqrt(vx01 * vx01 + vy01 * vy01 + 0.0001) * 2
|
|
vx01 = (vx01 / norm) * r0
|
|
vy01 = (vy01 / norm) * r0
|
|
n_x0 = vy01
|
|
n_y0 = -vx01
|
|
vx21 = x1 - x2
|
|
vy21 = y1 - y2
|
|
norm = Math.sqrt(vx21 * vx21 + vy21 * vy21 + 0.0001) * 2
|
|
vx21 = (vx21 / norm) * r2
|
|
vy21 = (vy21 / norm) * r2
|
|
n_x2 = -vy21
|
|
n_y2 = vx21
|
|
a.push({ mx: x0 + n_x0, my: y0 + n_y0, color: '#1A1A1A' })
|
|
a.push({
|
|
c1x: x1 + n_x0,
|
|
c1y: y1 + n_y0,
|
|
c2x: x1 + n_x2,
|
|
c2y: y1 + n_y2,
|
|
ex: x2 + n_x2,
|
|
ey: y2 + n_y2
|
|
})
|
|
a.push({
|
|
c1x: x2 + n_x2 - vx21,
|
|
c1y: y2 + n_y2 - vy21,
|
|
c2x: x2 - n_x2 - vx21,
|
|
c2y: y2 - n_y2 - vy21,
|
|
ex: x2 - n_x2,
|
|
ey: y2 - n_y2
|
|
})
|
|
a.push({
|
|
c1x: x1 - n_x2,
|
|
c1y: y1 - n_y2,
|
|
c2x: x1 - n_x0,
|
|
c2y: y1 - n_y0,
|
|
ex: x0 - n_x0,
|
|
ey: y0 - n_y0
|
|
})
|
|
a.push({
|
|
c1x: x0 - n_x0 - vx01,
|
|
c1y: y0 - n_y0 - vy01,
|
|
c2x: x0 + n_x0 - vx01,
|
|
c2y: y0 + n_y0 - vy01,
|
|
ex: x0 + n_x0,
|
|
ey: y0 + n_y0
|
|
})
|
|
a[0].mx = a[0].mx.toFixed(1)
|
|
a[0].mx = parseFloat(a[0].mx)
|
|
a[0].my = a[0].my.toFixed(1)
|
|
a[0].my = parseFloat(a[0].my)
|
|
for (let i = 1; i < a.length; i++) {
|
|
a[i].c1x = a[i].c1x.toFixed(1)
|
|
a[i].c1x = parseFloat(a[i].c1x)
|
|
a[i].c1y = a[i].c1y.toFixed(1)
|
|
a[i].c1y = parseFloat(a[i].c1y)
|
|
a[i].c2x = a[i].c2x.toFixed(1)
|
|
a[i].c2x = parseFloat(a[i].c2x)
|
|
a[i].c2y = a[i].c2y.toFixed(1)
|
|
a[i].c2y = parseFloat(a[i].c2y)
|
|
a[i].ex = a[i].ex.toFixed(1)
|
|
a[i].ex = parseFloat(a[i].ex)
|
|
a[i].ey = a[i].ey.toFixed(1)
|
|
a[i].ey = parseFloat(a[i].ey)
|
|
}
|
|
return a
|
|
},
|
|
|
|
bethelDraw(point, is_fill, color) {
|
|
let ctx = this.data.ctx
|
|
ctx.beginPath()
|
|
ctx.moveTo(point[0].mx, point[0].my)
|
|
if (undefined != color) {
|
|
ctx.fillStyle = color
|
|
ctx.strokeStyle = color
|
|
} else {
|
|
ctx.fillStyle = point[0].color
|
|
ctx.strokeStyle = point[0].color
|
|
}
|
|
for (let i = 1; i < point.length; i++) {
|
|
ctx.bezierCurveTo(
|
|
point[i].c1x,
|
|
point[i].c1y,
|
|
point[i].c2x,
|
|
point[i].c2y,
|
|
point[i].ex,
|
|
point[i].ey
|
|
)
|
|
}
|
|
ctx.stroke()
|
|
if (undefined != is_fill) {
|
|
ctx.fill()
|
|
}
|
|
},
|
|
|
|
setCanvasBg(color) {
|
|
this.data.ctx.rect(0, 0, this.data.canvasWidth, this.data.canvasHeight - 4)
|
|
this.data.ctx.fillStyle = color
|
|
this.data.ctx.fill()
|
|
},
|
|
|
|
subCanvas() {
|
|
if (Object.keys(this.data.currentPoint).length == 0) {
|
|
wx.showModal({
|
|
title: "提示",
|
|
content: "签名内容不能为空!",
|
|
showCancel: false
|
|
});
|
|
} else {
|
|
console.log('========sub')
|
|
const canvas = this.data.canvas;
|
|
const ctx = canvas.getContext('2d');
|
|
ctx.save();
|
|
ctx.translate(canvas.width/2, canvas.height/2);
|
|
ctx.rotate(Math.PI/2);
|
|
ctx.restore();
|
|
// 然后生成图片
|
|
let imgSrc = canvas.toDataURL('image/png', 1);
|
|
wx.showLoading({
|
|
title: '正在跳转',
|
|
})
|
|
setTimeout(function () {
|
|
wx.hideLoading()
|
|
wx.navigateTo({
|
|
url: `/subpages/index/checkOutConfirm/index/index?imgSrc=${encodeURIComponent(
|
|
imgSrc
|
|
)}`
|
|
});
|
|
}, 1500)
|
|
}
|
|
|
|
},
|
|
})
|