admin管理员组

文章数量:1277383

I have six floors of a building drawn on a canvas with fabric.js. In order to show only one floor, I do this:

building.selectFloor = function(floorId){

    for (var i = 0; i < floors.length; i++){
        if (floorId == floors[i].name){
            floors[i].visible = true;
        }else{
            floors[i].visible = false;          
        }
    }
    canvas.renderAll();
};

But nothing changes - all floors are still visible. The floors set to visible = false don't disappear until renderAll() is called later on a window resize:

$(window).resize(setSize);
setSize();


function setSize(){
    viewportWidth = $(window).width();
    viewportHeight = $(window).height();
    $appContainer.css({ "width": viewportWidth, "height": viewportHeight}); 
    canvas.setDimensions({ width: viewportWidth, height: viewportHeight });
    if (canvas.building){
        canvas.building.center();
        canvas.building.scaleX = canvas.building.scaleY = (viewportWidth + viewportHeight) / (1920 + 1080);
        canvas.renderAll();
    }
}

but then they do disappear. Why is one renderAll() working, and the other not? I've tried wrapping the non-functioning renderAll() in a window.timeOut to see if a delay helps, but no luck.

I have six floors of a building drawn on a canvas with fabric.js. In order to show only one floor, I do this:

building.selectFloor = function(floorId){

    for (var i = 0; i < floors.length; i++){
        if (floorId == floors[i].name){
            floors[i].visible = true;
        }else{
            floors[i].visible = false;          
        }
    }
    canvas.renderAll();
};

But nothing changes - all floors are still visible. The floors set to visible = false don't disappear until renderAll() is called later on a window resize:

$(window).resize(setSize);
setSize();


function setSize(){
    viewportWidth = $(window).width();
    viewportHeight = $(window).height();
    $appContainer.css({ "width": viewportWidth, "height": viewportHeight}); 
    canvas.setDimensions({ width: viewportWidth, height: viewportHeight });
    if (canvas.building){
        canvas.building.center();
        canvas.building.scaleX = canvas.building.scaleY = (viewportWidth + viewportHeight) / (1920 + 1080);
        canvas.renderAll();
    }
}

but then they do disappear. Why is one renderAll() working, and the other not? I've tried wrapping the non-functioning renderAll() in a window.timeOut to see if a delay helps, but no luck.

Share Improve this question asked Jan 20, 2017 at 23:39 wagsterwagster 5381 gold badge4 silver badges16 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 5

Ok - so I figured it out in the end: building is a group which appears to be getting cached by some internal fabric magic, and the cached version is being rendered instead of the updated version. To render the updated version you have to do this

canvas.building.set('dirty', true);
canvas.renderAll();

Hope that helps someone on down the line.

EDIT

Turns out there's an easier solution still:

canvas.building.objectCaching = false

There is a new version that changed the format to:

canvas.requestRenderAll();

You have to update (at least in the new version) object properties with object.set({...}) or set object.dirty = true in order to make the cache system recognize the change in the object properties. Disabling cache might not be the best idea, it has been included for a reason. canvas.requestRenderAll(); then works as intended.

This worked for me in later versions:

// for one canvas
myCanvas.objectCaching = false;

// for all canvas
fabric.Object.prototype.objectCaching = false;

// in both case it still needs to be re-rendered
myCanvas.renderAll();

ps: using version 4.2.0

本文标签: javascriptrenderAll() not working in fabricjsStack Overflow