Update wmts-hidpi, add nicer-api-docs
This commit is contained in:
@@ -0,0 +1,441 @@
|
||||
// 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 Graphics utility functions and factory methods.
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.AbstractGraphics');
|
||||
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.graphics.Path');
|
||||
goog.require('goog.math.Coordinate');
|
||||
goog.require('goog.math.Size');
|
||||
goog.require('goog.style');
|
||||
goog.require('goog.ui.Component');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Base class for the different graphics. You should never construct objects
|
||||
* of this class. Instead us goog.graphics.createGraphics
|
||||
* @param {number|string} width The width in pixels or percent.
|
||||
* @param {number|string} height The height in pixels or percent.
|
||||
* @param {?number=} opt_coordWidth Optional coordinate system width - if
|
||||
* omitted or null, defaults to same as width.
|
||||
* @param {?number=} opt_coordHeight Optional coordinate system height - if
|
||||
* omitted or null, defaults to same as height.
|
||||
* @param {goog.dom.DomHelper=} opt_domHelper The DOM helper object for the
|
||||
* document we want to render in.
|
||||
* @constructor
|
||||
* @extends {goog.ui.Component}
|
||||
*/
|
||||
goog.graphics.AbstractGraphics = function(width, height,
|
||||
opt_coordWidth, opt_coordHeight,
|
||||
opt_domHelper) {
|
||||
goog.ui.Component.call(this, opt_domHelper);
|
||||
|
||||
/**
|
||||
* Width of graphics in pixels or percentage points.
|
||||
* @type {number|string}
|
||||
* @protected
|
||||
*/
|
||||
this.width = width;
|
||||
|
||||
/**
|
||||
* Height of graphics in pixels or precentage points.
|
||||
* @type {number|string}
|
||||
* @protected
|
||||
*/
|
||||
this.height = height;
|
||||
|
||||
/**
|
||||
* Width of coordinate system in units.
|
||||
* @type {?number}
|
||||
* @protected
|
||||
*/
|
||||
this.coordWidth = opt_coordWidth || null;
|
||||
|
||||
/**
|
||||
* Height of coordinate system in units.
|
||||
* @type {?number}
|
||||
* @protected
|
||||
*/
|
||||
this.coordHeight = opt_coordHeight || null;
|
||||
};
|
||||
goog.inherits(goog.graphics.AbstractGraphics, goog.ui.Component);
|
||||
|
||||
|
||||
/**
|
||||
* The root level group element.
|
||||
* @type {goog.graphics.GroupElement?}
|
||||
* @protected
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.canvasElement = null;
|
||||
|
||||
|
||||
/**
|
||||
* Left coordinate of the view box
|
||||
* @type {number}
|
||||
* @protected
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.coordLeft = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Top coordinate of the view box
|
||||
* @type {number}
|
||||
* @protected
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.coordTop = 0;
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.graphics.GroupElement} The root level canvas element.
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.getCanvasElement = function() {
|
||||
return this.canvasElement;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Changes the coordinate size.
|
||||
* @param {number} coordWidth The coordinate width.
|
||||
* @param {number} coordHeight The coordinate height.
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.setCoordSize = function(coordWidth,
|
||||
coordHeight) {
|
||||
this.coordWidth = coordWidth;
|
||||
this.coordHeight = coordHeight;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.math.Size} The coordinate size.
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.getCoordSize = function() {
|
||||
if (this.coordWidth) {
|
||||
return new goog.math.Size(this.coordWidth,
|
||||
/** @type {number} */ (this.coordHeight));
|
||||
} else {
|
||||
return this.getPixelSize();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Changes the coordinate system position.
|
||||
* @param {number} left The coordinate system left bound.
|
||||
* @param {number} top The coordinate system top bound.
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.setCoordOrigin = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.math.Coordinate} The coordinate system position.
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.getCoordOrigin = function() {
|
||||
return new goog.math.Coordinate(this.coordLeft, this.coordTop);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Change the size of the canvas.
|
||||
* @param {number} pixelWidth The width in pixels.
|
||||
* @param {number} pixelHeight The height in pixels.
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.setSize = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.math.Size} The size of canvas.
|
||||
* @deprecated Use getPixelSize.
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.getSize = function() {
|
||||
return this.getPixelSize();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.math.Size?} Returns the number of pixels spanned by the
|
||||
* surface, or null if the size could not be computed due to the size being
|
||||
* specified in percentage points and the component not being in the
|
||||
* document.
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.getPixelSize = function() {
|
||||
if (this.isInDocument()) {
|
||||
return goog.style.getSize(this.getElement());
|
||||
}
|
||||
if (goog.isNumber(this.width) && goog.isNumber(this.height)) {
|
||||
return new goog.math.Size(this.width, this.height);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} Returns the number of pixels per unit in the x direction.
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.getPixelScaleX = function() {
|
||||
var pixelSize = this.getPixelSize();
|
||||
return pixelSize ? pixelSize.width / this.getCoordSize().width : 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} Returns the number of pixels per unit in the y direction.
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.getPixelScaleY = function() {
|
||||
var pixelSize = this.getPixelSize();
|
||||
return pixelSize ? pixelSize.height / this.getCoordSize().height : 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Remove all drawing elements from the graphics.
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.clear = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* Remove a single drawing element from the surface. The default implementation
|
||||
* assumes a DOM based drawing surface.
|
||||
* @param {goog.graphics.Element} element The element to remove.
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.removeElement = function(element) {
|
||||
goog.dom.removeNode(element.getElement());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the fill for the given element.
|
||||
* @param {goog.graphics.StrokeAndFillElement} element The element wrapper.
|
||||
* @param {goog.graphics.Fill?} fill The fill object.
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.setElementFill = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* Sets the stroke for the given element.
|
||||
* @param {goog.graphics.StrokeAndFillElement} element The element wrapper.
|
||||
* @param {goog.graphics.Stroke?} stroke The stroke object.
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.setElementStroke = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* Set the transformation of an element.
|
||||
* @param {goog.graphics.Element} element The element wrapper.
|
||||
* @param {number} x The x coordinate of the translation transform.
|
||||
* @param {number} y The y coordinate of the translation transform.
|
||||
* @param {number} angle The angle of the rotation transform.
|
||||
* @param {number} centerX The horizontal center of the rotation transform.
|
||||
* @param {number} centerY The vertical center of the rotation transform.
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.setElementTransform =
|
||||
goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* Draw a circle
|
||||
*
|
||||
* @param {number} cx Center X coordinate.
|
||||
* @param {number} cy Center Y coordinate.
|
||||
* @param {number} r Radius length.
|
||||
* @param {goog.graphics.Stroke?} stroke Stroke object describing the
|
||||
* stroke.
|
||||
* @param {goog.graphics.Fill?} fill Fill object describing the fill.
|
||||
* @param {goog.graphics.GroupElement=} opt_group The group wrapper element to
|
||||
* append to. If not specified, appends to the main canvas.
|
||||
*
|
||||
* @return {goog.graphics.EllipseElement} The newly created element.
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.drawCircle = function(
|
||||
cx, cy, r, stroke, fill, opt_group) {
|
||||
return this.drawEllipse(cx, cy, r, r, stroke, fill, opt_group);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Draw an ellipse
|
||||
*
|
||||
* @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 Stroke object describing the
|
||||
* stroke.
|
||||
* @param {goog.graphics.Fill?} fill Fill object describing the fill.
|
||||
* @param {goog.graphics.GroupElement=} opt_group The group wrapper element to
|
||||
* append to. If not specified, appends to the main canvas.
|
||||
*
|
||||
* @return {goog.graphics.EllipseElement} The newly created element.
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.drawEllipse = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* Draw a rectangle
|
||||
*
|
||||
* @param {number} x X coordinate (left).
|
||||
* @param {number} y Y coordinate (top).
|
||||
* @param {number} width Width of rectangle.
|
||||
* @param {number} height Height of rectangle.
|
||||
* @param {goog.graphics.Stroke?} stroke Stroke object describing the
|
||||
* stroke.
|
||||
* @param {goog.graphics.Fill?} fill Fill object describing the fill.
|
||||
* @param {goog.graphics.GroupElement=} opt_group The group wrapper element to
|
||||
* append to. If not specified, appends to the main canvas.
|
||||
*
|
||||
* @return {goog.graphics.RectElement} The newly created element.
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.drawRect = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* Draw a text string within a rectangle (drawing is horizontal)
|
||||
*
|
||||
* @param {string} text The text to draw.
|
||||
* @param {number} x X coordinate (left).
|
||||
* @param {number} y Y coordinate (top).
|
||||
* @param {number} width Width of rectangle.
|
||||
* @param {number} height Height of rectangle.
|
||||
* @param {string} align Horizontal alignment: left (default), center, right.
|
||||
* @param {string} vAlign Vertical alignment: top (default), center, bottom.
|
||||
* @param {goog.graphics.Font} font Font describing the font properties.
|
||||
* @param {goog.graphics.Stroke?} stroke Stroke object describing the
|
||||
* stroke.
|
||||
* @param {goog.graphics.Fill?} fill Fill object describing the fill.
|
||||
* @param {goog.graphics.GroupElement=} opt_group The group wrapper element to
|
||||
* append to. If not specified, appends to the main canvas.
|
||||
*
|
||||
* @return {goog.graphics.TextElement} The newly created element.
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.drawText = function(
|
||||
text, x, y, width, height, align, vAlign, font, stroke, fill, opt_group) {
|
||||
var baseline = font.size / 2; // Baseline is middle of line
|
||||
var textY;
|
||||
if (vAlign == 'bottom') {
|
||||
textY = y + height - baseline;
|
||||
} else if (vAlign == 'center') {
|
||||
textY = y + height / 2;
|
||||
} else {
|
||||
textY = y + baseline;
|
||||
}
|
||||
|
||||
return this.drawTextOnLine(text, x, textY, x + width, textY, align,
|
||||
font, stroke, fill, opt_group);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Draw a text string vertically centered on a given line.
|
||||
*
|
||||
* @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 alingnment: left (default), center, right.
|
||||
* @param {goog.graphics.Font} font Font describing the font properties.
|
||||
* @param {goog.graphics.Stroke?} stroke Stroke object describing the
|
||||
* stroke.
|
||||
* @param {goog.graphics.Fill?} fill Fill object describing the fill.
|
||||
* @param {goog.graphics.GroupElement=} opt_group The group wrapper element to
|
||||
* append to. If not specified, appends to the main canvas.
|
||||
*
|
||||
* @return {goog.graphics.TextElement} The newly created element.
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.drawTextOnLine = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* Draw a path.
|
||||
*
|
||||
* @param {!goog.graphics.Path} path The path object to draw.
|
||||
* @param {goog.graphics.Stroke?} stroke Stroke object describing the
|
||||
* stroke.
|
||||
* @param {goog.graphics.Fill?} fill Fill object describing the fill.
|
||||
* @param {goog.graphics.GroupElement=} opt_group The group wrapper element to
|
||||
* append to. If not specified, appends to the main canvas.
|
||||
*
|
||||
* @return {goog.graphics.PathElement} The newly created element.
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.drawPath = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* Create an empty group of drawing elements.
|
||||
*
|
||||
* @param {goog.graphics.GroupElement=} opt_group The group wrapper element to
|
||||
* append to. If not specified, appends to the main canvas.
|
||||
*
|
||||
* @return {goog.graphics.GroupElement} The newly created group.
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.createGroup = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* Create an empty path.
|
||||
*
|
||||
* @return {goog.graphics.Path} The path.
|
||||
* @deprecated Use {@code new goog.graphics.Path()}.
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.createPath = function() {
|
||||
return new goog.graphics.Path();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Measure and return the width (in pixels) of a given text string.
|
||||
* Text measurement is needed to make sure a text can fit in the allocated
|
||||
* area. The way text length is measured is by writing it into a div that is
|
||||
* after the visible area, measure the div width, and immediatly erase the
|
||||
* written value.
|
||||
*
|
||||
* @param {string} text The text string to measure.
|
||||
* @param {goog.graphics.Font} font The font object describing the font style.
|
||||
*
|
||||
* @return {number} The width in pixels of the text strings.
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.getTextWidth = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the underlying element can be cloned resulting in
|
||||
* an accurate reproduction of the graphics contents.
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.isDomClonable = function() {
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Start preventing redraws - useful for chaining large numbers of changes
|
||||
* together. Not guaranteed to do anything - i.e. only use this for
|
||||
* optimization of a single code path.
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.suspend = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Stop preventing redraws. If any redraws had been prevented, a redraw will
|
||||
* be done now.
|
||||
*/
|
||||
goog.graphics.AbstractGraphics.prototype.resume = function() {
|
||||
};
|
||||
@@ -0,0 +1,587 @@
|
||||
// Copyright 2008 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 Provides an object representation of an AffineTransform and
|
||||
* methods for working with it.
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.AffineTransform');
|
||||
|
||||
goog.require('goog.math');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates a 2D affine transform. An affine transform performs a linear
|
||||
* mapping from 2D coordinates to other 2D coordinates that preserves the
|
||||
* "straightness" and "parallelness" of lines.
|
||||
*
|
||||
* Such a coordinate transformation can be represented by a 3 row by 3 column
|
||||
* matrix with an implied last row of [ 0 0 1 ]. This matrix transforms source
|
||||
* coordinates (x,y) into destination coordinates (x',y') by considering them
|
||||
* to be a column vector and multiplying the coordinate vector by the matrix
|
||||
* according to the following process:
|
||||
* <pre>
|
||||
* [ x'] [ m00 m01 m02 ] [ x ] [ m00x + m01y + m02 ]
|
||||
* [ y'] = [ m10 m11 m12 ] [ y ] = [ m10x + m11y + m12 ]
|
||||
* [ 1 ] [ 0 0 1 ] [ 1 ] [ 1 ]
|
||||
* </pre>
|
||||
*
|
||||
* This class is optimized for speed and minimizes calculations based on its
|
||||
* knowledge of the underlying matrix (as opposed to say simply performing
|
||||
* matrix multiplication).
|
||||
*
|
||||
* @param {number=} opt_m00 The m00 coordinate of the transform.
|
||||
* @param {number=} opt_m10 The m10 coordinate of the transform.
|
||||
* @param {number=} opt_m01 The m01 coordinate of the transform.
|
||||
* @param {number=} opt_m11 The m11 coordinate of the transform.
|
||||
* @param {number=} opt_m02 The m02 coordinate of the transform.
|
||||
* @param {number=} opt_m12 The m12 coordinate of the transform.
|
||||
* @constructor
|
||||
*/
|
||||
goog.graphics.AffineTransform = function(opt_m00, opt_m10, opt_m01,
|
||||
opt_m11, opt_m02, opt_m12) {
|
||||
if (arguments.length == 6) {
|
||||
this.setTransform(/** @type {number} */ (opt_m00),
|
||||
/** @type {number} */ (opt_m10),
|
||||
/** @type {number} */ (opt_m01),
|
||||
/** @type {number} */ (opt_m11),
|
||||
/** @type {number} */ (opt_m02),
|
||||
/** @type {number} */ (opt_m12));
|
||||
} else if (arguments.length != 0) {
|
||||
throw Error('Insufficient matrix parameters');
|
||||
} else {
|
||||
this.m00_ = this.m11_ = 1;
|
||||
this.m10_ = this.m01_ = this.m02_ = this.m12_ = 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether this transform is the identity transform.
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.isIdentity = function() {
|
||||
return this.m00_ == 1 && this.m10_ == 0 && this.m01_ == 0 &&
|
||||
this.m11_ == 1 && this.m02_ == 0 && this.m12_ == 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!goog.graphics.AffineTransform} A copy of this transform.
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.clone = function() {
|
||||
return new goog.graphics.AffineTransform(this.m00_, this.m10_, this.m01_,
|
||||
this.m11_, this.m02_, this.m12_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets this transform to the matrix specified by the 6 values.
|
||||
*
|
||||
* @param {number} m00 The m00 coordinate of the transform.
|
||||
* @param {number} m10 The m10 coordinate of the transform.
|
||||
* @param {number} m01 The m01 coordinate of the transform.
|
||||
* @param {number} m11 The m11 coordinate of the transform.
|
||||
* @param {number} m02 The m02 coordinate of the transform.
|
||||
* @param {number} m12 The m12 coordinate of the transform.
|
||||
* @return {!goog.graphics.AffineTransform} This affine transform.
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.setTransform = function(m00, m10, m01,
|
||||
m11, m02, m12) {
|
||||
if (!goog.isNumber(m00) || !goog.isNumber(m10) || !goog.isNumber(m01) ||
|
||||
!goog.isNumber(m11) || !goog.isNumber(m02) || !goog.isNumber(m12)) {
|
||||
throw Error('Invalid transform parameters');
|
||||
}
|
||||
this.m00_ = m00;
|
||||
this.m10_ = m10;
|
||||
this.m01_ = m01;
|
||||
this.m11_ = m11;
|
||||
this.m02_ = m02;
|
||||
this.m12_ = m12;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets this transform to be identical to the given transform.
|
||||
*
|
||||
* @param {!goog.graphics.AffineTransform} tx The transform to copy.
|
||||
* @return {!goog.graphics.AffineTransform} This affine transform.
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.copyFrom = function(tx) {
|
||||
this.m00_ = tx.m00_;
|
||||
this.m10_ = tx.m10_;
|
||||
this.m01_ = tx.m01_;
|
||||
this.m11_ = tx.m11_;
|
||||
this.m02_ = tx.m02_;
|
||||
this.m12_ = tx.m12_;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Concatenates this transform with a scaling transformation.
|
||||
*
|
||||
* @param {number} sx The x-axis scaling factor.
|
||||
* @param {number} sy The y-axis scaling factor.
|
||||
* @return {!goog.graphics.AffineTransform} This affine transform.
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.scale = function(sx, sy) {
|
||||
this.m00_ *= sx;
|
||||
this.m10_ *= sx;
|
||||
this.m01_ *= sy;
|
||||
this.m11_ *= sy;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Pre-concatenates this transform with a scaling transformation,
|
||||
* i.e. calculates the following matrix product:
|
||||
*
|
||||
* <pre>
|
||||
* [sx 0 0] [m00 m01 m02]
|
||||
* [ 0 sy 0] [m10 m11 m12]
|
||||
* [ 0 0 1] [ 0 0 1]
|
||||
* </pre>
|
||||
*
|
||||
* @param {number} sx The x-axis scaling factor.
|
||||
* @param {number} sy The y-axis scaling factor.
|
||||
* @return {!goog.graphics.AffineTransform} This affine transform.
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.preScale = function(sx, sy) {
|
||||
this.m00_ *= sx;
|
||||
this.m01_ *= sx;
|
||||
this.m02_ *= sx;
|
||||
this.m10_ *= sy;
|
||||
this.m11_ *= sy;
|
||||
this.m12_ *= sy;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Concatenates this transform with a translate transformation.
|
||||
*
|
||||
* @param {number} dx The distance to translate in the x direction.
|
||||
* @param {number} dy The distance to translate in the y direction.
|
||||
* @return {!goog.graphics.AffineTransform} This affine transform.
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.translate = function(dx, dy) {
|
||||
this.m02_ += dx * this.m00_ + dy * this.m01_;
|
||||
this.m12_ += dx * this.m10_ + dy * this.m11_;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Pre-concatenates this transform with a translate transformation,
|
||||
* i.e. calculates the following matrix product:
|
||||
*
|
||||
* <pre>
|
||||
* [1 0 dx] [m00 m01 m02]
|
||||
* [0 1 dy] [m10 m11 m12]
|
||||
* [0 0 1] [ 0 0 1]
|
||||
* </pre>
|
||||
*
|
||||
* @param {number} dx The distance to translate in the x direction.
|
||||
* @param {number} dy The distance to translate in the y direction.
|
||||
* @return {!goog.graphics.AffineTransform} This affine transform.
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.preTranslate = function(dx, dy) {
|
||||
this.m02_ += dx;
|
||||
this.m12_ += dy;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Concatenates this transform with a rotation transformation around an anchor
|
||||
* point.
|
||||
*
|
||||
* @param {number} theta The angle of rotation measured in radians.
|
||||
* @param {number} x The x coordinate of the anchor point.
|
||||
* @param {number} y The y coordinate of the anchor point.
|
||||
* @return {!goog.graphics.AffineTransform} This affine transform.
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.rotate = function(theta, x, y) {
|
||||
return this.concatenate(
|
||||
goog.graphics.AffineTransform.getRotateInstance(theta, x, y));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Pre-concatenates this transform with a rotation transformation around an
|
||||
* anchor point.
|
||||
*
|
||||
* @param {number} theta The angle of rotation measured in radians.
|
||||
* @param {number} x The x coordinate of the anchor point.
|
||||
* @param {number} y The y coordinate of the anchor point.
|
||||
* @return {!goog.graphics.AffineTransform} This affine transform.
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.preRotate = function(theta, x, y) {
|
||||
return this.preConcatenate(
|
||||
goog.graphics.AffineTransform.getRotateInstance(theta, x, y));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Concatenates this transform with a shear transformation.
|
||||
*
|
||||
* @param {number} shx The x shear factor.
|
||||
* @param {number} shy The y shear factor.
|
||||
* @return {!goog.graphics.AffineTransform} This affine transform.
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.shear = function(shx, shy) {
|
||||
var m00 = this.m00_;
|
||||
var m10 = this.m10_;
|
||||
this.m00_ += shy * this.m01_;
|
||||
this.m10_ += shy * this.m11_;
|
||||
this.m01_ += shx * m00;
|
||||
this.m11_ += shx * m10;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Pre-concatenates this transform with a shear transformation.
|
||||
* i.e. calculates the following matrix product:
|
||||
*
|
||||
* <pre>
|
||||
* [ 1 shx 0] [m00 m01 m02]
|
||||
* [shy 1 0] [m10 m11 m12]
|
||||
* [ 0 0 1] [ 0 0 1]
|
||||
* </pre>
|
||||
*
|
||||
* @param {number} shx The x shear factor.
|
||||
* @param {number} shy The y shear factor.
|
||||
* @return {!goog.graphics.AffineTransform} This affine transform.
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.preShear = function(shx, shy) {
|
||||
var m00 = this.m00_;
|
||||
var m01 = this.m01_;
|
||||
var m02 = this.m02_;
|
||||
this.m00_ += shx * this.m10_;
|
||||
this.m01_ += shx * this.m11_;
|
||||
this.m02_ += shx * this.m12_;
|
||||
this.m10_ += shy * m00;
|
||||
this.m11_ += shy * m01;
|
||||
this.m12_ += shy * m02;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} A string representation of this transform. The format of
|
||||
* of the string is compatible with SVG matrix notation, i.e.
|
||||
* "matrix(a,b,c,d,e,f)".
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.toString = function() {
|
||||
return 'matrix(' +
|
||||
[this.m00_, this.m10_, this.m01_, this.m11_, this.m02_, this.m12_].join(
|
||||
',') +
|
||||
')';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The scaling factor in the x-direction (m00).
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.getScaleX = function() {
|
||||
return this.m00_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The scaling factor in the y-direction (m11).
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.getScaleY = function() {
|
||||
return this.m11_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The translation in the x-direction (m02).
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.getTranslateX = function() {
|
||||
return this.m02_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The translation in the y-direction (m12).
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.getTranslateY = function() {
|
||||
return this.m12_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The shear factor in the x-direction (m01).
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.getShearX = function() {
|
||||
return this.m01_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The shear factor in the y-direction (m10).
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.getShearY = function() {
|
||||
return this.m10_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Concatenates an affine transform to this transform.
|
||||
*
|
||||
* @param {!goog.graphics.AffineTransform} tx The transform to concatenate.
|
||||
* @return {!goog.graphics.AffineTransform} This affine transform.
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.concatenate = function(tx) {
|
||||
var m0 = this.m00_;
|
||||
var m1 = this.m01_;
|
||||
this.m00_ = tx.m00_ * m0 + tx.m10_ * m1;
|
||||
this.m01_ = tx.m01_ * m0 + tx.m11_ * m1;
|
||||
this.m02_ += tx.m02_ * m0 + tx.m12_ * m1;
|
||||
|
||||
m0 = this.m10_;
|
||||
m1 = this.m11_;
|
||||
this.m10_ = tx.m00_ * m0 + tx.m10_ * m1;
|
||||
this.m11_ = tx.m01_ * m0 + tx.m11_ * m1;
|
||||
this.m12_ += tx.m02_ * m0 + tx.m12_ * m1;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Pre-concatenates an affine transform to this transform.
|
||||
*
|
||||
* @param {!goog.graphics.AffineTransform} tx The transform to preconcatenate.
|
||||
* @return {!goog.graphics.AffineTransform} This affine transform.
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.preConcatenate = function(tx) {
|
||||
var m0 = this.m00_;
|
||||
var m1 = this.m10_;
|
||||
this.m00_ = tx.m00_ * m0 + tx.m01_ * m1;
|
||||
this.m10_ = tx.m10_ * m0 + tx.m11_ * m1;
|
||||
|
||||
m0 = this.m01_;
|
||||
m1 = this.m11_;
|
||||
this.m01_ = tx.m00_ * m0 + tx.m01_ * m1;
|
||||
this.m11_ = tx.m10_ * m0 + tx.m11_ * m1;
|
||||
|
||||
m0 = this.m02_;
|
||||
m1 = this.m12_;
|
||||
this.m02_ = tx.m00_ * m0 + tx.m01_ * m1 + tx.m02_;
|
||||
this.m12_ = tx.m10_ * m0 + tx.m11_ * m1 + tx.m12_;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Transforms an array of coordinates by this transform and stores the result
|
||||
* into a destination array.
|
||||
*
|
||||
* @param {!Array.<number>} src The array containing the source points
|
||||
* as x, y value pairs.
|
||||
* @param {number} srcOff The offset to the first point to be transformed.
|
||||
* @param {!Array.<number>} dst The array into which to store the transformed
|
||||
* point pairs.
|
||||
* @param {number} dstOff The offset of the location of the first transformed
|
||||
* point in the destination array.
|
||||
* @param {number} numPts The number of points to tranform.
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.transform = function(src, srcOff, dst,
|
||||
dstOff, numPts) {
|
||||
var i = srcOff;
|
||||
var j = dstOff;
|
||||
var srcEnd = srcOff + 2 * numPts;
|
||||
while (i < srcEnd) {
|
||||
var x = src[i++];
|
||||
var y = src[i++];
|
||||
dst[j++] = x * this.m00_ + y * this.m01_ + this.m02_;
|
||||
dst[j++] = x * this.m10_ + y * this.m11_ + this.m12_;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The determinant of this transform.
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.getDeterminant = function() {
|
||||
return this.m00_ * this.m11_ - this.m01_ * this.m10_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether the transform is invertible. A transform is not invertible
|
||||
* if the determinant is 0 or any value is non-finite or NaN.
|
||||
*
|
||||
* @return {boolean} Whether the transform is invertible.
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.isInvertible = function() {
|
||||
var det = this.getDeterminant();
|
||||
return goog.math.isFiniteNumber(det) &&
|
||||
goog.math.isFiniteNumber(this.m02_) &&
|
||||
goog.math.isFiniteNumber(this.m12_) &&
|
||||
det != 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!goog.graphics.AffineTransform} An AffineTransform object
|
||||
* representing the inverse transformation.
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.createInverse = function() {
|
||||
var det = this.getDeterminant();
|
||||
return new goog.graphics.AffineTransform(
|
||||
this.m11_ / det,
|
||||
-this.m10_ / det,
|
||||
-this.m01_ / det,
|
||||
this.m00_ / det,
|
||||
(this.m01_ * this.m12_ - this.m11_ * this.m02_) / det,
|
||||
(this.m10_ * this.m02_ - this.m00_ * this.m12_) / det);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a transform representing a scaling transformation.
|
||||
*
|
||||
* @param {number} sx The x-axis scaling factor.
|
||||
* @param {number} sy The y-axis scaling factor.
|
||||
* @return {!goog.graphics.AffineTransform} A transform representing a scaling
|
||||
* transformation.
|
||||
*/
|
||||
goog.graphics.AffineTransform.getScaleInstance = function(sx, sy) {
|
||||
return new goog.graphics.AffineTransform().setToScale(sx, sy);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a transform representing a translation transformation.
|
||||
*
|
||||
* @param {number} dx The distance to translate in the x direction.
|
||||
* @param {number} dy The distance to translate in the y direction.
|
||||
* @return {!goog.graphics.AffineTransform} A transform representing a
|
||||
* translation transformation.
|
||||
*/
|
||||
goog.graphics.AffineTransform.getTranslateInstance = function(dx, dy) {
|
||||
return new goog.graphics.AffineTransform().setToTranslation(dx, dy);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a transform representing a shearing transformation.
|
||||
*
|
||||
* @param {number} shx The x-axis shear factor.
|
||||
* @param {number} shy The y-axis shear factor.
|
||||
* @return {!goog.graphics.AffineTransform} A transform representing a shearing
|
||||
* transformation.
|
||||
*/
|
||||
goog.graphics.AffineTransform.getShearInstance = function(shx, shy) {
|
||||
return new goog.graphics.AffineTransform().setToShear(shx, shy);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a transform representing a rotation transformation.
|
||||
*
|
||||
* @param {number} theta The angle of rotation measured in radians.
|
||||
* @param {number} x The x coordinate of the anchor point.
|
||||
* @param {number} y The y coordinate of the anchor point.
|
||||
* @return {!goog.graphics.AffineTransform} A transform representing a rotation
|
||||
* transformation.
|
||||
*/
|
||||
goog.graphics.AffineTransform.getRotateInstance = function(theta, x, y) {
|
||||
return new goog.graphics.AffineTransform().setToRotation(theta, x, y);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets this transform to a scaling transformation.
|
||||
*
|
||||
* @param {number} sx The x-axis scaling factor.
|
||||
* @param {number} sy The y-axis scaling factor.
|
||||
* @return {!goog.graphics.AffineTransform} This affine transform.
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.setToScale = function(sx, sy) {
|
||||
return this.setTransform(sx, 0, 0, sy, 0, 0);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets this transform to a translation transformation.
|
||||
*
|
||||
* @param {number} dx The distance to translate in the x direction.
|
||||
* @param {number} dy The distance to translate in the y direction.
|
||||
* @return {!goog.graphics.AffineTransform} This affine transform.
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.setToTranslation = function(dx, dy) {
|
||||
return this.setTransform(1, 0, 0, 1, dx, dy);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets this transform to a shearing transformation.
|
||||
*
|
||||
* @param {number} shx The x-axis shear factor.
|
||||
* @param {number} shy The y-axis shear factor.
|
||||
* @return {!goog.graphics.AffineTransform} This affine transform.
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.setToShear = function(shx, shy) {
|
||||
return this.setTransform(1, shy, shx, 1, 0, 0);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets this transform to a rotation transformation.
|
||||
*
|
||||
* @param {number} theta The angle of rotation measured in radians.
|
||||
* @param {number} x The x coordinate of the anchor point.
|
||||
* @param {number} y The y coordinate of the anchor point.
|
||||
* @return {!goog.graphics.AffineTransform} This affine transform.
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.setToRotation = function(theta, x, y) {
|
||||
var cos = Math.cos(theta);
|
||||
var sin = Math.sin(theta);
|
||||
return this.setTransform(cos, sin, -sin, cos,
|
||||
x - x * cos + y * sin, y - x * sin - y * cos);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Compares two affine transforms for equality.
|
||||
*
|
||||
* @param {goog.graphics.AffineTransform} tx The other affine transform.
|
||||
* @return {boolean} whether the two transforms are equal.
|
||||
*/
|
||||
goog.graphics.AffineTransform.prototype.equals = function(tx) {
|
||||
if (this == tx) {
|
||||
return true;
|
||||
}
|
||||
if (!tx) {
|
||||
return false;
|
||||
}
|
||||
return this.m00_ == tx.m00_ &&
|
||||
this.m01_ == tx.m01_ &&
|
||||
this.m02_ == tx.m02_ &&
|
||||
this.m10_ == tx.m10_ &&
|
||||
this.m11_ == tx.m11_ &&
|
||||
this.m12_ == tx.m12_;
|
||||
};
|
||||
@@ -0,0 +1,792 @@
|
||||
// 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)
|
||||
* @author wcrosby@google.com (Wayne Crosby)
|
||||
*/
|
||||
|
||||
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.graphics.EllipseElement');
|
||||
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.math');
|
||||
goog.require('goog.string');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 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}
|
||||
*/
|
||||
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}
|
||||
*/
|
||||
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}
|
||||
*/
|
||||
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}
|
||||
*/
|
||||
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('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
|
||||
this.innerElement_.innerHTML =
|
||||
goog.array.map(this.text_.split(''),
|
||||
function(entry) { return goog.string.htmlEscape(entry); }).
|
||||
join('<br>');
|
||||
} else {
|
||||
this.innerElement_.innerHTML = goog.string.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}
|
||||
*/
|
||||
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();
|
||||
};
|
||||
@@ -0,0 +1,665 @@
|
||||
// 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 CanvasGraphics sub class that uses the canvas tag for drawing.
|
||||
* @author robbyw@google.com (Robby Walker)
|
||||
* @author wcrosby@google.com (Wayne Crosby)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.CanvasGraphics');
|
||||
|
||||
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('goog.graphics.AbstractGraphics');
|
||||
goog.require('goog.graphics.CanvasEllipseElement');
|
||||
goog.require('goog.graphics.CanvasGroupElement');
|
||||
goog.require('goog.graphics.CanvasImageElement');
|
||||
goog.require('goog.graphics.CanvasPathElement');
|
||||
goog.require('goog.graphics.CanvasRectElement');
|
||||
goog.require('goog.graphics.CanvasTextElement');
|
||||
goog.require('goog.graphics.SolidFill');
|
||||
goog.require('goog.math.Size');
|
||||
goog.require('goog.style');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A Graphics implementation for drawing using canvas.
|
||||
* @param {string|number} width The (non-zero) width in pixels. Strings
|
||||
* expressing percentages of parent with (e.g. '80%') are also accepted.
|
||||
* @param {string|number} height The (non-zero) height in pixels. Strings
|
||||
* expressing percentages of parent with (e.g. '80%') are also accepted.
|
||||
* @param {?number=} opt_coordWidth The coordinate width - if
|
||||
* omitted or null, defaults to same as width.
|
||||
* @param {?number=} opt_coordHeight The coordinate height - if
|
||||
* omitted or null, defaults to same as height.
|
||||
* @param {goog.dom.DomHelper=} opt_domHelper The DOM helper object for the
|
||||
* document we want to render in.
|
||||
* @constructor
|
||||
* @extends {goog.graphics.AbstractGraphics}
|
||||
* @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.
|
||||
*/
|
||||
goog.graphics.CanvasGraphics = function(width, height,
|
||||
opt_coordWidth, opt_coordHeight,
|
||||
opt_domHelper) {
|
||||
goog.graphics.AbstractGraphics.call(this, width, height,
|
||||
opt_coordWidth, opt_coordHeight,
|
||||
opt_domHelper);
|
||||
};
|
||||
goog.inherits(goog.graphics.CanvasGraphics, goog.graphics.AbstractGraphics);
|
||||
|
||||
|
||||
/**
|
||||
* Sets the fill for the given element.
|
||||
* @param {goog.graphics.StrokeAndFillElement} element The element
|
||||
* wrapper.
|
||||
* @param {goog.graphics.Fill} fill The fill object.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.setElementFill = function(element,
|
||||
fill) {
|
||||
this.redraw();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the stroke for the given element.
|
||||
* @param {goog.graphics.StrokeAndFillElement} element The element
|
||||
* wrapper.
|
||||
* @param {goog.graphics.Stroke} stroke The stroke object.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.setElementStroke = function(
|
||||
element, stroke) {
|
||||
this.redraw();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the transformation of an element.
|
||||
* @param {goog.graphics.Element} element The element wrapper.
|
||||
* @param {number} x The x coordinate of the translation transform.
|
||||
* @param {number} y The y coordinate of the translation transform.
|
||||
* @param {number} angle The angle of the rotation transform.
|
||||
* @param {number} centerX The horizontal center of the rotation transform.
|
||||
* @param {number} centerY The vertical center of the rotation transform.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.setElementTransform = function(element,
|
||||
x, y, angle, centerX, centerY) {
|
||||
this.redraw();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Push an element transform on to the transform stack.
|
||||
* @param {goog.graphics.Element} element The transformed element.
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.pushElementTransform = function(
|
||||
element) {
|
||||
var ctx = this.getContext();
|
||||
ctx.save();
|
||||
|
||||
var transform = element.getTransform();
|
||||
|
||||
// TODO(robbyw): Test for unsupported transforms i.e. skews.
|
||||
var tx = transform.getTranslateX();
|
||||
var ty = transform.getTranslateY();
|
||||
if (tx || ty) {
|
||||
ctx.translate(tx, ty);
|
||||
}
|
||||
|
||||
var sinTheta = transform.getShearY();
|
||||
if (sinTheta) {
|
||||
ctx.rotate(Math.asin(sinTheta));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Pop an element transform off of the transform stack.
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.popElementTransform = function() {
|
||||
this.getContext().restore();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates the DOM representation of the graphics area.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.createDom = function() {
|
||||
var element = this.dom_.createDom('div',
|
||||
{'style': 'position:relative;overflow:hidden'});
|
||||
this.setElementInternal(element);
|
||||
|
||||
this.canvas_ = this.dom_.createDom('canvas');
|
||||
element.appendChild(this.canvas_);
|
||||
|
||||
/**
|
||||
* The main canvas element.
|
||||
* @type {goog.graphics.CanvasGroupElement}
|
||||
*/
|
||||
this.canvasElement = new goog.graphics.CanvasGroupElement(this);
|
||||
|
||||
this.lastGroup_ = this.canvasElement;
|
||||
this.redrawTimeout_ = 0;
|
||||
|
||||
this.updateSize();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clears the drawing context object in response to actions that make the old
|
||||
* context invalid - namely resize of the canvas element.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.clearContext_ = function() {
|
||||
this.context_ = null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the drawing context.
|
||||
* @return {Object} The canvas element rendering context.
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.getContext = function() {
|
||||
if (!this.getElement()) {
|
||||
this.createDom();
|
||||
}
|
||||
if (!this.context_) {
|
||||
this.context_ = this.canvas_.getContext('2d');
|
||||
this.context_.save();
|
||||
}
|
||||
return this.context_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Changes the coordinate system position.
|
||||
* @param {number} left The coordinate system left bound.
|
||||
* @param {number} top The coordinate system top bound.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.setCoordOrigin = function(left, top) {
|
||||
this.coordLeft = left;
|
||||
this.coordTop = top;
|
||||
this.redraw();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Changes the coordinate size.
|
||||
* @param {number} coordWidth The coordinate width.
|
||||
* @param {number} coordHeight The coordinate height.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.setCoordSize = function(coordWidth,
|
||||
coordHeight) {
|
||||
goog.graphics.CanvasGraphics.superClass_.setCoordSize.apply(this, arguments);
|
||||
this.redraw();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Change the size of the canvas.
|
||||
* @param {number} pixelWidth The width in pixels.
|
||||
* @param {number} pixelHeight The height in pixels.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.setSize = function(pixelWidth,
|
||||
pixelHeight) {
|
||||
this.width = pixelWidth;
|
||||
this.height = pixelHeight;
|
||||
|
||||
this.updateSize();
|
||||
this.redraw();
|
||||
};
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.graphics.CanvasGraphics.prototype.getPixelSize = function() {
|
||||
// goog.style.getSize does not work for Canvas elements. We
|
||||
// have to compute the size manually if it is percentage based.
|
||||
var width = this.width;
|
||||
var height = this.height;
|
||||
var computeWidth = goog.isString(width) && width.indexOf('%') != -1;
|
||||
var computeHeight = goog.isString(height) && height.indexOf('%') != -1;
|
||||
|
||||
if (!this.isInDocument() && (computeWidth || computeHeight)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var parent;
|
||||
var parentSize;
|
||||
|
||||
if (computeWidth) {
|
||||
parent = /** @type {Element} */ (this.getElement().parentNode);
|
||||
parentSize = goog.style.getSize(parent);
|
||||
width = parseFloat(/** @type {string} */ (width)) * parentSize.width / 100;
|
||||
}
|
||||
|
||||
if (computeHeight) {
|
||||
parent = parent || /** @type {Element} */ (this.getElement().parentNode);
|
||||
parentSize = parentSize || goog.style.getSize(parent);
|
||||
height = parseFloat(/** @type {string} */ (height)) * parentSize.height /
|
||||
100;
|
||||
}
|
||||
|
||||
return new goog.math.Size(/** @type {number} */ (width),
|
||||
/** @type {number} */ (height));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update the size of the canvas.
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.updateSize = function() {
|
||||
goog.style.setSize(this.getElement(), this.width, this.height);
|
||||
|
||||
var pixels = this.getPixelSize();
|
||||
if (pixels) {
|
||||
goog.style.setSize(this.canvas_,
|
||||
/** @type {number} */ (pixels.width),
|
||||
/** @type {number} */ (pixels.height));
|
||||
this.canvas_.width = pixels.width;
|
||||
this.canvas_.height = pixels.height;
|
||||
this.clearContext_();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reset the canvas.
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.reset = function() {
|
||||
var ctx = this.getContext();
|
||||
ctx.restore();
|
||||
var size = this.getPixelSize();
|
||||
if (size.width && size.height) {
|
||||
ctx.clearRect(0, 0, size.width, size.height);
|
||||
}
|
||||
ctx.save();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Remove all drawing elements from the graphics.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.clear = function() {
|
||||
this.reset();
|
||||
this.canvasElement.clear();
|
||||
var el = this.getElement();
|
||||
|
||||
// Remove all children (text nodes) except the canvas (which is at index 0)
|
||||
while (el.childNodes.length > 1) {
|
||||
el.removeChild(el.lastChild);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Redraw the entire canvas.
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.redraw = function() {
|
||||
if (this.preventRedraw_) {
|
||||
this.needsRedraw_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isInDocument()) {
|
||||
this.reset();
|
||||
|
||||
if (this.coordWidth) {
|
||||
var pixels = this.getPixelSize();
|
||||
this.getContext().scale(pixels.width / this.coordWidth,
|
||||
pixels.height / this.coordHeight);
|
||||
}
|
||||
if (this.coordLeft || this.coordTop) {
|
||||
this.getContext().translate(-this.coordLeft, -this.coordTop);
|
||||
}
|
||||
this.pushElementTransform(this.canvasElement);
|
||||
this.canvasElement.draw(this.context_);
|
||||
this.popElementTransform();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Draw an element, including any stroke or fill.
|
||||
* @param {goog.graphics.Element} element The element to draw.
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.drawElement = function(element) {
|
||||
if (element instanceof goog.graphics.CanvasTextElement) {
|
||||
// Don't draw text since that is not implemented using canvas.
|
||||
return;
|
||||
}
|
||||
|
||||
var ctx = this.getContext();
|
||||
this.pushElementTransform(element);
|
||||
|
||||
if (!element.getFill || !element.getStroke) {
|
||||
// Draw without stroke or fill (e.g. the element is an image or group).
|
||||
element.draw(ctx);
|
||||
this.popElementTransform();
|
||||
return;
|
||||
}
|
||||
|
||||
var fill = element.getFill();
|
||||
if (fill) {
|
||||
if (fill instanceof goog.graphics.SolidFill) {
|
||||
if (fill.getOpacity() != 0) {
|
||||
ctx.globalAlpha = fill.getOpacity();
|
||||
ctx.fillStyle = fill.getColor();
|
||||
element.draw(ctx);
|
||||
ctx.fill();
|
||||
ctx.globalAlpha = 1;
|
||||
}
|
||||
} else { // (fill instanceof goog.graphics.LinearGradient)
|
||||
var linearGradient = ctx.createLinearGradient(fill.getX1(), fill.getY1(),
|
||||
fill.getX2(), fill.getY2());
|
||||
linearGradient.addColorStop(0.0, fill.getColor1());
|
||||
linearGradient.addColorStop(1.0, fill.getColor2());
|
||||
|
||||
ctx.fillStyle = linearGradient;
|
||||
element.draw(ctx);
|
||||
ctx.fill();
|
||||
}
|
||||
}
|
||||
|
||||
var stroke = element.getStroke();
|
||||
if (stroke) {
|
||||
element.draw(ctx);
|
||||
ctx.strokeStyle = stroke.getColor();
|
||||
|
||||
var width = stroke.getWidth();
|
||||
if (goog.isString(width) && width.indexOf('px') != -1) {
|
||||
width = parseFloat(width) / this.getPixelScaleX();
|
||||
}
|
||||
ctx.lineWidth = width;
|
||||
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
this.popElementTransform();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Append an element.
|
||||
*
|
||||
* @param {goog.graphics.Element} element The element to draw.
|
||||
* @param {goog.graphics.CanvasGroupElement|undefined} group The group to draw
|
||||
* it in. If null or undefined, defaults to the root group.
|
||||
* @private
|
||||
* @deprecated Use append instead.
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.append_ = function(element, group) {
|
||||
this.append(element, group);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Append an element.
|
||||
*
|
||||
* @param {goog.graphics.Element} element The element to draw.
|
||||
* @param {goog.graphics.GroupElement|undefined} group The group to draw
|
||||
* it in. If null or undefined, defaults to the root group.
|
||||
* @protected
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.append = function(element, group) {
|
||||
group = group || this.canvasElement;
|
||||
group.appendChild(element);
|
||||
|
||||
if (this.isDrawable(group)) {
|
||||
this.drawElement(element);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Draw an ellipse.
|
||||
*
|
||||
* @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 Stroke object describing the
|
||||
* stroke.
|
||||
* @param {goog.graphics.Fill} fill Fill object describing the fill.
|
||||
* @param {goog.graphics.GroupElement=} opt_group The group wrapper
|
||||
* element to append to. If not specified, appends to the main canvas.
|
||||
*
|
||||
* @return {goog.graphics.EllipseElement} The newly created element.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.drawEllipse = function(cx, cy, rx, ry,
|
||||
stroke, fill, opt_group) {
|
||||
var element = new goog.graphics.CanvasEllipseElement(null, this,
|
||||
cx, cy, rx, ry, stroke, fill);
|
||||
this.append(element, opt_group);
|
||||
return element;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Draw a rectangle.
|
||||
*
|
||||
* @param {number} x X coordinate (left).
|
||||
* @param {number} y Y coordinate (top).
|
||||
* @param {number} width Width of rectangle.
|
||||
* @param {number} height Height of rectangle.
|
||||
* @param {goog.graphics.Stroke} stroke Stroke object describing the
|
||||
* stroke.
|
||||
* @param {goog.graphics.Fill} fill Fill object describing the fill.
|
||||
* @param {goog.graphics.GroupElement=} opt_group The group wrapper
|
||||
* element to append to. If not specified, appends to the main canvas.
|
||||
*
|
||||
* @return {goog.graphics.RectElement} The newly created element.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.drawRect = function(x, y, width, height,
|
||||
stroke, fill, opt_group) {
|
||||
var element = new goog.graphics.CanvasRectElement(null, this,
|
||||
x, y, width, height, stroke, fill);
|
||||
this.append(element, opt_group);
|
||||
return element;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Draw an image.
|
||||
*
|
||||
* @param {number} x X coordinate (left).
|
||||
* @param {number} y Y coordinate (top).
|
||||
* @param {number} width Width of image.
|
||||
* @param {number} height Height of image.
|
||||
* @param {string} src Source of the image.
|
||||
* @param {goog.graphics.GroupElement=} opt_group The group wrapper
|
||||
* element to append to. If not specified, appends to the main canvas.
|
||||
*
|
||||
* @return {goog.graphics.ImageElement} The newly created element.
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.drawImage = function(x, y, width, height,
|
||||
src, opt_group) {
|
||||
var element = new goog.graphics.CanvasImageElement(null, this, x, y, width,
|
||||
height, src);
|
||||
this.append(element, opt_group);
|
||||
return element;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Draw a text string vertically centered on a given line.
|
||||
*
|
||||
* @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 Stroke object describing the stroke.
|
||||
* @param {goog.graphics.Fill} fill Fill object describing the fill.
|
||||
* @param {goog.graphics.GroupElement=} opt_group The group wrapper
|
||||
* element to append to. If not specified, appends to the main canvas.
|
||||
*
|
||||
* @return {goog.graphics.TextElement} The newly created element.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.drawTextOnLine = function(
|
||||
text, x1, y1, x2, y2, align, font, stroke, fill, opt_group) {
|
||||
var element = new goog.graphics.CanvasTextElement(this,
|
||||
text, x1, y1, x2, y2, align, /** @type {!goog.graphics.Font} */ (font),
|
||||
stroke, fill);
|
||||
this.append(element, opt_group);
|
||||
return element;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Draw a path.
|
||||
* @param {!goog.graphics.Path} path The path object to draw.
|
||||
* @param {goog.graphics.Stroke} stroke Stroke object describing the stroke.
|
||||
* @param {goog.graphics.Fill} fill Fill object describing the fill.
|
||||
* @param {goog.graphics.GroupElement=} opt_group The group wrapper
|
||||
* element to append to. If not specified, appends to the main canvas.
|
||||
*
|
||||
* @return {goog.graphics.PathElement} The newly created element.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.drawPath = function(path, stroke, fill,
|
||||
opt_group) {
|
||||
var element = new goog.graphics.CanvasPathElement(null, this,
|
||||
path, stroke, fill);
|
||||
this.append(element, opt_group);
|
||||
return element;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.graphics.GroupElement} group The group to possibly
|
||||
* draw to.
|
||||
* @return {boolean} Whether drawing can occur now.
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.isDrawable = function(group) {
|
||||
return this.isInDocument() && !this.redrawTimeout_ &&
|
||||
!this.isRedrawRequired(group);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if drawing to the given group means a redraw is required.
|
||||
* @param {goog.graphics.GroupElement} group The group to draw to.
|
||||
* @return {boolean} Whether drawing to this group should force a redraw.
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.isRedrawRequired = function(group) {
|
||||
// TODO(robbyw): Moving up to any parent of lastGroup should not force redraw.
|
||||
return group != this.canvasElement && group != this.lastGroup_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Create an empty group of drawing elements.
|
||||
*
|
||||
* @param {goog.graphics.GroupElement=} opt_group The group wrapper
|
||||
* element to append to. If not specified, appends to the main canvas.
|
||||
*
|
||||
* @return {goog.graphics.CanvasGroupElement} The newly created group.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.createGroup = function(opt_group) {
|
||||
var group = new goog.graphics.CanvasGroupElement(this);
|
||||
|
||||
opt_group = opt_group || this.canvasElement;
|
||||
|
||||
// TODO(robbyw): Moving up to any parent group should not force redraw.
|
||||
if (opt_group == this.canvasElement || opt_group == this.lastGroup_) {
|
||||
this.lastGroup_ = group;
|
||||
}
|
||||
|
||||
this.append(group, opt_group);
|
||||
|
||||
return group;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Measure and return the width (in pixels) of a given text string.
|
||||
* Text measurement is needed to make sure a text can fit in the allocated
|
||||
* area. The way text length is measured is by writing it into a div that is
|
||||
* after the visible area, measure the div width, and immediatly erase the
|
||||
* written value.
|
||||
*
|
||||
* @param {string} text The text string to measure.
|
||||
* @param {goog.graphics.Font} font The font object describing the font style.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.getTextWidth = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* Disposes of the component by removing event handlers, detacing DOM nodes from
|
||||
* the document body, and removing references to them.
|
||||
* @override
|
||||
* @protected
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.disposeInternal = function() {
|
||||
this.context_ = null;
|
||||
goog.graphics.CanvasGraphics.superClass_.disposeInternal.call(this);
|
||||
};
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.graphics.CanvasGraphics.prototype.enterDocument = function() {
|
||||
var oldPixelSize = this.getPixelSize();
|
||||
goog.graphics.CanvasGraphics.superClass_.enterDocument.call(this);
|
||||
if (!oldPixelSize) {
|
||||
this.updateSize();
|
||||
this.dispatchEvent(goog.events.EventType.RESIZE);
|
||||
}
|
||||
this.redraw();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Start preventing redraws - useful for chaining large numbers of changes
|
||||
* together. Not guaranteed to do anything - i.e. only use this for
|
||||
* optimization of a single code path.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.suspend = function() {
|
||||
this.preventRedraw_ = true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Stop preventing redraws. If any redraws had been prevented, a redraw will
|
||||
* be done now.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.CanvasGraphics.prototype.resume = function() {
|
||||
this.preventRedraw_ = false;
|
||||
|
||||
if (this.needsRedraw_) {
|
||||
this.redraw();
|
||||
this.needsRedraw_ = false;
|
||||
}
|
||||
};
|
||||
151
nicer-api-docs/closure-library/closure/goog/graphics/element.js
Normal file
151
nicer-api-docs/closure-library/closure/goog/graphics/element.js
Normal file
@@ -0,0 +1,151 @@
|
||||
// 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 A thin wrapper around the DOM element returned from
|
||||
* the different draw methods of the graphics implementation, and
|
||||
* all interfaces that the various element types support.
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
* @author yoah@google.com (Yoah Bar-David)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.Element');
|
||||
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.EventTarget');
|
||||
goog.require('goog.events.Listenable');
|
||||
goog.require('goog.graphics.AffineTransform');
|
||||
goog.require('goog.math');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Base class for a thin wrapper around the DOM element returned from
|
||||
* the different draw methods of the graphics.
|
||||
* 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.AbstractGraphics} graphics The graphics creating
|
||||
* this element.
|
||||
* @constructor
|
||||
* @extends {goog.events.EventTarget}
|
||||
* @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.
|
||||
*/
|
||||
goog.graphics.Element = function(element, graphics) {
|
||||
goog.events.EventTarget.call(this);
|
||||
this.element_ = element;
|
||||
this.graphics_ = graphics;
|
||||
// Overloading EventTarget field to state that this is not a custom event.
|
||||
// TODO(user) Should be handled in EventTarget.js (see bug 846824).
|
||||
this[goog.events.Listenable.IMPLEMENTED_BY_PROP] = false;
|
||||
};
|
||||
goog.inherits(goog.graphics.Element, goog.events.EventTarget);
|
||||
|
||||
|
||||
/**
|
||||
* The graphics object that contains this element.
|
||||
* @type {goog.graphics.AbstractGraphics?}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.Element.prototype.graphics_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* The native browser element this class wraps.
|
||||
* @type {Element}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.Element.prototype.element_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* The transformation applied to this element.
|
||||
* @type {goog.graphics.AffineTransform?}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.Element.prototype.transform_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Returns the underlying object.
|
||||
* @return {Element} The underlying element.
|
||||
*/
|
||||
goog.graphics.Element.prototype.getElement = function() {
|
||||
return this.element_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the graphics.
|
||||
* @return {goog.graphics.AbstractGraphics} The graphics that created the
|
||||
* element.
|
||||
*/
|
||||
goog.graphics.Element.prototype.getGraphics = function() {
|
||||
return this.graphics_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the transformation of the element.
|
||||
* @param {number} x The x coordinate of the translation transform.
|
||||
* @param {number} y The y coordinate of the translation transform.
|
||||
* @param {number} rotate The angle of the rotation transform.
|
||||
* @param {number} centerX The horizontal center of the rotation transform.
|
||||
* @param {number} centerY The vertical center of the rotation transform.
|
||||
*/
|
||||
goog.graphics.Element.prototype.setTransformation = function(x, y, rotate,
|
||||
centerX, centerY) {
|
||||
// TODO(robbyw): Add skew and scale.
|
||||
|
||||
this.transform_ = goog.graphics.AffineTransform.getRotateInstance(
|
||||
goog.math.toRadians(rotate), centerX, centerY).translate(x, y);
|
||||
this.getGraphics().setElementTransform(this, x, y, rotate, centerX, centerY);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.graphics.AffineTransform} The transformation applied to
|
||||
* this element.
|
||||
*/
|
||||
goog.graphics.Element.prototype.getTransform = function() {
|
||||
return this.transform_ ? this.transform_.clone() :
|
||||
new goog.graphics.AffineTransform();
|
||||
};
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.graphics.Element.prototype.addEventListener = function(
|
||||
type, handler, opt_capture, opt_handlerScope) {
|
||||
goog.events.listen(this.element_, type, handler, opt_capture,
|
||||
opt_handlerScope);
|
||||
};
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.graphics.Element.prototype.removeEventListener = function(
|
||||
type, handler, opt_capture, opt_handlerScope) {
|
||||
goog.events.unlisten(this.element_, type, handler, opt_capture,
|
||||
opt_handlerScope);
|
||||
};
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.graphics.Element.prototype.disposeInternal = function() {
|
||||
goog.graphics.Element.superClass_.disposeInternal.call(this);
|
||||
goog.events.removeAll(this.element_);
|
||||
};
|
||||
@@ -0,0 +1,64 @@
|
||||
// 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 A thin wrapper around the DOM element for ellipses.
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
* @author yoah@google.com (Yoah Bar-David)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.EllipseElement');
|
||||
|
||||
goog.require('goog.graphics.StrokeAndFillElement');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Interface for a graphics ellipse element.
|
||||
* You should not construct objects from this constructor. The graphics
|
||||
* will return an implementation of this interface for you.
|
||||
* @param {Element} element The DOM element to wrap.
|
||||
* @param {goog.graphics.AbstractGraphics} graphics The graphics creating
|
||||
* this element.
|
||||
* @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.StrokeAndFillElement}
|
||||
* @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.
|
||||
*/
|
||||
goog.graphics.EllipseElement = function(element, graphics, stroke, fill) {
|
||||
goog.graphics.StrokeAndFillElement.call(this, element, graphics, stroke,
|
||||
fill);
|
||||
};
|
||||
goog.inherits(goog.graphics.EllipseElement, goog.graphics.StrokeAndFillElement);
|
||||
|
||||
|
||||
/**
|
||||
* Update the center point of the ellipse.
|
||||
* @param {number} cx Center X coordinate.
|
||||
* @param {number} cy Center Y coordinate.
|
||||
*/
|
||||
goog.graphics.EllipseElement.prototype.setCenter = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* Update the radius of the ellipse.
|
||||
* @param {number} rx Radius length for the x-axis.
|
||||
* @param {number} ry Radius length for the y-axis.
|
||||
*/
|
||||
goog.graphics.EllipseElement.prototype.setRadius = goog.abstractMethod;
|
||||
@@ -0,0 +1,159 @@
|
||||
// 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 Graphics utility functions for advanced coordinates.
|
||||
*
|
||||
* This file assists the use of advanced coordinates in goog.graphics. Coords
|
||||
* can be specified as simple numbers which will correspond to units in the
|
||||
* graphics element's coordinate space. Alternately, coords can be expressed
|
||||
* in pixels, meaning no matter what tranformations or coordinate system changes
|
||||
* are present, the number of pixel changes will remain constant. Coords can
|
||||
* also be expressed as percentages of their parent's size.
|
||||
*
|
||||
* This file also allows for elements to have margins, expressable in any of
|
||||
* the ways described above.
|
||||
*
|
||||
* Additional pieces of advanced coordinate functionality can (soon) be found in
|
||||
* element.js and groupelement.js.
|
||||
*
|
||||
* @author robbyw@google.com (Robby Walker)
|
||||
*/
|
||||
|
||||
goog.provide('goog.graphics.ext.coordinates');
|
||||
|
||||
goog.require('goog.string');
|
||||
|
||||
|
||||
/**
|
||||
* Cache of boolean values. For a given string (key), is it special? (value)
|
||||
* @type {Object}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.coordinates.specialCoordinateCache_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* Determines if the given coordinate is a percent based coordinate or an
|
||||
* expression with a percent based component.
|
||||
* @param {string} coord The coordinate to test.
|
||||
* @return {boolean} Whether the coordinate contains the string '%'.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.coordinates.isPercent_ = function(coord) {
|
||||
return goog.string.contains(coord, '%');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Determines if the given coordinate is a pixel based coordinate or an
|
||||
* expression with a pixel based component.
|
||||
* @param {string} coord The coordinate to test.
|
||||
* @return {boolean} Whether the coordinate contains the string 'px'.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.coordinates.isPixels_ = function(coord) {
|
||||
return goog.string.contains(coord, 'px');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Determines if the given coordinate is special - i.e. not just a number.
|
||||
* @param {string|number|null} coord The coordinate to test.
|
||||
* @return {boolean} Whether the coordinate is special.
|
||||
*/
|
||||
goog.graphics.ext.coordinates.isSpecial = function(coord) {
|
||||
var cache = goog.graphics.ext.coordinates.specialCoordinateCache_;
|
||||
|
||||
if (!(coord in cache)) {
|
||||
cache[coord] = goog.isString(coord) && (
|
||||
goog.graphics.ext.coordinates.isPercent_(coord) ||
|
||||
goog.graphics.ext.coordinates.isPixels_(coord));
|
||||
}
|
||||
|
||||
return cache[coord];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value of the given expression in the given context.
|
||||
*
|
||||
* Should be treated as package scope.
|
||||
*
|
||||
* @param {string|number} coord The coordinate to convert.
|
||||
* @param {number} size The size of the parent element.
|
||||
* @param {number} scale The ratio of pixels to units.
|
||||
* @return {number} The number of coordinate space units that corresponds to
|
||||
* this coordinate.
|
||||
*/
|
||||
goog.graphics.ext.coordinates.computeValue = function(coord, size, scale) {
|
||||
var number = parseFloat(String(coord));
|
||||
if (goog.isString(coord)) {
|
||||
if (goog.graphics.ext.coordinates.isPercent_(coord)) {
|
||||
return number * size / 100;
|
||||
} else if (goog.graphics.ext.coordinates.isPixels_(coord)) {
|
||||
return number / scale;
|
||||
}
|
||||
}
|
||||
|
||||
return number;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts the given coordinate to a number value in units.
|
||||
*
|
||||
* Should be treated as package scope.
|
||||
*
|
||||
* @param {string|number} coord The coordinate to retrieve the value for.
|
||||
* @param {boolean|undefined} forMaximum Whether we are computing the largest
|
||||
* value this coordinate would be in a parent of no size. The container
|
||||
* size in this case should be set to the size of the current element.
|
||||
* @param {number} containerSize The unit value of the size of the container of
|
||||
* this element. Should be set to the minimum width of this element if
|
||||
* forMaximum is true.
|
||||
* @param {number} scale The ratio of pixels to units.
|
||||
* @param {Object=} opt_cache Optional (but highly recommend) object to store
|
||||
* cached computations in. The calling class should manage clearing out
|
||||
* the cache when the scale or containerSize changes.
|
||||
* @return {number} The correct number of coordinate space units.
|
||||
*/
|
||||
goog.graphics.ext.coordinates.getValue = function(coord, forMaximum,
|
||||
containerSize, scale, opt_cache) {
|
||||
if (!goog.isNumber(coord)) {
|
||||
var cacheString = opt_cache && ((forMaximum ? 'X' : '') + coord);
|
||||
|
||||
if (opt_cache && cacheString in opt_cache) {
|
||||
coord = opt_cache[cacheString];
|
||||
} else {
|
||||
if (goog.graphics.ext.coordinates.isSpecial(
|
||||
/** @type {string} */ (coord))) {
|
||||
coord = goog.graphics.ext.coordinates.computeValue(coord,
|
||||
containerSize, scale);
|
||||
} else {
|
||||
// Simple coordinates just need to be converted from a string to a
|
||||
// number.
|
||||
coord = parseFloat(/** @type {string} */ (coord));
|
||||
}
|
||||
|
||||
// Cache the result.
|
||||
if (opt_cache) {
|
||||
opt_cache[cacheString] = coord;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return coord;
|
||||
};
|
||||
@@ -0,0 +1,968 @@
|
||||
// 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 A thicker wrapper around the DOM element returned from
|
||||
* the different draw methods of the graphics implementation, and
|
||||
* all interfaces that the various element types support.
|
||||
* @author robbyw@google.com (Robby Walker)
|
||||
*/
|
||||
|
||||
goog.provide('goog.graphics.ext.Element');
|
||||
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.EventTarget');
|
||||
goog.require('goog.functions');
|
||||
goog.require('goog.graphics');
|
||||
goog.require('goog.graphics.ext.coordinates');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Base class for a wrapper around the goog.graphics wrapper that enables
|
||||
* more advanced functionality.
|
||||
* @param {goog.graphics.ext.Group?} group Parent for this element.
|
||||
* @param {goog.graphics.Element} wrapper The thin wrapper to wrap.
|
||||
* @constructor
|
||||
* @extends {goog.events.EventTarget}
|
||||
*/
|
||||
goog.graphics.ext.Element = function(group, wrapper) {
|
||||
goog.events.EventTarget.call(this);
|
||||
this.wrapper_ = wrapper;
|
||||
this.graphics_ = group ? group.getGraphics() : this;
|
||||
|
||||
this.xPosition_ = new goog.graphics.ext.Element.Position_(this, true);
|
||||
this.yPosition_ = new goog.graphics.ext.Element.Position_(this, false);
|
||||
|
||||
// Handle parent / child relationships.
|
||||
if (group) {
|
||||
this.parent_ = group;
|
||||
this.parent_.addChild(this);
|
||||
}
|
||||
};
|
||||
goog.inherits(goog.graphics.ext.Element, goog.events.EventTarget);
|
||||
|
||||
|
||||
/**
|
||||
* The graphics object that contains this element.
|
||||
* @type {goog.graphics.ext.Graphics|goog.graphics.ext.Element}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.graphics_;
|
||||
|
||||
|
||||
/**
|
||||
* The goog.graphics wrapper this class wraps.
|
||||
* @type {goog.graphics.Element}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.wrapper_;
|
||||
|
||||
|
||||
/**
|
||||
* The group or surface containing this element.
|
||||
* @type {goog.graphics.ext.Group|undefined}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.parent_;
|
||||
|
||||
|
||||
/**
|
||||
* Whether or not computation of this element's position or size depends on its
|
||||
* parent's size.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.parentDependent_ = false;
|
||||
|
||||
|
||||
/**
|
||||
* Whether the element has pending transformations.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.needsTransform_ = false;
|
||||
|
||||
|
||||
/**
|
||||
* The current angle of rotation, expressed in degrees.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.rotation_ = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Object representing the x position and size of the element.
|
||||
* @type {goog.graphics.ext.Element.Position_}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.xPosition_;
|
||||
|
||||
|
||||
/**
|
||||
* Object representing the y position and size of the element.
|
||||
* @type {goog.graphics.ext.Element.Position_}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.yPosition_;
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.graphics.Element} The underlying thin wrapper.
|
||||
* @protected
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getWrapper = function() {
|
||||
return this.wrapper_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.graphics.ext.Element|goog.graphics.ext.Graphics} The graphics
|
||||
* surface the element is a part of.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getGraphics = function() {
|
||||
return this.graphics_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the graphics implementation.
|
||||
* @return {goog.graphics.AbstractGraphics} The underlying graphics
|
||||
* implementation drawing this element's wrapper.
|
||||
* @protected
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getGraphicsImplementation = function() {
|
||||
return this.graphics_.getImplementation();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.graphics.ext.Group|undefined} The parent of this element.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getParent = function() {
|
||||
return this.parent_;
|
||||
};
|
||||
|
||||
|
||||
// GENERAL POSITIONING
|
||||
|
||||
|
||||
/**
|
||||
* Internal convenience method for setting position - either as a left/top,
|
||||
* center/middle, or right/bottom value. Only one should be specified.
|
||||
* @param {goog.graphics.ext.Element.Position_} position The position object to
|
||||
* set the value on.
|
||||
* @param {number|string} value The value of the coordinate.
|
||||
* @param {goog.graphics.ext.Element.PositionType_} type The type of the
|
||||
* coordinate.
|
||||
* @param {boolean=} opt_chain Optional flag to specify this function is part
|
||||
* of a chain of calls and therefore transformations should be set as
|
||||
* pending but not yet performed.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setPosition_ = function(position, value,
|
||||
type, opt_chain) {
|
||||
position.setPosition(value, type);
|
||||
this.computeIsParentDependent_(position);
|
||||
|
||||
this.needsTransform_ = true;
|
||||
if (!opt_chain) {
|
||||
this.transform();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the width/height of the element.
|
||||
* @param {goog.graphics.ext.Element.Position_} position The position object to
|
||||
* set the value on.
|
||||
* @param {string|number} size The new width/height value.
|
||||
* @param {boolean=} opt_chain Optional flag to specify this function is part
|
||||
* of a chain of calls and therefore transformations should be set as
|
||||
* pending but not yet performed.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setSize_ = function(position, size,
|
||||
opt_chain) {
|
||||
if (position.setSize(size)) {
|
||||
this.needsTransform_ = true;
|
||||
|
||||
this.computeIsParentDependent_(position);
|
||||
|
||||
if (!opt_chain) {
|
||||
this.reset();
|
||||
}
|
||||
} else if (!opt_chain && this.isPendingTransform()) {
|
||||
this.reset();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the minimum width/height of the element.
|
||||
* @param {goog.graphics.ext.Element.Position_} position The position object to
|
||||
* set the value on.
|
||||
* @param {string|number} minSize The minimum width/height of the element.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setMinSize_ = function(position, minSize) {
|
||||
position.setMinSize(minSize);
|
||||
this.needsTransform_ = true;
|
||||
this.computeIsParentDependent_(position);
|
||||
};
|
||||
|
||||
|
||||
// HORIZONTAL POSITIONING
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The distance from the left edge of this element to the left
|
||||
* edge of its parent, specified in units of the parent's coordinate system.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getLeft = function() {
|
||||
return this.xPosition_.getStart();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the left coordinate of the element. Overwrites any previous value of
|
||||
* left, center, or right for this element.
|
||||
* @param {string|number} left The left coordinate.
|
||||
* @param {boolean=} opt_chain Optional flag to specify this function is part
|
||||
* of a chain of calls and therefore transformations should be set as
|
||||
* pending but not yet performed.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setLeft = function(left, opt_chain) {
|
||||
this.setPosition_(this.xPosition_,
|
||||
left,
|
||||
goog.graphics.ext.Element.PositionType_.START,
|
||||
opt_chain);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The right coordinate of the element, in units of the
|
||||
* parent's coordinate system.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getRight = function() {
|
||||
return this.xPosition_.getEnd();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the right coordinate of the element. Overwrites any previous value of
|
||||
* left, center, or right for this element.
|
||||
* @param {string|number} right The right coordinate.
|
||||
* @param {boolean=} opt_chain Optional flag to specify this function is part
|
||||
* of a chain of calls and therefore transformations should be set as
|
||||
* pending but not yet performed.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setRight = function(right, opt_chain) {
|
||||
this.setPosition_(this.xPosition_,
|
||||
right,
|
||||
goog.graphics.ext.Element.PositionType_.END,
|
||||
opt_chain);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The center coordinate of the element, in units of the
|
||||
* parent's coordinate system.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getCenter = function() {
|
||||
return this.xPosition_.getMiddle();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the center coordinate of the element. Overwrites any previous value of
|
||||
* left, center, or right for this element.
|
||||
* @param {string|number} center The center coordinate.
|
||||
* @param {boolean=} opt_chain Optional flag to specify this function is part
|
||||
* of a chain of calls and therefore transformations should be set as
|
||||
* pending but not yet performed.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setCenter = function(center, opt_chain) {
|
||||
this.setPosition_(this.xPosition_,
|
||||
center,
|
||||
goog.graphics.ext.Element.PositionType_.MIDDLE,
|
||||
opt_chain);
|
||||
};
|
||||
|
||||
|
||||
// VERTICAL POSITIONING
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The distance from the top edge of this element to the top
|
||||
* edge of its parent, specified in units of the parent's coordinate system.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getTop = function() {
|
||||
return this.yPosition_.getStart();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the top coordinate of the element. Overwrites any previous value of
|
||||
* top, middle, or bottom for this element.
|
||||
* @param {string|number} top The top coordinate.
|
||||
* @param {boolean=} opt_chain Optional flag to specify this function is part
|
||||
* of a chain of calls and therefore transformations should be set as
|
||||
* pending but not yet performed.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setTop = function(top, opt_chain) {
|
||||
this.setPosition_(this.yPosition_,
|
||||
top,
|
||||
goog.graphics.ext.Element.PositionType_.START,
|
||||
opt_chain);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The bottom coordinate of the element, in units of the
|
||||
* parent's coordinate system.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getBottom = function() {
|
||||
return this.yPosition_.getEnd();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the bottom coordinate of the element. Overwrites any previous value of
|
||||
* top, middle, or bottom for this element.
|
||||
* @param {string|number} bottom The bottom coordinate.
|
||||
* @param {boolean=} opt_chain Optional flag to specify this function is part
|
||||
* of a chain of calls and therefore transformations should be set as
|
||||
* pending but not yet performed.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setBottom = function(bottom, opt_chain) {
|
||||
this.setPosition_(this.yPosition_,
|
||||
bottom,
|
||||
goog.graphics.ext.Element.PositionType_.END,
|
||||
opt_chain);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The middle coordinate of the element, in units of the
|
||||
* parent's coordinate system.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getMiddle = function() {
|
||||
return this.yPosition_.getMiddle();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the middle coordinate of the element. Overwrites any previous value of
|
||||
* top, middle, or bottom for this element
|
||||
* @param {string|number} middle The middle coordinate.
|
||||
* @param {boolean=} opt_chain Optional flag to specify this function is part
|
||||
* of a chain of calls and therefore transformations should be set as
|
||||
* pending but not yet performed.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setMiddle = function(middle, opt_chain) {
|
||||
this.setPosition_(this.yPosition_,
|
||||
middle,
|
||||
goog.graphics.ext.Element.PositionType_.MIDDLE,
|
||||
opt_chain);
|
||||
};
|
||||
|
||||
|
||||
// DIMENSIONS
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The width of the element, in units of the parent's
|
||||
* coordinate system.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getWidth = function() {
|
||||
return this.xPosition_.getSize();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the width of the element.
|
||||
* @param {string|number} width The new width value.
|
||||
* @param {boolean=} opt_chain Optional flag to specify this function is part
|
||||
* of a chain of calls and therefore transformations should be set as
|
||||
* pending but not yet performed.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setWidth = function(width, opt_chain) {
|
||||
this.setSize_(this.xPosition_, width, opt_chain);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The minimum width of the element, in units of the parent's
|
||||
* coordinate system.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getMinWidth = function() {
|
||||
return this.xPosition_.getMinSize();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the minimum width of the element.
|
||||
* @param {string|number} minWidth The minimum width of the element.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setMinWidth = function(minWidth) {
|
||||
this.setMinSize_(this.xPosition_, minWidth);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The height of the element, in units of the parent's
|
||||
* coordinate system.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getHeight = function() {
|
||||
return this.yPosition_.getSize();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the height of the element.
|
||||
* @param {string|number} height The new height value.
|
||||
* @param {boolean=} opt_chain Optional flag to specify this function is part
|
||||
* of a chain of calls and therefore transformations should be set as
|
||||
* pending but not yet performed.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setHeight = function(height, opt_chain) {
|
||||
this.setSize_(this.yPosition_, height, opt_chain);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The minimum height of the element, in units of the parent's
|
||||
* coordinate system.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getMinHeight = function() {
|
||||
return this.yPosition_.getMinSize();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the minimum height of the element.
|
||||
* @param {string|number} minHeight The minimum height of the element.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setMinHeight = function(minHeight) {
|
||||
this.setMinSize_(this.yPosition_, minHeight);
|
||||
};
|
||||
|
||||
|
||||
// BOUNDS SHORTCUTS
|
||||
|
||||
|
||||
/**
|
||||
* Shortcut for setting the left and top position.
|
||||
* @param {string|number} left The left coordinate.
|
||||
* @param {string|number} top The top coordinate.
|
||||
* @param {boolean=} opt_chain Optional flag to specify this function is part
|
||||
* of a chain of calls and therefore transformations should be set as
|
||||
* pending but not yet performed.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setPosition = function(left, top,
|
||||
opt_chain) {
|
||||
this.setLeft(left, true);
|
||||
this.setTop(top, opt_chain);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Shortcut for setting the width and height.
|
||||
* @param {string|number} width The new width value.
|
||||
* @param {string|number} height The new height value.
|
||||
* @param {boolean=} opt_chain Optional flag to specify this function is part
|
||||
* of a chain of calls and therefore transformations should be set as
|
||||
* pending but not yet performed.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setSize = function(width, height,
|
||||
opt_chain) {
|
||||
this.setWidth(width, true);
|
||||
this.setHeight(height, opt_chain);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Shortcut for setting the left, top, width, and height.
|
||||
* @param {string|number} left The left coordinate.
|
||||
* @param {string|number} top The top coordinate.
|
||||
* @param {string|number} width The new width value.
|
||||
* @param {string|number} height The new height value.
|
||||
* @param {boolean=} opt_chain Optional flag to specify this function is part
|
||||
* of a chain of calls and therefore transformations should be set as
|
||||
* pending but not yet performed.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setBounds = function(left, top, width,
|
||||
height, opt_chain) {
|
||||
this.setLeft(left, true);
|
||||
this.setTop(top, true);
|
||||
this.setWidth(width, true);
|
||||
this.setHeight(height, opt_chain);
|
||||
};
|
||||
|
||||
|
||||
// MAXIMUM BOUNDS
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} An estimate of the maximum x extent this element would have
|
||||
* in a parent of no width.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getMaxX = function() {
|
||||
return this.xPosition_.getMaxPosition();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} An estimate of the maximum y extent this element would have
|
||||
* in a parent of no height.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getMaxY = function() {
|
||||
return this.yPosition_.getMaxPosition();
|
||||
};
|
||||
|
||||
|
||||
// RESET
|
||||
|
||||
|
||||
/**
|
||||
* Reset the element. This is called when the element changes size, or when
|
||||
* the coordinate system changes in a way that would affect pixel based
|
||||
* rendering
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.reset = function() {
|
||||
this.xPosition_.resetCache();
|
||||
this.yPosition_.resetCache();
|
||||
|
||||
this.redraw();
|
||||
|
||||
this.needsTransform_ = true;
|
||||
this.transform();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Overridable function for subclass specific reset.
|
||||
* @protected
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.redraw = goog.nullFunction;
|
||||
|
||||
|
||||
// PARENT DEPENDENCY
|
||||
|
||||
|
||||
/**
|
||||
* Computes whether the element is still parent dependent.
|
||||
* @param {goog.graphics.ext.Element.Position_} position The recently changed
|
||||
* position object.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.computeIsParentDependent_ = function(
|
||||
position) {
|
||||
this.parentDependent_ = position.isParentDependent() ||
|
||||
this.xPosition_.isParentDependent() ||
|
||||
this.yPosition_.isParentDependent() ||
|
||||
this.checkParentDependent();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether this element's bounds depend on its parents.
|
||||
*
|
||||
* This function should be treated as if it has package scope.
|
||||
* @return {boolean} Whether this element's bounds depend on its parents.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.isParentDependent = function() {
|
||||
return this.parentDependent_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Overridable function for subclass specific parent dependency.
|
||||
* @return {boolean} Whether this shape's bounds depends on its parent's.
|
||||
* @protected
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.checkParentDependent =
|
||||
goog.functions.FALSE;
|
||||
|
||||
|
||||
// ROTATION
|
||||
|
||||
|
||||
/**
|
||||
* Set the rotation of this element.
|
||||
* @param {number} angle The angle of rotation, in degrees.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setRotation = function(angle) {
|
||||
if (this.rotation_ != angle) {
|
||||
this.rotation_ = angle;
|
||||
|
||||
this.needsTransform_ = true;
|
||||
this.transform();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The angle of rotation of this element, in degrees.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getRotation = function() {
|
||||
return this.rotation_;
|
||||
};
|
||||
|
||||
|
||||
// TRANSFORMS
|
||||
|
||||
|
||||
/**
|
||||
* Called by the parent when the parent has transformed.
|
||||
*
|
||||
* Should be treated as package scope.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.parentTransform = function() {
|
||||
this.needsTransform_ = this.needsTransform_ || this.parentDependent_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether this element has pending transforms.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.isPendingTransform = function() {
|
||||
return this.needsTransform_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Performs a pending transform.
|
||||
* @protected
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.transform = function() {
|
||||
if (this.isPendingTransform()) {
|
||||
this.needsTransform_ = false;
|
||||
|
||||
this.wrapper_.setTransformation(
|
||||
this.getLeft(),
|
||||
this.getTop(),
|
||||
this.rotation_,
|
||||
(this.getWidth() || 1) / 2,
|
||||
(this.getHeight() || 1) / 2);
|
||||
|
||||
// TODO(robbyw): this._fireEvent('transform', [ this ]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// PIXEL SCALE
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} Returns the number of pixels per unit in the x direction.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getPixelScaleX = function() {
|
||||
return this.getGraphics().getPixelScaleX();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} Returns the number of pixels per unit in the y direction.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getPixelScaleY = function() {
|
||||
return this.getGraphics().getPixelScaleY();
|
||||
};
|
||||
|
||||
|
||||
// EVENT HANDLING
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.graphics.ext.Element.prototype.disposeInternal = function() {
|
||||
goog.graphics.ext.Element.superClass_.disposeInternal.call();
|
||||
this.wrapper_.dispose();
|
||||
};
|
||||
|
||||
|
||||
// INTERNAL POSITION OBJECT
|
||||
|
||||
|
||||
/**
|
||||
* Position specification types. Start corresponds to left/top, middle to
|
||||
* center/middle, and end to right/bottom.
|
||||
* @enum {number}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.PositionType_ = {
|
||||
START: 0,
|
||||
MIDDLE: 1,
|
||||
END: 2
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Manages a position and size, either horizontal or vertical.
|
||||
* @param {goog.graphics.ext.Element} element The element the position applies
|
||||
* to.
|
||||
* @param {boolean} horizontal Whether the position is horizontal or vertical.
|
||||
* @constructor
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_ = function(element, horizontal) {
|
||||
this.element_ = element;
|
||||
this.horizontal_ = horizontal;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {Object} The coordinate value computation cache.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.getCoordinateCache_ = function() {
|
||||
return this.coordinateCache_ || (this.coordinateCache_ = {});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The size of the parent's coordinate space.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.getParentSize_ = function() {
|
||||
var parent = this.element_.getParent();
|
||||
return this.horizontal_ ?
|
||||
parent.getCoordinateWidth() :
|
||||
parent.getCoordinateHeight();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The minimum width/height of the element.
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.getMinSize = function() {
|
||||
return this.getValue_(this.minSize_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the minimum width/height of the element.
|
||||
* @param {string|number} minSize The minimum width/height of the element.
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.setMinSize = function(minSize) {
|
||||
this.minSize_ = minSize;
|
||||
this.resetCache();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The width/height of the element.
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.getSize = function() {
|
||||
return Math.max(this.getValue_(this.size_), this.getMinSize());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the width/height of the element.
|
||||
* @param {string|number} size The width/height of the element.
|
||||
* @return {boolean} Whether the value was changed.
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.setSize = function(size) {
|
||||
if (size != this.size_) {
|
||||
this.size_ = size;
|
||||
this.resetCache();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts the given x coordinate to a number value in units.
|
||||
* @param {string|number} v The coordinate to retrieve the value for.
|
||||
* @param {boolean=} opt_forMaximum Whether we are computing the largest value
|
||||
* this coordinate would be in a parent of no size.
|
||||
* @return {number} The correct number of coordinate space units.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.getValue_ = function(v,
|
||||
opt_forMaximum) {
|
||||
if (!goog.graphics.ext.coordinates.isSpecial(v)) {
|
||||
return parseFloat(String(v));
|
||||
}
|
||||
|
||||
var cache = this.getCoordinateCache_();
|
||||
var scale = this.horizontal_ ?
|
||||
this.element_.getPixelScaleX() :
|
||||
this.element_.getPixelScaleY();
|
||||
|
||||
var containerSize;
|
||||
if (opt_forMaximum) {
|
||||
containerSize = goog.graphics.ext.coordinates.computeValue(
|
||||
this.size_ || 0, 0, scale);
|
||||
} else {
|
||||
var parent = this.element_.getParent();
|
||||
containerSize = this.horizontal_ ? parent.getWidth() : parent.getHeight();
|
||||
}
|
||||
|
||||
return goog.graphics.ext.coordinates.getValue(v, opt_forMaximum,
|
||||
containerSize, scale, cache);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The distance from the left/top edge of this element to the
|
||||
* left/top edge of its parent, specified in units of the parent's
|
||||
* coordinate system.
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.getStart = function() {
|
||||
if (this.cachedValue_ == null) {
|
||||
var value = this.getValue_(this.distance_);
|
||||
if (this.distanceType_ == goog.graphics.ext.Element.PositionType_.START) {
|
||||
this.cachedValue_ = value;
|
||||
} else if (this.distanceType_ ==
|
||||
goog.graphics.ext.Element.PositionType_.MIDDLE) {
|
||||
this.cachedValue_ = value + (this.getParentSize_() - this.getSize()) / 2;
|
||||
} else {
|
||||
this.cachedValue_ = this.getParentSize_() - value - this.getSize();
|
||||
}
|
||||
}
|
||||
|
||||
return this.cachedValue_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The middle coordinate of the element, in units of the
|
||||
* parent's coordinate system.
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.getMiddle = function() {
|
||||
return this.distanceType_ == goog.graphics.ext.Element.PositionType_.MIDDLE ?
|
||||
this.getValue_(this.distance_) :
|
||||
(this.getParentSize_() - this.getSize()) / 2 - this.getStart();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The end coordinate of the element, in units of the
|
||||
* parent's coordinate system.
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.getEnd = function() {
|
||||
return this.distanceType_ == goog.graphics.ext.Element.PositionType_.END ?
|
||||
this.getValue_(this.distance_) :
|
||||
this.getParentSize_() - this.getStart() - this.getSize();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the position, either as a left/top, center/middle, or right/bottom
|
||||
* value.
|
||||
* @param {number|string} value The value of the coordinate.
|
||||
* @param {goog.graphics.ext.Element.PositionType_} type The type of the
|
||||
* coordinate.
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.setPosition = function(value,
|
||||
type) {
|
||||
this.distance_ = value;
|
||||
this.distanceType_ = type;
|
||||
|
||||
// Clear cached value.
|
||||
this.cachedValue_ = null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} An estimate of the maximum x/y extent this element would
|
||||
* have in a parent of no width/height.
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.getMaxPosition = function() {
|
||||
// TODO(robbyw): Handle transformed or rotated coordinates
|
||||
// TODO(robbyw): Handle pixel based sizes?
|
||||
|
||||
return this.getValue_(this.distance_ || 0) + (
|
||||
goog.graphics.ext.coordinates.isSpecial(this.size_) ? 0 : this.getSize());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Resets the caches of position values and coordinate values.
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.resetCache = function() {
|
||||
this.coordinateCache_ = null;
|
||||
this.cachedValue_ = null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the size or position of this element depends on
|
||||
* the size of the parent element.
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.isParentDependent = function() {
|
||||
return this.distanceType_ != goog.graphics.ext.Element.PositionType_.START ||
|
||||
goog.graphics.ext.coordinates.isSpecial(this.size_) ||
|
||||
goog.graphics.ext.coordinates.isSpecial(this.minSize_) ||
|
||||
goog.graphics.ext.coordinates.isSpecial(this.distance_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The lazy loaded distance from the parent's top/left edge to this element's
|
||||
* top/left edge expressed in the parent's coordinate system. We cache this
|
||||
* because it is most freqeuently requested by the element and it is easy to
|
||||
* compute middle and end values from it.
|
||||
* @type {?number}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.cachedValue_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* A cache of computed x coordinates.
|
||||
* @type {Object}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.coordinateCache_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* The minimum width/height of this element, as specified by the caller.
|
||||
* @type {string|number}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.minSize_ = 0;
|
||||
|
||||
|
||||
/**
|
||||
* The width/height of this object, as specified by the caller.
|
||||
* @type {string|number}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.size_ = 0;
|
||||
|
||||
|
||||
/**
|
||||
* The coordinate of this object, as specified by the caller. The type of
|
||||
* coordinate is specified by distanceType_.
|
||||
* @type {string|number}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.distance_ = 0;
|
||||
|
||||
|
||||
/**
|
||||
* The coordinate type specified by distance_.
|
||||
* @type {goog.graphics.ext.Element.PositionType_}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.distanceType_ =
|
||||
goog.graphics.ext.Element.PositionType_.START;
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
// 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 A thick wrapper around ellipses.
|
||||
* @author robbyw@google.com (Robby Walker)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.ext.Ellipse');
|
||||
|
||||
goog.require('goog.graphics.ext.StrokeAndFillElement');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper for a graphics ellipse element.
|
||||
* @param {goog.graphics.ext.Group} group Parent for this element.
|
||||
* @constructor
|
||||
* @extends {goog.graphics.ext.StrokeAndFillElement}
|
||||
*/
|
||||
goog.graphics.ext.Ellipse = function(group) {
|
||||
// Initialize with some stock values.
|
||||
var wrapper = group.getGraphicsImplementation().drawEllipse(1, 1, 2, 2, null,
|
||||
null, group.getWrapper());
|
||||
goog.graphics.ext.StrokeAndFillElement.call(this, group, wrapper);
|
||||
};
|
||||
goog.inherits(goog.graphics.ext.Ellipse,
|
||||
goog.graphics.ext.StrokeAndFillElement);
|
||||
|
||||
|
||||
/**
|
||||
* Redraw the ellipse. Called when the coordinate system is changed.
|
||||
* @protected
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Ellipse.prototype.redraw = function() {
|
||||
goog.graphics.ext.Ellipse.superClass_.redraw.call(this);
|
||||
|
||||
// Our position is already transformed in transform_, but because this is an
|
||||
// ellipse we need to position the center.
|
||||
var xRadius = this.getWidth() / 2;
|
||||
var yRadius = this.getHeight() / 2;
|
||||
var wrapper = this.getWrapper();
|
||||
wrapper.setCenter(xRadius, yRadius);
|
||||
wrapper.setRadius(xRadius, yRadius);
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
// 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 Extended graphics namespace.
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.ext');
|
||||
|
||||
goog.require('goog.graphics.ext.Ellipse');
|
||||
goog.require('goog.graphics.ext.Graphics');
|
||||
goog.require('goog.graphics.ext.Group');
|
||||
goog.require('goog.graphics.ext.Image');
|
||||
goog.require('goog.graphics.ext.Rectangle');
|
||||
goog.require('goog.graphics.ext.Shape');
|
||||
goog.require('goog.graphics.ext.coordinates');
|
||||
@@ -0,0 +1,215 @@
|
||||
// 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 Graphics surface type.
|
||||
* @author robbyw@google.com (Robby Walker)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.ext.Graphics');
|
||||
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('goog.graphics.ext.Group');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper for a graphics surface.
|
||||
* @param {string|number} width The width in pixels. Strings
|
||||
* expressing percentages of parent with (e.g. '80%') are also accepted.
|
||||
* @param {string|number} height The height in pixels. Strings
|
||||
* expressing percentages of parent with (e.g. '80%') are also accepted.
|
||||
* @param {?number=} opt_coordWidth The coordinate width - if
|
||||
* omitted or null, defaults to same as width.
|
||||
* @param {?number=} opt_coordHeight The coordinate height. - if
|
||||
* omitted or null, defaults to same as height.
|
||||
* @param {goog.dom.DomHelper=} opt_domHelper The DOM helper object for the
|
||||
* document we want to render in.
|
||||
* @param {boolean=} opt_isSimple Flag used to indicate the graphics object will
|
||||
* be drawn to in a single pass, and the fastest implementation for this
|
||||
* scenario should be favored. NOTE: Setting to true may result in
|
||||
* degradation of text support.
|
||||
* @constructor
|
||||
* @extends {goog.graphics.ext.Group}
|
||||
*/
|
||||
goog.graphics.ext.Graphics = function(width, height, opt_coordWidth,
|
||||
opt_coordHeight, opt_domHelper, opt_isSimple) {
|
||||
var surface = opt_isSimple ?
|
||||
goog.graphics.createSimpleGraphics(width, height,
|
||||
opt_coordWidth, opt_coordHeight, opt_domHelper) :
|
||||
goog.graphics.createGraphics(width, height,
|
||||
opt_coordWidth, opt_coordHeight, opt_domHelper);
|
||||
this.implementation_ = surface;
|
||||
|
||||
goog.graphics.ext.Group.call(this, null, surface.getCanvasElement());
|
||||
|
||||
goog.events.listen(surface, goog.events.EventType.RESIZE,
|
||||
this.updateChildren, false, this);
|
||||
};
|
||||
goog.inherits(goog.graphics.ext.Graphics, goog.graphics.ext.Group);
|
||||
|
||||
|
||||
/**
|
||||
* The root level graphics implementation.
|
||||
* @type {goog.graphics.AbstractGraphics}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.implementation_;
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.graphics.AbstractGraphics} The graphics implementation layer.
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.getImplementation = function() {
|
||||
return this.implementation_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Changes the coordinate size.
|
||||
* @param {number} coordWidth The coordinate width.
|
||||
* @param {number} coordHeight The coordinate height.
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.setCoordSize = function(coordWidth,
|
||||
coordHeight) {
|
||||
this.implementation_.setCoordSize(coordWidth, coordHeight);
|
||||
goog.graphics.ext.Graphics.superClass_.setSize.call(this, coordWidth,
|
||||
coordHeight);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.math.Size} The coordinate size.
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.getCoordSize = function() {
|
||||
return this.implementation_.getCoordSize();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Changes the coordinate system position.
|
||||
* @param {number} left The coordinate system left bound.
|
||||
* @param {number} top The coordinate system top bound.
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.setCoordOrigin = function(left, top) {
|
||||
this.implementation_.setCoordOrigin(left, top);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.math.Coordinate} The coordinate system position.
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.getCoordOrigin = function() {
|
||||
return this.implementation_.getCoordOrigin();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Change the size of the canvas.
|
||||
* @param {number} pixelWidth The width in pixels.
|
||||
* @param {number} pixelHeight The height in pixels.
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.setPixelSize = function(pixelWidth,
|
||||
pixelHeight) {
|
||||
this.implementation_.setSize(pixelWidth, pixelHeight);
|
||||
|
||||
var coordSize = this.getCoordSize();
|
||||
goog.graphics.ext.Graphics.superClass_.setSize.call(this, coordSize.width,
|
||||
coordSize.height);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.math.Size?} Returns the number of pixels spanned by the
|
||||
* surface, or null if the size could not be computed due to the size being
|
||||
* specified in percentage points and the component not being in the
|
||||
* document.
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.getPixelSize = function() {
|
||||
return this.implementation_.getPixelSize();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The coordinate width of the canvas.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.getWidth = function() {
|
||||
return this.implementation_.getCoordSize().width;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The coordinate width of the canvas.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.getHeight = function() {
|
||||
return this.implementation_.getCoordSize().height;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} Returns the number of pixels per unit in the x direction.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.getPixelScaleX = function() {
|
||||
return this.implementation_.getPixelScaleX();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} Returns the number of pixels per unit in the y direction.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.getPixelScaleY = function() {
|
||||
return this.implementation_.getPixelScaleY();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {Element} The root element of the graphics surface.
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.getElement = function() {
|
||||
return this.implementation_.getElement();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Renders the underlying graphics.
|
||||
*
|
||||
* @param {Element} parentElement Parent element to render the component into.
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.render = function(parentElement) {
|
||||
this.implementation_.render(parentElement);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Never transform a surface.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.transform = goog.nullFunction;
|
||||
|
||||
|
||||
/**
|
||||
* Called from the parent class, this method resets any pre-computed positions
|
||||
* and sizes.
|
||||
* @protected
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.redraw = function() {
|
||||
this.transformChildren();
|
||||
};
|
||||
@@ -0,0 +1,215 @@
|
||||
// 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 A thicker wrapper around graphics groups.
|
||||
* @author robbyw@google.com (Robby Walker)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.ext.Group');
|
||||
|
||||
goog.require('goog.graphics.ext.Element');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper for a graphics group.
|
||||
* @param {goog.graphics.ext.Group} group Parent for this element. Can
|
||||
* be null if this is a Graphics instance.
|
||||
* @param {goog.graphics.GroupElement=} opt_wrapper The thin wrapper
|
||||
* to wrap. If omitted, a new group will be created. Must be included
|
||||
* when group is null.
|
||||
* @constructor
|
||||
* @extends {goog.graphics.ext.Element}
|
||||
*/
|
||||
goog.graphics.ext.Group = function(group, opt_wrapper) {
|
||||
opt_wrapper = opt_wrapper || group.getGraphicsImplementation().createGroup(
|
||||
group.getWrapper());
|
||||
goog.graphics.ext.Element.call(this, group, opt_wrapper);
|
||||
|
||||
/**
|
||||
* Array of child elements this group contains.
|
||||
* @type {Array.<goog.graphics.ext.Element>}
|
||||
* @private
|
||||
*/
|
||||
this.children_ = [];
|
||||
};
|
||||
goog.inherits(goog.graphics.ext.Group, goog.graphics.ext.Element);
|
||||
|
||||
|
||||
/**
|
||||
* Add an element to the group. This should be treated as package local, as
|
||||
* it is called by the draw* methods.
|
||||
* @param {!goog.graphics.ext.Element} element The element to add.
|
||||
* @param {boolean=} opt_chain Whether this addition is part of a longer set
|
||||
* of element additions.
|
||||
*/
|
||||
goog.graphics.ext.Group.prototype.addChild = function(element, opt_chain) {
|
||||
if (!goog.array.contains(this.children_, element)) {
|
||||
this.children_.push(element);
|
||||
}
|
||||
|
||||
var transformed = this.growToFit_(element);
|
||||
|
||||
if (element.isParentDependent()) {
|
||||
element.parentTransform();
|
||||
}
|
||||
|
||||
if (!opt_chain && element.isPendingTransform()) {
|
||||
element.reset();
|
||||
}
|
||||
|
||||
if (transformed) {
|
||||
this.reset();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Remove an element from the group.
|
||||
* @param {goog.graphics.ext.Element} element The element to remove.
|
||||
*/
|
||||
goog.graphics.ext.Group.prototype.removeChild = function(element) {
|
||||
goog.array.remove(this.children_, element);
|
||||
|
||||
// TODO(robbyw): shape.fireEvent('delete')
|
||||
|
||||
this.getGraphicsImplementation().removeElement(element.getWrapper());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calls the given function on each of this component's children in order. If
|
||||
* {@code opt_obj} is provided, it will be used as the 'this' object in the
|
||||
* function when called. The function should take two arguments: the child
|
||||
* component and its 0-based index. The return value is ignored.
|
||||
* @param {Function} f The function to call for every child component; should
|
||||
* take 2 arguments (the child and its index).
|
||||
* @param {Object=} opt_obj Used as the 'this' object in f when called.
|
||||
*/
|
||||
goog.graphics.ext.Group.prototype.forEachChild = function(f, opt_obj) {
|
||||
if (this.children_) {
|
||||
goog.array.forEach(this.children_, f, opt_obj);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.graphics.GroupElement} The underlying thin wrapper.
|
||||
* @protected
|
||||
*/
|
||||
goog.graphics.ext.Group.prototype.getWrapper;
|
||||
|
||||
|
||||
/**
|
||||
* Reset the element.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Group.prototype.reset = function() {
|
||||
goog.graphics.ext.Group.superClass_.reset.call(this);
|
||||
|
||||
this.updateChildren();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Called from the parent class, this method resets any pre-computed positions
|
||||
* and sizes.
|
||||
* @protected
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Group.prototype.redraw = function() {
|
||||
this.getWrapper().setSize(this.getWidth(), this.getHeight());
|
||||
this.transformChildren();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Transform the children that need to be transformed.
|
||||
* @protected
|
||||
*/
|
||||
goog.graphics.ext.Group.prototype.transformChildren = function() {
|
||||
this.forEachChild(function(child) {
|
||||
if (child.isParentDependent()) {
|
||||
child.parentTransform();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* As part of the reset process, update child elements.
|
||||
*/
|
||||
goog.graphics.ext.Group.prototype.updateChildren = function() {
|
||||
this.forEachChild(function(child) {
|
||||
if (child.isParentDependent() || child.isPendingTransform()) {
|
||||
child.reset();
|
||||
} else if (child.updateChildren) {
|
||||
child.updateChildren();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* When adding an element, grow this group's bounds to fit it.
|
||||
* @param {!goog.graphics.ext.Element} element The added element.
|
||||
* @return {boolean} Whether the size of this group changed.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Group.prototype.growToFit_ = function(element) {
|
||||
var transformed = false;
|
||||
|
||||
var x = element.getMaxX();
|
||||
if (x > this.getWidth()) {
|
||||
this.setMinWidth(x);
|
||||
transformed = true;
|
||||
}
|
||||
|
||||
var y = element.getMaxY();
|
||||
if (y > this.getHeight()) {
|
||||
this.setMinHeight(y);
|
||||
transformed = true;
|
||||
}
|
||||
|
||||
return transformed;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The width of the element's coordinate space.
|
||||
*/
|
||||
goog.graphics.ext.Group.prototype.getCoordinateWidth = function() {
|
||||
return this.getWidth();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The height of the element's coordinate space.
|
||||
*/
|
||||
goog.graphics.ext.Group.prototype.getCoordinateHeight = function() {
|
||||
return this.getHeight();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Remove all drawing elements from the group.
|
||||
*/
|
||||
goog.graphics.ext.Group.prototype.clear = function() {
|
||||
while (this.children_.length) {
|
||||
this.removeChild(this.children_[0]);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,63 @@
|
||||
// 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 A thick wrapper around images.
|
||||
* @author robbyw@google.com (Robby Walker)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.ext.Image');
|
||||
|
||||
goog.require('goog.graphics.ext.Element');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper for a graphics image element.
|
||||
* @param {goog.graphics.ext.Group} group Parent for this element.
|
||||
* @param {string} src The path to the image to display.
|
||||
* @constructor
|
||||
* @extends {goog.graphics.ext.Element}
|
||||
*/
|
||||
goog.graphics.ext.Image = function(group, src) {
|
||||
// Initialize with some stock values.
|
||||
var wrapper = group.getGraphicsImplementation().drawImage(0, 0, 1, 1, src,
|
||||
group.getWrapper());
|
||||
goog.graphics.ext.Element.call(this, group, wrapper);
|
||||
};
|
||||
goog.inherits(goog.graphics.ext.Image, goog.graphics.ext.Element);
|
||||
|
||||
|
||||
/**
|
||||
* Redraw the image. Called when the coordinate system is changed.
|
||||
* @protected
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Image.prototype.redraw = function() {
|
||||
goog.graphics.ext.Image.superClass_.redraw.call(this);
|
||||
|
||||
// Our position is already handled bu transform_.
|
||||
this.getWrapper().setSize(this.getWidth(), this.getHeight());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update the source of the image.
|
||||
* @param {string} src Source of the image.
|
||||
*/
|
||||
goog.graphics.ext.Image.prototype.setSource = function(src) {
|
||||
this.getWrapper().setSource(src);
|
||||
};
|
||||
142
nicer-api-docs/closure-library/closure/goog/graphics/ext/path.js
Normal file
142
nicer-api-docs/closure-library/closure/goog/graphics/ext/path.js
Normal file
@@ -0,0 +1,142 @@
|
||||
// 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 A thick wrapper around paths.
|
||||
* @author robbyw@google.com (Robby Walker)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.ext.Path');
|
||||
|
||||
goog.require('goog.graphics.AffineTransform');
|
||||
goog.require('goog.graphics.Path');
|
||||
goog.require('goog.math');
|
||||
goog.require('goog.math.Rect');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates a path object
|
||||
* @constructor
|
||||
* @extends {goog.graphics.Path}
|
||||
*/
|
||||
goog.graphics.ext.Path = function() {
|
||||
goog.graphics.Path.call(this);
|
||||
};
|
||||
goog.inherits(goog.graphics.ext.Path, goog.graphics.Path);
|
||||
|
||||
|
||||
/**
|
||||
* Optional cached or user specified bounding box. A user may wish to
|
||||
* precompute a bounding box to save time and include more accurate
|
||||
* computations.
|
||||
* @type {goog.math.Rect?}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Path.prototype.bounds_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Clones the path.
|
||||
* @return {!goog.graphics.ext.Path} A clone of this path.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Path.prototype.clone = function() {
|
||||
var output = /** @type {goog.graphics.ext.Path} */
|
||||
(goog.graphics.ext.Path.superClass_.clone.call(this));
|
||||
output.bounds_ = this.bounds_ && this.bounds_.clone();
|
||||
return output;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Transforms the path. Only simple paths are transformable. Attempting
|
||||
* to transform a non-simple path will throw an error.
|
||||
* @param {!goog.graphics.AffineTransform} tx The transformation to perform.
|
||||
* @return {!goog.graphics.ext.Path} The path itself.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Path.prototype.transform = function(tx) {
|
||||
goog.graphics.ext.Path.superClass_.transform.call(this, tx);
|
||||
|
||||
// Make sure the precomputed bounds are cleared when the path is transformed.
|
||||
this.bounds_ = null;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Modify the bounding box of the path. This may cause the path to be
|
||||
* simplified (i.e. arcs converted to curves) as a side-effect.
|
||||
* @param {number} deltaX How far to translate the x coordinates.
|
||||
* @param {number} deltaY How far to translate the y coordinates.
|
||||
* @param {number} xFactor After translation, all x coordinates are multiplied
|
||||
* by this number.
|
||||
* @param {number} yFactor After translation, all y coordinates are multiplied
|
||||
* by this number.
|
||||
* @return {goog.graphics.ext.Path} The path itself.
|
||||
*/
|
||||
goog.graphics.ext.Path.prototype.modifyBounds = function(deltaX, deltaY,
|
||||
xFactor, yFactor) {
|
||||
if (!this.isSimple()) {
|
||||
var simple = goog.graphics.Path.createSimplifiedPath(this);
|
||||
this.clear();
|
||||
this.appendPath(simple);
|
||||
}
|
||||
|
||||
return this.transform(goog.graphics.AffineTransform.getScaleInstance(
|
||||
xFactor, yFactor).translate(deltaX, deltaY));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the precomputed bounds.
|
||||
* @param {goog.math.Rect?} bounds The bounds to use, or set to null to clear
|
||||
* and recompute on the next call to getBoundingBox.
|
||||
*/
|
||||
goog.graphics.ext.Path.prototype.useBoundingBox = function(bounds) {
|
||||
this.bounds_ = bounds && bounds.clone();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.math.Rect?} The bounding box of the path, or null if the
|
||||
* path is empty.
|
||||
*/
|
||||
goog.graphics.ext.Path.prototype.getBoundingBox = function() {
|
||||
if (!this.bounds_ && !this.isEmpty()) {
|
||||
var minY;
|
||||
var minX = minY = Number.POSITIVE_INFINITY;
|
||||
var maxY;
|
||||
var maxX = maxY = Number.NEGATIVE_INFINITY;
|
||||
|
||||
var simplePath = this.isSimple() ? this :
|
||||
goog.graphics.Path.createSimplifiedPath(this);
|
||||
simplePath.forEachSegment(function(type, points) {
|
||||
for (var i = 0, len = points.length; i < len; i += 2) {
|
||||
minX = Math.min(minX, points[i]);
|
||||
maxX = Math.max(maxX, points[i]);
|
||||
minY = Math.min(minY, points[i + 1]);
|
||||
maxY = Math.max(maxY, points[i + 1]);
|
||||
}
|
||||
});
|
||||
|
||||
this.bounds_ = new goog.math.Rect(minX, minY, maxX - minX, maxY - minY);
|
||||
}
|
||||
|
||||
return this.bounds_;
|
||||
};
|
||||
@@ -0,0 +1,54 @@
|
||||
// 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 A thick wrapper around rectangles.
|
||||
* @author robbyw@google.com (Robby Walker)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.ext.Rectangle');
|
||||
|
||||
goog.require('goog.graphics.ext.StrokeAndFillElement');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper for a graphics rectangle element.
|
||||
* @param {goog.graphics.ext.Group} group Parent for this element.
|
||||
* @constructor
|
||||
* @extends {goog.graphics.ext.StrokeAndFillElement}
|
||||
*/
|
||||
goog.graphics.ext.Rectangle = function(group) {
|
||||
// Initialize with some stock values.
|
||||
var wrapper = group.getGraphicsImplementation().drawRect(0, 0, 1, 1, null,
|
||||
null, group.getWrapper());
|
||||
goog.graphics.ext.StrokeAndFillElement.call(this, group, wrapper);
|
||||
};
|
||||
goog.inherits(goog.graphics.ext.Rectangle,
|
||||
goog.graphics.ext.StrokeAndFillElement);
|
||||
|
||||
|
||||
/**
|
||||
* Redraw the rectangle. Called when the coordinate system is changed.
|
||||
* @protected
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Rectangle.prototype.redraw = function() {
|
||||
goog.graphics.ext.Rectangle.superClass_.redraw.call(this);
|
||||
|
||||
// Our position is already handled by transform_.
|
||||
this.getWrapper().setSize(this.getWidth(), this.getHeight());
|
||||
};
|
||||
@@ -0,0 +1,146 @@
|
||||
// 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 A thick wrapper around shapes with custom paths.
|
||||
* @author robbyw@google.com (Robby Walker)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.ext.Shape');
|
||||
|
||||
goog.require('goog.graphics.ext.Path');
|
||||
goog.require('goog.graphics.ext.StrokeAndFillElement');
|
||||
goog.require('goog.math.Rect');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper for a graphics shape element.
|
||||
* @param {goog.graphics.ext.Group} group Parent for this element.
|
||||
* @param {!goog.graphics.ext.Path} path The path to draw.
|
||||
* @param {boolean=} opt_autoSize Optional flag to specify the path should
|
||||
* automatically resize to fit the element. Defaults to false.
|
||||
* @constructor
|
||||
* @extends {goog.graphics.ext.StrokeAndFillElement}
|
||||
*/
|
||||
goog.graphics.ext.Shape = function(group, path, opt_autoSize) {
|
||||
this.autoSize_ = !!opt_autoSize;
|
||||
|
||||
var graphics = group.getGraphicsImplementation();
|
||||
var wrapper = graphics.drawPath(path, null, null,
|
||||
group.getWrapper());
|
||||
goog.graphics.ext.StrokeAndFillElement.call(this, group, wrapper);
|
||||
this.setPath(path);
|
||||
};
|
||||
goog.inherits(goog.graphics.ext.Shape, goog.graphics.ext.StrokeAndFillElement);
|
||||
|
||||
|
||||
/**
|
||||
* Whether or not to automatically resize the shape's path when the element
|
||||
* itself is resized.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Shape.prototype.autoSize_ = false;
|
||||
|
||||
|
||||
/**
|
||||
* The original path, specified by the caller.
|
||||
* @type {goog.graphics.Path}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Shape.prototype.path_;
|
||||
|
||||
|
||||
/**
|
||||
* The bounding box of the original path.
|
||||
* @type {goog.math.Rect?}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Shape.prototype.boundingBox_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* The scaled path.
|
||||
* @type {goog.graphics.Path}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Shape.prototype.scaledPath_;
|
||||
|
||||
|
||||
/**
|
||||
* Get the path drawn by this shape.
|
||||
* @return {goog.graphics.Path?} The path drawn by this shape.
|
||||
*/
|
||||
goog.graphics.ext.Shape.prototype.getPath = function() {
|
||||
return this.path_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the path to draw.
|
||||
* @param {goog.graphics.ext.Path} path The path to draw.
|
||||
*/
|
||||
goog.graphics.ext.Shape.prototype.setPath = function(path) {
|
||||
this.path_ = path;
|
||||
|
||||
if (this.autoSize_) {
|
||||
this.boundingBox_ = path.getBoundingBox();
|
||||
}
|
||||
|
||||
this.scaleAndSetPath_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Scale the internal path to fit.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Shape.prototype.scaleAndSetPath_ = function() {
|
||||
this.scaledPath_ = this.boundingBox_ ? this.path_.clone().modifyBounds(
|
||||
-this.boundingBox_.left, -this.boundingBox_.top,
|
||||
this.getWidth() / (this.boundingBox_.width || 1),
|
||||
this.getHeight() / (this.boundingBox_.height || 1)) : this.path_;
|
||||
|
||||
var wrapper = this.getWrapper();
|
||||
if (wrapper) {
|
||||
wrapper.setPath(this.scaledPath_);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Redraw the ellipse. Called when the coordinate system is changed.
|
||||
* @protected
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Shape.prototype.redraw = function() {
|
||||
goog.graphics.ext.Shape.superClass_.redraw.call(this);
|
||||
if (this.autoSize_) {
|
||||
this.scaleAndSetPath_();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the shape is parent dependent.
|
||||
* @protected
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Shape.prototype.checkParentDependent = function() {
|
||||
return this.autoSize_ ||
|
||||
goog.graphics.ext.Shape.superClass_.checkParentDependent.call(this);
|
||||
};
|
||||
@@ -0,0 +1,70 @@
|
||||
// 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 A thick wrapper around elements with stroke and fill.
|
||||
* @author robbyw@google.com (Robby Walker)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.ext.StrokeAndFillElement');
|
||||
|
||||
goog.require('goog.graphics.ext.Element');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Interface for a graphics element that has a stroke and fill.
|
||||
* This is the base interface for ellipse, rectangle and other
|
||||
* shape interfaces.
|
||||
* You should not construct objects from this constructor. Use a subclass.
|
||||
* @param {goog.graphics.ext.Group} group Parent for this element.
|
||||
* @param {goog.graphics.StrokeAndFillElement} wrapper The thin wrapper to wrap.
|
||||
* @constructor
|
||||
* @extends {goog.graphics.ext.Element}
|
||||
*/
|
||||
goog.graphics.ext.StrokeAndFillElement = function(group, wrapper) {
|
||||
goog.graphics.ext.Element.call(this, group, wrapper);
|
||||
};
|
||||
goog.inherits(goog.graphics.ext.StrokeAndFillElement,
|
||||
goog.graphics.ext.Element);
|
||||
|
||||
|
||||
/**
|
||||
* Sets the fill for this element.
|
||||
* @param {goog.graphics.Fill?} fill The fill object.
|
||||
*/
|
||||
goog.graphics.ext.StrokeAndFillElement.prototype.setFill = function(fill) {
|
||||
this.getWrapper().setFill(fill);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the stroke for this element.
|
||||
* @param {goog.graphics.Stroke?} stroke The stroke object.
|
||||
*/
|
||||
goog.graphics.ext.StrokeAndFillElement.prototype.setStroke = function(stroke) {
|
||||
this.getWrapper().setStroke(stroke);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Redraw the rectangle. Called when the coordinate system is changed.
|
||||
* @protected
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.StrokeAndFillElement.prototype.redraw = function() {
|
||||
this.getWrapper().reapplyStroke();
|
||||
};
|
||||
46
nicer-api-docs/closure-library/closure/goog/graphics/fill.js
Normal file
46
nicer-api-docs/closure-library/closure/goog/graphics/fill.js
Normal file
@@ -0,0 +1,46 @@
|
||||
// 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 Represents a fill goog.graphics.
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.Fill');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates a fill object
|
||||
* @constructor
|
||||
* @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.
|
||||
*/
|
||||
goog.graphics.Fill = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} The start color of a gradient fill.
|
||||
*/
|
||||
goog.graphics.Fill.prototype.getColor1 = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} The end color of a gradient fill.
|
||||
*/
|
||||
goog.graphics.Fill.prototype.getColor2 = goog.abstractMethod;
|
||||
|
||||
63
nicer-api-docs/closure-library/closure/goog/graphics/font.js
Normal file
63
nicer-api-docs/closure-library/closure/goog/graphics/font.js
Normal file
@@ -0,0 +1,63 @@
|
||||
// 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 Represents a font to be used with a Renderer.
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
* @see ../demos/graphics/basicelements.html
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.Font');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This class represents a font to be used with a renderer.
|
||||
* @param {number} size The font size.
|
||||
* @param {string} family The font family.
|
||||
* @constructor
|
||||
* @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.
|
||||
*/
|
||||
goog.graphics.Font = function(size, family) {
|
||||
/**
|
||||
* Font size.
|
||||
* @type {number}
|
||||
*/
|
||||
this.size = size;
|
||||
// TODO(arv): Is this in pixels or drawing units based on the coord size?
|
||||
|
||||
/**
|
||||
* The name of the font family to use, can be a comma separated string.
|
||||
* @type {string}
|
||||
*/
|
||||
this.family = family;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Indication if text should be bolded
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.graphics.Font.prototype.bold = false;
|
||||
|
||||
|
||||
/**
|
||||
* Indication if text should be in italics
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.graphics.Font.prototype.italic = false;
|
||||
135
nicer-api-docs/closure-library/closure/goog/graphics/graphics.js
Normal file
135
nicer-api-docs/closure-library/closure/goog/graphics/graphics.js
Normal file
@@ -0,0 +1,135 @@
|
||||
// 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 Graphics utility functions and factory methods.
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
* @see ../demos/graphics/advancedcoordinates.html
|
||||
* @see ../demos/graphics/advancedcoordinates2.html
|
||||
* @see ../demos/graphics/basicelements.html
|
||||
* @see ../demos/graphics/events.html
|
||||
* @see ../demos/graphics/modifyelements.html
|
||||
* @see ../demos/graphics/tiger.html
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics');
|
||||
|
||||
goog.require('goog.graphics.CanvasGraphics');
|
||||
goog.require('goog.graphics.SvgGraphics');
|
||||
goog.require('goog.graphics.VmlGraphics');
|
||||
goog.require('goog.userAgent');
|
||||
|
||||
|
||||
/**
|
||||
* Returns an instance of goog.graphics.AbstractGraphics that knows how to draw
|
||||
* for the current platform (A factory for the proper Graphics implementation)
|
||||
* @param {string|number} width The width in pixels. Strings
|
||||
* expressing percentages of parent with (e.g. '80%') are also accepted.
|
||||
* @param {string|number} height The height in pixels. Strings
|
||||
* expressing percentages of parent with (e.g. '80%') are also accepted.
|
||||
* @param {?number=} opt_coordWidth The optional coordinate width - if
|
||||
* omitted or null, defaults to same as width.
|
||||
* @param {?number=} opt_coordHeight The optional coordinate height - if
|
||||
* omitted or null, defaults to same as height.
|
||||
* @param {goog.dom.DomHelper=} opt_domHelper The DOM helper object for the
|
||||
* document we want to render in.
|
||||
* @return {goog.graphics.AbstractGraphics} The created instance.
|
||||
* @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.
|
||||
*/
|
||||
goog.graphics.createGraphics = function(width, height, opt_coordWidth,
|
||||
opt_coordHeight, opt_domHelper) {
|
||||
var graphics;
|
||||
if (goog.userAgent.IE && !goog.userAgent.isVersionOrHigher('9')) {
|
||||
graphics = new goog.graphics.VmlGraphics(width, height,
|
||||
opt_coordWidth, opt_coordHeight, opt_domHelper);
|
||||
} else if (goog.userAgent.WEBKIT &&
|
||||
(!goog.userAgent.isVersionOrHigher('420') ||
|
||||
goog.userAgent.MOBILE)) {
|
||||
graphics = new goog.graphics.CanvasGraphics(width, height,
|
||||
opt_coordWidth, opt_coordHeight, opt_domHelper);
|
||||
} else {
|
||||
graphics = new goog.graphics.SvgGraphics(width, height,
|
||||
opt_coordWidth, opt_coordHeight, opt_domHelper);
|
||||
}
|
||||
|
||||
// Create the dom now, because all drawing methods require that the
|
||||
// main dom element (the canvas) has been already created.
|
||||
graphics.createDom();
|
||||
|
||||
return graphics;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns an instance of goog.graphics.AbstractGraphics that knows how to draw
|
||||
* for the current platform (A factory for the proper Graphics implementation)
|
||||
* @param {string|number} width The width in pixels. Strings
|
||||
* expressing percentages of parent with (e.g. '80%') are also accepted.
|
||||
* @param {string|number} height The height in pixels. Strings
|
||||
* expressing percentages of parent with (e.g. '80%') are also accepted.
|
||||
* @param {?number=} opt_coordWidth The optional coordinate width, defaults to
|
||||
* same as width.
|
||||
* @param {?number=} opt_coordHeight The optional coordinate height, defaults to
|
||||
* same as height.
|
||||
* @param {goog.dom.DomHelper=} opt_domHelper The DOM helper object for the
|
||||
* document we want to render in.
|
||||
* @return {goog.graphics.AbstractGraphics} The created instance.
|
||||
* @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.
|
||||
*/
|
||||
goog.graphics.createSimpleGraphics = function(width, height,
|
||||
opt_coordWidth, opt_coordHeight, opt_domHelper) {
|
||||
if (goog.userAgent.MAC && goog.userAgent.GECKO &&
|
||||
!goog.userAgent.isVersionOrHigher('1.9a')) {
|
||||
// Canvas is 6x faster than SVG on Mac FF 2.0
|
||||
var graphics = new goog.graphics.CanvasGraphics(
|
||||
width, height, opt_coordWidth, opt_coordHeight,
|
||||
opt_domHelper);
|
||||
graphics.createDom();
|
||||
return graphics;
|
||||
}
|
||||
|
||||
// Otherwise, defer to normal graphics object creation.
|
||||
return goog.graphics.createGraphics(width, height, opt_coordWidth,
|
||||
opt_coordHeight, opt_domHelper);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Static function to check if the current browser has Graphics support.
|
||||
* @return {boolean} True if the current browser has Graphics support.
|
||||
* @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.
|
||||
*/
|
||||
goog.graphics.isBrowserSupported = function() {
|
||||
if (goog.userAgent.IE) {
|
||||
return goog.userAgent.isVersionOrHigher('5.5');
|
||||
}
|
||||
if (goog.userAgent.GECKO) {
|
||||
return goog.userAgent.isVersionOrHigher('1.8');
|
||||
}
|
||||
if (goog.userAgent.OPERA) {
|
||||
return goog.userAgent.isVersionOrHigher('9.0');
|
||||
}
|
||||
if (goog.userAgent.WEBKIT) {
|
||||
return goog.userAgent.isVersionOrHigher('412');
|
||||
}
|
||||
return false;
|
||||
};
|
||||
@@ -0,0 +1,59 @@
|
||||
// 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 A thin wrapper around the DOM element for graphics groups.
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
* @author yoah@google.com (Yoah Bar-David)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.GroupElement');
|
||||
|
||||
goog.require('goog.graphics.Element');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Interface for a graphics group element.
|
||||
* 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.AbstractGraphics} graphics The graphics creating
|
||||
* this element.
|
||||
* @constructor
|
||||
* @extends {goog.graphics.Element}
|
||||
* @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.
|
||||
*/
|
||||
goog.graphics.GroupElement = function(element, graphics) {
|
||||
goog.graphics.Element.call(this, element, graphics);
|
||||
};
|
||||
goog.inherits(goog.graphics.GroupElement, goog.graphics.Element);
|
||||
|
||||
|
||||
/**
|
||||
* Remove all drawing elements from the group.
|
||||
*/
|
||||
goog.graphics.GroupElement.prototype.clear = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
goog.graphics.GroupElement.prototype.setSize = goog.abstractMethod;
|
||||
@@ -0,0 +1,70 @@
|
||||
// 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 A thin wrapper around the DOM element for images.
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.ImageElement');
|
||||
|
||||
goog.require('goog.graphics.Element');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Interface for a graphics image element.
|
||||
* You should not construct objects from this constructor. Instead,
|
||||
* you should use {@code goog.graphics.Graphics.drawImage} and it
|
||||
* will return an implementation of this interface for you.
|
||||
*
|
||||
* @param {Element} element The DOM element to wrap.
|
||||
* @param {goog.graphics.AbstractGraphics} graphics The graphics creating
|
||||
* this element.
|
||||
* @constructor
|
||||
* @extends {goog.graphics.Element}
|
||||
* @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.
|
||||
*/
|
||||
goog.graphics.ImageElement = function(element, graphics) {
|
||||
goog.graphics.Element.call(this, element, graphics);
|
||||
};
|
||||
goog.inherits(goog.graphics.ImageElement, goog.graphics.Element);
|
||||
|
||||
|
||||
/**
|
||||
* Update the position of the image.
|
||||
*
|
||||
* @param {number} x X coordinate (left).
|
||||
* @param {number} y Y coordinate (top).
|
||||
*/
|
||||
goog.graphics.ImageElement.prototype.setPosition = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* Update the size of the image.
|
||||
*
|
||||
* @param {number} width Width of image.
|
||||
* @param {number} height Height of image.
|
||||
*/
|
||||
goog.graphics.ImageElement.prototype.setSize = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* Update the source of the image.
|
||||
* @param {string} src Source of the image.
|
||||
*/
|
||||
goog.graphics.ImageElement.prototype.setSource = goog.abstractMethod;
|
||||
@@ -0,0 +1,174 @@
|
||||
// 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 Represents a gradient to be used with a Graphics implementor.
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.LinearGradient');
|
||||
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.graphics.Fill');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates an immutable linear gradient fill object.
|
||||
*
|
||||
* @param {number} x1 Start X position of the gradient.
|
||||
* @param {number} y1 Start Y position of the gradient.
|
||||
* @param {number} x2 End X position of the gradient.
|
||||
* @param {number} y2 End Y position of the gradient.
|
||||
* @param {string} color1 Start color of the gradient.
|
||||
* @param {string} color2 End color of the gradient.
|
||||
* @param {?number=} opt_opacity1 Start opacity of the gradient, both or neither
|
||||
* of opt_opacity1 and opt_opacity2 have to be set.
|
||||
* @param {?number=} opt_opacity2 End opacity of the gradient.
|
||||
* @constructor
|
||||
* @extends {goog.graphics.Fill}
|
||||
* @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.
|
||||
*/
|
||||
goog.graphics.LinearGradient =
|
||||
function(x1, y1, x2, y2, color1, color2, opt_opacity1, opt_opacity2) {
|
||||
/**
|
||||
* Start X position of the gradient.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.x1_ = x1;
|
||||
|
||||
/**
|
||||
* Start Y position of the gradient.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.y1_ = y1;
|
||||
|
||||
/**
|
||||
* End X position of the gradient.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.x2_ = x2;
|
||||
|
||||
/**
|
||||
* End Y position of the gradient.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.y2_ = y2;
|
||||
|
||||
/**
|
||||
* Start color of the gradient.
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
this.color1_ = color1;
|
||||
|
||||
/**
|
||||
* End color of the gradient.
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
this.color2_ = color2;
|
||||
|
||||
goog.asserts.assert(
|
||||
goog.isNumber(opt_opacity1) == goog.isNumber(opt_opacity2),
|
||||
'Both or neither of opt_opacity1 and opt_opacity2 have to be set.');
|
||||
|
||||
/**
|
||||
* Start opacity of the gradient.
|
||||
* @type {?number}
|
||||
* @private
|
||||
*/
|
||||
this.opacity1_ = goog.isDef(opt_opacity1) ? opt_opacity1 : null;
|
||||
|
||||
/**
|
||||
* End opacity of the gradient.
|
||||
* @type {?number}
|
||||
* @private
|
||||
*/
|
||||
this.opacity2_ = goog.isDef(opt_opacity2) ? opt_opacity2 : null;
|
||||
};
|
||||
goog.inherits(goog.graphics.LinearGradient, goog.graphics.Fill);
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The start X position of the gradient.
|
||||
*/
|
||||
goog.graphics.LinearGradient.prototype.getX1 = function() {
|
||||
return this.x1_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The start Y position of the gradient.
|
||||
*/
|
||||
goog.graphics.LinearGradient.prototype.getY1 = function() {
|
||||
return this.y1_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The end X position of the gradient.
|
||||
*/
|
||||
goog.graphics.LinearGradient.prototype.getX2 = function() {
|
||||
return this.x2_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The end Y position of the gradient.
|
||||
*/
|
||||
goog.graphics.LinearGradient.prototype.getY2 = function() {
|
||||
return this.y2_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.LinearGradient.prototype.getColor1 = function() {
|
||||
return this.color1_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.LinearGradient.prototype.getColor2 = function() {
|
||||
return this.color2_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {?number} The start opacity of the gradient.
|
||||
*/
|
||||
goog.graphics.LinearGradient.prototype.getOpacity1 = function() {
|
||||
return this.opacity1_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {?number} The end opacity of the gradient.
|
||||
*/
|
||||
goog.graphics.LinearGradient.prototype.getOpacity2 = function() {
|
||||
return this.opacity2_;
|
||||
};
|
||||
512
nicer-api-docs/closure-library/closure/goog/graphics/path.js
Normal file
512
nicer-api-docs/closure-library/closure/goog/graphics/path.js
Normal file
@@ -0,0 +1,512 @@
|
||||
// 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 Represents a path used with a Graphics implementation.
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
* @author glenning@google.com (Anthony Glenning)
|
||||
*/
|
||||
|
||||
goog.provide('goog.graphics.Path');
|
||||
goog.provide('goog.graphics.Path.Segment');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.math');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates a path object. A path is a sequence of segments and may be open or
|
||||
* closed. Path uses the EVEN-ODD fill rule for determining the interior of the
|
||||
* path. A path must start with a moveTo command.
|
||||
*
|
||||
* A "simple" path does not contain any arcs and may be transformed using
|
||||
* the {@code transform} method.
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
goog.graphics.Path = function() {
|
||||
/**
|
||||
* The segment types that constitute this path.
|
||||
* @type {!Array.<number>}
|
||||
* @private
|
||||
*/
|
||||
this.segments_ = [];
|
||||
|
||||
/**
|
||||
* The number of repeated segments of the current type.
|
||||
* @type {!Array.<number>}
|
||||
* @private
|
||||
*/
|
||||
this.count_ = [];
|
||||
|
||||
/**
|
||||
* The arguments corresponding to each of the segments.
|
||||
* @type {!Array.<number>}
|
||||
* @private
|
||||
*/
|
||||
this.arguments_ = [];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The coordinates of the point which closes the path (the point of the
|
||||
* last moveTo command).
|
||||
* @type {Array.<number>?}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.Path.prototype.closePoint_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* The coordinates most recently added to the end of the path.
|
||||
* @type {Array.<number>?}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.Path.prototype.currentPoint_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Flag for whether this is a simple path (contains no arc segments).
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.Path.prototype.simple_ = true;
|
||||
|
||||
|
||||
/**
|
||||
* Path segment types.
|
||||
* @enum {number}
|
||||
*/
|
||||
goog.graphics.Path.Segment = {
|
||||
MOVETO: 0,
|
||||
LINETO: 1,
|
||||
CURVETO: 2,
|
||||
ARCTO: 3,
|
||||
CLOSE: 4
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The number of points for each segment type.
|
||||
* @type {!Array.<number>}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.Path.segmentArgCounts_ = (function() {
|
||||
var counts = [];
|
||||
counts[goog.graphics.Path.Segment.MOVETO] = 2;
|
||||
counts[goog.graphics.Path.Segment.LINETO] = 2;
|
||||
counts[goog.graphics.Path.Segment.CURVETO] = 6;
|
||||
counts[goog.graphics.Path.Segment.ARCTO] = 6;
|
||||
counts[goog.graphics.Path.Segment.CLOSE] = 0;
|
||||
return counts;
|
||||
})();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the number of points for a segment type.
|
||||
*
|
||||
* @param {number} segment The segment type.
|
||||
* @return {number} The number of points.
|
||||
*/
|
||||
goog.graphics.Path.getSegmentCount = function(segment) {
|
||||
return goog.graphics.Path.segmentArgCounts_[segment];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Appends another path to the end of this path.
|
||||
*
|
||||
* @param {!goog.graphics.Path} path The path to append.
|
||||
* @return {!goog.graphics.Path} This path.
|
||||
*/
|
||||
goog.graphics.Path.prototype.appendPath = function(path) {
|
||||
if (path.currentPoint_) {
|
||||
Array.prototype.push.apply(this.segments_, path.segments_);
|
||||
Array.prototype.push.apply(this.count_, path.count_);
|
||||
Array.prototype.push.apply(this.arguments_, path.arguments_);
|
||||
this.currentPoint_ = path.currentPoint_.concat();
|
||||
this.closePoint_ = path.closePoint_.concat();
|
||||
this.simple_ = this.simple_ && path.simple_;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clears the path.
|
||||
*
|
||||
* @return {!goog.graphics.Path} The path itself.
|
||||
*/
|
||||
goog.graphics.Path.prototype.clear = function() {
|
||||
this.segments_.length = 0;
|
||||
this.count_.length = 0;
|
||||
this.arguments_.length = 0;
|
||||
delete this.closePoint_;
|
||||
delete this.currentPoint_;
|
||||
delete this.simple_;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds a point to the path by moving to the specified point. Repeated moveTo
|
||||
* commands are collapsed into a single moveTo.
|
||||
*
|
||||
* @param {number} x X coordinate of destination point.
|
||||
* @param {number} y Y coordinate of destination point.
|
||||
* @return {!goog.graphics.Path} The path itself.
|
||||
*/
|
||||
goog.graphics.Path.prototype.moveTo = function(x, y) {
|
||||
if (goog.array.peek(this.segments_) == goog.graphics.Path.Segment.MOVETO) {
|
||||
this.arguments_.length -= 2;
|
||||
} else {
|
||||
this.segments_.push(goog.graphics.Path.Segment.MOVETO);
|
||||
this.count_.push(1);
|
||||
}
|
||||
this.arguments_.push(x, y);
|
||||
this.currentPoint_ = this.closePoint_ = [x, y];
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds points to the path by drawing a straight line to each point.
|
||||
*
|
||||
* @param {...number} var_args The coordinates of each destination point as x, y
|
||||
* value pairs.
|
||||
* @return {!goog.graphics.Path} The path itself.
|
||||
*/
|
||||
goog.graphics.Path.prototype.lineTo = function(var_args) {
|
||||
var lastSegment = goog.array.peek(this.segments_);
|
||||
if (lastSegment == null) {
|
||||
throw Error('Path cannot start with lineTo');
|
||||
}
|
||||
if (lastSegment != goog.graphics.Path.Segment.LINETO) {
|
||||
this.segments_.push(goog.graphics.Path.Segment.LINETO);
|
||||
this.count_.push(0);
|
||||
}
|
||||
for (var i = 0; i < arguments.length; i += 2) {
|
||||
var x = arguments[i];
|
||||
var y = arguments[i + 1];
|
||||
this.arguments_.push(x, y);
|
||||
}
|
||||
this.count_[this.count_.length - 1] += i / 2;
|
||||
this.currentPoint_ = [x, y];
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds points to the path by drawing cubic Bezier curves. Each curve is
|
||||
* specified using 3 points (6 coordinates) - two control points and the end
|
||||
* point of the curve.
|
||||
*
|
||||
* @param {...number} var_args The coordinates specifiying each curve in sets of
|
||||
* 6 points: {@code [x1, y1]} the first control point, {@code [x2, y2]} the
|
||||
* second control point and {@code [x, y]} the end point.
|
||||
* @return {!goog.graphics.Path} The path itself.
|
||||
*/
|
||||
goog.graphics.Path.prototype.curveTo = function(var_args) {
|
||||
var lastSegment = goog.array.peek(this.segments_);
|
||||
if (lastSegment == null) {
|
||||
throw Error('Path cannot start with curve');
|
||||
}
|
||||
if (lastSegment != goog.graphics.Path.Segment.CURVETO) {
|
||||
this.segments_.push(goog.graphics.Path.Segment.CURVETO);
|
||||
this.count_.push(0);
|
||||
}
|
||||
for (var i = 0; i < arguments.length; i += 6) {
|
||||
var x = arguments[i + 4];
|
||||
var y = arguments[i + 5];
|
||||
this.arguments_.push(arguments[i], arguments[i + 1],
|
||||
arguments[i + 2], arguments[i + 3], x, y);
|
||||
}
|
||||
this.count_[this.count_.length - 1] += i / 6;
|
||||
this.currentPoint_ = [x, y];
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds a path command to close the path by connecting the
|
||||
* last point to the first point.
|
||||
*
|
||||
* @return {!goog.graphics.Path} The path itself.
|
||||
*/
|
||||
goog.graphics.Path.prototype.close = function() {
|
||||
var lastSegment = goog.array.peek(this.segments_);
|
||||
if (lastSegment == null) {
|
||||
throw Error('Path cannot start with close');
|
||||
}
|
||||
if (lastSegment != goog.graphics.Path.Segment.CLOSE) {
|
||||
this.segments_.push(goog.graphics.Path.Segment.CLOSE);
|
||||
this.count_.push(1);
|
||||
this.currentPoint_ = this.closePoint_;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds a path command to draw an arc centered at the point {@code (cx, cy)}
|
||||
* with radius {@code rx} along the x-axis and {@code ry} along the y-axis from
|
||||
* {@code startAngle} through {@code extent} degrees. Positive rotation is in
|
||||
* the direction from positive x-axis to positive y-axis.
|
||||
*
|
||||
* @param {number} cx X coordinate of center of ellipse.
|
||||
* @param {number} cy Y coordinate of center of ellipse.
|
||||
* @param {number} rx Radius of ellipse on x axis.
|
||||
* @param {number} ry Radius of ellipse on y axis.
|
||||
* @param {number} fromAngle Starting angle measured in degrees from the
|
||||
* positive x-axis.
|
||||
* @param {number} extent The span of the arc in degrees.
|
||||
* @param {boolean} connect If true, the starting point of the arc is connected
|
||||
* to the current point.
|
||||
* @return {!goog.graphics.Path} The path itself.
|
||||
* @deprecated Use {@code arcTo} or {@code arcToAsCurves} instead.
|
||||
*/
|
||||
goog.graphics.Path.prototype.arc = function(cx, cy, rx, ry,
|
||||
fromAngle, extent, connect) {
|
||||
var startX = cx + goog.math.angleDx(fromAngle, rx);
|
||||
var startY = cy + goog.math.angleDy(fromAngle, ry);
|
||||
if (connect) {
|
||||
if (!this.currentPoint_ || startX != this.currentPoint_[0] ||
|
||||
startY != this.currentPoint_[1]) {
|
||||
this.lineTo(startX, startY);
|
||||
}
|
||||
} else {
|
||||
this.moveTo(startX, startY);
|
||||
}
|
||||
return this.arcTo(rx, ry, fromAngle, extent);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds a path command to draw an arc starting at the path's current point,
|
||||
* with radius {@code rx} along the x-axis and {@code ry} along the y-axis from
|
||||
* {@code startAngle} through {@code extent} degrees. Positive rotation is in
|
||||
* the direction from positive x-axis to positive y-axis.
|
||||
*
|
||||
* This method makes the path non-simple.
|
||||
*
|
||||
* @param {number} rx Radius of ellipse on x axis.
|
||||
* @param {number} ry Radius of ellipse on y axis.
|
||||
* @param {number} fromAngle Starting angle measured in degrees from the
|
||||
* positive x-axis.
|
||||
* @param {number} extent The span of the arc in degrees.
|
||||
* @return {!goog.graphics.Path} The path itself.
|
||||
*/
|
||||
goog.graphics.Path.prototype.arcTo = function(rx, ry, fromAngle, extent) {
|
||||
var cx = this.currentPoint_[0] - goog.math.angleDx(fromAngle, rx);
|
||||
var cy = this.currentPoint_[1] - goog.math.angleDy(fromAngle, ry);
|
||||
var ex = cx + goog.math.angleDx(fromAngle + extent, rx);
|
||||
var ey = cy + goog.math.angleDy(fromAngle + extent, ry);
|
||||
this.segments_.push(goog.graphics.Path.Segment.ARCTO);
|
||||
this.count_.push(1);
|
||||
this.arguments_.push(rx, ry, fromAngle, extent, ex, ey);
|
||||
this.simple_ = false;
|
||||
this.currentPoint_ = [ex, ey];
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Same as {@code arcTo}, but approximates the arc using bezier curves.
|
||||
.* As a result, this method does not affect the simplified status of this path.
|
||||
* The algorithm is adapted from {@code java.awt.geom.ArcIterator}.
|
||||
*
|
||||
* @param {number} rx Radius of ellipse on x axis.
|
||||
* @param {number} ry Radius of ellipse on y axis.
|
||||
* @param {number} fromAngle Starting angle measured in degrees from the
|
||||
* positive x-axis.
|
||||
* @param {number} extent The span of the arc in degrees.
|
||||
* @return {!goog.graphics.Path} The path itself.
|
||||
*/
|
||||
goog.graphics.Path.prototype.arcToAsCurves = function(
|
||||
rx, ry, fromAngle, extent) {
|
||||
var cx = this.currentPoint_[0] - goog.math.angleDx(fromAngle, rx);
|
||||
var cy = this.currentPoint_[1] - goog.math.angleDy(fromAngle, ry);
|
||||
var extentRad = goog.math.toRadians(extent);
|
||||
var arcSegs = Math.ceil(Math.abs(extentRad) / Math.PI * 2);
|
||||
var inc = extentRad / arcSegs;
|
||||
var angle = goog.math.toRadians(fromAngle);
|
||||
for (var j = 0; j < arcSegs; j++) {
|
||||
var relX = Math.cos(angle);
|
||||
var relY = Math.sin(angle);
|
||||
var z = 4 / 3 * Math.sin(inc / 2) / (1 + Math.cos(inc / 2));
|
||||
var c0 = cx + (relX - z * relY) * rx;
|
||||
var c1 = cy + (relY + z * relX) * ry;
|
||||
angle += inc;
|
||||
relX = Math.cos(angle);
|
||||
relY = Math.sin(angle);
|
||||
this.curveTo(c0, c1,
|
||||
cx + (relX + z * relY) * rx,
|
||||
cy + (relY - z * relX) * ry,
|
||||
cx + relX * rx,
|
||||
cy + relY * ry);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Iterates over the path calling the supplied callback once for each path
|
||||
* segment. The arguments to the callback function are the segment type and
|
||||
* an array of its arguments.
|
||||
*
|
||||
* The {@code LINETO} and {@code CURVETO} arrays can contain multiple
|
||||
* segments of the same type. The number of segments is the length of the
|
||||
* array divided by the segment length (2 for lines, 6 for curves).
|
||||
*
|
||||
* As a convenience the {@code ARCTO} segment also includes the end point as the
|
||||
* last two arguments: {@code rx, ry, fromAngle, extent, x, y}.
|
||||
*
|
||||
* @param {function(number, Array)} callback The function to call with each
|
||||
* path segment.
|
||||
*/
|
||||
goog.graphics.Path.prototype.forEachSegment = function(callback) {
|
||||
var points = this.arguments_;
|
||||
var index = 0;
|
||||
for (var i = 0, length = this.segments_.length; i < length; i++) {
|
||||
var seg = this.segments_[i];
|
||||
var n = goog.graphics.Path.segmentArgCounts_[seg] * this.count_[i];
|
||||
callback(seg, points.slice(index, index + n));
|
||||
index += n;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the coordinates most recently added to the end of the path.
|
||||
*
|
||||
* @return {Array.<number>?} An array containing the ending coordinates of the
|
||||
* path of the form {@code [x, y]}.
|
||||
*/
|
||||
goog.graphics.Path.prototype.getCurrentPoint = function() {
|
||||
return this.currentPoint_ && this.currentPoint_.concat();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!goog.graphics.Path} A copy of this path.
|
||||
*/
|
||||
goog.graphics.Path.prototype.clone = function() {
|
||||
var path = new this.constructor();
|
||||
path.segments_ = this.segments_.concat();
|
||||
path.count_ = this.count_.concat();
|
||||
path.arguments_ = this.arguments_.concat();
|
||||
path.closePoint_ = this.closePoint_ && this.closePoint_.concat();
|
||||
path.currentPoint_ = this.currentPoint_ && this.currentPoint_.concat();
|
||||
path.simple_ = this.simple_;
|
||||
return path;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this path contains no arcs. Simplified paths can be
|
||||
* created using {@code createSimplifiedPath}.
|
||||
*
|
||||
* @return {boolean} True if the path contains no arcs.
|
||||
*/
|
||||
goog.graphics.Path.prototype.isSimple = function() {
|
||||
return this.simple_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A map from segment type to the path function to call to simplify a path.
|
||||
* @type {!Object}
|
||||
* @private
|
||||
* @suppress {deprecated} goog.graphics.Path is deprecated.
|
||||
*/
|
||||
goog.graphics.Path.simplifySegmentMap_ = (function() {
|
||||
var map = {};
|
||||
map[goog.graphics.Path.Segment.MOVETO] = goog.graphics.Path.prototype.moveTo;
|
||||
map[goog.graphics.Path.Segment.LINETO] = goog.graphics.Path.prototype.lineTo;
|
||||
map[goog.graphics.Path.Segment.CLOSE] = goog.graphics.Path.prototype.close;
|
||||
map[goog.graphics.Path.Segment.CURVETO] =
|
||||
goog.graphics.Path.prototype.curveTo;
|
||||
map[goog.graphics.Path.Segment.ARCTO] =
|
||||
goog.graphics.Path.prototype.arcToAsCurves;
|
||||
return map;
|
||||
})();
|
||||
|
||||
|
||||
/**
|
||||
* Creates a copy of the given path, replacing {@code arcTo} with
|
||||
* {@code arcToAsCurves}. The resulting path is simplified and can
|
||||
* be transformed.
|
||||
*
|
||||
* @param {!goog.graphics.Path} src The path to simplify.
|
||||
* @return {!goog.graphics.Path} A new simplified path.
|
||||
* @suppress {deprecated} goog.graphics is deprecated.
|
||||
*/
|
||||
goog.graphics.Path.createSimplifiedPath = function(src) {
|
||||
if (src.isSimple()) {
|
||||
return src.clone();
|
||||
}
|
||||
var path = new goog.graphics.Path();
|
||||
src.forEachSegment(function(segment, args) {
|
||||
goog.graphics.Path.simplifySegmentMap_[segment].apply(path, args);
|
||||
});
|
||||
return path;
|
||||
};
|
||||
|
||||
|
||||
// TODO(chrisn): Delete this method
|
||||
/**
|
||||
* Creates a transformed copy of this path. The path is simplified
|
||||
* {@see #createSimplifiedPath} prior to transformation.
|
||||
*
|
||||
* @param {!goog.graphics.AffineTransform} tx The transformation to perform.
|
||||
* @return {!goog.graphics.Path} A new, transformed path.
|
||||
*/
|
||||
goog.graphics.Path.prototype.createTransformedPath = function(tx) {
|
||||
var path = goog.graphics.Path.createSimplifiedPath(this);
|
||||
path.transform(tx);
|
||||
return path;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Transforms the path. Only simple paths are transformable. Attempting
|
||||
* to transform a non-simple path will throw an error.
|
||||
*
|
||||
* @param {!goog.graphics.AffineTransform} tx The transformation to perform.
|
||||
* @return {!goog.graphics.Path} The path itself.
|
||||
*/
|
||||
goog.graphics.Path.prototype.transform = function(tx) {
|
||||
if (!this.isSimple()) {
|
||||
throw Error('Non-simple path');
|
||||
}
|
||||
tx.transform(this.arguments_, 0, this.arguments_, 0,
|
||||
this.arguments_.length / 2);
|
||||
if (this.closePoint_) {
|
||||
tx.transform(this.closePoint_, 0, this.closePoint_, 0, 1);
|
||||
}
|
||||
if (this.currentPoint_ && this.closePoint_ != this.currentPoint_) {
|
||||
tx.transform(this.currentPoint_, 0, this.currentPoint_, 0, 1);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the path is empty.
|
||||
*/
|
||||
goog.graphics.Path.prototype.isEmpty = function() {
|
||||
return this.segments_.length == 0;
|
||||
};
|
||||
@@ -0,0 +1,55 @@
|
||||
// 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 A thin wrapper around the DOM element for paths.
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
* @author yoah@google.com (Yoah Bar-David)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.PathElement');
|
||||
|
||||
goog.require('goog.graphics.StrokeAndFillElement');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Interface for a graphics path element.
|
||||
* You should not construct objects from this constructor. The graphics
|
||||
* will return an implementation of this interface for you.
|
||||
* @param {Element} element The DOM element to wrap.
|
||||
* @param {goog.graphics.AbstractGraphics} graphics The graphics creating
|
||||
* this element.
|
||||
* @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.StrokeAndFillElement}
|
||||
* @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.
|
||||
*/
|
||||
goog.graphics.PathElement = function(element, graphics, stroke, fill) {
|
||||
goog.graphics.StrokeAndFillElement.call(this, element, graphics, stroke,
|
||||
fill);
|
||||
};
|
||||
goog.inherits(goog.graphics.PathElement, goog.graphics.StrokeAndFillElement);
|
||||
|
||||
|
||||
/**
|
||||
* Update the underlying path.
|
||||
* @param {!goog.graphics.Path} path The path object to draw.
|
||||
*/
|
||||
goog.graphics.PathElement.prototype.setPath = goog.abstractMethod;
|
||||
@@ -0,0 +1,86 @@
|
||||
// Copyright 2010 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 Factories for common path types.
|
||||
* @author nicksantos@google.com (Nick Santos)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.paths');
|
||||
|
||||
goog.require('goog.graphics.Path');
|
||||
goog.require('goog.math.Coordinate');
|
||||
|
||||
|
||||
/**
|
||||
* Defines a regular n-gon by specifing the center, a vertex, and the total
|
||||
* number of vertices.
|
||||
* @param {goog.math.Coordinate} center The center point.
|
||||
* @param {goog.math.Coordinate} vertex The vertex, which implicitly defines
|
||||
* a radius as well.
|
||||
* @param {number} n The number of vertices.
|
||||
* @return {!goog.graphics.Path} The path.
|
||||
*/
|
||||
goog.graphics.paths.createRegularNGon = function(center, vertex, n) {
|
||||
var path = new goog.graphics.Path();
|
||||
path.moveTo(vertex.x, vertex.y);
|
||||
|
||||
var startAngle = Math.atan2(vertex.y - center.y, vertex.x - center.x);
|
||||
var radius = goog.math.Coordinate.distance(center, vertex);
|
||||
for (var i = 1; i < n; i++) {
|
||||
var angle = startAngle + 2 * Math.PI * (i / n);
|
||||
path.lineTo(center.x + radius * Math.cos(angle),
|
||||
center.y + radius * Math.sin(angle));
|
||||
}
|
||||
path.close();
|
||||
return path;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Defines an arrow.
|
||||
* @param {goog.math.Coordinate} a Point A.
|
||||
* @param {goog.math.Coordinate} b Point B.
|
||||
* @param {?number} aHead The size of the arrow head at point A.
|
||||
* 0 omits the head.
|
||||
* @param {?number} bHead The size of the arrow head at point B.
|
||||
* 0 omits the head.
|
||||
* @return {!goog.graphics.Path} The path.
|
||||
*/
|
||||
goog.graphics.paths.createArrow = function(a, b, aHead, bHead) {
|
||||
var path = new goog.graphics.Path();
|
||||
path.moveTo(a.x, a.y);
|
||||
path.lineTo(b.x, b.y);
|
||||
|
||||
var angle = Math.atan2(b.y - a.y, b.x - a.x);
|
||||
if (aHead) {
|
||||
path.appendPath(
|
||||
goog.graphics.paths.createRegularNGon(
|
||||
new goog.math.Coordinate(
|
||||
a.x + aHead * Math.cos(angle),
|
||||
a.y + aHead * Math.sin(angle)),
|
||||
a, 3));
|
||||
}
|
||||
if (bHead) {
|
||||
path.appendPath(
|
||||
goog.graphics.paths.createRegularNGon(
|
||||
new goog.math.Coordinate(
|
||||
b.x + bHead * Math.cos(angle + Math.PI),
|
||||
b.y + bHead * Math.sin(angle + Math.PI)),
|
||||
b, 3));
|
||||
}
|
||||
return path;
|
||||
};
|
||||
@@ -0,0 +1,64 @@
|
||||
// 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 A thin wrapper around the DOM element for rectangles.
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
* @author yoah@google.com (Yoah Bar-David)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.RectElement');
|
||||
|
||||
goog.require('goog.graphics.StrokeAndFillElement');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Interface for a graphics rectangle element.
|
||||
* You should not construct objects from this constructor. The graphics
|
||||
* will return an implementation of this interface for you.
|
||||
* @param {Element} element The DOM element to wrap.
|
||||
* @param {goog.graphics.AbstractGraphics} graphics The graphics creating
|
||||
* this element.
|
||||
* @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.StrokeAndFillElement}
|
||||
* @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.
|
||||
*/
|
||||
goog.graphics.RectElement = function(element, graphics, stroke, fill) {
|
||||
goog.graphics.StrokeAndFillElement.call(this, element, graphics, stroke,
|
||||
fill);
|
||||
};
|
||||
goog.inherits(goog.graphics.RectElement, goog.graphics.StrokeAndFillElement);
|
||||
|
||||
|
||||
/**
|
||||
* Update the position of the rectangle.
|
||||
* @param {number} x X coordinate (left).
|
||||
* @param {number} y Y coordinate (top).
|
||||
*/
|
||||
goog.graphics.RectElement.prototype.setPosition = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* Update the size of the rectangle.
|
||||
* @param {number} width Width of rectangle.
|
||||
* @param {number} height Height of rectangle.
|
||||
*/
|
||||
goog.graphics.RectElement.prototype.setSize = goog.abstractMethod;
|
||||
@@ -0,0 +1,74 @@
|
||||
// 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 Represents a solid color fill goog.graphics.
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.SolidFill');
|
||||
|
||||
|
||||
goog.require('goog.graphics.Fill');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates an immutable solid color fill object.
|
||||
*
|
||||
* @param {string} color The color of the background.
|
||||
* @param {number=} opt_opacity The opacity of the background fill. The value
|
||||
* must be greater than or equal to zero (transparent) and less than or
|
||||
* equal to 1 (opaque).
|
||||
* @constructor
|
||||
* @extends {goog.graphics.Fill}
|
||||
* @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.
|
||||
*/
|
||||
goog.graphics.SolidFill = function(color, opt_opacity) {
|
||||
/**
|
||||
* The color with which to fill.
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
this.color_ = color;
|
||||
|
||||
|
||||
/**
|
||||
* The opacity of the fill.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.opacity_ = opt_opacity == null ? 1.0 : opt_opacity;
|
||||
};
|
||||
goog.inherits(goog.graphics.SolidFill, goog.graphics.Fill);
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} The color of this fill.
|
||||
*/
|
||||
goog.graphics.SolidFill.prototype.getColor = function() {
|
||||
return this.color_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The opacity of this fill.
|
||||
*/
|
||||
goog.graphics.SolidFill.prototype.getOpacity = function() {
|
||||
return this.opacity_;
|
||||
};
|
||||
@@ -0,0 +1,67 @@
|
||||
// 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 Represents a stroke object for goog.graphics.
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.Stroke');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates an immutable stroke object.
|
||||
*
|
||||
* @param {number|string} width The width of the stroke.
|
||||
* @param {string} color The color of the stroke.
|
||||
* @constructor
|
||||
* @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.
|
||||
*/
|
||||
goog.graphics.Stroke = function(width, color) {
|
||||
/**
|
||||
* The width of the stroke.
|
||||
* @type {number|string}
|
||||
* @private
|
||||
*/
|
||||
this.width_ = width;
|
||||
|
||||
|
||||
/**
|
||||
* The color with which to fill.
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
this.color_ = color;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number|string} The width of this stroke.
|
||||
*/
|
||||
goog.graphics.Stroke.prototype.getWidth = function() {
|
||||
return this.width_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} The color of this stroke.
|
||||
*/
|
||||
goog.graphics.Stroke.prototype.getColor = function() {
|
||||
return this.color_;
|
||||
};
|
||||
@@ -0,0 +1,115 @@
|
||||
// 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 A thin wrapper around the DOM element for elements with a
|
||||
* stroke and fill.
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
* @author yoah@google.com (Yoah Bar-David)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.StrokeAndFillElement');
|
||||
|
||||
goog.require('goog.graphics.Element');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Interface for a graphics element with a stroke and fill.
|
||||
* This is the base interface for ellipse, rectangle and other
|
||||
* shape interfaces.
|
||||
* You should not construct objects from this constructor. The graphics
|
||||
* will return an implementation of this interface for you.
|
||||
*
|
||||
* @param {Element} element The DOM element to wrap.
|
||||
* @param {goog.graphics.AbstractGraphics} graphics The graphics creating
|
||||
* this element.
|
||||
* @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.Element}
|
||||
* @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.
|
||||
*/
|
||||
goog.graphics.StrokeAndFillElement = function(element, graphics, stroke, fill) {
|
||||
goog.graphics.Element.call(this, element, graphics);
|
||||
this.setStroke(stroke);
|
||||
this.setFill(fill);
|
||||
};
|
||||
goog.inherits(goog.graphics.StrokeAndFillElement, goog.graphics.Element);
|
||||
|
||||
|
||||
/**
|
||||
* The latest fill applied to this element.
|
||||
* @type {goog.graphics.Fill?}
|
||||
* @protected
|
||||
*/
|
||||
goog.graphics.StrokeAndFillElement.prototype.fill = null;
|
||||
|
||||
|
||||
/**
|
||||
* The latest stroke applied to this element.
|
||||
* @type {goog.graphics.Stroke?}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.StrokeAndFillElement.prototype.stroke_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Sets the fill for this element.
|
||||
* @param {goog.graphics.Fill?} fill The fill object.
|
||||
*/
|
||||
goog.graphics.StrokeAndFillElement.prototype.setFill = function(fill) {
|
||||
this.fill = fill;
|
||||
this.getGraphics().setElementFill(this, fill);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.graphics.Fill?} fill The fill object.
|
||||
*/
|
||||
goog.graphics.StrokeAndFillElement.prototype.getFill = function() {
|
||||
return this.fill;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the stroke for this element.
|
||||
* @param {goog.graphics.Stroke?} stroke The stroke object.
|
||||
*/
|
||||
goog.graphics.StrokeAndFillElement.prototype.setStroke = function(stroke) {
|
||||
this.stroke_ = stroke;
|
||||
this.getGraphics().setElementStroke(this, stroke);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.graphics.Stroke?} stroke The stroke object.
|
||||
*/
|
||||
goog.graphics.StrokeAndFillElement.prototype.getStroke = function() {
|
||||
return this.stroke_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Re-strokes the element to react to coordinate size changes.
|
||||
*/
|
||||
goog.graphics.StrokeAndFillElement.prototype.reapplyStroke = function() {
|
||||
if (this.stroke_) {
|
||||
this.setStroke(this.stroke_);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,279 @@
|
||||
// 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 Thin wrappers around the DOM element returned from
|
||||
* the different draw methods of the graphics. This is the SVG implementation.
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
* @author yoah@google.com (Yoah Bar-David)
|
||||
*/
|
||||
|
||||
goog.provide('goog.graphics.SvgEllipseElement');
|
||||
goog.provide('goog.graphics.SvgGroupElement');
|
||||
goog.provide('goog.graphics.SvgImageElement');
|
||||
goog.provide('goog.graphics.SvgPathElement');
|
||||
goog.provide('goog.graphics.SvgRectElement');
|
||||
goog.provide('goog.graphics.SvgTextElement');
|
||||
|
||||
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.graphics.EllipseElement');
|
||||
goog.require('goog.graphics.GroupElement');
|
||||
goog.require('goog.graphics.ImageElement');
|
||||
goog.require('goog.graphics.PathElement');
|
||||
goog.require('goog.graphics.RectElement');
|
||||
goog.require('goog.graphics.TextElement');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Thin wrapper for SVG group elements.
|
||||
* 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.SvgGraphics} 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.
|
||||
*/
|
||||
goog.graphics.SvgGroupElement = function(element, graphics) {
|
||||
goog.graphics.GroupElement.call(this, element, graphics);
|
||||
};
|
||||
goog.inherits(goog.graphics.SvgGroupElement, goog.graphics.GroupElement);
|
||||
|
||||
|
||||
/**
|
||||
* Remove all drawing elements from the group.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.SvgGroupElement.prototype.clear = function() {
|
||||
goog.dom.removeChildren(this.getElement());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 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.SvgGroupElement.prototype.setSize = function(width, height) {
|
||||
this.getGraphics().setElementAttributes(this.getElement(),
|
||||
{'width': width, 'height': height});
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Thin wrapper for SVG 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.SvgGraphics} graphics The graphics creating
|
||||
* this element.
|
||||
* @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}
|
||||
*/
|
||||
goog.graphics.SvgEllipseElement = function(element, graphics, stroke, fill) {
|
||||
goog.graphics.EllipseElement.call(this, element, graphics, stroke, fill);
|
||||
};
|
||||
goog.inherits(goog.graphics.SvgEllipseElement, goog.graphics.EllipseElement);
|
||||
|
||||
|
||||
/**
|
||||
* Update the center point of the ellipse.
|
||||
* @param {number} cx Center X coordinate.
|
||||
* @param {number} cy Center Y coordinate.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.SvgEllipseElement.prototype.setCenter = function(cx, cy) {
|
||||
this.getGraphics().setElementAttributes(this.getElement(),
|
||||
{'cx': cx, 'cy': cy});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update the radius of the ellipse.
|
||||
* @param {number} rx Radius length for the x-axis.
|
||||
* @param {number} ry Radius length for the y-axis.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.SvgEllipseElement.prototype.setRadius = function(rx, ry) {
|
||||
this.getGraphics().setElementAttributes(this.getElement(),
|
||||
{'rx': rx, 'ry': ry});
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Thin wrapper for SVG 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.SvgGraphics} graphics The graphics creating
|
||||
* this element.
|
||||
* @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}
|
||||
*/
|
||||
goog.graphics.SvgRectElement = function(element, graphics, stroke, fill) {
|
||||
goog.graphics.RectElement.call(this, element, graphics, stroke, fill);
|
||||
};
|
||||
goog.inherits(goog.graphics.SvgRectElement, goog.graphics.RectElement);
|
||||
|
||||
|
||||
/**
|
||||
* Update the position of the rectangle.
|
||||
* @param {number} x X coordinate (left).
|
||||
* @param {number} y Y coordinate (top).
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.SvgRectElement.prototype.setPosition = function(x, y) {
|
||||
this.getGraphics().setElementAttributes(this.getElement(), {'x': x, 'y': y});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update the size of the rectangle.
|
||||
* @param {number} width Width of rectangle.
|
||||
* @param {number} height Height of rectangle.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.SvgRectElement.prototype.setSize = function(width, height) {
|
||||
this.getGraphics().setElementAttributes(this.getElement(),
|
||||
{'width': width, 'height': height});
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Thin wrapper for SVG 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.SvgGraphics} graphics The graphics creating
|
||||
* this element.
|
||||
* @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}
|
||||
*/
|
||||
goog.graphics.SvgPathElement = function(element, graphics, stroke, fill) {
|
||||
goog.graphics.PathElement.call(this, element, graphics, stroke, fill);
|
||||
};
|
||||
goog.inherits(goog.graphics.SvgPathElement, goog.graphics.PathElement);
|
||||
|
||||
|
||||
/**
|
||||
* Update the underlying path.
|
||||
* @param {!goog.graphics.Path} path The path object to draw.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.SvgPathElement.prototype.setPath = function(path) {
|
||||
this.getGraphics().setElementAttributes(this.getElement(),
|
||||
{'d': /** @suppress {missingRequire} */
|
||||
goog.graphics.SvgGraphics.getSvgPath(path)});
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Thin wrapper for SVG 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 {Element} element The DOM element to wrap.
|
||||
* @param {goog.graphics.SvgGraphics} graphics The graphics creating
|
||||
* this element.
|
||||
* @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}
|
||||
*/
|
||||
goog.graphics.SvgTextElement = function(element, graphics, stroke, fill) {
|
||||
goog.graphics.TextElement.call(this, element, graphics, stroke, fill);
|
||||
};
|
||||
goog.inherits(goog.graphics.SvgTextElement, goog.graphics.TextElement);
|
||||
|
||||
|
||||
/**
|
||||
* Update the displayed text of the element.
|
||||
* @param {string} text The text to draw.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.SvgTextElement.prototype.setText = function(text) {
|
||||
this.getElement().firstChild.data = text;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Thin wrapper for SVG 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.SvgGraphics} graphics The graphics creating
|
||||
* this element.
|
||||
* @constructor
|
||||
* @extends {goog.graphics.ImageElement}
|
||||
*/
|
||||
goog.graphics.SvgImageElement = function(element, graphics) {
|
||||
goog.graphics.ImageElement.call(this, element, graphics);
|
||||
};
|
||||
goog.inherits(goog.graphics.SvgImageElement, goog.graphics.ImageElement);
|
||||
|
||||
|
||||
/**
|
||||
* Update the position of the image.
|
||||
* @param {number} x X coordinate (left).
|
||||
* @param {number} y Y coordinate (top).
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.SvgImageElement.prototype.setPosition = function(x, y) {
|
||||
this.getGraphics().setElementAttributes(this.getElement(), {'x': x, 'y': y});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update the size of the image.
|
||||
* @param {number} width Width of image.
|
||||
* @param {number} height Height of image.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.SvgImageElement.prototype.setSize = function(width, height) {
|
||||
this.getGraphics().setElementAttributes(this.getElement(),
|
||||
{'width': width, 'height': height});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update the source of the image.
|
||||
* @param {string} src Source of the image.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.SvgImageElement.prototype.setSource = function(src) {
|
||||
this.getGraphics().setElementAttributes(this.getElement(),
|
||||
{'xlink:href': src});
|
||||
};
|
||||
@@ -0,0 +1,857 @@
|
||||
// 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 SvgGraphics sub class that uses SVG to draw the graphics.
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
* @author yoah@google.com (Yoah Bar-David)
|
||||
*/
|
||||
|
||||
goog.provide('goog.graphics.SvgGraphics');
|
||||
|
||||
goog.require('goog.Timer');
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.events.EventHandler');
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('goog.graphics.AbstractGraphics');
|
||||
goog.require('goog.graphics.LinearGradient');
|
||||
goog.require('goog.graphics.Path');
|
||||
goog.require('goog.graphics.SolidFill');
|
||||
goog.require('goog.graphics.Stroke');
|
||||
goog.require('goog.graphics.SvgEllipseElement');
|
||||
goog.require('goog.graphics.SvgGroupElement');
|
||||
goog.require('goog.graphics.SvgImageElement');
|
||||
goog.require('goog.graphics.SvgPathElement');
|
||||
goog.require('goog.graphics.SvgRectElement');
|
||||
goog.require('goog.graphics.SvgTextElement');
|
||||
goog.require('goog.math');
|
||||
goog.require('goog.math.Size');
|
||||
goog.require('goog.style');
|
||||
goog.require('goog.userAgent');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A Graphics implementation for drawing using SVG.
|
||||
* @param {string|number} width The width in pixels. Strings
|
||||
* expressing percentages of parent with (e.g. '80%') are also accepted.
|
||||
* @param {string|number} height The height in pixels. Strings
|
||||
* expressing percentages of parent with (e.g. '80%') are also accepted.
|
||||
* @param {?number=} opt_coordWidth The coordinate width - if
|
||||
* omitted or null, defaults to same as width.
|
||||
* @param {?number=} opt_coordHeight The coordinate height - if
|
||||
* omitted or null, defaults to same as height.
|
||||
* @param {goog.dom.DomHelper=} opt_domHelper The DOM helper object for the
|
||||
* document we want to render in.
|
||||
* @constructor
|
||||
* @extends {goog.graphics.AbstractGraphics}
|
||||
* @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.
|
||||
*/
|
||||
goog.graphics.SvgGraphics = function(width, height,
|
||||
opt_coordWidth, opt_coordHeight,
|
||||
opt_domHelper) {
|
||||
goog.graphics.AbstractGraphics.call(this, width, height,
|
||||
opt_coordWidth, opt_coordHeight,
|
||||
opt_domHelper);
|
||||
|
||||
/**
|
||||
* Map from def key to id of def root element.
|
||||
* Defs are global "defines" of svg that are used to share common attributes,
|
||||
* for example gradients.
|
||||
* @type {Object}
|
||||
* @private
|
||||
*/
|
||||
this.defs_ = {};
|
||||
|
||||
/**
|
||||
* Whether to manually implement viewBox by using a coordinate transform.
|
||||
* As of 1/11/08 this is necessary for Safari 3 but not for the nightly
|
||||
* WebKit build. Apply to webkit versions < 526. 525 is the
|
||||
* last version used by Safari 3.1.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
this.useManualViewbox_ = goog.userAgent.WEBKIT &&
|
||||
!goog.userAgent.isVersionOrHigher(526);
|
||||
|
||||
/**
|
||||
* Event handler.
|
||||
* @type {goog.events.EventHandler}
|
||||
* @private
|
||||
*/
|
||||
this.handler_ = new goog.events.EventHandler(this);
|
||||
};
|
||||
goog.inherits(goog.graphics.SvgGraphics, goog.graphics.AbstractGraphics);
|
||||
|
||||
|
||||
/**
|
||||
* The SVG namespace URN
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
goog.graphics.SvgGraphics.SVG_NS_ = 'http://www.w3.org/2000/svg';
|
||||
|
||||
|
||||
/**
|
||||
* The name prefix for def entries
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
goog.graphics.SvgGraphics.DEF_ID_PREFIX_ = '_svgdef_';
|
||||
|
||||
|
||||
/**
|
||||
* The next available unique identifier for a def entry.
|
||||
* This is a static variable, so that when multiple graphics are used in one
|
||||
* document, the same def id can not be re-defined by another SvgGraphics.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.SvgGraphics.nextDefId_ = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Svg element for definitions for other elements, e.g. linear gradients.
|
||||
* @type {Element}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.SvgGraphics.prototype.defsElement_;
|
||||
|
||||
|
||||
/**
|
||||
* Creates an SVG element. Used internally and by different SVG classes.
|
||||
* @param {string} tagName The type of element to create.
|
||||
* @param {Object=} opt_attributes Map of name-value pairs for attributes.
|
||||
* @return {Element} The created element.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.SvgGraphics.prototype.createSvgElement_ = function(tagName,
|
||||
opt_attributes) {
|
||||
var element = this.dom_.getDocument().createElementNS(
|
||||
goog.graphics.SvgGraphics.SVG_NS_, tagName);
|
||||
|
||||
if (opt_attributes) {
|
||||
this.setElementAttributes(element, opt_attributes);
|
||||
}
|
||||
|
||||
return element;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets properties to an SVG element. Used internally and by different
|
||||
* SVG elements.
|
||||
* @param {Element} element The svg element.
|
||||
* @param {Object} attributes Map of name-value pairs for attributes.
|
||||
*/
|
||||
goog.graphics.SvgGraphics.prototype.setElementAttributes = function(element,
|
||||
attributes) {
|
||||
for (var key in attributes) {
|
||||
element.setAttribute(key, attributes[key]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Appends an element.
|
||||
*
|
||||
* @param {goog.graphics.Element} element The element wrapper.
|
||||
* @param {goog.graphics.GroupElement=} opt_group The group wrapper element
|
||||
* to append to. If not specified, appends to the main canvas.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.SvgGraphics.prototype.append_ = function(element, opt_group) {
|
||||
var parent = opt_group || this.canvasElement;
|
||||
parent.getElement().appendChild(element.getElement());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the fill of the given element.
|
||||
* @param {goog.graphics.StrokeAndFillElement} element The element wrapper.
|
||||
* @param {goog.graphics.Fill?} fill The fill object.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.SvgGraphics.prototype.setElementFill = function(element, fill) {
|
||||
var svgElement = element.getElement();
|
||||
if (fill instanceof goog.graphics.SolidFill) {
|
||||
svgElement.setAttribute('fill', fill.getColor());
|
||||
svgElement.setAttribute('fill-opacity', fill.getOpacity());
|
||||
} else if (fill instanceof goog.graphics.LinearGradient) {
|
||||
// create a def key which is just a concat of all the relevant fields
|
||||
var defKey = 'lg-' +
|
||||
fill.getX1() + '-' + fill.getY1() + '-' +
|
||||
fill.getX2() + '-' + fill.getY2() + '-' +
|
||||
fill.getColor1() + '-' + fill.getColor2();
|
||||
// It seems that the SVG version accepts opacity where the VML does not
|
||||
|
||||
var id = this.getDef(defKey);
|
||||
|
||||
if (!id) { // No def for this yet, create it
|
||||
// Create the gradient def entry (only linear gradient are supported)
|
||||
var gradient = this.createSvgElement_('linearGradient', {
|
||||
'x1': fill.getX1(),
|
||||
'y1': fill.getY1(),
|
||||
'x2': fill.getX2(),
|
||||
'y2': fill.getY2(),
|
||||
'gradientUnits': 'userSpaceOnUse'
|
||||
});
|
||||
|
||||
var gstyle = 'stop-color:' + fill.getColor1();
|
||||
if (goog.isNumber(fill.getOpacity1())) {
|
||||
gstyle += ';stop-opacity:' + fill.getOpacity1();
|
||||
}
|
||||
var stop1 = this.createSvgElement_(
|
||||
'stop', {'offset': '0%', 'style': gstyle});
|
||||
gradient.appendChild(stop1);
|
||||
|
||||
// LinearGradients don't have opacity in VML so implement that before
|
||||
// enabling the following code.
|
||||
// if (fill.getOpacity() != null) {
|
||||
// gstyles += 'opacity:' + fill.getOpacity() + ';'
|
||||
// }
|
||||
gstyle = 'stop-color:' + fill.getColor2();
|
||||
if (goog.isNumber(fill.getOpacity2())) {
|
||||
gstyle += ';stop-opacity:' + fill.getOpacity2();
|
||||
}
|
||||
var stop2 = this.createSvgElement_(
|
||||
'stop', {'offset': '100%', 'style': gstyle});
|
||||
gradient.appendChild(stop2);
|
||||
|
||||
// LinearGradients don't have opacity in VML so implement that before
|
||||
// enabling the following code.
|
||||
// if (fill.getOpacity() != null) {
|
||||
// gstyles += 'opacity:' + fill.getOpacity() + ';'
|
||||
// }
|
||||
|
||||
id = this.addDef(defKey, gradient);
|
||||
}
|
||||
|
||||
// Link element to linearGradient definition
|
||||
svgElement.setAttribute('fill', 'url(#' + id + ')');
|
||||
} else {
|
||||
svgElement.setAttribute('fill', 'none');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the stroke of the given element.
|
||||
* @param {goog.graphics.StrokeAndFillElement} element The element wrapper.
|
||||
* @param {goog.graphics.Stroke?} stroke The stroke object.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.SvgGraphics.prototype.setElementStroke = function(element,
|
||||
stroke) {
|
||||
var svgElement = element.getElement();
|
||||
if (stroke) {
|
||||
svgElement.setAttribute('stroke', stroke.getColor());
|
||||
|
||||
var width = stroke.getWidth();
|
||||
if (goog.isString(width) && width.indexOf('px') != -1) {
|
||||
svgElement.setAttribute('stroke-width',
|
||||
parseFloat(width) / this.getPixelScaleX());
|
||||
} else {
|
||||
svgElement.setAttribute('stroke-width', width);
|
||||
}
|
||||
} else {
|
||||
svgElement.setAttribute('stroke', 'none');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the transformation of an element.
|
||||
* @param {goog.graphics.Element} element The element wrapper.
|
||||
* @param {number} x The x coordinate of the translation transform.
|
||||
* @param {number} y The y coordinate of the translation transform.
|
||||
* @param {number} angle The angle of the rotation transform.
|
||||
* @param {number} centerX The horizontal center of the rotation transform.
|
||||
* @param {number} centerY The vertical center of the rotation transform.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.SvgGraphics.prototype.setElementTransform = function(element, x,
|
||||
y, angle, centerX, centerY) {
|
||||
element.getElement().setAttribute('transform', 'translate(' + x + ',' + y +
|
||||
') rotate(' + angle + ' ' + centerX + ' ' + centerY + ')');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates the DOM representation of the graphics area.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.SvgGraphics.prototype.createDom = function() {
|
||||
// Set up the standard attributes.
|
||||
var attributes = {
|
||||
'width': this.width,
|
||||
'height': this.height,
|
||||
'overflow': 'hidden'
|
||||
};
|
||||
|
||||
var svgElement = this.createSvgElement_('svg', attributes);
|
||||
|
||||
var groupElement = this.createSvgElement_('g');
|
||||
|
||||
this.defsElement_ = this.createSvgElement_('defs');
|
||||
this.canvasElement = new goog.graphics.SvgGroupElement(groupElement, this);
|
||||
|
||||
svgElement.appendChild(this.defsElement_);
|
||||
svgElement.appendChild(groupElement);
|
||||
|
||||
// Use the svgElement as the root element.
|
||||
this.setElementInternal(svgElement);
|
||||
|
||||
// Set up the coordinate system.
|
||||
this.setViewBox_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Changes the coordinate system position.
|
||||
* @param {number} left The coordinate system left bound.
|
||||
* @param {number} top The coordinate system top bound.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.SvgGraphics.prototype.setCoordOrigin = function(left, top) {
|
||||
this.coordLeft = left;
|
||||
this.coordTop = top;
|
||||
|
||||
this.setViewBox_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Changes the coordinate size.
|
||||
* @param {number} coordWidth The coordinate width.
|
||||
* @param {number} coordHeight The coordinate height.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.SvgGraphics.prototype.setCoordSize = function(coordWidth,
|
||||
coordHeight) {
|
||||
goog.graphics.SvgGraphics.superClass_.setCoordSize.apply(
|
||||
this, arguments);
|
||||
this.setViewBox_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} The view box string.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.SvgGraphics.prototype.getViewBox_ = function() {
|
||||
return this.coordLeft + ' ' + this.coordTop + ' ' +
|
||||
(this.coordWidth ? this.coordWidth + ' ' + this.coordHeight : '');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets up the view box.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.SvgGraphics.prototype.setViewBox_ = function() {
|
||||
if (this.coordWidth || this.coordLeft || this.coordTop) {
|
||||
this.getElement().setAttribute('preserveAspectRatio', 'none');
|
||||
if (this.useManualViewbox_) {
|
||||
this.updateManualViewBox_();
|
||||
} else {
|
||||
this.getElement().setAttribute('viewBox', this.getViewBox_());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Updates the transform of the root element to fake a viewBox. Should only
|
||||
* be called when useManualViewbox_ is set.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.SvgGraphics.prototype.updateManualViewBox_ = function() {
|
||||
if (!this.isInDocument() ||
|
||||
!(this.coordWidth || this.coordLeft || !this.coordTop)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var size = this.getPixelSize();
|
||||
if (size.width == 0) {
|
||||
// In Safari, invisible SVG is sometimes shown. Explicitly hide it.
|
||||
this.getElement().style.visibility = 'hidden';
|
||||
return;
|
||||
}
|
||||
|
||||
this.getElement().style.visibility = '';
|
||||
|
||||
var offsetX = - this.coordLeft;
|
||||
var offsetY = - this.coordTop;
|
||||
var scaleX = size.width / this.coordWidth;
|
||||
var scaleY = size.height / this.coordHeight;
|
||||
|
||||
this.canvasElement.getElement().setAttribute('transform',
|
||||
'scale(' + scaleX + ' ' + scaleY + ') ' +
|
||||
'translate(' + offsetX + ' ' + offsetY + ')');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Change the size of the canvas.
|
||||
* @param {number} pixelWidth The width in pixels.
|
||||
* @param {number} pixelHeight The height in pixels.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.SvgGraphics.prototype.setSize = function(pixelWidth,
|
||||
pixelHeight) {
|
||||
goog.style.setSize(this.getElement(), pixelWidth, pixelHeight);
|
||||
};
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.graphics.SvgGraphics.prototype.getPixelSize = function() {
|
||||
if (!goog.userAgent.GECKO) {
|
||||
return this.isInDocument() ?
|
||||
goog.style.getSize(this.getElement()) :
|
||||
goog.base(this, 'getPixelSize');
|
||||
}
|
||||
|
||||
// In Gecko, goog.style.getSize does not work for SVG elements. We have to
|
||||
// compute the size manually if it is percentage based.
|
||||
var width = this.width;
|
||||
var height = this.height;
|
||||
var computeWidth = goog.isString(width) && width.indexOf('%') != -1;
|
||||
var computeHeight = goog.isString(height) && height.indexOf('%') != -1;
|
||||
|
||||
if (!this.isInDocument() && (computeWidth || computeHeight)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var parent;
|
||||
var parentSize;
|
||||
|
||||
if (computeWidth) {
|
||||
parent = /** @type {Element} */ (this.getElement().parentNode);
|
||||
parentSize = goog.style.getSize(parent);
|
||||
width = parseFloat(/** @type {string} */ (width)) * parentSize.width / 100;
|
||||
}
|
||||
|
||||
if (computeHeight) {
|
||||
parent = parent || /** @type {Element} */ (this.getElement().parentNode);
|
||||
parentSize = parentSize || goog.style.getSize(parent);
|
||||
height = parseFloat(/** @type {string} */ (height)) * parentSize.height /
|
||||
100;
|
||||
}
|
||||
|
||||
return new goog.math.Size(/** @type {number} */ (width),
|
||||
/** @type {number} */ (height));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Remove all drawing elements from the graphics.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.SvgGraphics.prototype.clear = function() {
|
||||
this.canvasElement.clear();
|
||||
goog.dom.removeChildren(this.defsElement_);
|
||||
this.defs_ = {};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Draw an ellipse.
|
||||
*
|
||||
* @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 Stroke object describing the
|
||||
* stroke.
|
||||
* @param {goog.graphics.Fill?} fill Fill object describing the fill.
|
||||
* @param {goog.graphics.GroupElement=} opt_group The group wrapper element
|
||||
* to append to. If not specified, appends to the main canvas.
|
||||
*
|
||||
* @return {goog.graphics.EllipseElement} The newly created element.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.SvgGraphics.prototype.drawEllipse = function(
|
||||
cx, cy, rx, ry, stroke, fill, opt_group) {
|
||||
var element = this.createSvgElement_('ellipse',
|
||||
{'cx': cx, 'cy': cy, 'rx': rx, 'ry': ry});
|
||||
var wrapper = new goog.graphics.SvgEllipseElement(element, this, stroke,
|
||||
fill);
|
||||
this.append_(wrapper, opt_group);
|
||||
return wrapper;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Draw a rectangle.
|
||||
*
|
||||
* @param {number} x X coordinate (left).
|
||||
* @param {number} y Y coordinate (top).
|
||||
* @param {number} width Width of rectangle.
|
||||
* @param {number} height Height of rectangle.
|
||||
* @param {goog.graphics.Stroke?} stroke Stroke object describing the
|
||||
* stroke.
|
||||
* @param {goog.graphics.Fill?} fill Fill object describing the fill.
|
||||
* @param {goog.graphics.GroupElement=} opt_group The group wrapper element
|
||||
* to append to. If not specified, appends to the main canvas.
|
||||
*
|
||||
* @return {goog.graphics.RectElement} The newly created element.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.SvgGraphics.prototype.drawRect = function(x, y, width, height,
|
||||
stroke, fill, opt_group) {
|
||||
var element = this.createSvgElement_('rect',
|
||||
{'x': x, 'y': y, 'width': width, 'height': height});
|
||||
var wrapper = new goog.graphics.SvgRectElement(element, this, stroke, fill);
|
||||
this.append_(wrapper, opt_group);
|
||||
return wrapper;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Draw an image.
|
||||
*
|
||||
* @param {number} x X coordinate (left).
|
||||
* @param {number} y Y coordinate (top).
|
||||
* @param {number} width Width of the image.
|
||||
* @param {number} height Height of the image.
|
||||
* @param {string} src The source fo the image.
|
||||
* @param {goog.graphics.GroupElement=} opt_group The group wrapper element
|
||||
* to append to. If not specified, appends to the main canvas.
|
||||
*
|
||||
* @return {goog.graphics.ImageElement} The newly created image wrapped in a
|
||||
* rectangle element.
|
||||
*/
|
||||
goog.graphics.SvgGraphics.prototype.drawImage = function(x, y, width, height,
|
||||
src, opt_group) {
|
||||
var element = this.createSvgElement_('image', {
|
||||
'x': x,
|
||||
'y': y,
|
||||
'width': width,
|
||||
'height': height,
|
||||
'image-rendering': 'optimizeQuality',
|
||||
'preserveAspectRatio': 'none'
|
||||
});
|
||||
element.setAttributeNS('http://www.w3.org/1999/xlink', 'href', src);
|
||||
var wrapper = new goog.graphics.SvgImageElement(element, this);
|
||||
this.append_(wrapper, opt_group);
|
||||
return wrapper;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Draw a text string vertically centered on a given line.
|
||||
*
|
||||
* @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 Stroke object describing the
|
||||
* stroke.
|
||||
* @param {goog.graphics.Fill?} fill Fill object describing the fill.
|
||||
* @param {goog.graphics.GroupElement=} opt_group The group wrapper element
|
||||
* to append to. If not specified, appends to the main canvas.
|
||||
*
|
||||
* @return {goog.graphics.TextElement} The newly created element.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.SvgGraphics.prototype.drawTextOnLine = function(
|
||||
text, x1, y1, x2, y2, align, font, stroke, fill, opt_group) {
|
||||
var angle = Math.round(goog.math.angle(x1, y1, x2, y2));
|
||||
var dx = x2 - x1;
|
||||
var dy = y2 - y1;
|
||||
var lineLength = Math.round(Math.sqrt(dx * dx + dy * dy)); // Length of line
|
||||
|
||||
// SVG baseline is on the glyph's base line. We estimate it as 85% of the
|
||||
// font height. This is just a rough estimate, but do not have a better way.
|
||||
var fontSize = font.size;
|
||||
var attributes = {'font-family': font.family, 'font-size': fontSize};
|
||||
var baseline = Math.round(fontSize * 0.85);
|
||||
var textY = Math.round(y1 - (fontSize / 2) + baseline);
|
||||
var textX = x1;
|
||||
if (align == 'center') {
|
||||
textX += Math.round(lineLength / 2);
|
||||
attributes['text-anchor'] = 'middle';
|
||||
} else if (align == 'right') {
|
||||
textX += lineLength;
|
||||
attributes['text-anchor'] = 'end';
|
||||
}
|
||||
attributes['x'] = textX;
|
||||
attributes['y'] = textY;
|
||||
if (font.bold) {
|
||||
attributes['font-weight'] = 'bold';
|
||||
}
|
||||
if (font.italic) {
|
||||
attributes['font-style'] = 'italic';
|
||||
}
|
||||
if (angle != 0) {
|
||||
attributes['transform'] = 'rotate(' + angle + ' ' + x1 + ' ' + y1 + ')';
|
||||
}
|
||||
|
||||
var element = this.createSvgElement_('text', attributes);
|
||||
element.appendChild(this.dom_.getDocument().createTextNode(text));
|
||||
|
||||
// Bypass a Firefox-Mac bug where text fill is ignored. If text has no stroke,
|
||||
// set a stroke, otherwise the text will not be visible.
|
||||
if (stroke == null && goog.userAgent.GECKO && goog.userAgent.MAC) {
|
||||
var color = 'black';
|
||||
// For solid fills, use the fill color
|
||||
if (fill instanceof goog.graphics.SolidFill) {
|
||||
color = fill.getColor();
|
||||
}
|
||||
stroke = new goog.graphics.Stroke(1, color);
|
||||
}
|
||||
|
||||
var wrapper = new goog.graphics.SvgTextElement(element, this, stroke, fill);
|
||||
this.append_(wrapper, opt_group);
|
||||
return wrapper;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Draw a path.
|
||||
*
|
||||
* @param {!goog.graphics.Path} path The path object to draw.
|
||||
* @param {goog.graphics.Stroke?} stroke Stroke object describing the
|
||||
* stroke.
|
||||
* @param {goog.graphics.Fill?} fill Fill object describing the fill.
|
||||
* @param {goog.graphics.GroupElement=} opt_group The group wrapper element
|
||||
* to append to. If not specified, appends to the main canvas.
|
||||
*
|
||||
* @return {goog.graphics.PathElement} The newly created element.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.SvgGraphics.prototype.drawPath = function(
|
||||
path, stroke, fill, opt_group) {
|
||||
|
||||
var element = this.createSvgElement_('path',
|
||||
{'d': goog.graphics.SvgGraphics.getSvgPath(path)});
|
||||
var wrapper = new goog.graphics.SvgPathElement(element, this, stroke, fill);
|
||||
this.append_(wrapper, opt_group);
|
||||
return wrapper;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string representation of a logical path suitable for use in
|
||||
* an SVG element.
|
||||
*
|
||||
* @param {goog.graphics.Path} path The logical path.
|
||||
* @return {string} The SVG path representation.
|
||||
* @suppress {deprecated} goog.graphics is deprecated.
|
||||
*/
|
||||
goog.graphics.SvgGraphics.getSvgPath = function(path) {
|
||||
var list = [];
|
||||
path.forEachSegment(function(segment, args) {
|
||||
switch (segment) {
|
||||
case goog.graphics.Path.Segment.MOVETO:
|
||||
list.push('M');
|
||||
Array.prototype.push.apply(list, args);
|
||||
break;
|
||||
case goog.graphics.Path.Segment.LINETO:
|
||||
list.push('L');
|
||||
Array.prototype.push.apply(list, args);
|
||||
break;
|
||||
case goog.graphics.Path.Segment.CURVETO:
|
||||
list.push('C');
|
||||
Array.prototype.push.apply(list, args);
|
||||
break;
|
||||
case goog.graphics.Path.Segment.ARCTO:
|
||||
var extent = args[3];
|
||||
var toAngle = args[2] + extent;
|
||||
list.push('A', args[0], args[1],
|
||||
0, Math.abs(extent) > 180 ? 1 : 0, extent > 0 ? 1 : 0,
|
||||
args[4], args[5]);
|
||||
break;
|
||||
case goog.graphics.Path.Segment.CLOSE:
|
||||
list.push('Z');
|
||||
break;
|
||||
}
|
||||
});
|
||||
return list.join(' ');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Create an empty group of drawing elements.
|
||||
*
|
||||
* @param {goog.graphics.GroupElement=} opt_group The group wrapper element
|
||||
* to append to. If not specified, appends to the main canvas.
|
||||
*
|
||||
* @return {goog.graphics.GroupElement} The newly created group.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.SvgGraphics.prototype.createGroup = function(opt_group) {
|
||||
var element = this.createSvgElement_('g');
|
||||
var parent = opt_group || this.canvasElement;
|
||||
parent.getElement().appendChild(element);
|
||||
return new goog.graphics.SvgGroupElement(element, this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Measure and return the width (in pixels) of a given text string.
|
||||
* Text measurement is needed to make sure a text can fit in the allocated area.
|
||||
* The way text length is measured is by writing it into a div that is after
|
||||
* the visible area, measure the div width, and immediatly erase the written
|
||||
* value.
|
||||
*
|
||||
* @param {string} text The text string to measure.
|
||||
* @param {goog.graphics.Font} font The font object describing the font style.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.SvgGraphics.prototype.getTextWidth = function(text, font) {
|
||||
// TODO(user) Implement
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds a defintion of an element to the global definitions.
|
||||
* @param {string} defKey This is a key that should be unique in a way that
|
||||
* if two definitions are equal the should have the same key.
|
||||
* @param {Element} defElement DOM element to add as a definition. It must
|
||||
* have an id attribute set.
|
||||
* @return {string} The assigned id of the defElement.
|
||||
*/
|
||||
goog.graphics.SvgGraphics.prototype.addDef = function(defKey, defElement) {
|
||||
if (defKey in this.defs_) {
|
||||
return this.defs_[defKey];
|
||||
}
|
||||
var id = goog.graphics.SvgGraphics.DEF_ID_PREFIX_ +
|
||||
goog.graphics.SvgGraphics.nextDefId_++;
|
||||
defElement.setAttribute('id', id);
|
||||
this.defs_[defKey] = id;
|
||||
|
||||
// Add the def defElement of the defs list.
|
||||
var defs = this.defsElement_;
|
||||
defs.appendChild(defElement);
|
||||
return id;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the id of a definition element.
|
||||
* @param {string} defKey This is a key that should be unique in a way that
|
||||
* if two definitions are equal the should have the same key.
|
||||
* @return {?string} The id of the found definition element or null if
|
||||
* not found.
|
||||
*/
|
||||
goog.graphics.SvgGraphics.prototype.getDef = function(defKey) {
|
||||
return defKey in this.defs_ ? this.defs_[defKey] : null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Removes a definition of an elemnt from the global definitions.
|
||||
* @param {string} defKey This is a key that should be unique in a way that
|
||||
* if two definitions are equal they should have the same key.
|
||||
*/
|
||||
goog.graphics.SvgGraphics.prototype.removeDef = function(defKey) {
|
||||
var id = this.getDef(defKey);
|
||||
if (id) {
|
||||
var element = this.dom_.getElement(id);
|
||||
this.defsElement_.removeChild(element);
|
||||
delete this.defs_[defKey];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.graphics.SvgGraphics.prototype.enterDocument = function() {
|
||||
var oldPixelSize = this.getPixelSize();
|
||||
goog.graphics.SvgGraphics.superClass_.enterDocument.call(this);
|
||||
|
||||
// Dispatch a resize if this is the first time the size value is accurate.
|
||||
if (!oldPixelSize) {
|
||||
this.dispatchEvent(goog.events.EventType.RESIZE);
|
||||
}
|
||||
|
||||
|
||||
// For percentage based heights, listen for changes to size.
|
||||
if (this.useManualViewbox_) {
|
||||
var width = this.width;
|
||||
var height = this.height;
|
||||
|
||||
if (typeof width == 'string' && width.indexOf('%') != -1 &&
|
||||
typeof height == 'string' && height.indexOf('%') != -1) {
|
||||
// SVG elements don't behave well with respect to size events, so we
|
||||
// resort to polling.
|
||||
this.handler_.listen(goog.graphics.SvgGraphics.getResizeCheckTimer_(),
|
||||
goog.Timer.TICK, this.updateManualViewBox_);
|
||||
}
|
||||
|
||||
this.updateManualViewBox_();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.graphics.SvgGraphics.prototype.exitDocument = function() {
|
||||
goog.graphics.SvgGraphics.superClass_.exitDocument.call(this);
|
||||
|
||||
// Stop polling.
|
||||
if (this.useManualViewbox_) {
|
||||
this.handler_.unlisten(goog.graphics.SvgGraphics.getResizeCheckTimer_(),
|
||||
goog.Timer.TICK, this.updateManualViewBox_);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Disposes of the component by removing event handlers, detacing DOM nodes from
|
||||
* the document body, and removing references to them.
|
||||
* @override
|
||||
* @protected
|
||||
*/
|
||||
goog.graphics.SvgGraphics.prototype.disposeInternal = function() {
|
||||
delete this.defs_;
|
||||
delete this.defsElement_;
|
||||
delete this.canvasElement;
|
||||
goog.graphics.SvgGraphics.superClass_.disposeInternal.call(this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The centralized resize checking timer.
|
||||
* @type {goog.Timer|undefined}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.SvgGraphics.resizeCheckTimer_;
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.Timer} The centralized timer object used for interval timing.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.SvgGraphics.getResizeCheckTimer_ = function() {
|
||||
if (!goog.graphics.SvgGraphics.resizeCheckTimer_) {
|
||||
goog.graphics.SvgGraphics.resizeCheckTimer_ = new goog.Timer(400);
|
||||
goog.graphics.SvgGraphics.resizeCheckTimer_.start();
|
||||
}
|
||||
|
||||
return /** @type {goog.Timer} */ (
|
||||
goog.graphics.SvgGraphics.resizeCheckTimer_);
|
||||
};
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.graphics.SvgGraphics.prototype.isDomClonable = function() {
|
||||
return true;
|
||||
};
|
||||
@@ -0,0 +1,56 @@
|
||||
// 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 A thin wrapper around the DOM element for text elements.
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
* @author yoah@google.com (Yoah Bar-David)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.TextElement');
|
||||
|
||||
goog.require('goog.graphics.StrokeAndFillElement');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Interface for a graphics text element.
|
||||
* You should not construct objects from this constructor. The graphics
|
||||
* will return an implementation of this interface for you.
|
||||
*
|
||||
* @param {Element} element The DOM element to wrap.
|
||||
* @param {goog.graphics.AbstractGraphics} graphics The graphics creating
|
||||
* this element.
|
||||
* @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.StrokeAndFillElement}
|
||||
* @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.
|
||||
*/
|
||||
goog.graphics.TextElement = function(element, graphics, stroke, fill) {
|
||||
goog.graphics.StrokeAndFillElement.call(this, element, graphics, stroke,
|
||||
fill);
|
||||
};
|
||||
goog.inherits(goog.graphics.TextElement, goog.graphics.StrokeAndFillElement);
|
||||
|
||||
|
||||
/**
|
||||
* Update the displayed text of the element.
|
||||
* @param {string} text The text to draw.
|
||||
*/
|
||||
goog.graphics.TextElement.prototype.setText = goog.abstractMethod;
|
||||
@@ -0,0 +1,433 @@
|
||||
// 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 Thin wrappers around the DOM element returned from
|
||||
* the different draw methods of the graphics. This is the VML implementation.
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
* @author yoah@google.com (Yoah Bar-David)
|
||||
*/
|
||||
|
||||
goog.provide('goog.graphics.VmlEllipseElement');
|
||||
goog.provide('goog.graphics.VmlGroupElement');
|
||||
goog.provide('goog.graphics.VmlImageElement');
|
||||
goog.provide('goog.graphics.VmlPathElement');
|
||||
goog.provide('goog.graphics.VmlRectElement');
|
||||
goog.provide('goog.graphics.VmlTextElement');
|
||||
|
||||
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.graphics.EllipseElement');
|
||||
goog.require('goog.graphics.GroupElement');
|
||||
goog.require('goog.graphics.ImageElement');
|
||||
goog.require('goog.graphics.PathElement');
|
||||
goog.require('goog.graphics.RectElement');
|
||||
goog.require('goog.graphics.TextElement');
|
||||
|
||||
|
||||
/**
|
||||
* Returns the VML element corresponding to this object. This method is added
|
||||
* to several classes below. Note that the return value of this method may
|
||||
* change frequently in IE8, so it should not be cached externally.
|
||||
* @return {Element} The VML element corresponding to this object.
|
||||
* @this {goog.graphics.VmlGroupElement|goog.graphics.VmlEllipseElement|
|
||||
* goog.graphics.VmlRectElement|goog.graphics.VmlPathElement|
|
||||
* goog.graphics.VmlTextElement|goog.graphics.VmlImageElement}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.vmlGetElement_ = function() {
|
||||
this.element_ = this.getGraphics().getVmlElement(this.id_) || this.element_;
|
||||
return this.element_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Thin wrapper for VML group elements.
|
||||
* 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 {Element} element The DOM element to wrap.
|
||||
* @param {goog.graphics.VmlGraphics} 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.
|
||||
*/
|
||||
goog.graphics.VmlGroupElement = function(element, graphics) {
|
||||
this.id_ = element.id;
|
||||
goog.graphics.GroupElement.call(this, element, graphics);
|
||||
};
|
||||
goog.inherits(goog.graphics.VmlGroupElement, goog.graphics.GroupElement);
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.graphics.VmlGroupElement.prototype.getElement =
|
||||
goog.graphics.vmlGetElement_;
|
||||
|
||||
|
||||
/**
|
||||
* Remove all drawing elements from the group.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.VmlGroupElement.prototype.clear = function() {
|
||||
goog.dom.removeChildren(this.getElement());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} True if this group is the root canvas element.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.VmlGroupElement.prototype.isRootElement_ = function() {
|
||||
return this.getGraphics().getCanvasElement() == this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 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.VmlGroupElement.prototype.setSize = function(width, height) {
|
||||
var element = this.getElement();
|
||||
|
||||
var style = element.style;
|
||||
style.width = /** @suppress {missingRequire} */ (
|
||||
goog.graphics.VmlGraphics.toSizePx(width));
|
||||
style.height = /** @suppress {missingRequire} */ (
|
||||
goog.graphics.VmlGraphics.toSizePx(height));
|
||||
|
||||
element.coordsize = /** @suppress {missingRequire} */
|
||||
goog.graphics.VmlGraphics.toSizeCoord(width) +
|
||||
' ' +
|
||||
/** @suppress {missingRequire} */
|
||||
goog.graphics.VmlGraphics.toSizeCoord(height);
|
||||
|
||||
// Don't overwrite the root element's origin.
|
||||
if (!this.isRootElement_()) {
|
||||
element.coordorigin = '0 0';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Thin wrapper for VML 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.VmlGraphics} 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}
|
||||
* @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.
|
||||
*/
|
||||
goog.graphics.VmlEllipseElement = function(element, graphics,
|
||||
cx, cy, rx, ry, stroke, fill) {
|
||||
this.id_ = element.id;
|
||||
|
||||
goog.graphics.EllipseElement.call(this, element, graphics, stroke, fill);
|
||||
|
||||
// Store center and radius for future calls to setRadius or setCenter.
|
||||
|
||||
/**
|
||||
* X coordinate of the ellipse center.
|
||||
* @type {number}
|
||||
*/
|
||||
this.cx = cx;
|
||||
|
||||
|
||||
/**
|
||||
* Y coordinate of the ellipse center.
|
||||
* @type {number}
|
||||
*/
|
||||
this.cy = cy;
|
||||
|
||||
|
||||
/**
|
||||
* Radius length for the x-axis.
|
||||
* @type {number}
|
||||
*/
|
||||
this.rx = rx;
|
||||
|
||||
|
||||
/**
|
||||
* Radius length for the y-axis.
|
||||
* @type {number}
|
||||
*/
|
||||
this.ry = ry;
|
||||
};
|
||||
goog.inherits(goog.graphics.VmlEllipseElement, goog.graphics.EllipseElement);
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.graphics.VmlEllipseElement.prototype.getElement =
|
||||
goog.graphics.vmlGetElement_;
|
||||
|
||||
|
||||
/**
|
||||
* Update the center point of the ellipse.
|
||||
* @param {number} cx Center X coordinate.
|
||||
* @param {number} cy Center Y coordinate.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.VmlEllipseElement.prototype.setCenter = function(cx, cy) {
|
||||
this.cx = cx;
|
||||
this.cy = cy;
|
||||
/** @suppress {missingRequire} */
|
||||
goog.graphics.VmlGraphics.setPositionAndSize(this.getElement(),
|
||||
cx - this.rx, cy - this.ry, this.rx * 2, this.ry * 2);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update the radius of the ellipse.
|
||||
* @param {number} rx Center X coordinate.
|
||||
* @param {number} ry Center Y coordinate.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.VmlEllipseElement.prototype.setRadius = function(rx, ry) {
|
||||
this.rx = rx;
|
||||
this.ry = ry;
|
||||
/** @suppress {missingRequire} */
|
||||
goog.graphics.VmlGraphics.setPositionAndSize(this.getElement(),
|
||||
this.cx - rx, this.cy - ry, rx * 2, ry * 2);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Thin wrapper for VML 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.VmlGraphics} graphics The graphics creating
|
||||
* this element.
|
||||
* @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}
|
||||
* @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.
|
||||
*/
|
||||
goog.graphics.VmlRectElement = function(element, graphics, stroke, fill) {
|
||||
this.id_ = element.id;
|
||||
goog.graphics.RectElement.call(this, element, graphics, stroke, fill);
|
||||
};
|
||||
goog.inherits(goog.graphics.VmlRectElement, goog.graphics.RectElement);
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.graphics.VmlRectElement.prototype.getElement =
|
||||
goog.graphics.vmlGetElement_;
|
||||
|
||||
|
||||
/**
|
||||
* Update the position of the rectangle.
|
||||
* @param {number} x X coordinate (left).
|
||||
* @param {number} y Y coordinate (top).
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.VmlRectElement.prototype.setPosition = function(x, y) {
|
||||
var style = this.getElement().style;
|
||||
|
||||
style.left = /** @suppress {missingRequire} */
|
||||
goog.graphics.VmlGraphics.toPosPx(x);
|
||||
style.top = /** @suppress {missingRequire} */
|
||||
goog.graphics.VmlGraphics.toPosPx(y);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update the size of the rectangle.
|
||||
* @param {number} width Width of rectangle.
|
||||
* @param {number} height Height of rectangle.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.VmlRectElement.prototype.setSize = function(width, height) {
|
||||
var style = this.getElement().style;
|
||||
style.width = /** @suppress {missingRequire} */
|
||||
goog.graphics.VmlGraphics.toSizePx(width);
|
||||
style.height = /** @suppress {missingRequire} */
|
||||
goog.graphics.VmlGraphics.toSizePx(height);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Thin wrapper for VML 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.VmlGraphics} graphics The graphics creating
|
||||
* this element.
|
||||
* @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}
|
||||
* @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.
|
||||
*/
|
||||
goog.graphics.VmlPathElement = function(element, graphics, stroke, fill) {
|
||||
this.id_ = element.id;
|
||||
goog.graphics.PathElement.call(this, element, graphics, stroke, fill);
|
||||
};
|
||||
goog.inherits(goog.graphics.VmlPathElement, goog.graphics.PathElement);
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.graphics.VmlPathElement.prototype.getElement =
|
||||
goog.graphics.vmlGetElement_;
|
||||
|
||||
|
||||
/**
|
||||
* Update the underlying path.
|
||||
* @param {!goog.graphics.Path} path The path object to draw.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.VmlPathElement.prototype.setPath = function(path) {
|
||||
/** @suppress {missingRequire} */
|
||||
goog.graphics.VmlGraphics.setAttribute(
|
||||
this.getElement(), 'path',
|
||||
/** @suppress {missingRequire} */
|
||||
goog.graphics.VmlGraphics.getVmlPath(path));
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Thin wrapper for VML 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 {Element} element The DOM element to wrap.
|
||||
* @param {goog.graphics.VmlGraphics} graphics The graphics creating
|
||||
* this element.
|
||||
* @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}
|
||||
* @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.
|
||||
*/
|
||||
goog.graphics.VmlTextElement = function(element, graphics, stroke, fill) {
|
||||
this.id_ = element.id;
|
||||
goog.graphics.TextElement.call(this, element, graphics, stroke, fill);
|
||||
};
|
||||
goog.inherits(goog.graphics.VmlTextElement, goog.graphics.TextElement);
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.graphics.VmlTextElement.prototype.getElement =
|
||||
goog.graphics.vmlGetElement_;
|
||||
|
||||
|
||||
/**
|
||||
* Update the displayed text of the element.
|
||||
* @param {string} text The text to draw.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.VmlTextElement.prototype.setText = function(text) {
|
||||
/** @suppress {missingRequire} */
|
||||
goog.graphics.VmlGraphics.setAttribute(this.getElement().childNodes[1],
|
||||
'string', text);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Thin wrapper for VML 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.VmlGraphics} graphics The graphics creating
|
||||
* this element.
|
||||
* @constructor
|
||||
* @extends {goog.graphics.ImageElement}
|
||||
* @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.
|
||||
*/
|
||||
goog.graphics.VmlImageElement = function(element, graphics) {
|
||||
this.id_ = element.id;
|
||||
goog.graphics.ImageElement.call(this, element, graphics);
|
||||
};
|
||||
goog.inherits(goog.graphics.VmlImageElement, goog.graphics.ImageElement);
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.graphics.VmlImageElement.prototype.getElement =
|
||||
goog.graphics.vmlGetElement_;
|
||||
|
||||
|
||||
/**
|
||||
* Update the position of the image.
|
||||
* @param {number} x X coordinate (left).
|
||||
* @param {number} y Y coordinate (top).
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.VmlImageElement.prototype.setPosition = function(x, y) {
|
||||
var style = this.getElement().style;
|
||||
|
||||
style.left = /** @suppress {missingRequire} */
|
||||
goog.graphics.VmlGraphics.toPosPx(x);
|
||||
style.top = /** @suppress {missingRequire} */
|
||||
goog.graphics.VmlGraphics.toPosPx(y);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update the size of the image.
|
||||
* @param {number} width Width of rectangle.
|
||||
* @param {number} height Height of rectangle.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.VmlImageElement.prototype.setSize = function(width, height) {
|
||||
var style = this.getElement().style;
|
||||
style.width = /** @suppress {missingRequire} */
|
||||
goog.graphics.VmlGraphics.toPosPx(width);
|
||||
style.height = /** @suppress {missingRequire} */
|
||||
goog.graphics.VmlGraphics.toPosPx(height);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update the source of the image.
|
||||
* @param {string} src Source of the image.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.VmlImageElement.prototype.setSource = function(src) {
|
||||
/** @suppress {missingRequire} */
|
||||
goog.graphics.VmlGraphics.setAttribute(this.getElement(), 'src', src);
|
||||
};
|
||||
@@ -0,0 +1,893 @@
|
||||
// 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 VmlGraphics sub class that uses VML to draw the graphics.
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
* @author yoah@google.com (Yoah Bar-David)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.VmlGraphics');
|
||||
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.EventHandler');
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('goog.graphics.AbstractGraphics');
|
||||
goog.require('goog.graphics.LinearGradient');
|
||||
goog.require('goog.graphics.Path');
|
||||
goog.require('goog.graphics.SolidFill');
|
||||
goog.require('goog.graphics.VmlEllipseElement');
|
||||
goog.require('goog.graphics.VmlGroupElement');
|
||||
goog.require('goog.graphics.VmlImageElement');
|
||||
goog.require('goog.graphics.VmlPathElement');
|
||||
goog.require('goog.graphics.VmlRectElement');
|
||||
goog.require('goog.graphics.VmlTextElement');
|
||||
goog.require('goog.math');
|
||||
goog.require('goog.math.Size');
|
||||
goog.require('goog.string');
|
||||
goog.require('goog.style');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A Graphics implementation for drawing using VML.
|
||||
* @param {string|number} width The (non-zero) width in pixels. Strings
|
||||
* expressing percentages of parent with (e.g. '80%') are also accepted.
|
||||
* @param {string|number} height The (non-zero) height in pixels. Strings
|
||||
* expressing percentages of parent with (e.g. '80%') are also accepted.
|
||||
* @param {?number=} opt_coordWidth The coordinate width - if
|
||||
* omitted or null, defaults to same as width.
|
||||
* @param {?number=} opt_coordHeight The coordinate height - if
|
||||
* omitted or null, defaults to same as height.
|
||||
* @param {goog.dom.DomHelper=} opt_domHelper The DOM helper object for the
|
||||
* document we want to render in.
|
||||
* @constructor
|
||||
* @extends {goog.graphics.AbstractGraphics}
|
||||
* @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.
|
||||
*/
|
||||
goog.graphics.VmlGraphics = function(width, height,
|
||||
opt_coordWidth, opt_coordHeight,
|
||||
opt_domHelper) {
|
||||
goog.graphics.AbstractGraphics.call(this, width, height,
|
||||
opt_coordWidth, opt_coordHeight,
|
||||
opt_domHelper);
|
||||
this.handler_ = new goog.events.EventHandler(this);
|
||||
};
|
||||
goog.inherits(goog.graphics.VmlGraphics, goog.graphics.AbstractGraphics);
|
||||
|
||||
|
||||
/**
|
||||
* The prefix to use for VML elements
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
goog.graphics.VmlGraphics.VML_PREFIX_ = 'g_vml_';
|
||||
|
||||
|
||||
/**
|
||||
* The VML namespace URN
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
goog.graphics.VmlGraphics.VML_NS_ = 'urn:schemas-microsoft-com:vml';
|
||||
|
||||
|
||||
/**
|
||||
* The VML behavior URL.
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
goog.graphics.VmlGraphics.VML_IMPORT_ = '#default#VML';
|
||||
|
||||
|
||||
/**
|
||||
* Whether the document is using IE8 standards mode, and therefore needs hacks.
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.graphics.VmlGraphics.IE8_MODE_ = document.documentMode &&
|
||||
document.documentMode >= 8;
|
||||
|
||||
|
||||
/**
|
||||
* The coordinate multiplier to allow sub-pixel rendering
|
||||
* @type {number}
|
||||
*/
|
||||
goog.graphics.VmlGraphics.COORD_MULTIPLIER = 100;
|
||||
|
||||
|
||||
/**
|
||||
* Converts the given size to a css size. If it is a percentage, leaves it
|
||||
* alone. Otherwise assumes px.
|
||||
*
|
||||
* @param {number|string} size The size to use.
|
||||
* @return {string} The position adjusted for COORD_MULTIPLIER.
|
||||
*/
|
||||
goog.graphics.VmlGraphics.toCssSize = function(size) {
|
||||
return goog.isString(size) && goog.string.endsWith(size, '%') ?
|
||||
size : parseFloat(size.toString()) + 'px';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Multiplies positioning coordinates by COORD_MULTIPLIER to allow sub-pixel
|
||||
* coordinates. Also adds a half pixel offset to match SVG.
|
||||
*
|
||||
* This function is internal for the VML supporting classes, and
|
||||
* should not be used externally.
|
||||
*
|
||||
* @param {number|string} number A position in pixels.
|
||||
* @return {number} The position adjusted for COORD_MULTIPLIER.
|
||||
*/
|
||||
goog.graphics.VmlGraphics.toPosCoord = function(number) {
|
||||
return Math.round((parseFloat(number.toString()) - 0.5) *
|
||||
goog.graphics.VmlGraphics.COORD_MULTIPLIER);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Add a "px" suffix to a number of pixels, and multiplies all coordinates by
|
||||
* COORD_MULTIPLIER to allow sub-pixel coordinates.
|
||||
*
|
||||
* This function is internal for the VML supporting classes, and
|
||||
* should not be used externally.
|
||||
*
|
||||
* @param {number|string} number A position in pixels.
|
||||
* @return {string} The position with suffix 'px'.
|
||||
*/
|
||||
goog.graphics.VmlGraphics.toPosPx = function(number) {
|
||||
return goog.graphics.VmlGraphics.toPosCoord(number) + 'px';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Multiplies the width or height coordinate by COORD_MULTIPLIER to allow
|
||||
* sub-pixel coordinates.
|
||||
*
|
||||
* This function is internal for the VML supporting classes, and
|
||||
* should not be used externally.
|
||||
*
|
||||
* @param {string|number} number A size in units.
|
||||
* @return {number} The size multiplied by the correct factor.
|
||||
*/
|
||||
goog.graphics.VmlGraphics.toSizeCoord = function(number) {
|
||||
return Math.round(parseFloat(number.toString()) *
|
||||
goog.graphics.VmlGraphics.COORD_MULTIPLIER);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Add a "px" suffix to a number of pixels, and multiplies all coordinates by
|
||||
* COORD_MULTIPLIER to allow sub-pixel coordinates.
|
||||
*
|
||||
* This function is internal for the VML supporting classes, and
|
||||
* should not be used externally.
|
||||
*
|
||||
* @param {number|string} number A size in pixels.
|
||||
* @return {string} The size with suffix 'px'.
|
||||
*/
|
||||
goog.graphics.VmlGraphics.toSizePx = function(number) {
|
||||
return goog.graphics.VmlGraphics.toSizeCoord(number) + 'px';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets an attribute on the given VML element, in the way best suited to the
|
||||
* current version of IE. Should only be used in the goog.graphics package.
|
||||
* @param {Element} element The element to set an attribute
|
||||
* on.
|
||||
* @param {string} name The name of the attribute to set.
|
||||
* @param {string} value The value to set it to.
|
||||
*/
|
||||
goog.graphics.VmlGraphics.setAttribute = function(element, name, value) {
|
||||
if (goog.graphics.VmlGraphics.IE8_MODE_) {
|
||||
element[name] = value;
|
||||
} else {
|
||||
element.setAttribute(name, value);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Event handler.
|
||||
* @type {goog.events.EventHandler}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.VmlGraphics.prototype.handler_;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a VML element. Used internally and by different VML classes.
|
||||
* @param {string} tagName The type of element to create.
|
||||
* @return {Element} The created element.
|
||||
*/
|
||||
goog.graphics.VmlGraphics.prototype.createVmlElement = function(tagName) {
|
||||
var element =
|
||||
this.dom_.createElement(goog.graphics.VmlGraphics.VML_PREFIX_ + ':' +
|
||||
tagName);
|
||||
element.id = goog.string.createUniqueString();
|
||||
return element;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the VML element with the given id that is a child of this graphics
|
||||
* object.
|
||||
* Should be considered package private, and not used externally.
|
||||
* @param {string} id The element id to find.
|
||||
* @return {Element} The element with the given id, or null if none is found.
|
||||
*/
|
||||
goog.graphics.VmlGraphics.prototype.getVmlElement = function(id) {
|
||||
return this.dom_.getElement(id);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Resets the graphics so they will display properly on IE8. Noop in older
|
||||
* versions.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.VmlGraphics.prototype.updateGraphics_ = function() {
|
||||
if (goog.graphics.VmlGraphics.IE8_MODE_ && this.isInDocument()) {
|
||||
this.getElement().innerHTML = this.getElement().innerHTML;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Appends an element.
|
||||
*
|
||||
* @param {goog.graphics.Element} element The element wrapper.
|
||||
* @param {goog.graphics.GroupElement=} opt_group The group wrapper element
|
||||
* to append to. If not specified, appends to the main canvas.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.VmlGraphics.prototype.append_ = function(element, opt_group) {
|
||||
var parent = opt_group || this.canvasElement;
|
||||
parent.getElement().appendChild(element.getElement());
|
||||
this.updateGraphics_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the fill for the given element.
|
||||
* @param {goog.graphics.StrokeAndFillElement} element The element wrapper.
|
||||
* @param {goog.graphics.Fill?} fill The fill object.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.VmlGraphics.prototype.setElementFill = function(element, fill) {
|
||||
var vmlElement = element.getElement();
|
||||
this.removeFill(vmlElement);
|
||||
if (fill instanceof goog.graphics.SolidFill) {
|
||||
// NOTE(arv): VML does not understand 'transparent' so hard code support
|
||||
// for it.
|
||||
if (fill.getColor() == 'transparent') {
|
||||
vmlElement.filled = false;
|
||||
} else if (fill.getOpacity() != 1) {
|
||||
vmlElement.filled = true;
|
||||
// Set opacity (number 0-1 is translated to percent)
|
||||
var fillNode = this.createVmlElement('fill');
|
||||
fillNode.opacity = Math.round(fill.getOpacity() * 100) + '%';
|
||||
fillNode.color = fill.getColor();
|
||||
vmlElement.appendChild(fillNode);
|
||||
} else {
|
||||
vmlElement.filled = true;
|
||||
vmlElement.fillcolor = fill.getColor();
|
||||
}
|
||||
} else if (fill instanceof goog.graphics.LinearGradient) {
|
||||
vmlElement.filled = true;
|
||||
// Add a 'fill' element
|
||||
var gradient = this.createVmlElement('fill');
|
||||
gradient.color = fill.getColor1();
|
||||
gradient.color2 = fill.getColor2();
|
||||
if (goog.isNumber(fill.getOpacity1())) {
|
||||
gradient.opacity = fill.getOpacity1();
|
||||
}
|
||||
if (goog.isNumber(fill.getOpacity2())) {
|
||||
gradient.opacity2 = fill.getOpacity2();
|
||||
}
|
||||
var angle = goog.math.angle(fill.getX1(), fill.getY1(),
|
||||
fill.getX2(), fill.getY2());
|
||||
// Our angles start from 0 to the right, and grow clockwise.
|
||||
// MSIE starts from 0 to top, and grows anti-clockwise.
|
||||
angle = Math.round(goog.math.standardAngle(270 - angle));
|
||||
gradient.angle = angle;
|
||||
gradient.type = 'gradient';
|
||||
vmlElement.appendChild(gradient);
|
||||
} else {
|
||||
vmlElement.filled = false;
|
||||
}
|
||||
this.updateGraphics_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the stroke for the given element.
|
||||
* @param {goog.graphics.StrokeAndFillElement} element The element wrapper.
|
||||
* @param {goog.graphics.Stroke?} stroke The stroke object.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.VmlGraphics.prototype.setElementStroke = function(element,
|
||||
stroke) {
|
||||
var vmlElement = element.getElement();
|
||||
if (stroke) {
|
||||
vmlElement.stroked = true;
|
||||
|
||||
var width = stroke.getWidth();
|
||||
if (goog.isString(width) && width.indexOf('px') == -1) {
|
||||
width = parseFloat(width);
|
||||
} else {
|
||||
width = width * this.getPixelScaleX();
|
||||
}
|
||||
|
||||
var strokeElement = vmlElement.getElementsByTagName('stroke')[0];
|
||||
if (width < 1) {
|
||||
strokeElement = strokeElement || this.createVmlElement('stroke');
|
||||
strokeElement.opacity = width;
|
||||
strokeElement.weight = '1px';
|
||||
strokeElement.color = stroke.getColor();
|
||||
vmlElement.appendChild(strokeElement);
|
||||
} else {
|
||||
if (strokeElement) {
|
||||
vmlElement.removeChild(strokeElement);
|
||||
}
|
||||
vmlElement.strokecolor = stroke.getColor();
|
||||
vmlElement.strokeweight = width + 'px';
|
||||
}
|
||||
} else {
|
||||
vmlElement.stroked = false;
|
||||
}
|
||||
this.updateGraphics_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the transformation of an element.
|
||||
* @param {goog.graphics.Element} element The element wrapper.
|
||||
* @param {number} x The x coordinate of the translation transform.
|
||||
* @param {number} y The y coordinate of the translation transform.
|
||||
* @param {number} angle The angle of the rotation transform.
|
||||
* @param {number} centerX The horizontal center of the rotation transform.
|
||||
* @param {number} centerY The vertical center of the rotation transform.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.VmlGraphics.prototype.setElementTransform = function(element, x,
|
||||
y, angle, centerX, centerY) {
|
||||
var el = element.getElement();
|
||||
|
||||
el.style.left = goog.graphics.VmlGraphics.toPosPx(x);
|
||||
el.style.top = goog.graphics.VmlGraphics.toPosPx(y);
|
||||
if (angle || el.rotation) {
|
||||
el.rotation = angle;
|
||||
el.coordsize = goog.graphics.VmlGraphics.toSizeCoord(centerX * 2) + ' ' +
|
||||
goog.graphics.VmlGraphics.toSizeCoord(centerY * 2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Removes the fill information from a dom element.
|
||||
* @param {Element} element DOM element.
|
||||
*/
|
||||
goog.graphics.VmlGraphics.prototype.removeFill = function(element) {
|
||||
element.fillcolor = '';
|
||||
var v = element.childNodes.length;
|
||||
for (var i = 0; i < element.childNodes.length; i++) {
|
||||
var child = element.childNodes[i];
|
||||
if (child.tagName == 'fill') {
|
||||
element.removeChild(child);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set top, left, width and height for an element.
|
||||
* This function is internal for the VML supporting classes, and
|
||||
* should not be used externally.
|
||||
*
|
||||
* @param {Element} element DOM element.
|
||||
* @param {number} left Left ccordinate in pixels.
|
||||
* @param {number} top Top ccordinate in pixels.
|
||||
* @param {number} width Width in pixels.
|
||||
* @param {number} height Height in pixels.
|
||||
*/
|
||||
goog.graphics.VmlGraphics.setPositionAndSize = function(
|
||||
element, left, top, width, height) {
|
||||
var style = element.style;
|
||||
style.position = 'absolute';
|
||||
style.left = goog.graphics.VmlGraphics.toPosPx(left);
|
||||
style.top = goog.graphics.VmlGraphics.toPosPx(top);
|
||||
style.width = goog.graphics.VmlGraphics.toSizePx(width);
|
||||
style.height = goog.graphics.VmlGraphics.toSizePx(height);
|
||||
|
||||
if (element.tagName == 'shape') {
|
||||
element.coordsize = goog.graphics.VmlGraphics.toSizeCoord(width) + ' ' +
|
||||
goog.graphics.VmlGraphics.toSizeCoord(height);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates an element spanning the surface.
|
||||
*
|
||||
* @param {string} type The type of element to create.
|
||||
* @return {Element} The created, positioned, and sized element.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.VmlGraphics.prototype.createFullSizeElement_ = function(type) {
|
||||
var element = this.createVmlElement(type);
|
||||
var size = this.getCoordSize();
|
||||
goog.graphics.VmlGraphics.setPositionAndSize(element, 0, 0, size.width,
|
||||
size.height);
|
||||
return element;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* IE magic - if this "no-op" line is not here, the if statement below will
|
||||
* fail intermittently. The eval is used to prevent the JsCompiler from
|
||||
* stripping this piece of code, which it quite reasonably thinks is doing
|
||||
* nothing. Put it in try-catch block to prevent "Unspecified Error" when
|
||||
* this statement is executed in a defer JS in IE.
|
||||
* More info here:
|
||||
* http://www.mail-archive.com/users@openlayers.org/msg01838.html
|
||||
*/
|
||||
try {
|
||||
eval('document.namespaces');
|
||||
} catch (ex) {}
|
||||
|
||||
|
||||
/**
|
||||
* Creates the DOM representation of the graphics area.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.VmlGraphics.prototype.createDom = function() {
|
||||
var doc = this.dom_.getDocument();
|
||||
|
||||
// Add the namespace.
|
||||
if (!doc.namespaces[goog.graphics.VmlGraphics.VML_PREFIX_]) {
|
||||
if (goog.graphics.VmlGraphics.IE8_MODE_) {
|
||||
doc.namespaces.add(goog.graphics.VmlGraphics.VML_PREFIX_,
|
||||
goog.graphics.VmlGraphics.VML_NS_,
|
||||
goog.graphics.VmlGraphics.VML_IMPORT_);
|
||||
} else {
|
||||
doc.namespaces.add(goog.graphics.VmlGraphics.VML_PREFIX_,
|
||||
goog.graphics.VmlGraphics.VML_NS_);
|
||||
}
|
||||
|
||||
// We assume that we only need to add the CSS if the namespace was not
|
||||
// present
|
||||
var ss = doc.createStyleSheet();
|
||||
ss.cssText = goog.graphics.VmlGraphics.VML_PREFIX_ + '\\:*' +
|
||||
'{behavior:url(#default#VML)}';
|
||||
}
|
||||
|
||||
// Outer a DIV with overflow hidden for clipping.
|
||||
// All inner elements are absolutly positioned on-top of this div.
|
||||
var pixelWidth = this.width;
|
||||
var pixelHeight = this.height;
|
||||
var divElement = this.dom_.createDom('div', {
|
||||
'style': 'overflow:hidden;position:relative;width:' +
|
||||
goog.graphics.VmlGraphics.toCssSize(pixelWidth) + ';height:' +
|
||||
goog.graphics.VmlGraphics.toCssSize(pixelHeight)
|
||||
});
|
||||
|
||||
this.setElementInternal(divElement);
|
||||
|
||||
var group = this.createVmlElement('group');
|
||||
var style = group.style;
|
||||
|
||||
style.position = 'absolute';
|
||||
style.left = style.top = 0;
|
||||
style.width = this.width;
|
||||
style.height = this.height;
|
||||
if (this.coordWidth) {
|
||||
group.coordsize =
|
||||
goog.graphics.VmlGraphics.toSizeCoord(this.coordWidth) + ' ' +
|
||||
goog.graphics.VmlGraphics.toSizeCoord(
|
||||
/** @type {number} */ (this.coordHeight));
|
||||
} else {
|
||||
group.coordsize = goog.graphics.VmlGraphics.toSizeCoord(pixelWidth) + ' ' +
|
||||
goog.graphics.VmlGraphics.toSizeCoord(pixelHeight);
|
||||
}
|
||||
|
||||
if (goog.isDef(this.coordLeft)) {
|
||||
group.coordorigin = goog.graphics.VmlGraphics.toSizeCoord(this.coordLeft) +
|
||||
' ' + goog.graphics.VmlGraphics.toSizeCoord(this.coordTop);
|
||||
} else {
|
||||
group.coordorigin = '0 0';
|
||||
}
|
||||
divElement.appendChild(group);
|
||||
|
||||
this.canvasElement = new goog.graphics.VmlGroupElement(group, this);
|
||||
|
||||
goog.events.listen(divElement, goog.events.EventType.RESIZE, goog.bind(
|
||||
this.handleContainerResize_, this));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Changes the canvas element size to match the container element size.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.VmlGraphics.prototype.handleContainerResize_ = function() {
|
||||
var size = goog.style.getSize(this.getElement());
|
||||
var style = this.canvasElement.getElement().style;
|
||||
|
||||
if (size.width) {
|
||||
style.width = size.width + 'px';
|
||||
style.height = size.height + 'px';
|
||||
} else {
|
||||
var current = this.getElement();
|
||||
while (current && current.currentStyle &&
|
||||
current.currentStyle.display != 'none') {
|
||||
current = current.parentNode;
|
||||
}
|
||||
if (current && current.currentStyle) {
|
||||
this.handler_.listen(current, 'propertychange',
|
||||
this.handleContainerResize_);
|
||||
}
|
||||
}
|
||||
|
||||
this.dispatchEvent(goog.events.EventType.RESIZE);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handle property changes on hidden ancestors.
|
||||
* @param {goog.events.BrowserEvent} e The browser event.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.VmlGraphics.prototype.handlePropertyChange_ = function(e) {
|
||||
var prop = e.getBrowserEvent().propertyName;
|
||||
if (prop == 'display' || prop == 'className') {
|
||||
this.handler_.unlisten(/** @type {Element} */(e.target),
|
||||
'propertychange', this.handlePropertyChange_);
|
||||
this.handleContainerResize_();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Changes the coordinate system position.
|
||||
* @param {number} left The coordinate system left bound.
|
||||
* @param {number} top The coordinate system top bound.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.VmlGraphics.prototype.setCoordOrigin = function(left, top) {
|
||||
this.coordLeft = left;
|
||||
this.coordTop = top;
|
||||
|
||||
this.canvasElement.getElement().coordorigin =
|
||||
goog.graphics.VmlGraphics.toSizeCoord(this.coordLeft) + ' ' +
|
||||
goog.graphics.VmlGraphics.toSizeCoord(this.coordTop);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Changes the coordinate size.
|
||||
* @param {number} coordWidth The coordinate width.
|
||||
* @param {number} coordHeight The coordinate height.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.VmlGraphics.prototype.setCoordSize = function(coordWidth,
|
||||
coordHeight) {
|
||||
goog.graphics.VmlGraphics.superClass_.setCoordSize.apply(this, arguments);
|
||||
|
||||
this.canvasElement.getElement().coordsize =
|
||||
goog.graphics.VmlGraphics.toSizeCoord(coordWidth) + ' ' +
|
||||
goog.graphics.VmlGraphics.toSizeCoord(coordHeight);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Change the size of the canvas.
|
||||
* @param {number} pixelWidth The width in pixels.
|
||||
* @param {number} pixelHeight The height in pixels.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.VmlGraphics.prototype.setSize = function(pixelWidth,
|
||||
pixelHeight) {
|
||||
goog.style.setSize(this.getElement(), pixelWidth, pixelHeight);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.math.Size} Returns the number of pixels spanned by the surface.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.VmlGraphics.prototype.getPixelSize = function() {
|
||||
var el = this.getElement();
|
||||
// The following relies on the fact that the size can never be 0.
|
||||
return new goog.math.Size(el.style.pixelWidth || el.offsetWidth || 1,
|
||||
el.style.pixelHeight || el.offsetHeight || 1);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Remove all drawing elements from the graphics.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.VmlGraphics.prototype.clear = function() {
|
||||
this.canvasElement.clear();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Draw an ellipse.
|
||||
*
|
||||
* @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 Stroke object describing the
|
||||
* stroke.
|
||||
* @param {goog.graphics.Fill?} fill Fill object describing the fill.
|
||||
* @param {goog.graphics.GroupElement=} opt_group The group wrapper element
|
||||
* to append to. If not specified, appends to the main canvas.
|
||||
*
|
||||
* @return {goog.graphics.EllipseElement} The newly created element.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.VmlGraphics.prototype.drawEllipse = function(cx, cy, rx, ry,
|
||||
stroke, fill, opt_group) {
|
||||
var element = this.createVmlElement('oval');
|
||||
goog.graphics.VmlGraphics.setPositionAndSize(element, cx - rx, cy - ry,
|
||||
rx * 2, ry * 2);
|
||||
var wrapper = new goog.graphics.VmlEllipseElement(element, this,
|
||||
cx, cy, rx, ry, stroke, fill);
|
||||
this.append_(wrapper, opt_group);
|
||||
return wrapper;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Draw a rectangle.
|
||||
*
|
||||
* @param {number} x X coordinate (left).
|
||||
* @param {number} y Y coordinate (top).
|
||||
* @param {number} width Width of rectangle.
|
||||
* @param {number} height Height of rectangle.
|
||||
* @param {goog.graphics.Stroke?} stroke Stroke object describing the
|
||||
* stroke.
|
||||
* @param {goog.graphics.Fill?} fill Fill object describing the fill.
|
||||
* @param {goog.graphics.GroupElement=} opt_group The group wrapper element
|
||||
* to append to. If not specified, appends to the main canvas.
|
||||
*
|
||||
* @return {goog.graphics.RectElement} The newly created element.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.VmlGraphics.prototype.drawRect = function(x, y, width, height,
|
||||
stroke, fill, opt_group) {
|
||||
var element = this.createVmlElement('rect');
|
||||
goog.graphics.VmlGraphics.setPositionAndSize(element, x, y, width, height);
|
||||
var wrapper = new goog.graphics.VmlRectElement(element, this, stroke, fill);
|
||||
this.append_(wrapper, opt_group);
|
||||
return wrapper;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Draw an image.
|
||||
*
|
||||
* @param {number} x X coordinate (left).
|
||||
* @param {number} y Y coordinate (top).
|
||||
* @param {number} width Width of image.
|
||||
* @param {number} height Height of image.
|
||||
* @param {string} src Source of the image.
|
||||
* @param {goog.graphics.GroupElement=} opt_group The group wrapper element
|
||||
* to append to. If not specified, appends to the main canvas.
|
||||
*
|
||||
* @return {goog.graphics.ImageElement} The newly created element.
|
||||
*/
|
||||
goog.graphics.VmlGraphics.prototype.drawImage = function(x, y, width, height,
|
||||
src, opt_group) {
|
||||
var element = this.createVmlElement('image');
|
||||
goog.graphics.VmlGraphics.setPositionAndSize(element, x, y, width, height);
|
||||
goog.graphics.VmlGraphics.setAttribute(element, 'src', src);
|
||||
var wrapper = new goog.graphics.VmlImageElement(element, this);
|
||||
this.append_(wrapper, opt_group);
|
||||
return wrapper;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Draw a text string vertically centered on a given line.
|
||||
*
|
||||
* @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 Stroke object describing the stroke.
|
||||
* @param {goog.graphics.Fill?} fill Fill object describing the fill.
|
||||
* @param {goog.graphics.GroupElement=} opt_group The group wrapper element
|
||||
* to append to. If not specified, appends to the main canvas.
|
||||
*
|
||||
* @return {goog.graphics.TextElement} The newly created element.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.VmlGraphics.prototype.drawTextOnLine = function(
|
||||
text, x1, y1, x2, y2, align, font, stroke, fill, opt_group) {
|
||||
var shape = this.createFullSizeElement_('shape');
|
||||
|
||||
var pathElement = this.createVmlElement('path');
|
||||
var path = 'M' + goog.graphics.VmlGraphics.toPosCoord(x1) + ',' +
|
||||
goog.graphics.VmlGraphics.toPosCoord(y1) + 'L' +
|
||||
goog.graphics.VmlGraphics.toPosCoord(x2) + ',' +
|
||||
goog.graphics.VmlGraphics.toPosCoord(y2) + 'E';
|
||||
goog.graphics.VmlGraphics.setAttribute(pathElement, 'v', path);
|
||||
goog.graphics.VmlGraphics.setAttribute(pathElement, 'textpathok', 'true');
|
||||
|
||||
var textPathElement = this.createVmlElement('textpath');
|
||||
textPathElement.setAttribute('on', 'true');
|
||||
var style = textPathElement.style;
|
||||
style.fontSize = font.size * this.getPixelScaleX();
|
||||
style.fontFamily = font.family;
|
||||
if (align != null) {
|
||||
style['v-text-align'] = align;
|
||||
}
|
||||
if (font.bold) {
|
||||
style.fontWeight = 'bold';
|
||||
}
|
||||
if (font.italic) {
|
||||
style.fontStyle = 'italic';
|
||||
}
|
||||
goog.graphics.VmlGraphics.setAttribute(textPathElement, 'string', text);
|
||||
|
||||
shape.appendChild(pathElement);
|
||||
shape.appendChild(textPathElement);
|
||||
var wrapper = new goog.graphics.VmlTextElement(shape, this, stroke, fill);
|
||||
this.append_(wrapper, opt_group);
|
||||
return wrapper;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Draw a path.
|
||||
*
|
||||
* @param {!goog.graphics.Path} path The path object to draw.
|
||||
* @param {goog.graphics.Stroke?} stroke Stroke object describing the stroke.
|
||||
* @param {goog.graphics.Fill?} fill Fill object describing the fill.
|
||||
* @param {goog.graphics.GroupElement=} opt_group The group wrapper element
|
||||
* to append to. If not specified, appends to the main canvas.
|
||||
*
|
||||
* @return {goog.graphics.PathElement} The newly created element.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.VmlGraphics.prototype.drawPath = function(path, stroke, fill,
|
||||
opt_group) {
|
||||
var element = this.createFullSizeElement_('shape');
|
||||
goog.graphics.VmlGraphics.setAttribute(element, 'path',
|
||||
goog.graphics.VmlGraphics.getVmlPath(path));
|
||||
|
||||
var wrapper = new goog.graphics.VmlPathElement(element, this, stroke, fill);
|
||||
this.append_(wrapper, opt_group);
|
||||
return wrapper;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string representation of a logical path suitable for use in
|
||||
* a VML element.
|
||||
*
|
||||
* @param {goog.graphics.Path} path The logical path.
|
||||
* @return {string} The VML path representation.
|
||||
* @suppress {deprecated} goog.graphics is deprecated.
|
||||
*/
|
||||
goog.graphics.VmlGraphics.getVmlPath = function(path) {
|
||||
var list = [];
|
||||
path.forEachSegment(function(segment, args) {
|
||||
switch (segment) {
|
||||
case goog.graphics.Path.Segment.MOVETO:
|
||||
list.push('m');
|
||||
Array.prototype.push.apply(list, goog.array.map(args,
|
||||
goog.graphics.VmlGraphics.toSizeCoord));
|
||||
break;
|
||||
case goog.graphics.Path.Segment.LINETO:
|
||||
list.push('l');
|
||||
Array.prototype.push.apply(list, goog.array.map(args,
|
||||
goog.graphics.VmlGraphics.toSizeCoord));
|
||||
break;
|
||||
case goog.graphics.Path.Segment.CURVETO:
|
||||
list.push('c');
|
||||
Array.prototype.push.apply(list, goog.array.map(args,
|
||||
goog.graphics.VmlGraphics.toSizeCoord));
|
||||
break;
|
||||
case goog.graphics.Path.Segment.CLOSE:
|
||||
list.push('x');
|
||||
break;
|
||||
case goog.graphics.Path.Segment.ARCTO:
|
||||
var toAngle = args[2] + args[3];
|
||||
var cx = goog.graphics.VmlGraphics.toSizeCoord(
|
||||
args[4] - goog.math.angleDx(toAngle, args[0]));
|
||||
var cy = goog.graphics.VmlGraphics.toSizeCoord(
|
||||
args[5] - goog.math.angleDy(toAngle, args[1]));
|
||||
var rx = goog.graphics.VmlGraphics.toSizeCoord(args[0]);
|
||||
var ry = goog.graphics.VmlGraphics.toSizeCoord(args[1]);
|
||||
// VML angles are in fd units (see http://www.w3.org/TR/NOTE-VML) and
|
||||
// are positive counter-clockwise.
|
||||
var fromAngle = Math.round(args[2] * -65536);
|
||||
var extent = Math.round(args[3] * -65536);
|
||||
list.push('ae', cx, cy, rx, ry, fromAngle, extent);
|
||||
break;
|
||||
}
|
||||
});
|
||||
return list.join(' ');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Create an empty group of drawing elements.
|
||||
*
|
||||
* @param {goog.graphics.GroupElement=} opt_group The group wrapper element
|
||||
* to append to. If not specified, appends to the main canvas.
|
||||
*
|
||||
* @return {goog.graphics.GroupElement} The newly created group.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.VmlGraphics.prototype.createGroup = function(opt_group) {
|
||||
var element = this.createFullSizeElement_('group');
|
||||
var parent = opt_group || this.canvasElement;
|
||||
parent.getElement().appendChild(element);
|
||||
return new goog.graphics.VmlGroupElement(element, this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Measure and return the width (in pixels) of a given text string.
|
||||
* Text measurement is needed to make sure a text can fit in the allocated
|
||||
* area. The way text length is measured is by writing it into a div that is
|
||||
* after the visible area, measure the div width, and immediatly erase the
|
||||
* written value.
|
||||
*
|
||||
* @param {string} text The text string to measure.
|
||||
* @param {goog.graphics.Font} font The font object describing the font style.
|
||||
*
|
||||
* @return {number} The width in pixels of the text strings.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.VmlGraphics.prototype.getTextWidth = function(text, font) {
|
||||
// TODO(arv): Implement
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.graphics.VmlGraphics.prototype.enterDocument = function() {
|
||||
goog.graphics.VmlGraphics.superClass_.enterDocument.call(this);
|
||||
this.handleContainerResize_();
|
||||
this.updateGraphics_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Disposes of the component by removing event handlers, detacing DOM nodes from
|
||||
* the document body, and removing references to them.
|
||||
* @override
|
||||
* @protected
|
||||
*/
|
||||
goog.graphics.VmlGraphics.prototype.disposeInternal = function() {
|
||||
this.canvasElement = null;
|
||||
goog.graphics.VmlGraphics.superClass_.disposeInternal.call(this);
|
||||
};
|
||||
Reference in New Issue
Block a user