本文所有内容均参照 canvas实现截图
😺 效果图
话不多说,先看下效果
📒 实现思路
- 考虑了一下这个功能,肯定得用hook,因为是一个有状态的东西,hook需要返回截图,取消截图的功能函数以及截取的图片数据
- 在图片所在的同一父元素节点下添加两个canvas,【canvas A】用于展示截图动效(比如,未被截取区域背景置灰,截取区域显示边框);【canvas B】用于展示完整图片,便于截取动作进行以及生成截图数据(记住canvas A 和 canvas B,后面讲解还会用到)
- 通过在【canvas A】上通过监听mouseup,mousemove,mousedown三个事件计算截取的区域,生成截取动效,生成截取图片等
- 截图动作完毕的时候即时生成截取图片数据返回
🤔 难点
1. 计算截取区域
在截图开始后,在【canvas A】的mousedown事件记录起点坐标A, 通过mousemove事件实时监听具体的坐标,document级的mouseup事件记录结束坐标B(鼠标有可能会跑出截图区域外,所以是在document上监听mouseup),以A为起点,B为终点,AB两点就能够计算出截取区域
// 获取截图开始的点
【canvas A】.onmousedown = function (e) {
记录起点坐标A
}
// 获取鼠标坐标
【canvas A】.onmousemove = function (坐标数据) {
1. 记录鼠标坐标
2. 生成截图区域动效
}
// 获取截图结束的点
document.addEventListener('mouseup', function (e) {
1.记录终点坐标
2. 生成截图()
}
2 截图动画效果(未被选取部分置灰,截取部分添加边框等)
在mousedown事件上把【canvas A】给置灰
// 设置截图时灰色背景
【canvas A】.fillStyle = 'rgba(0,0,0,0.6)'
【canvas A】.strokeStyle = 'rgba(0,143,255,1)'
在mouseup事件上绘制被截取效果
- 第一步:遮罩层:globalCompositeOperation = ‘source-over’ 表示在目标图像上显示源图像,那么此时进行
fillRect(0, 0, 【canvas A】.width, 【canvas A】.height)
那就是把我们之前设置好置灰样式在目标图片上层进行绘制,实现了第一步置灰效果 - 第二步:画框:globalCompositeOperation = ‘destination-out’ 在源图像之外显示目标图像。只有源图像之外的目标图像部分会被显示,源图像是透明的。
【canvas A】.fillRect(x, y, w, h)
使得截取内部透明 - 第三步:描边:懂的都懂,不细讲了
//第一步:遮罩层
【canvas A】.globalCompositeOperation = 'source-over'
【canvas A】.fillRect(0, 0, 【canvas A】.width, 【canva