javascript - 动态更改画布的 feColorMatrix 值
问题描述
我feColorMatrix
在画布 2D 渲染上下文中使用 SVG 过滤器。我希望能够动态更新矩阵的values
属性,以动态更改颜色映射。但是,当我使用setAttribute
更新矩阵时,它对画布的后续绘制没有影响。
下面的示例重现了该问题。该矩阵最初交换了红色和绿色通道,并且正确应用了此过滤器,以便左侧的正方形以绿色而不是红色绘制。预期的结果是,将filter的values
属性改为redToBlue
矩阵后,右边的方块应该是蓝色的;实际结果是,尽管更新了矩阵值,右侧的方块仍保持绿色。
let redToBlue = '0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0';
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
let filter = document.getElementById('filter');
ctx.fillStyle = 'red';
ctx.filter = 'url(#filter)';
ctx.fillRect(10, 10, 80, 80);
filter.setAttribute('values', redToBlue);
ctx.fillRect(110, 10, 80, 80);
<svg>
<filter id="filter">
<feColorMatrix type="matrix" values="0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 1 0" />
</filter>
</svg>
<canvas id="canvas" width="200" height="100"></canvas>
我试过filter.values = ...
代替setAttribute
,在更新属性后重新分配ctx.filter = 'url(#filter)'
,并重置画布或 SVG 宽度以“强制”更新;这些都没有效果。
理想情况下,我正在寻找一种不需要创建新元素并将其添加到 DOMfilter
的解决方案。feColorMatrix
在实际应用中,矩阵值将被动态计算,因此不可能预先编写不同的过滤器并根据id
.
解决方案
您正在定位<filter>
元素以设置新值。但是你需要定位<feColorMatrix>
:
let redToBlue = '0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0';
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
let filter = document.querySelector('#filter feColorMatrix');
ctx.fillStyle = 'red';
ctx.filter = 'url(#filter)';
ctx.fillRect(10, 10, 80, 80);
filter.setAttribute('values', redToBlue);
ctx.fillRect(110, 10, 80, 80);
<svg>
<filter id="filter">
<feColorMatrix type="matrix" values="0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 1 0" />
</filter>
</svg>
<canvas id="canvas" width="200" height="100"></canvas>
推荐阅读
- ruby - 总和目录的总文件大小相差很大:Ruby -e,du -ach,ls -al“total”
- python - 尝试在 lambda 中同步两个 s3 存储桶
- swift - 为什么几天后我的每日重复本地通知不起作用?
- c++ - 动态分配的数组 - 类对象
- python-3.x - 循环遍历具有时间的数据帧并在时间小于当前时间时执行操作
- sharepoint - 使用 HTTP 请求在电源自动化中创建具有格式化模式的列
- html - 为 HTML 页面之间的 JS“onclick”事件创建 CSS 转换
- react-native - 带有变音符号的 Firestore 文档,两个不同的“ö”
- xml - Xslt 将标签移动到上一级的新元素
- localhost - 无法在 google colab 上完成 ngrok 隧道连接