Я хочу реализовать пользовательский фильтр, но не могу получить объект canvas2d, потому что мне нужно изменить imageData. Изменение imageData в соответствии с методом документа applyTo2d не имеет реального эффекта. Даже если я удалю его, ошибки не будет, независимо от того, можно ли настроить фрагментSource. Я написал этот метод, applyTo и applyToWebGl возвращают trafficgl, возвращенный canvasEl: true, есть ли способ вернуть canvas2d, можно напрямую получить imageData, я видел почти похожую проблему, не нашел, кто мне может помочь?
fabric3.4.0
fabric.Image.filters.HSL = fabric.util.createClass(fabric.Image.filters.BaseFilter, {
type: 'HSL',
initialize: function(options) {
console.log(options);
options || (options = {});
this.rotation = options.rotation || 0;
this.saturation = options.saturation || 0;
this.lightness = options.lightness || 0;
this.brightness = options.brightness || 0;
this.contrast = options.contrast || 0;
this.img = options.img;
},
changeImageDate: function(imgData, H, S, L, B, C) {
let data = imgData.data;
for (let i = 0; i < data.length / 4; i++) {
let rgb = [ data[i * 4], data[i * 4 + 1], data[i * 4 + 2] ];
if (H || S || L) {
rgb = this.changeHSL(rgb, H, S, L);
}
if (B || C) {
rgb = this.changeBC(rgb, B, C);
}
data[i * 4] = rgb[0];
data[i * 4 + 1] = rgb[1];
data[i * 4 + 2] = rgb[2];
}
return imgData;
},
changeHSL: function(rgb, H1, S1, L1) {
let hsl = this.rgb2Hsl(rgb[0], rgb[1], rgb[2]);
let H = (hsl[0] + 1 + H1 / 360) % 1;
let S = Math.min(Math.max(hsl[1] + S1 / 100, 0), 1);
let L = Math.min(Math.max(hsl[2] + L1 / 100, 0), 1);
let RGB = this.hsl2Rgb(H, S, L);
return RGB;
},
changeBC: function(rgb, B1, C1) {
let k = Math.tan((45 + 44 * (C1 / 100)) / 180 * Math.PI);
let R = [ rgb[0] - 127.5 * (1 - B1 / 100) ] * k + 127.5 * (1 + C1 / 100);
let G = [ rgb[1] - 127.5 * (1 - B1 / 100) ] * k + 127.5 * (1 + C1 / 100);
let B = [ rgb[2] - 127.5 * (1 - B1 / 100) ] * k + 127.5 * (1 + C1 / 100);
let RGB = [ R, G, B ];
RGB.forEach((it, i) => {
it = Math.min(Math.max(it, 0), 255);
});
return RGB;
},
rgb2Hsl: function(r, g, b) {
r = r / 255;
g = g / 255;
b = b / 255;
let max = Math.max(r, g, b),
min = Math.min(r, g, b);
let h,
s,
l = (max + min) / 2;
if (max == min) {
h = s = 0; // achromatic
} else {
let d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
}
h /= 6;
}
return [ Math.round(h * 100) / 100, Math.round(s * 100) / 100, Math.round(l * 100) / 100 ];
},
hsl2Rgb: function(h, s, l) {
let r, g, b;
if (s == 0) {
r = g = b = l; // achromatic
} else {
let q = l < 0.5 ? l * (1 + s) : l + s - l * s;
let p = 2 * l - q;
r = this.hue2(p, q, h + 1 / 3);
g = this.hue2(p, q, h);
b = this.hue2(p, q, h - 1 / 3);
}
return [ Math.round(r * 255), Math.round(g * 255), Math.round(b * 255) ];
},
hue2: function(p, q, t) {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1 / 6) return p + (q - p) * 6 * t;
if (t < 1 / 2) return q;
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
return p;
},
applyToWebGL: function(canvasEl) {
console.log(canvasEl);
let origin = this.img;
let index = canvas.getObjects().indexOf(origin);
let originalElement = origin._originalElement;
let width = origin.width * origin.scaleX;
let height = origin.height * origin.scaleY;
let d = Math.sqrt(width * width + height * height);
let element = fabric.util.createCanvasElement();
element.width = d;
element.height = d;
let context = element.getContext('2d');
context.drawImage(originalElement, 0, 0, width, height);
let imageData = context.getImageData(0, 0, width, height);
let data = this.changeImageDate(imageData, this.rotation, this.saturation, this.lightness, this.brightness, this.contrast);
context.putImageData(data,0,0)
},
toObject: function() {
return fabric.util.object.extend(this.callSuper('toObject'), {
rotation: this.rotation,
saturation: this.saturation,
lightness: this.lightness
});
}
});
fabric.Image.filters.HSL.fromObject = fabric.Image.filters.BaseFilter.fromObject;
var filterHSL = new fabric.Image.filters.HSL({
img: origin,
rotation,
saturation,
lightness,
brightness,
contrast
});
origin.filters = [ filterHSL ];
origin.applyFilters();
Элемент, который нужно изменить, исчез