one of interface elements being rendered using html5 <canvas>
element , associated javascript api. element used in several places on same screen , on multiple screens throughout app. efficient way display everywhere it's required?
my first idea draw master canvas, clone , insert needed in page. master canvas might like:
var master = $('<canvas>').attr({ width: 100, height: 100 }), c = master[0], ctx = c.getcontext("2d"); ctx.fillstyle = "#ff0000"; ctx.fillrect(0, 0, 150, 75);
let's want duplicate canvas in these div
containers:
<div class="square-container" id="square_header"></div> ... <div class="square-container" id="square_datatable"></div> ... <div class="square-container" id="square_gallery"></div> ....
when page loads, i'll insert duplicate canvas element each container:
$(document).ready(function() { $('.square-container').each(function() { master.clone().appendto($(this)); }); });
the content being rendered on canvas going more complex simple square used in example still end being static image. possible, though, there dozens of different images each cloned dozens of times per page.
the other approach had in mind create image using todataurl()
method , set appropriate images' sources:
var master = $('<canvas>').attr({ width: 100, height: 100 }), c = master[0], ctx = c.getcontext("2d"); ctx.fillstyle = "#ff0000"; ctx.fillrect(0,0,150,75); var square = c.todataurl('image/png');
i add image tags necessary:
<img src="" id="square_header" class="square" alt="" /> ... <img src="" id="square_datatable1" class="square" alt="" /> ... <img src="" id="square_gallery" class="square" alt="" /> ....
and set of srcs newly created image:
$(document).ready(function() { $('img.square').attr('src', square); });
to me, pretty looks 6 of one, half dozen of other. i'm wondering if 1 way considered better practice other? if content being rendered on <canvas>
more complex, 1 way more efficient other?
in same spirit, when need use element on subsequent pages, best execute javascript (from whatever solution deemed best above) on each page or saving value of canvas_element.todataurl()
in cookie , using on subsequent pages more efficient?
cloning canvas duplicate dimensions , styling, not image data. can copy image data calling drawimage
on context. paint contents of originalcanvas
onto duplicatecanvas
, write:
duplicatecanvas.getcontext('2d').drawimage(originalcanvas, 0, 0);
as demonstration, following snippet generates 4 canvases:
an original canvas small scene painted onto it
a copy made calling
clonenode
onlya copy made calling
clonenode
,drawimage
a copy made creating new image , setting source data uri
function message(s) { document.getelementbyid('message').innerhtml += s + '<br />'; } function timeit(action, description, initializer) { var totaltime = 0, initializer = initializer || function () {}; initializer(); var starttime = performance.now(); action(); var elapsed = performance.now() - starttime; message('<span class="time"><span class="number">' + math.round(elapsed * 1000) + ' μs</span></span> ' + description); } function makecanvas() { var canvas = document.createelement('canvas'), context = canvas.getcontext('2d'); canvas.width = 100; canvas.height = 100; timeit(function () { context.fillstyle = '#a63d3d'; context.fillrect(10, 10, 80, 40); // paint small scene. context.fillstyle = '#3b618c'; context.beginpath(); context.arc(60, 60, 25, 0, 2*math.pi); context.closepath(); context.fill(); }, '(millionths of second) draw original scene', function () { context.clearrect(0, 0, canvas.width, canvas.height); }); return canvas; } // copycanvas returns canvas containing same image given canvas. function copycanvas(original) { var copy; timeit(function () { copy = original.clonenode(); // copy canvas dimensions. copy.getcontext('2d').drawimage(original, 0, 0); // copy image. }, 'to copy canvas clonenode , drawimage'); return copy; } // imagefromstorage extracts image data canvas, stores image data // in browser session, retrieves image data session , // makes new image element out of it. measure total time retrieve // data , make image. function imagefromstorage(original) { var image, datauri = original.todataurl(); timeit(function () { image = document.createelement('img'); image.src = datauri; }, 'to make image datauri'); return image; } function pageload() { var target = document.getelementbyid('canvases'), containers = {}, // we'll put canvases inside divs. names = ['original', 'clonenode', 'drawimage', 'datauri']; (var = 0; < names.length; ++i) { var name = names[i], // use name id , visible header. container = document.createelement('div'), header = document.createelement('div'); container.classname = 'container'; header.classname = 'header'; header.innerhtml = container.id = name; container.appendchild(header); target.appendchild(container); containers[name] = container; // canvas container ready. } var canvas = makecanvas(); containers.original.appendchild(canvas); // original canvas. containers.clonenode.appendchild(canvas.clonenode()); // clonenode containers.drawimage.appendchild(copycanvas(canvas)); // clonenode + drawimage containers.datauri.appendchild(imagefromstorage(canvas)); // localstorage } pageload();
body { font-family: sans-serif; } .header { font-size: 18px; } .container { margin: 10px; display: inline-block; } canvas, img { border: 1px solid #eee; } #message { color: #666; font-size: 16px; line-height: 28px; } #message .time { display: inline-block; text-align: right; width: 100px; } #message .number { font-weight: bold; padding: 1px 3px; color: #222; background: #efedd4; }
<div id="canvases"></div> <div id="message"></div>
if call todataurl
copy image data string use in other pages, don't put string cookie. cookies meant store small amounts of data. instead, use html5 web storage api store image data in browser. alternatively, if image doesn't change between user sessions, can render png image on server , use cache-control header encourage browser cache image file fast retrieval.
when comes performance of client-side image rendering, may faster draw scene anew paint stringified image data onto canvas. decoding string , painting pixels relatively expensive operation. find out if makes sense redraw scene on each page, can time drawing operations performance.now
, demonstrated in snippet.
Comments
Post a Comment