The best way to do this is with an image filter, I'd say. Fortunately, Fabric provides an image filter with a very similar functionality - RemoveColor
(http://fabricjs.com/docs/fabric.js.html#line23120). We can take that implementation, tweak it a little to replace with a configurable color instead of removing, and that should do the trick.
There are three main changes we make to the RemoveColor
class to create our ReplaceColor
class:
- Adding a
replacementColor
field that takes a 4 wide array of the color to replace with
- Modifying the webGL to take in an extra parameter for the replacement color:
fragmentSource: 'precision highp float;
' +
'uniform sampler2D uTexture;
' +
'uniform vec4 uLow;
' +
'uniform vec4 uHigh;
' +
'uniform vec4 uRep;
' + // New variable for replacement color
'varying vec2 vTexCoord;
' +
'void main() {
' +
'gl_FragColor = texture2D(uTexture, vTexCoord);
' +
'if(all(greaterThan(gl_FragColor.rgb,uLow.rgb)) && all(greaterThan(uHigh.rgb,gl_FragColor.rgb))) {
' +
'gl_FragColor.rgb = uRep.rgb;
' + // Here we set the color instead of 0-ing out the alpha
'gl_FragColor.a = uRep.a;
' +
'}
' +
'}',
- Updating the
applyTo2d
method to also use the replacement color:
applyTo2d: function (options) {
var imageData = options.imageData,
data = imageData.data, i,
distance = this.distance * 255,
r, g, b,
source = new fabric.Color(this.color).getSource(),
lowC = [
source[0] - distance,
source[1] - distance,
source[2] - distance,
],
highC = [
source[0] + distance,
source[1] + distance,
source[2] + distance,
];
for (i = 0; i < data.length; i += 4) {
r = data[i];
g = data[i + 1];
b = data[i + 2];
if (r > lowC[0] &&
g > lowC[1] &&
b > lowC[2] &&
r < highC[0] &&
g < highC[1] &&
b < highC[2]) {
data[i] = this.replacementColor[0]; // Here we also modify the color directly instead of 0-ing out the alpha
data[i + 1] = this.replacementColor[1];
data[i + 2] = this.replacementColor[2];
data[i + 3] = this.replacementColor[3];
}
}
}
JSFiddle: https://jsfiddle.net/8coka6yv/
Note that on the JSFiddle I cranked up the distance field, so it's a pretty drastic modification. The default value is normally 0.02
.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…