123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836 |
- // Copyright 2007 The Closure Library Authors. All Rights Reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS-IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- /**
- * @fileoverview Objects representing shapes drawn on a canvas.
- * @author robbyw@google.com (Robby Walker)
- */
- goog.provide('goog.graphics.CanvasEllipseElement');
- goog.provide('goog.graphics.CanvasGroupElement');
- goog.provide('goog.graphics.CanvasImageElement');
- goog.provide('goog.graphics.CanvasPathElement');
- goog.provide('goog.graphics.CanvasRectElement');
- goog.provide('goog.graphics.CanvasTextElement');
- goog.require('goog.array');
- goog.require('goog.dom');
- goog.require('goog.dom.TagName');
- goog.require('goog.dom.safe');
- goog.require('goog.graphics.EllipseElement');
- goog.require('goog.graphics.Font');
- goog.require('goog.graphics.GroupElement');
- goog.require('goog.graphics.ImageElement');
- goog.require('goog.graphics.Path');
- goog.require('goog.graphics.PathElement');
- goog.require('goog.graphics.RectElement');
- goog.require('goog.graphics.TextElement');
- goog.require('goog.html.SafeHtml');
- goog.require('goog.html.uncheckedconversions');
- goog.require('goog.math');
- goog.require('goog.string');
- goog.require('goog.string.Const');
- /**
- * Object representing a group of objects in a canvas.
- * This is an implementation of the goog.graphics.GroupElement interface.
- * You should not construct objects from this constructor. The graphics
- * will return the object for you.
- * @param {goog.graphics.CanvasGraphics} graphics The graphics creating
- * this element.
- * @constructor
- * @extends {goog.graphics.GroupElement}
- * @deprecated goog.graphics is deprecated. It existed to abstract over browser
- * differences before the canvas tag was widely supported. See
- * http://en.wikipedia.org/wiki/Canvas_element for details.
- * @final
- */
- goog.graphics.CanvasGroupElement = function(graphics) {
- goog.graphics.GroupElement.call(this, null, graphics);
- /**
- * Children contained by this group.
- * @type {Array<goog.graphics.Element>}
- * @private
- */
- this.children_ = [];
- };
- goog.inherits(goog.graphics.CanvasGroupElement, goog.graphics.GroupElement);
- /**
- * Remove all drawing elements from the group.
- * @override
- */
- goog.graphics.CanvasGroupElement.prototype.clear = function() {
- if (this.children_.length) {
- this.children_.length = 0;
- this.getGraphics().redraw();
- }
- };
- /**
- * Set the size of the group element.
- * @param {number|string} width The width of the group element.
- * @param {number|string} height The height of the group element.
- * @override
- */
- goog.graphics.CanvasGroupElement.prototype.setSize = function(width, height) {
- // Do nothing.
- };
- /**
- * Append a child to the group. Does not draw it
- * @param {goog.graphics.Element} element The child to append.
- */
- goog.graphics.CanvasGroupElement.prototype.appendChild = function(element) {
- this.children_.push(element);
- };
- /**
- * Draw the group.
- * @param {CanvasRenderingContext2D} ctx The context to draw the element in.
- */
- goog.graphics.CanvasGroupElement.prototype.draw = function(ctx) {
- for (var i = 0, len = this.children_.length; i < len; i++) {
- this.getGraphics().drawElement(this.children_[i]);
- }
- };
- /**
- * Removes an element from the group.
- * @param {!goog.graphics.Element} elem the element to remove.
- */
- goog.graphics.CanvasGroupElement.prototype.removeElement = function(elem) {
- goog.array.removeIf(this.children_, function(child) {
- // If the child has children (and thus is a group element)
- // call removeElement on that group
- if (child.children_) {
- child.removeElement(elem);
- return false;
- } else {
- return child === elem;
- }
- });
- };
- /**
- * Thin wrapper for canvas ellipse elements.
- * This is an implementation of the goog.graphics.EllipseElement interface.
- * You should not construct objects from this constructor. The graphics
- * will return the object for you.
- * @param {Element} element The DOM element to wrap.
- * @param {goog.graphics.CanvasGraphics} graphics The graphics creating
- * this element.
- * @param {number} cx Center X coordinate.
- * @param {number} cy Center Y coordinate.
- * @param {number} rx Radius length for the x-axis.
- * @param {number} ry Radius length for the y-axis.
- * @param {goog.graphics.Stroke} stroke The stroke to use for this element.
- * @param {goog.graphics.Fill} fill The fill to use for this element.
- * @constructor
- * @extends {goog.graphics.EllipseElement}
- * @final
- */
- goog.graphics.CanvasEllipseElement = function(
- element, graphics, cx, cy, rx, ry, stroke, fill) {
- goog.graphics.EllipseElement.call(this, element, graphics, stroke, fill);
- /**
- * X coordinate of the ellipse center.
- * @type {number}
- * @private
- */
- this.cx_ = cx;
- /**
- * Y coordinate of the ellipse center.
- * @type {number}
- * @private
- */
- this.cy_ = cy;
- /**
- * Radius length for the x-axis.
- * @type {number}
- * @private
- */
- this.rx_ = rx;
- /**
- * Radius length for the y-axis.
- * @type {number}
- * @private
- */
- this.ry_ = ry;
- /**
- * Internal path approximating an ellipse.
- * @type {goog.graphics.Path}
- * @private
- */
- this.path_ = new goog.graphics.Path();
- this.setUpPath_();
- /**
- * Internal path element that actually does the drawing.
- * @type {goog.graphics.CanvasPathElement}
- * @private
- */
- this.pathElement_ = new goog.graphics.CanvasPathElement(
- null, graphics, this.path_, stroke, fill);
- };
- goog.inherits(goog.graphics.CanvasEllipseElement, goog.graphics.EllipseElement);
- /**
- * Sets up the path.
- * @private
- */
- goog.graphics.CanvasEllipseElement.prototype.setUpPath_ = function() {
- this.path_.clear();
- this.path_.moveTo(
- this.cx_ + goog.math.angleDx(0, this.rx_),
- this.cy_ + goog.math.angleDy(0, this.ry_));
- this.path_.arcTo(this.rx_, this.ry_, 0, 360);
- this.path_.close();
- };
- /**
- * Update the center point of the ellipse.
- * @param {number} cx Center X coordinate.
- * @param {number} cy Center Y coordinate.
- * @override
- */
- goog.graphics.CanvasEllipseElement.prototype.setCenter = function(cx, cy) {
- this.cx_ = cx;
- this.cy_ = cy;
- this.setUpPath_();
- this.pathElement_.setPath(/** @type {!goog.graphics.Path} */ (this.path_));
- };
- /**
- * Update the radius of the ellipse.
- * @param {number} rx Center X coordinate.
- * @param {number} ry Center Y coordinate.
- * @override
- */
- goog.graphics.CanvasEllipseElement.prototype.setRadius = function(rx, ry) {
- this.rx_ = rx;
- this.ry_ = ry;
- this.setUpPath_();
- this.pathElement_.setPath(/** @type {!goog.graphics.Path} */ (this.path_));
- };
- /**
- * Draw the ellipse. Should be treated as package scope.
- * @param {CanvasRenderingContext2D} ctx The context to draw the element in.
- */
- goog.graphics.CanvasEllipseElement.prototype.draw = function(ctx) {
- this.pathElement_.draw(ctx);
- };
- /**
- * Thin wrapper for canvas rectangle elements.
- * This is an implementation of the goog.graphics.RectElement interface.
- * You should not construct objects from this constructor. The graphics
- * will return the object for you.
- * @param {Element} element The DOM element to wrap.
- * @param {goog.graphics.CanvasGraphics} graphics The graphics creating
- * this element.
- * @param {number} x X coordinate (left).
- * @param {number} y Y coordinate (top).
- * @param {number} w Width of rectangle.
- * @param {number} h Height of rectangle.
- * @param {goog.graphics.Stroke} stroke The stroke to use for this element.
- * @param {goog.graphics.Fill} fill The fill to use for this element.
- * @constructor
- * @extends {goog.graphics.RectElement}
- * @final
- */
- goog.graphics.CanvasRectElement = function(
- element, graphics, x, y, w, h, stroke, fill) {
- goog.graphics.RectElement.call(this, element, graphics, stroke, fill);
- /**
- * X coordinate of the top left corner.
- * @type {number}
- * @private
- */
- this.x_ = x;
- /**
- * Y coordinate of the top left corner.
- * @type {number}
- * @private
- */
- this.y_ = y;
- /**
- * Width of the rectangle.
- * @type {number}
- * @private
- */
- this.w_ = w;
- /**
- * Height of the rectangle.
- * @type {number}
- * @private
- */
- this.h_ = h;
- };
- goog.inherits(goog.graphics.CanvasRectElement, goog.graphics.RectElement);
- /**
- * Update the position of the rectangle.
- * @param {number} x X coordinate (left).
- * @param {number} y Y coordinate (top).
- * @override
- */
- goog.graphics.CanvasRectElement.prototype.setPosition = function(x, y) {
- this.x_ = x;
- this.y_ = y;
- if (this.drawn_) {
- this.getGraphics().redraw();
- }
- };
- /**
- * Whether the rectangle has been drawn yet.
- * @type {boolean}
- * @private
- */
- goog.graphics.CanvasRectElement.prototype.drawn_ = false;
- /**
- * Update the size of the rectangle.
- * @param {number} width Width of rectangle.
- * @param {number} height Height of rectangle.
- * @override
- */
- goog.graphics.CanvasRectElement.prototype.setSize = function(width, height) {
- this.w_ = width;
- this.h_ = height;
- if (this.drawn_) {
- this.getGraphics().redraw();
- }
- };
- /**
- * Draw the rectangle. Should be treated as package scope.
- * @param {CanvasRenderingContext2D} ctx The context to draw the element in.
- */
- goog.graphics.CanvasRectElement.prototype.draw = function(ctx) {
- this.drawn_ = true;
- ctx.beginPath();
- ctx.moveTo(this.x_, this.y_);
- ctx.lineTo(this.x_, this.y_ + this.h_);
- ctx.lineTo(this.x_ + this.w_, this.y_ + this.h_);
- ctx.lineTo(this.x_ + this.w_, this.y_);
- ctx.closePath();
- };
- /**
- * Thin wrapper for canvas path elements.
- * This is an implementation of the goog.graphics.PathElement interface.
- * You should not construct objects from this constructor. The graphics
- * will return the object for you.
- * @param {Element} element The DOM element to wrap.
- * @param {goog.graphics.CanvasGraphics} graphics The graphics creating
- * this element.
- * @param {!goog.graphics.Path} path The path object to draw.
- * @param {goog.graphics.Stroke} stroke The stroke to use for this element.
- * @param {goog.graphics.Fill} fill The fill to use for this element.
- * @constructor
- * @extends {goog.graphics.PathElement}
- * @final
- */
- goog.graphics.CanvasPathElement = function(
- element, graphics, path, stroke, fill) {
- goog.graphics.PathElement.call(this, element, graphics, stroke, fill);
- this.setPath(path);
- };
- goog.inherits(goog.graphics.CanvasPathElement, goog.graphics.PathElement);
- /**
- * Whether the shape has been drawn yet.
- * @type {boolean}
- * @private
- */
- goog.graphics.CanvasPathElement.prototype.drawn_ = false;
- /**
- * The path to draw.
- * @type {goog.graphics.Path}
- * @private
- */
- goog.graphics.CanvasPathElement.prototype.path_;
- /**
- * Update the underlying path.
- * @param {!goog.graphics.Path} path The path object to draw.
- * @override
- */
- goog.graphics.CanvasPathElement.prototype.setPath = function(path) {
- this.path_ =
- path.isSimple() ? path : goog.graphics.Path.createSimplifiedPath(path);
- if (this.drawn_) {
- this.getGraphics().redraw();
- }
- };
- /**
- * Draw the path. Should be treated as package scope.
- * @param {CanvasRenderingContext2D} ctx The context to draw the element in.
- * @suppress {deprecated} goog.graphics is deprecated.
- */
- goog.graphics.CanvasPathElement.prototype.draw = function(ctx) {
- this.drawn_ = true;
- ctx.beginPath();
- this.path_.forEachSegment(function(segment, args) {
- switch (segment) {
- case goog.graphics.Path.Segment.MOVETO:
- ctx.moveTo(args[0], args[1]);
- break;
- case goog.graphics.Path.Segment.LINETO:
- for (var i = 0; i < args.length; i += 2) {
- ctx.lineTo(args[i], args[i + 1]);
- }
- break;
- case goog.graphics.Path.Segment.CURVETO:
- for (var i = 0; i < args.length; i += 6) {
- ctx.bezierCurveTo(
- args[i], args[i + 1], args[i + 2], args[i + 3], args[i + 4],
- args[i + 5]);
- }
- break;
- case goog.graphics.Path.Segment.ARCTO:
- throw Error('Canvas paths cannot contain arcs');
- case goog.graphics.Path.Segment.CLOSE:
- ctx.closePath();
- break;
- }
- });
- };
- /**
- * Thin wrapper for canvas text elements.
- * This is an implementation of the goog.graphics.TextElement interface.
- * You should not construct objects from this constructor. The graphics
- * will return the object for you.
- * @param {!goog.graphics.CanvasGraphics} graphics The graphics creating
- * this element.
- * @param {string} text The text to draw.
- * @param {number} x1 X coordinate of start of line.
- * @param {number} y1 Y coordinate of start of line.
- * @param {number} x2 X coordinate of end of line.
- * @param {number} y2 Y coordinate of end of line.
- * @param {?string} align Horizontal alignment: left (default), center, right.
- * @param {!goog.graphics.Font} font Font describing the font properties.
- * @param {goog.graphics.Stroke} stroke The stroke to use for this element.
- * @param {goog.graphics.Fill} fill The fill to use for this element.
- * @constructor
- * @extends {goog.graphics.TextElement}
- * @final
- */
- goog.graphics.CanvasTextElement = function(
- graphics, text, x1, y1, x2, y2, align, font, stroke, fill) {
- var element = goog.dom.createDom(
- goog.dom.TagName.DIV,
- {'style': 'display:table;position:absolute;padding:0;margin:0;border:0'});
- goog.graphics.TextElement.call(this, element, graphics, stroke, fill);
- /**
- * The text to draw.
- * @type {string}
- * @private
- */
- this.text_ = text;
- /**
- * X coordinate of the start of the line the text is drawn on.
- * @type {number}
- * @private
- */
- this.x1_ = x1;
- /**
- * Y coordinate of the start of the line the text is drawn on.
- * @type {number}
- * @private
- */
- this.y1_ = y1;
- /**
- * X coordinate of the end of the line the text is drawn on.
- * @type {number}
- * @private
- */
- this.x2_ = x2;
- /**
- * Y coordinate of the end of the line the text is drawn on.
- * @type {number}
- * @private
- */
- this.y2_ = y2;
- /**
- * Horizontal alignment: left (default), center, right.
- * @type {string}
- * @private
- */
- this.align_ = align || 'left';
- /**
- * Font object describing the font properties.
- * @type {goog.graphics.Font}
- * @private
- */
- this.font_ = font;
- /**
- * The inner element that contains the text.
- * @type {Element}
- * @private
- */
- this.innerElement_ = goog.dom.createDom(
- goog.dom.TagName.DIV,
- {'style': 'display:table-cell;padding: 0;margin: 0;border: 0'});
- this.updateStyle_();
- this.updateText_();
- // Append to the DOM.
- graphics.getElement().appendChild(element);
- element.appendChild(this.innerElement_);
- };
- goog.inherits(goog.graphics.CanvasTextElement, goog.graphics.TextElement);
- /**
- * Update the displayed text of the element.
- * @param {string} text The text to draw.
- * @override
- */
- goog.graphics.CanvasTextElement.prototype.setText = function(text) {
- this.text_ = text;
- this.updateText_();
- };
- /**
- * Sets the fill for this element.
- * @param {goog.graphics.Fill} fill The fill object.
- * @override
- */
- goog.graphics.CanvasTextElement.prototype.setFill = function(fill) {
- this.fill = fill;
- var element = this.getElement();
- if (element) {
- element.style.color = fill.getColor() || fill.getColor1();
- }
- };
- /**
- * Sets the stroke for this element.
- * @param {goog.graphics.Stroke} stroke The stroke object.
- * @override
- */
- goog.graphics.CanvasTextElement.prototype.setStroke = function(stroke) {
- // Ignore stroke
- };
- /**
- * Draw the text. Should be treated as package scope.
- * @param {CanvasRenderingContext2D} ctx The context to draw the element in.
- */
- goog.graphics.CanvasTextElement.prototype.draw = function(ctx) {
- // Do nothing - the text is already drawn.
- };
- /**
- * Update the styles of the DIVs.
- * @private
- */
- goog.graphics.CanvasTextElement.prototype.updateStyle_ = function() {
- var x1 = this.x1_;
- var x2 = this.x2_;
- var y1 = this.y1_;
- var y2 = this.y2_;
- var align = this.align_;
- var font = this.font_;
- var style = this.getElement().style;
- var scaleX = this.getGraphics().getPixelScaleX();
- var scaleY = this.getGraphics().getPixelScaleY();
- if (x1 == x2) {
- // Special case vertical text
- style.lineHeight = '90%';
- this.innerElement_.style.verticalAlign =
- align == 'center' ? 'middle' : align == 'left' ?
- (y1 < y2 ? 'top' : 'bottom') :
- y1 < y2 ? 'bottom' : 'top';
- style.textAlign = 'center';
- var w = font.size * scaleX;
- style.top = Math.round(Math.min(y1, y2) * scaleY) + 'px';
- style.left = Math.round((x1 - w / 2) * scaleX) + 'px';
- style.width = Math.round(w) + 'px';
- style.height = Math.abs(y1 - y2) * scaleY + 'px';
- style.fontSize = font.size * 0.6 * scaleY + 'pt';
- } else {
- style.lineHeight = '100%';
- this.innerElement_.style.verticalAlign = 'top';
- style.textAlign = align;
- style.top = Math.round(((y1 + y2) / 2 - font.size * 2 / 3) * scaleY) + 'px';
- style.left = Math.round(x1 * scaleX) + 'px';
- style.width = Math.round(Math.abs(x2 - x1) * scaleX) + 'px';
- style.height = 'auto';
- style.fontSize = font.size * scaleY + 'pt';
- }
- style.fontWeight = font.bold ? 'bold' : 'normal';
- style.fontStyle = font.italic ? 'italic' : 'normal';
- style.fontFamily = font.family;
- var fill = this.getFill();
- style.color = fill.getColor() || fill.getColor1();
- };
- /**
- * Update the text content.
- * @private
- */
- goog.graphics.CanvasTextElement.prototype.updateText_ = function() {
- if (this.x1_ == this.x2_) {
- // Special case vertical text
- var html =
- goog.array
- .map(
- this.text_.split(''),
- function(entry) { return goog.string.htmlEscape(entry); })
- .join('<br>');
- // Creating a SafeHtml for each character would be quite expensive, and it's
- // obvious that this is safe, so an unchecked conversion is appropriate.
- var safeHtml =
- goog.html.uncheckedconversions
- .safeHtmlFromStringKnownToSatisfyTypeContract(
- goog.string.Const.from('Concatenate escaped chars and <br>'),
- html);
- goog.dom.safe.setInnerHtml(
- /** @type {!Element} */ (this.innerElement_), safeHtml);
- } else {
- goog.dom.safe.setInnerHtml(
- /** @type {!Element} */ (this.innerElement_),
- goog.html.SafeHtml.htmlEscape(this.text_));
- }
- };
- /**
- * Thin wrapper for canvas image elements.
- * This is an implementation of the goog.graphics.ImageElement interface.
- * You should not construct objects from this constructor. The graphics
- * will return the object for you.
- * @param {Element} element The DOM element to wrap.
- * @param {goog.graphics.CanvasGraphics} graphics The graphics creating
- * this element.
- * @param {number} x X coordinate (left).
- * @param {number} y Y coordinate (top).
- * @param {number} w Width of rectangle.
- * @param {number} h Height of rectangle.
- * @param {string} src Source of the image.
- * @constructor
- * @extends {goog.graphics.ImageElement}
- * @final
- */
- goog.graphics.CanvasImageElement = function(
- element, graphics, x, y, w, h, src) {
- goog.graphics.ImageElement.call(this, element, graphics);
- /**
- * X coordinate of the top left corner.
- * @type {number}
- * @private
- */
- this.x_ = x;
- /**
- * Y coordinate of the top left corner.
- * @type {number}
- * @private
- */
- this.y_ = y;
- /**
- * Width of the rectangle.
- * @type {number}
- * @private
- */
- this.w_ = w;
- /**
- * Height of the rectangle.
- * @type {number}
- * @private
- */
- this.h_ = h;
- /**
- * URL of the image source.
- * @type {string}
- * @private
- */
- this.src_ = src;
- };
- goog.inherits(goog.graphics.CanvasImageElement, goog.graphics.ImageElement);
- /**
- * Whether the image has been drawn yet.
- * @type {boolean}
- * @private
- */
- goog.graphics.CanvasImageElement.prototype.drawn_ = false;
- /**
- * Update the position of the image.
- * @param {number} x X coordinate (left).
- * @param {number} y Y coordinate (top).
- * @override
- */
- goog.graphics.CanvasImageElement.prototype.setPosition = function(x, y) {
- this.x_ = x;
- this.y_ = y;
- if (this.drawn_) {
- this.getGraphics().redraw();
- }
- };
- /**
- * Update the size of the image.
- * @param {number} width Width of rectangle.
- * @param {number} height Height of rectangle.
- * @override
- */
- goog.graphics.CanvasImageElement.prototype.setSize = function(width, height) {
- this.w_ = width;
- this.h_ = height;
- if (this.drawn_) {
- this.getGraphics().redraw();
- }
- };
- /**
- * Update the source of the image.
- * @param {string} src Source of the image.
- * @override
- */
- goog.graphics.CanvasImageElement.prototype.setSource = function(src) {
- this.src_ = src;
- if (this.drawn_) {
- // TODO(robbyw): Probably need to reload the image here.
- this.getGraphics().redraw();
- }
- };
- /**
- * Draw the image. Should be treated as package scope.
- * @param {CanvasRenderingContext2D} ctx The context to draw the element in.
- */
- goog.graphics.CanvasImageElement.prototype.draw = function(ctx) {
- if (this.img_) {
- if (this.w_ && this.h_) {
- // If the image is already loaded, draw it.
- ctx.drawImage(this.img_, this.x_, this.y_, this.w_, this.h_);
- }
- this.drawn_ = true;
- } else {
- // Otherwise, load it.
- var img = new Image();
- img.onload = goog.bind(this.handleImageLoad_, this, img);
- // TODO(robbyw): Handle image load errors.
- img.src = this.src_;
- }
- };
- /**
- * Handle an image load.
- * @param {Element} img The image element that finished loading.
- * @private
- */
- goog.graphics.CanvasImageElement.prototype.handleImageLoad_ = function(img) {
- this.img_ = img;
- // TODO(robbyw): Add a small delay to catch batched images
- this.getGraphics().redraw();
- };
|