blob: b8b75533443e202b655733d211584b0f49e8741e [file] [log] [blame]
<!-- The <canvas-layers-sk> custom element declaration.
This is a utility element that is used around an img element, which places
layers of multiple canvas elements directly over the img element. Useful for
drawing annotations, crosshairs, etc. over an image.
The canvas-layers-sk element listens for 'load' events from the img element
and resizes each canvas when the image changes.
The canvas also listens for the builtin event "resize" on window, and also for
the custom event "partial-resize" also on window. You can send a
"partial-resize" custom event to window to trigger the canvas layers to check
the size of the image and resize appropriately.
Attributes:
layers - A JSON serialized array of layer names. There will be one canvas
for each name. Call canvas(name) to get the underlying canvas object.
Note that the order in layers determines the DOM order, with the last
member of layers being the last DOM canvas, which, for example, will
be the only canvas to get 'click' events because it will be on top.
Events:
canvas-update - Triggered when the underlying image has changed.
canvas-layers-updated - Triggered when the templating has finished
and the canvases are in place.
Methods:
canvas(name) - Returns the canvas object for the layer 'name'. See
the layers attribute.
-->
<link rel="import" href="/res/imp/bower_components/polymer/polymer.html">
<dom-module id="canvas-layers-sk">
<style>
:host {
display: inline-block;
position: relative;
}
canvas {
position: absolute;
top: 0;
left: 0;
}
</style>
<template>
<content></content>
<template is="dom-repeat" items="{{ layers }}" as="layer">
<canvas id$="{{ id }}-{{ layer }}" width=500 height=500>
</template>
</template>
</dom-module>
<script>
Polymer({
is: "canvas-layers-sk",
properties: {
layers: {
type: Array,
value: function() { return []; },
reflectToAttribute: false,
},
},
ready: function() {
this._img = $$$('img', this);
this._imageLoadedBound = this._imageLoaded.bind(this);
this._img.addEventListener('load', this._imageLoadedBound );
this.addEventListener('dom-change', this._imageLoadedBound);
this.addEventListener('dom-change', this._domChanged.bind(this));
this._resizing = false;
window.addEventListener('resize', function() {
if (this._resizing == true) {
return;
}
this._resizing = true;
window.requestAnimationFrame(function(){
this._resizing = false;
this._imageLoaded();
}.bind(this));
}.bind(this));
window.addEventListener('partial-resize', function() {
this._imageLoaded();
}.bind(this));
this._imageLoaded();
},
_domChanged: function() {
this.dispatchEvent(new CustomEvent('canvas-layers-updated', { bubbles: true }));
},
_imageLoaded: function() {
var detail = {
width: this._img.width,
height: this._img.height,
};
$$('canvas', this).forEach(function(c) {
c.width = this._img.width;
c.height = this._img.height;
c.dispatchEvent(new CustomEvent("canvas-update", { detail: detail, bubbles: true }));
}.bind(this));
},
canvas: function(name) {
return $$$("#" + this.id + "-" + name, this);
},
img: function() {
return this._img;
},
});
</script>