javascript - Fabric JS 多重过滤器处理(更换或添加过滤器)
问题描述
我有几个滑块,每个滑块都对我的画布应用不同的过滤器(见下图)。
但是当我多次使用相同的滑块时,相同的过滤器会被应用到画布上。(见下filters
图中的属性)。
我希望过滤器仅在它们来自相同的滑块输入时才能相互替换。ieBrightness
并且Saturation
可以同时存在,但永远不会有 2 个Brightness
堆叠在一起。我还发现我不能依赖 in 的type
属性,filters
因为我的一些滑块可能会导致相同的type
. 这个问题有什么顺利的解决方案吗?
以下是当前如何将过滤器应用于画布的示例代码。
function saturate(o, value){
value = value / 100
let filter = new fabric.Image.filters.Saturation({
saturation: value,
});
if (o.filters) {
o.filters = []
o.filters.push(filter);
o.applyFilters();
}
}
**Below is the output of `canvas.toObject()` (see the `filter` attribute)**
解决方案
您fabric.Image.filters
在每个用户输入上创建一个新的,您只需初始化一次过滤器并将其注册到对象或数组中,并在需要应用更改时检索和编辑其值。
在这个演示页面中,您可以看到过滤器只创建一次,存储在一个filters
对象中,并根据用户输入进行更新。
const canvas = new fabric.Canvas("c");
const filters = {};
init()
async function init() {
const [width, height] = [window.innerWidth, window.innerHeight/2];
// Setting the canvas size
canvas.setWidth( width );
canvas.setHeight( height );
canvas.calcOffset();
// load the image
const img = new Image();
img.crossOrigin = "";
await new Promise(res => {
img.onload = res;
img.src = `https://picsum.photos/${width}/${height}`;
});
const image = new fabric.Image(img);
canvas.add(image)
// Create and register the filters in `filters` object
const filters = {
brightness: new fabric.Image.filters.Brightness(),
saturation: new fabric.Image.filters.Saturation(),
contrast: new fabric.Image.filters.Contrast(),
hue: new fabric.Image.filters.HueRotation(),
}
// - Brightness
// Attach the filter to the image
image.filters.push(filters.brightness);
const brightnessInput = document.querySelector("#brightness")
brightnessInput.oninput = () => {
const value = parseFloat(brightnessInput.value);
// Edit the filter value
filters.brightness.brightness = value;
// Apply the changes
image.applyFilters();
// Display the result
canvas.renderAll();
}
// - Saturation
// Attach the filter to the image
image.filters.push(filters.saturation);
const saturationInput = document.querySelector("#saturation")
saturationInput.oninput = () => {
const value = parseFloat(saturationInput.value);
// Edit the filter value
filters.saturation.saturation = value;
// Apply the changes
image.applyFilters();
// Display the result
canvas.renderAll();
}
// - Contrast
// Attach the filter to the image
image.filters.push(filters.contrast);
const contrastInput = document.querySelector("#contrast")
contrastInput.oninput = () => {
const value = parseFloat(contrastInput.value);
// Edit the filter value
filters.contrast.contrast = value;
// Apply the changes
image.applyFilters();
// Display the result
canvas.renderAll();
}
// - Hue
// Attach the filter to the image
image.filters.push(filters.hue);
const hueInput = document.querySelector("#hue")
hueInput.oninput = () => {
const value = parseFloat(hueInput.value);
// Edit the filter value
filters.hue.rotation = value;
// Apply the changes
image.applyFilters();
// Display the result
canvas.renderAll();
}
}
body {
margin: 0;
font-family: arial;
}
div {
padding: .5em 1em;
}
p {
display: flex;
margin: 0 0 .5em;
}
label{
flex:.2;
}
input {
flex:1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/451/fabric.min.js" integrity="sha512-qeu8RcLnpzoRnEotT3r1CxB17JtHrBqlfSTOm4MQzb7efBdkcL03t343gyRmI6OTUW6iI+hShiysszISQ/IahA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<canvas id="c"></canvas>
<div>
<p>
<label for="brightness">Brightness</label>
<input type="range" id="brightness" value="0" min="-1" max="1" step="0.01">
<p>
<p>
<label for="saturation">Saturation</label>
<input type="range" id="saturation" value="0" min="-1" max="1" step="0.01">
<p>
<p>
<label for="contrast">Contrast</label>
<input type="range" id="contrast" value="0" min="-1" max="1" step="0.01">
<p>
<p>
<label for="hue-value">Hue</label>
<input type="range" id="hue" value="0" min="-2" max="2" step="0.01">
<p>
</div>
推荐阅读
- pine-script - 如何将变量从版本 2 转换为 pinescript 版本 4?
- ios - 在 nativescript 核心上使用平移手势自定义转换
- javascript - 是否可以循环 ws.send?
- python-3.x - 如何使用flask在html中单击提交时调用python函数
- email - 有什么方法可以检索通过 EWS 创建的电子邮件的 ItemID
- php - 如何在php中存储firebase返回的第一个数组的所有值
- java - 如何将字典、数组作为 java 数据源库中的自定义属性添加到 Google 可视化(图表)
- c++ - “使用命名空间:std;”的功能是什么 在 C++ 中?
- python - 合并排序执行中的逻辑错误
- node.js - Express:自动查看路由