Re: Standardising canvas-driven background images

On Fri, Feb 20, 2015 at 7:51 AM, Ashley Gullen <ashley@scirra.com> wrote:
> Forgive me if I've missed past discussion on this feature but I need it so
> I'm wondering what the status of it is. (Ref:
> https://www.webkit.org/blog/176/css-canvas-drawing/ and
> http://updates.html5rocks.com/2012/12/Canvas-driven-background-images, also
> known as -webkit-canvas() or -moz-element())
>
> The use case I have for it is this: we are building a large web app that
> could end up dealing with thousands of dynamically generated icons since it
> deals with large user-generated projects. The most efficient way to deal
> with this many small images is to basically sprite sheet them on to a canvas
> 2d context. For example a 512x512 canvas would have room for a grid of 256
> different 32x32 icons. (These are drawn scaled down from user-generated
> content, so they are not known at the time the app loads and so a normal
> image cannot be used.) To display an icon, a 32x32 div sets its background
> image to the canvas at an offset, like a normal CSS sprite sheet but with a
> canvas.
>
> -webkit-canvas solves this, but I immediately ran in to bugs (in Chrome
> updating the canvas does not always redraw the background image), and as far
> as I can tell it has an uncertain future so I'm wary of depending on it. The
> workarounds are:
> - toDataURL() - synchronous so will jank the main thread, data URL inflation
> (+30% size), general insanity of dumping a huge string in to CSS properties
> - toBlob() - asynchronous which raises complexity problems (needs a way of
> firing events to all dependent icons to update them; updating them requires
> DOM/style changes; needs to handle awkward cases like the canvas changing
> while toBlob() is processing; needs to be carefully scheduled to avoid
> thrashing toBlob() if changes being made regularly e.g. as network requests
> complete). I also assume this uses more memory, since it effectively
> requires creating a separate image the same size which is stored in addition
> to the canvas.
>
> In comparison being able to put a canvas in a background images solves this
> elegantly: there is no need to convert the canvas or update the DOM as it
> changes, and it seems the memory overhead would be lower. It also opens up
> other use cases such as animated backgrounds.
>
> I see there may be security concerns around -moz-element() since it can use
> any DOM content. This does not appear to be necessary or even useful (what
> use cases is arbitrary DOM content for?). If video is desirable, then video
> can already be rendered to canvases, so -webkit-canvas still covers that.
>
> Therefore I would like to propose standardising this feature based off the
> -webkit-canvas() implementation.

The correct standardized approach is the element() function, defined
in Images level 4 (I'd link you, but I think I accidentally killed the
spec; wait a bit).  -moz-element() is a pre-spec implementation of
this that mostly matches the spec.

There aren't any security bugs; this just lets you paint a part of the
tree twice.  Anything you can do to attack the image generated by
element(), you can do to attack the DOM that element() is pointing to.

~TJ

Received on Friday, 20 February 2015 19:26:11 UTC