/**
* @license
* Copyright The Closure Library Authors.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Graphics utility functions and factory methods.
*/
goog.provide('goog.graphics.AbstractGraphics');
goog.require('goog.dom');
goog.require('goog.graphics.AffineTransform');
goog.require('goog.graphics.Element');
goog.require('goog.graphics.EllipseElement');
goog.require('goog.graphics.Fill');
goog.require('goog.graphics.Font');
goog.require('goog.graphics.GroupElement');
goog.require('goog.graphics.Path');
goog.require('goog.graphics.PathElement');
goog.require('goog.graphics.RectElement');
goog.require('goog.graphics.Stroke');
goog.require('goog.graphics.StrokeAndFillElement');
goog.require('goog.graphics.TextElement');
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) {
'use strict';
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 percentage 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() {
'use strict';
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) {
'use strict';
this.coordWidth = coordWidth;
this.coordHeight = coordHeight;
};
/**
* @return {goog.math.Size} The coordinate size.
*/
goog.graphics.AbstractGraphics.prototype.getCoordSize = function() {
'use strict';
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() {
'use strict';
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() {
'use strict';
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() {
'use strict';
if (this.isInDocument()) {
return goog.style.getSize(this.getElement());
}
if (typeof this.width === 'number' && typeof this.height === 'number') {
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() {
'use strict';
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() {
'use strict';
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) {
'use strict';
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.
*
* If a more general affine transform is needed than this provides
* (e.g. skew and scale) then use setElementAffineTransform.
* @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;
/**
* Set the affine transform of an element.
* @param {!goog.graphics.Element} element The element wrapper.
* @param {!goog.graphics.AffineTransform} affineTransform The
* transformation applied to this element.
*/
goog.graphics.AbstractGraphics.prototype.setElementAffineTransform =
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) {
'use strict';
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) {
'use strict';
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() {
'use strict';
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 immediately 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() {
'use strict';
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() {};