console
var ctx = null
var IMAGE_WIDTH = 0
var IMAGE_HEIGHT = 0
var CANVAS_WIDTH = 800
var CANVAS_HEIGHT = 800
var arcRadius = 15
var originPoints, newPoints, splitPoints = [], splitH = 0, splitV = 0
var originSplitPoints
var newSplitPoints
var imgLeft, imgTop
var img = new Image()
img.src = 'https://gaisama.gitee.io/js-demos/img/test.jpg'
img.onload = function () {
var canvas = document.getElementById('cas')
var pageWidth = document.documentElement.clientWidth
var pageHeight = document.documentElement.clientHeight
var canvasLeft = (pageWidth - CANVAS_WIDTH) / 2
var canvasTop = 80
var targetPoint, mouseX, mouseY
ctx = canvas.getContext('2d')
IMAGE_WIDTH = img.width / 2
IMAGE_HEIGHT = img.height / 2
canvas.width = CANVAS_WIDTH
canvas.height = CANVAS_HEIGHT
imgLeft = (canvas.width - IMAGE_WIDTH) / 2
imgTop = (canvas.height - IMAGE_HEIGHT) / 2
img.width = IMAGE_WIDTH
img.height = IMAGE_HEIGHT
splitH = 20
splitV = 20
originPoints = [
{
x: imgLeft, y: imgTop
},
{
x: imgLeft + IMAGE_WIDTH, y: imgTop
},
{
x: imgLeft + IMAGE_WIDTH, y: imgTop + IMAGE_HEIGHT
},
{
x: imgLeft, y: imgTop + IMAGE_HEIGHT
},
]
originSplitPoints = generatePoints(originPoints, splitH, splitV)
newPoints = JSON.parse(JSON.stringify(originPoints))
window.onresize = function () {
pageWidth = document.documentElement.clientWidth
pageHeight = document.documentElement.clientHeight
canvasLeft = (pageWidth - CANVAS_WIDTH) / 2
canvasTop = 80
}
var dragging = false
document.body.onmousedown = function (e) {
dragging = true
mouseX = e.clientX - canvasLeft
mouseY = e.clientY - canvasTop
for (var i = 0; i < 4; i++) {
if (mouseX > newPoints[i].x - arcRadius && mouseX < newPoints[i].x + arcRadius && mouseY > newPoints[i].y - arcRadius && mouseY < newPoints[i].y + arcRadius) {
targetPoint = newPoints[i]
console.log('targetPoint:', targetPoint)
break
}
}
}
document.body.onmousemove = function (e) {
if (dragging && targetPoint) {
targetPoint.x = e.clientX - canvasLeft
targetPoint.y = e.clientY - canvasTop
update()
}
}
document.body.onmouseup = function (e) {
dragging = false
}
update()
}
function update () {
newSplitPoints = generatePoints(newPoints, splitH, splitV)
ctx.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT)
ctx.save()
ctx.fillStyle = 'rgba(255,255,255,0.2)'
ctx.fillRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT)
for (var i = 0; i < newSplitPoints.length; i++) {
if (i < newSplitPoints.length - splitH - 2 && (i + 1) % (splitH + 1) !== 0) {
drawTriangleImage(
originSplitPoints[i + 1], originSplitPoints[i + 1 + splitH + 1], originSplitPoints[i + splitH + 1],
newSplitPoints[i + 1], newSplitPoints[i + 1 + splitH + 1], newSplitPoints[i + splitH + 1]
)
drawTriangleImage(
originSplitPoints[i], originSplitPoints[i + 1], originSplitPoints[i + splitH + 1],
newSplitPoints[i], newSplitPoints[i + 1], newSplitPoints[i + splitH + 1]
)
}
if (i === 0 || i === splitH || i === (splitH + 1) * splitV || i === (splitH + 1) * (splitV + 1) - 1) {
drawArc(newSplitPoints[i])
}
}
ctx.restore()
}
function generatePoints (points, splitH, splitV) {
splitPoints = []
var vLeft = {
x: (points[3].x - points[0].x) / splitV,
y: (points[3].y - points[0].y) / splitV
}
var vRight = {
x: (points[2].x - points[1].x) / splitV,
y: (points[2].y - points[1].y) / splitV
}
var x1, y1, x2, y2
var i, j
for (i = 0; i <= splitV; i++) {
x1 = points[0].x + vLeft.x * i
y1 = points[0].y + vLeft.y * i
x2 = points[1].x + vRight.x * i
y2 = points[1].y + vRight.y * i
for (j = 0; j <= splitH; j++) {
splitPoints.push({
x: x1 + (x2 - x1) / splitH * j,
y: y1 + (y2 - y1) / splitH * j
})
}
}
return splitPoints
}
function drawTriangleImage (p1, p2, p3, newP1, newP2, newP3) {
var result = mathUtil.Matrix.get2DTransformMatrix(p1, p2, p3, newP1, newP2, newP3)
ctx.save()
ctx.beginPath()
ctx.moveTo(newP1.x, newP1.y)
ctx.lineTo(newP2.x, newP2.y)
ctx.lineTo(newP3.x, newP3.y)
ctx.closePath()
ctx.lineWidth = 1
ctx.strokeStyle = 'red'
ctx.stroke()
ctx.clip()
ctx.transform(result.a, result.b, result.c, result.d, result.e, result.f)
ctx.drawImage(img, imgLeft, imgTop, IMAGE_WIDTH, IMAGE_HEIGHT)
ctx.restore()
}
function drawArc (point) {
ctx.save()
ctx.beginPath()
ctx.arc(point.x, point.y, arcRadius, 0, 2 * Math.PI)
ctx.strokeWidth = 3
ctx.strokeStyle = '#fff'
ctx.stroke()
ctx.restore()
}
<div>
<canvas id='cas' width="500" height="500" style="background-color:#000">浏览器不支持canvas</canvas>
</div>
body {
padding: 0;
margin: 0;
overflow: hidden;
}
#cas {
display: block;
margin: 80px auto;
}