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

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

大体就这样子啦!


<div className="mark-paper__wrap" ref={wrapRef}>
<canvas
ref={canvasRef}
className="mark-paper__canvas">
<p>很可惜,这个东东与您的电脑不搭!</p>
</canvas>
<div className="mark-paper__sider" />
</div>

我们唯一需要的一点就是,容器需要设置属性

overflow: hidden
用来隐藏内部canvas画布溢出的内容,也就是说,我们要控制我们可视的区域。同时我们需要动态获取容器宽高来为canvas设置尺寸

2. 初始化canvas画布与填充图片

我们可以弄个方法来初始化并且填充画布,以下截取主要部分,其实就是为canvas画布设置尺寸与填充我们的图片


const fillImage = async () => {
// 此处省略...

const img: HTMLImageElement = new Image()

img.src = await getURLBase64(fillImageSrc)
img.onload = () => {
canvas.width = img.width
canvas.height = img.height
context.drawImage(img, 0, 0)

// 设置变化基点,为画布容器中央
canvas.style.transformOrigin = `${wrap?.offsetWidth / 2}px ${wrap?.offsetHeight / 2}px`
// 清除上一次变化的效果
canvas.style.transform = ''
}
}

3. 监听canvas画布的各种鼠标事件

这个控制移动的话,我们首先可以弄一个方法来监听画布鼠标的各种事件,可以区分不同的模式来进行不同的事件处理


const handleCanvas = () => {
const { current: canvas } = canvasRef
const { current: wrap } = wrapRef
const context: CanvasRenderingContext2D | undefined | null = canvas?.getContext('2d')
if (!context || !wrap) return

// 清除上一次设置的监听,以防获取参数错误
wrap.onmousedown = null
wrap.onmousedown = function (event: MouseEvent) {
const downX: number = event.pageX
const downY: number = event.pageY

// 区分我们现在选择的鼠标模式:移动、画笔、橡皮擦
switch (mouseMode) {
case MOVE_MODE:
handleMoveMode(downX, downY)
break
case LINE_MODE:
handleLineMode(downX, downY)
break
case ERASER_MODE:
handleEraserMode(downX, downY)
break
default:
break
}
}

4. 实现画布移动

这个就比较好办啦,我们只需要利用鼠标按下的坐标,和我们拖动的距离就可以实现画布的移动啦,因为涉及到每次移动都需要计算最新的位移距离,我们可以定义几个变量来进行计算。

这里监听的是容器的鼠标事件,而不是canvas画布的事件,因为这样子我们可以再移动超过边界的时候也可以进行移动操作