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

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

我们还需要在初始化canvas的时候,我们就添加入当前的状态存入列表中,作为最先开始的空画布状态


const fillImage = async () => {
// 省略一万字...

img.src = await getURLBase64(fillImageSrc)
img.onload = () => {
const imageData: ImageData = context.getImageData(0, 0, canvas.width, canvas.height)
canvasHistroyListRef.current = []canvasHistroyListRef.current.push(imageData)
setCanvasCurrentHistory(1)
}
}

然后我们就实现一下,画笔更新时候,我们也需要将当前的状态添加入 画笔状态列表 ,并且更新当前状态对应的下标,还需要处理一下一些细节

总结一下:

鼠标抬起时,获取当前canvas画布状态
添加进状态列表中,并且更新状态下标
如果当前处于撤销状态,若使用画笔更新状态,则将当前的最为最新的状态,原先位置之后的状态全部清空


const handleLineMode = (downX: number, downY: number) => {
// 省略一万字...
canvas.onmouseup = () => {
const imageData: ImageData = context.getImageData(0, 0, canvas.width, canvas.height)

// 如果此时处于撤销状态,此时再使用画笔,则将之后的状态清空,以刚画的作为最新的画布状态
if (canvasCurrentHistory < canvasHistroyListRef.current.length) {
canvasHistroyListRef.current = canvasHistroyListRef.current.slice(0, canvasCurrentHistory)
}
canvasHistroyListRef.current.push(imageData)
setCanvasCurrentHistory(canvasCurrentHistory + 1)
context.closePath()
canvas.onmousemove = null
canvas.onmouseup = null
}
}

画布状态的撤销与恢复

ok,其实现在关于画布状态的更新,我们已经完成了。接下来我们需要处理一下状态的撤销与恢复的功能啦

我们先定义一下这个工具栏吧

然后我们设置对应的事件,分别是撤销,恢复,与清空,其实都很容易看懂,最多就是处理一下边界情况。


const handleRollBack = () => {
const isFirstHistory: boolean = canvasCurrentHistory === 1
if (isFirstHistory) return
setCanvasCurrentHistory(canvasCurrentHistory - 1)
}

const handleRollForward = () => {
const { current: canvasHistroyList } = canvasHistroyListRef
const isLastHistory: boolean = canvasCurrentHistory === canvasHistroyList.length
if (isLastHistory) return
setCanvasCurrentHistory(canvasCurrentHistory + 1)
}

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