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

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

简单的总结一下:

传入鼠标按下的坐标
计算当前位移距离,并更新css变化效果
鼠标抬起时更新最新的位移状态


// 定义一些变量,来保存当前/最新的移动状态
// 当前位移的距离
const translatePointXRef: MutableRefObject<number> = useRef(0)
const translatePointYRef: MutableRefObject<number> = useRef(0)
// 上一次位移结束的位移距离
const fillStartPointXRef: MutableRefObject<number> = useRef(0)
const fillStartPointYRef: MutableRefObject<number> = useRef(0)

// 移动时候的监听函数
const handleMoveMode = (downX: number, downY: number) => {
const { current: canvas } = canvasRef
const { current: wrap } = wrapRef
const { current: fillStartPointX } = fillStartPointXRef
const { current: fillStartPointY } = fillStartPointYRef
if (!canvas || !wrap || mouseMode !== 0) return

// 为容器添加移动事件,可以在空白处移动图片
wrap.onmousemove = (event: MouseEvent) => {
const moveX: number = event.pageX
const moveY: number = event.pageY

// 更新现在的位移距离,值为:上一次位移结束的坐标+移动的距离
translatePointXRef.current = fillStartPointX + (moveX - downX)
translatePointYRef.current = fillStartPointY + (moveY - downY)

// 更新画布的css变化
canvas.style.transform = `scale(${canvasScale},${canvasScale}) translate(${translatePointXRef.current}px,${translatePointYRef.current}px)`
}

wrap.onmouseup = (event: MouseEvent) => {
const upX: number = event.pageX
const upY: number = event.pageY

// 取消事件监听
wrap.onmousemove = null
wrap.onmouseup = null;

// 鼠标抬起时候,更新“上一次唯一结束的坐标”
fillStartPointXRef.current = fillStartPointX + (upX - downX)
fillStartPointYRef.current = fillStartPointY + (upY - downY)
}
}

5. 实现画布缩放

画布缩放我主要通过右侧的滑动条以及鼠标滚轮来实现,首先我们再监听画布鼠标事件的函数中加一下监听滚轮的事件

总结一下:

监听鼠标滚轮的变化
更新缩放倍数,并改变样式


// 监听鼠标滚轮,更新画布缩放倍数
const handleCanvas = () => {
const { current: wrap } = wrapRef

// 省略一万字...

wrap.onwheel = null
wrap.onwheel = (e: MouseWheelEvent) => {
const { deltaY } = e
// 这里要注意一下,我是0.1来递增递减,但是因为JS使用IEEE 754,来计算,所以精度有问题,我们自己处理一下
const newScale: number = deltaY > 0
? (canvasScale * 10 - 0.1 * 10) / 10
: (canvasScale * 10 + 0.1 * 10) / 10
if (newScale < 0.1 || newScale > 2) return