Html5 Canvas实现图片标记、缩放、移动和保存历史状态功能 (附转

2020-04-25 07:29:21易采站长站整理

setCanvasScale(newScale)
}
}

// 监听滑动条来控制缩放
<Slider
min={0.1}
max={2.01}
step={0.1}
value={canvasScale}
tipFormatter={(value) => `${(value).toFixed(2)}x`}
onChange={handleScaleChange} />

const handleScaleChange = (value: number) => {
setCanvasScale(value)
}

接着我们使用hooks的副作用函数,依赖于画布缩放倍数来进行样式的更新


//监听缩放画布
useEffect(() => {
const { current: canvas } = canvasRef
const { current: translatePointX } = translatePointXRef
const { current: translatePointY } = translatePointYRef
canvas && (canvas.style.transform = `scale(${canvasScale},${canvasScale}) translate(${translatePointX}px,${translatePointY}px)`)
}, [canvasScale])

6. 实现画笔绘制

这个就需要用到我们之前推导出来的公式啦!因为呢,仔细想一下,如果我们缩放位移之后,我们鼠标按下的位置,他的坐标可能就相对于画布来说会有变化, 所以我们需要转换一下才能进行鼠标按下的位置与画布的位置一一对应的效果

稍微总结一下:

传入鼠标按下的坐标
通过公式转换,开始在对应坐标下绘制
鼠标抬起时,取消事件监听


// 利用公式转换一下坐标
const generateLinePoint = (x: number, y: number) => {
const { current: wrap } = wrapRef
const { current: translatePointX } = translatePointXRef
const { current: translatePointY } = translatePointYRef
const wrapWidth: number = wrap?.offsetWidth || 0
const wrapHeight: number = wrap?.offsetHeight || 0
// 缩放位移坐标变化规律
// (transformOrigin - downX) / scale * (scale-1) + downX - translateX = pointX
const pointX: number = ((wrapWidth / 2) - x) / canvasScale * (canvasScale - 1) + x - translatePointX
const pointY: number = ((wrapHeight / 2) - y) / canvasScale * (canvasScale - 1) + y - translatePointY

return {
pointX,
pointY
}
}

// 监听鼠标画笔事件
const handleLineMode = (downX: number, downY: number) => {
const { current: canvas } = canvasRef
const { current: wrap } = wrapRef
const context: CanvasRenderingContext2D | undefined | null = canvas?.getContext('2d')
if (!canvas || !wrap || !context) return

const offsetLeft: number = canvas.offsetLeft
const offsetTop: number = canvas.offsetTop
// 减去画布偏移的距离(以画布为基准进行计算坐标)
downX = downX - offsetLeft
downY = downY - offsetTop

const { pointX, pointY } = generateLinePoint(downX, downY)
context.globalCompositeOperation = "source-over"
context.beginPath()
// 设置画笔起点
context.moveTo(pointX, pointY)

canvas.onmousemove = null
canvas.onmousemove = (event: MouseEvent) => {