简体   繁体   English

Fabric.js object 在加载 DOM 时从 JSON 呈现时无法更改填充颜色

[英]Fabric.js object fails to change fill color when rendered from a JSON at the time the DOM loads

I am attempting to take a canvas element stylized with Fabric.js, convert it into a JSON and then presenting a limited/slightly static version of the Canvas on a page that a user with lower authorization can access.我正在尝试使用 Fabric.js 风格化的 canvas 元素,将其转换为 JSON,然后在权限较低的用户可以访问的页面上显示 Canvas 的有限/略微 static 版本。 When presenting this user version of the form I call the canvas.loadFromJSON() method with JQuery when the DOM loads and in the callback function I do some validation/editing to the objects(ie fill color, hasControls, selectable, etc.).当显示此用户版本的表单时,我在 DOM 加载时使用 JQuery 调用 canvas.loadFromJSON() 方法,并在回调 function 中对对象(即填充颜色、hasControls、可选等)进行一些验证/编辑。 However, only some of these changes take effect, with the one I'm having trouble with being the color.但是,这些更改中只有一部分会生效,而我在设置颜色时遇到了麻烦。 The interesting thing is that when I console.log the objects and look at the fill property it's changed.有趣的是,当我 console.log 对象并查看 fill 属性时,它发生了变化。 It's only the actual visual of it that is not.只有它的实际视觉效果不是。

Here is the code...这是代码...

let canvas = new fabric.Canvas("leasables-configuration");
// arrays that store different entities up for lease based on their status
//I need each of the elements in these to be different colors
let leasables = []; 
let closed = [];
let available = [];
let leased = [];

//use JQuery to run async requests so that I can 
//sort the various entities up for lease

$(function(){
    fetch("/api/leasables/get-all",{method: 'GET'})
        .then(response =>response.json())
        .then(data => {console.log(data);
                for (let leasable in data) {
                    leasables.push(data[leasable])
                    switch (data[leasable].leasableStatus.leasableStatus) {
                        case "leased":
                            console.log(data[leasable].leasableCode);
                            leased.push(data[leasable].leasableCode);
                            break;
                        case "open":
                            console.log(data[leasable].leasableCode);
                            available.push(data[leasable].leasableCode);
                            break;
                        case "closed":
                            console.log(data[leasable].leasableCode);
                            closed.push(data[leasable].leasableCode);
                            break;
                        default: break;
                    };
                }
//Start second async request to fetch JSON string from my POJO that is currently //published
                return fetch("/api/configurations/load", {method: 'GET'})
            }).then(response => response.json())
                .then(data => {
                    for (let field in data) {
                        if (field === "jsonification") {

// I have tried using canvas.renderOnAddRemove = false to see if there was a problem //with the timing of the data being rendered and my alterations to the fill color

                            canvas.loadFromJSON(data[field]);
                            canvas.renderAll();
                        }
                    }
                    clientLayer();
                });
    });

//I have tried keeping this logic in the callback section of the loadOnJSON function //but got the same result.

function clientLayer(){
    let objects = canvas.getObjects();
    console.log(objects);
    for (let element in objects) {
        let currentElement = objects[element];
//class is an attribute I gave to objects that were generic, the leasable objects do //not have the class attribute
        if (currentElement.class != undefined) {
            currentElement.selectable = false;
            currentElement.hoverCursor = 'default';
            canvas.sendToBack(currentElement);
        } else {
 //hasControls is commented out as after I adjust the size of the object the color //will change
            // currentElement.hasControls = false;
            if (leased.includes(currentElement.id)) {
               
                currentElement.fill = 'black';
            } else if (closed.includes(currentElement.id)) {
               
                currentElement.fill = 'grey';
            } else {
            
                currentElement.fill = 'white';
            }
        }
    }
//Still not too sure what the difference between requestRenderAll and renderAll is
    canvas.requestRenderAll();
}

This image shows that when expanded, the element has a fill attribute of white, yet it is still black.此图像显示展开时,元素的填充属性为白色,但它仍然是黑色。

This image was from directly after using the controls to change the size.此图像来自使用控件更改大小后直接生成的图像。 As you can see, the rectangle is now white.如您所见,矩形现在是白色的。 But I want the rectangle to be white without having to use the controls.但我希望矩形是白色的,而不必使用控件。

I'm happy to announce that I have figured out a way around my problem.我很高兴地宣布,我已经找到解决问题的方法。 Instead of altering the objects after they were added to the canvas element as objects, I simply modified the JSON I was passing to the canvas.loadFromJSON method.在将对象作为对象添加到 canvas 元素后,我没有更改对象,而是简单地修改了传递给 canvas.loadFromJSON 方法的 JSON。 This worked like a charm except when I assigned a strokeWidth property to the white squares, I got some funky behavior.这就像一个魅力,除了当我将 strokeWidth 属性分配给白色方块时,我得到了一些时髦的行为。 Not to worry though as I changed the colors to better fit my overall color scheme.不过不用担心,因为我更改了 colors 以更好地适应我的整体配色方案。

let leasables = [];
let closed = [];
let available = [];
let leased = [];


window.onload = function(){
    fetch("/api/leasables/get-all",{method: 'GET'})
        .then(response =>response.json())
        .then(data => {console.log(data);
                for (let leasable in data) {
                    leasables.push(data[leasable])
                    switch (data[leasable].leasableStatus.leasableStatus) {
                        case "leased":
                            console.log(data[leasable].leasableCode);
                            leased.push(data[leasable].leasableCode);
                            break;
                        case "open":
                            console.log(data[leasable].leasableCode);
                            available.push(data[leasable].leasableCode);
                            break;
                        case "closed":
                            console.log(data[leasable].leasableCode);
                            closed.push(data[leasable].leasableCode);
                            break;
                        default: break;
                    };
                }
                return fetch("/api/configurations/load", {method: 'GET'})
            }).then(response => response.json())
                .then(data => {
                    for (let field in data) {
                        if (field === "jsonification") {
//Here is where the magic happens, a simple reordering of logic :)
                            let json = clientLayer(data[field]);
                            canvas.loadFromJSON(json);
                            canvas.renderAll();
                        }
                    }
                });
    };

function clientLayer(unmodifiedJson){
    unmodifiedJson = JSON.parse(unmodifiedJson);
    console.log("unmodified json");
    console.log(unmodifiedJson);
    for (let element of unmodifiedJson.objects) {
        console.log("element");
        console.log(element);
        if (element.class != undefined) {
            element.selectable = false;
            element.hoverCursor = 'default';
            canvas.sendToBack(element);
        } else {
            element.hasControls = false;
            element.hoverCursor = 'pointer';
            if (leased.includes(element.id)) {
                console.log("included in leased");
                element.fill = 'orange';
            } else if (closed.includes(element.id)) {
                console.log("included in closed");
                element.fill = 'grey';
            } else {
                console.log("included in open");
                element.fill = 'green';
                element.stroke = 'black';
                // element.strokeWidth = '0.5';
            }
        }
    }
    let modifiedJson = unmodifiedJson;
    console.log(modifiedJson);
    return modifiedJson;
}```

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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