😎嘿!首先,先来看超酷的效果哦😃!🎨素描图在用户鼠标按下后,就像被施了魔法一样🧙♂️,将鼠标范围内的素描像素神奇地转换成有色像素🌈。
橡皮擦
效果,即鼠标点下去移动所经过位置擦除,鼠标松开不清除。关于绘制图形,图形操作,前端一般都是用Canvas进行处理。
最近抖音豆包AI的插件MarsCode也进入了插件市场,咱们拿来用用,提升下速度,自己也可以少敲点代码。
首先,先来实现鼠标按下滑动后画出线条,先来让AI助手来生成下代码。
这里我们必须要把需求描述清楚,要说使用Canvas来实现,不然AI理解不了你要干嘛。
先把代码粘贴进来试下。结果报错了。
onMouseMove
方法重复了,这里它给的代码有点小bug,在引入时引入了onMouseMove
和onMouseUp
,但vue中并没有这两个方法,我们把这两个引入删除。除了这个bug,效果还是可以的。
现在完成了滑动时画出内容,但是我们需要的是滑动时清除内容,这里就要用到cavas的一个神奇的属性-globalCompositeOperation,该属性定义了我们在绘制图形时如何将新内容
合成现有图形
,合成为新图形。
常用的混合结果如下:
可以看到,我们需要的效果正是destination-out,画笔划过的地方将原有内容擦除。ctx.globalCompositeOperation = 'destination-out'
接着我们将原图的背景填充上,先来个灰色背景试试。问问AI,代码少写点
根据它的代码,我们再加上destination-out
的设置,写一个初始化
Canvas的方法init()。
function init() {
const canvas = myCanvas.value;
const ctx =canvas.getContext('2d');
//填充整个画布为灰色
ctx.fillStyle ='gray';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.globalCompositeOperation = 'destination-out'
}
擦除效果有了后,我们还需要考虑在擦除的时候我们并不需要将全部的的遮挡都擦除,因此需要设置当擦除完大部分的灰色前景后就自动将全部的灰色抹除,也就需要判断当前擦除面积
是否达到一定百分比
。
在Canvas中擦除实际是改变已有图像的透明度,Canvas给我们提供了getImageData()查看当前图像的像素信息,通过在onMouseMove
中统计图像当前有效像素比
,看是否需要直接清空前景。
有了思路后,让AI给我们生成代码,我们再来看合不合适。
给我们生成了checkAndClearForeground
方法,这里这个方法我们不太清楚,让豆包MarsCode给我们注释下。
/**
* 检查并清空前景
* @param {number} x - 鼠标在画布上的 x 坐标
* @param {number} y - 鼠标在画布上的 y 坐标
*/
function checkAndClearForeground(x, y) {
// 获取对当前画布元素的引用
const canvas = myCanvas.value;
// 从画布上获取图像数据
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
// 初始化有效像素计数为 0
let validPixels = 0;
// 遍历图像数据中的每个像素点
// rgba 显示的模式,所以一个像素表示有 4 个分量,透明度是最后一个分量
for (let i = 0; i < imageData.data.length; i += 4) {
// 提取当前像素点的 alpha 通道值
const alpha = imageData.data[i + 3];
// 判断 alpha 通道值是否大于 0,若大于 0 则表示当前像素点有效
if (alpha > 0) {
validPixels++;
}
}
// 计算有效像素比例(有效像素数除以总像素数)
const validPixelRatio = validPixels / (imageData.data.length / 4);
// 判断有效像素比例是否小于 50%
if (validPixelRatio < 0.5) {
// 将填充样式设置为灰色
ctx.fillStyle = 'gray';
// 用灰色填充整个画布
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
}
计算的关键原来在于,在rgba
模式下,一个像素有4个分量,最后一个分量表示透明度,当透明度的分量大于0时,表示这个像素点就是有效的,通过计算有效的像素点就能知道百分比了
有了基本的功能,我们再让UI小姐姐将我们的原图转为素描图,来替换之前的灰色前景。
function init() {
const canvas = myCanvas.value;
const ctx =canvas.getContext('2d');
const image = new Image();
image.src = imagePath;
// 图片加载完成后执行
image.onload = function() {
//填充画布为图像
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
ctx.globalCompositeOperation = 'destination-out'
};
}
因为gif帧率的问题,擦除完毕后,清空页面后感觉像变成了白色的,但其实清空后屏幕就透明了。
接着,我们把有色原图设置到Canvas的背景上,这样擦除后,显示的就是有色背景了。
canvas {
background-image: url('@/assets/erase/back.jpg');
background-size: cover;
background-position: center;
}
基于此原理,我们还可以做擦除原本模糊的图像,露出清晰的原图。
或者给前景写上文字后,擦除后露出内容的刮刮卡效果。
在线体验:http://bulibuli.top:11083/
源码地址:(gitee.com)
有了MarsCode帮助我们生成代码后,确实可以减少我们开发的难度和成本,但目前AI给我们的代码也不一定是完全正确的😏,对于部分bug还是需要我们手动去处理。不过当我们有了思路与具体的实现方法后,让AI给我们生成代码后我们就只需要大体看下代码,再改一些参数配置后就能很方便的和我们项目适配,目前AI时代已经来临,我们程序员应该尽快找到一个自己喜欢顺手的AI,辅助开发,加快我们开发效率🎈。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。