javascript - 如何在 HTML5 Canvas 中展开模糊滤镜半径?
问题描述
我正在尝试使用 HTML5 画布的模糊滤镜创建水彩填充效果,但我遇到了问题。当我将鼠标保持在一个位置超过一秒钟左右时,我会留下一个奇怪的圆形/靶心残留物(附有图片)。我可以将鼠标在一个圆圈上晃动一会儿,然后将其模糊掉,但这样做很令人沮丧,而且看起来不太好。如何分散模糊半径以避免出现这种奇怪的残留效果?
我的代码:
const canvas = document.getElementById('myCanvas');
let c = canvas.getContext("2d");
width = window.innerWidth;
height = window.innerHeight;
canvas.width = width;
canvas.height = height;
var mouseX, mouseY, pMouseX, pMouseY;
let baseR, baseG, baseB;
let color;
setup();
function setup() {
width = window.innerWidth;
height = window.innerHeight;
canvas.width = width;
canvas.height = height;
baseR = Math.floor(Math.random() * 255);
baseG = Math.floor(Math.random() * 255);
baseB = Math.floor(Math.random() * 255);
color = `rgba(${baseR}, ${baseG}, ${baseB})`;
background("rgba(255, 255, 255, 0.00025)");
draw();
};
function draw() {
c.lineCap = "round";
c.lineJoin = "round";
background("rgba(255, 255, 255, .00001");
c.strokeStyle = color;
c.beginPath();
c.lineWidth = 30;
c.globalCompositeOperation = 'source-over';
c.filter = `blur(30px) opacity(5%)`;
c.stroke();
c.lineWidth = 28;
c.globalCompositeOperation = 'darken';
c.filter = `blur(30px) opacity(10%)`;
c.moveTo(pMouseX, pMouseY);
c.lineTo(mouseX, mouseY);
c.stroke();
c.closePath();
setTimeout(draw, 10);
};
function background(color) {
c.beginPath();
c.rect(0, 0, width, height);
c.fillStyle = color;
c.fill();
c.closePath();
}
document.onmousemove = function (e) {
pMouseX = mouseX;
pMouseY = mouseY;
mouseX = e.clientX;
mouseY = e.clientY;
};
window.onresize = function (event) {
setup();
};
document.onkeydown = function () {
console.log('hi');
color = `rgba(${Math.floor(Math.random() * baseR)},
${Math.floor(Math.random() * baseG)},
${Math.floor(Math.random() * baseB)})`;
console.log(color);
}
<canvas id="myCanvas"></canvas>
解决方案
每次绘制画布时,您都可以向鼠标位置添加随机偏移。
const canvas = document.getElementById('myCanvas');
let c = canvas.getContext("2d");
width = window.innerWidth;
height = window.innerHeight;
canvas.width = width;
canvas.height = height;
var mouseX, mouseY, pMouseX, pMouseY;
let baseR, baseG, baseB;
let color;
setup();
function setup() {
width = window.innerWidth;
height = window.innerHeight;
canvas.width = width;
canvas.height = height;
baseR = Math.floor(Math.random() * 255);
baseG = Math.floor(Math.random() * 255);
baseB = Math.floor(Math.random() * 255);
color = `rgba(${baseR}, ${baseG}, ${baseB})`;
background("rgba(255, 255, 255, 0.00025)");
draw();
};
function draw() {
c.lineCap = "round";
c.lineJoin = "round";
background("rgba(255, 255, 255, .00001");
c.strokeStyle = color;
c.beginPath();
c.lineWidth = 30;
c.globalCompositeOperation = 'source-over';
c.filter = `blur(30px) opacity(5%)`;
c.stroke();
c.lineWidth = 28;
c.globalCompositeOperation = 'darken';
c.filter = `blur(30px) opacity(10%)`;
c.moveTo(pMouseX, pMouseY);
const xOffset = (Math.random() - .5) * 30,
yOffset = (Math.random() - .5) * 30;
c.lineTo(mouseX + xOffset, mouseY + yOffset);
c.stroke();
c.closePath();
setTimeout(draw, 10);
};
function background(color) {
c.beginPath();
c.rect(0, 0, width, height);
c.fillStyle = color;
c.fill();
c.closePath();
}
document.onmousemove = function (e) {
pMouseX = mouseX;
pMouseY = mouseY;
mouseX = e.clientX;
mouseY = e.clientY;
};
window.onresize = function (event) {
setup();
};
document.onkeydown = function () {
console.log('hi');
color = `rgba(${Math.floor(Math.random() * baseR)},
${Math.floor(Math.random() * baseG)},
${Math.floor(Math.random() * baseB)})`;
console.log(color);
}
<canvas id="myCanvas"></canvas>
另一个想法是在鼠标静止时降低不透明度或扩大偏移范围。
推荐阅读
- json - 需要用 JQ 提取特定的字符串
- macos - 有没有办法删除所有者对 macOS 中文件的读取权限?
- html - 当css具有@supports时,Chrome在页面调整大小时重新加载背景
- node.js - Heroku:主机密钥验证失败,无法从远程存储库中读取
- javascript - 如何循环嵌套对象数组
- java - 如何使用多线程持久化 Spring Transactions 和 EntityManager 实体?
- git - git cherry-pick 可以追溯到多远?
- python - Python:如何将多个 Excel 文件合并到一个文件中?(不附加)
- r - 按活动将日历条目转换为每天的时间
- r - 错误:参数既不是数字也不是逻辑:返回 NA