简体   繁体   中英

HTML5 Canvas render/caching issue

So basically I was looking for a way to order elements in SVG files. That's why I chose to use canvas and make it look like a grid with cells. And every element has its own coordinates. So far so good. I created a demo with most of the functionality I have (I excluded the methods for saving those items in the database).

You can select an element and put it into a cell and choose another element and put it in the same cell and they will be ordered based on their z-index and so on. Also you can right-click on the cell and remove some/all of the items in the cell.

Everything works as I want to (it has some glitches, but I will improve it). However there's a problem with refreshing the page.

When I save all elements to the database and then fetch them and prepare them for rendering on the canvas. They are not set until the page HARD refreshes (I'm on Chrome CTRL + R ).

I believe it's some kind of a caching issue. Is there a way to prevent caching the page or some workaround?

I will post just a jsfiddle since my javascript it's a bit long: http://jsfiddle.net/FakeHeal/ozd06eu0/4/

PS : for refreshing the page after updating the items in my DB I use window.location.reaload() on $.ajax() success.

As requested how I store my items:

DB table has element_id , x , y .

I prepare the data with this function:

var prepare = function (items) {
    var prepared = [];
    for (var i = 0; i < items.length; i++) {
        prepared[i] = {
            id: items[i].id,
            pos: items[i].x + ',' + items[i].y
        };
    }
    return prepared;
};

* this function is needed because my backend ( php ) has some limits in the INPUT ( $_POST , $_GET , $_COOKIE ).

And I have a click Listener on a button:

$('#update').on('click', function () {
    $.ajax({
        type: 'POST',
        data: {elements: prepare(items)},
        url: '/update'
    }).done(function (result) {
        location.reload(true);
    }, "json");
});

EDIT : What I mean by "not rendering properly" is that some of the elements are missing on the canvas (or atleast not shown) until I hover the cell (which triggers refreshCell() ).

What you may need to do is make sure your images have loaded before you attempt to output the results.

You can use document.ready or you could put your draw code in OnLoad method which is called after everything has loaded. I used document.ready and it fixed my issue. How ever I only had a few images loading I didn't have 100+ or anything like that.

The problem seems to be that you are drawing images which are not yet loaded.

What happens when you do

var img = document.createElement('img');
img.src = [url]

is that an empty image is created which stays empty until the image was downloaded and parsed. In the meantime the execution of your script continues. When it tries to use context.drawImage with an image which is not yet loaded, it won't draw anything.

To solve this issue, add an onLoad handler function to all images you create before you set the .src attribute and postpone any calls to drawImage until that function was called.

How do you postpone these calls?

There are several possible architectures you could use.

One is to build a simple preloader. Set a global variable to the number of images you have, decrement that global counter in each of your onLoad handlers, and when it reaches 0, initialize your actual application.

Another is to build a draw-function which acts like a Promise. Should the image be already loaded, it is drawn immediately. but when it is not, the draw-call gets added to a queue of drawing operations which is processed in the onLoad handler.

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