简体   繁体   中英

Fabric.js loadFromJSON is not working with rgba fill

I have a simple canvas on which I am adding shapes (triangle, circle, rectangle). I have used spectrum color picker which supports rgba and I am setting the fill of the shapes as per color selected. To this point everything works fine. Now I am exporting the canvas as JSON,

var json = JSON.stringify(canvas);
console.log(json);

This JSON output will be saved to the database later but for testing purpose I am copying the json from console and using it as follow,

canvas.loadFromJSON('{"objects":[{"type":"circle","originX":"center","originY":"center","left":400,"top":200,"width":100,"height":100,"fill":{"_originalInput":{"h":"0%","s":"100%","v":"100%","a":0.13},"_r":255,"_g":0,"_b":0,"_a":0.13,"_roundA":0.13,"_format":"rgb","_ok":true,"_tc_id":3288},"stroke":{"_originalInput":{"h":"0%","s":"0%","v":"0%","a":1},"_r":0,"_g":0,"_b":0,"_a":1,"_roundA":1,"_format":"rgb","_ok":true,"_tc_id":3783},"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeLineJoin":"miter","strokeMiterLimit":10,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":0.4,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"radius":50,"startAngle":0,"endAngle":6.283185307179586},{"type":"triangle","originX":"left","originY":"top","left":583,"top":89,"width":50,"height":50,"fill":{"_originalInput":{"h":"17.374213836477992%","s":"86.88524590163934%","v":"95.68627450980392%","a":0.34},"_r":235.01046366720004,"_g":243.98400000000004,"_b":32.01070080000003,"_a":0.34,"_roundA":0.34,"_format":"hex","_ok":true,"_tc_id":2503},"stroke":"rgb(0, 0, 0)","strokeWidth":6,"strokeDashArray":null,"strokeLineCap":"butt","strokeLineJoin":"miter","strokeMiterLimit":10,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0},{"type":"rect","originX":"left","originY":"top","left":485,"top":196,"width":50,"height":50,"fill":"#1d128f","stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeLineJoin":"miter","strokeMiterLimit":10,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":0.4,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"rx":0,"ry":0}],"background":""}');
canvas.renderAll();

The problem I am facing is that as the exported JSON has rgba values so when the shapes are rendered on canvas then the fill is black. The canvas is ignoring the rgba value present in the JSON string.

However when I use the following JSON string (which has the fill 'green' and 'red') then the shapes are rendered fine with color green and red.

canvas.loadFromJSON('{"objects":[{"type":"rect","left":50,"top":50,"width":20,"height":20,"fill":"green","overlayFill":null,"stroke":null,"strokeWidth":1,"strokeDashArray":null,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"selectable":true,"hasControls":true,"hasBorders":true,"hasRotatingPoint":false,"transparentCorners":true,"perPixelTargetFind":false,"rx":0,"ry":0},{"type":"circle","left":100,"top":100,"width":100,"height":100,"fill":"red","overlayFill":null,"stroke":null,"strokeWidth":1,"strokeDashArray":null,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"selectable":true,"hasControls":true,"hasBorders":true,"hasRotatingPoint":false,"transparentCorners":true,"perPixelTargetFind":false,"radius":50}],"background":"rgba(0, 0, 0, 0)"}');

Is this a bug in fabric.js or there is something which I am doing wrong?

OK. I have found out why it is happening. The problem is how I am setting the color for shape objects. I am using Spectrum color picker and using following code to initialize the Spectrum and also adding code that when a color is selected on spectrum colorpicker then it is also changed for the selected shape object on canvas.

$(".spectrumColor").spectrum({
        showAlpha: true,
        showButtons: false,
        showPalette: true,
        palette: defaultPallete,
        allowEmpty: true,
        showInput: true,
        move: function (color) {

            var selectedObject = canvas.getActiveObject();
            if (selectedObject != null) {
                if ($(this).attr('id') == "FillColor") {
                    selectedObject.set('fill', color);
                    canvas.renderAll();
                }
                else if ($(this).attr('id') == "StrokeColor") {
                    selectedObject.set('stroke', color);
                    canvas.renderAll();
                }
            }
        }
    });

Here the problem is with this line,

selectedObject.set('stroke', color);

I have passed the whole color object from spectrum to the Fabric shape object. When I check the value of color in console then it is simple rgb string "rgb(255, 0, 0)" but when the complete object is assigned to the Fabric's shape object then it is adding hsv (hue, saturation, and lightness) string along with RGB to the Fabric shape object like this,

fill":{"_originalInput":{"h":"0%","s":"100%","v":"100%","a":0.13},"_r":255,"_g":0,"_b":0,"_a":0.13

As HSV is not recognizable by Fabric.js so it is rendering the shape objects in black color. To solve this I had to replace,

    selectedObject.set('stroke', color);

with

    selectedObject.set('stroke', color.toRgbString());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM