Path: blob/trunk/third_party/closure/goog/graphics/ext/path.js
2868 views
// Copyright 2007 The Closure Library Authors. All Rights Reserved.1//2// Licensed under the Apache License, Version 2.0 (the "License");3// you may not use this file except in compliance with the License.4// You may obtain a copy of the License at5//6// http://www.apache.org/licenses/LICENSE-2.07//8// Unless required by applicable law or agreed to in writing, software9// distributed under the License is distributed on an "AS-IS" BASIS,10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11// See the License for the specific language governing permissions and12// limitations under the License.131415/**16* @fileoverview A thick wrapper around paths.17* @author [email protected] (Robby Walker)18*/192021goog.provide('goog.graphics.ext.Path');2223goog.require('goog.graphics.AffineTransform');24goog.require('goog.graphics.Path');25goog.require('goog.math.Rect');26272829/**30* Creates a path object31* @constructor32* @extends {goog.graphics.Path}33* @final34*/35goog.graphics.ext.Path = function() {36goog.graphics.Path.call(this);37};38goog.inherits(goog.graphics.ext.Path, goog.graphics.Path);394041/**42* Optional cached or user specified bounding box. A user may wish to43* precompute a bounding box to save time and include more accurate44* computations.45* @type {goog.math.Rect?}46* @private47*/48goog.graphics.ext.Path.prototype.bounds_ = null;495051/**52* Clones the path.53* @return {!goog.graphics.ext.Path} A clone of this path.54* @override55*/56goog.graphics.ext.Path.prototype.clone = function() {57var output = /** @type {goog.graphics.ext.Path} */58(goog.graphics.ext.Path.superClass_.clone.call(this));59output.bounds_ = this.bounds_ && this.bounds_.clone();60return output;61};626364/**65* Transforms the path. Only simple paths are transformable. Attempting66* to transform a non-simple path will throw an error.67* @param {!goog.graphics.AffineTransform} tx The transformation to perform.68* @return {!goog.graphics.ext.Path} The path itself.69* @override70*/71goog.graphics.ext.Path.prototype.transform = function(tx) {72goog.graphics.ext.Path.superClass_.transform.call(this, tx);7374// Make sure the precomputed bounds are cleared when the path is transformed.75this.bounds_ = null;7677return this;78};798081/**82* Modify the bounding box of the path. This may cause the path to be83* simplified (i.e. arcs converted to curves) as a side-effect.84* @param {number} deltaX How far to translate the x coordinates.85* @param {number} deltaY How far to translate the y coordinates.86* @param {number} xFactor After translation, all x coordinates are multiplied87* by this number.88* @param {number} yFactor After translation, all y coordinates are multiplied89* by this number.90* @return {!goog.graphics.ext.Path} The path itself.91*/92goog.graphics.ext.Path.prototype.modifyBounds = function(93deltaX, deltaY, xFactor, yFactor) {94if (!this.isSimple()) {95var simple = goog.graphics.Path.createSimplifiedPath(this);96this.clear();97this.appendPath(simple);98}99100return this.transform(101goog.graphics.AffineTransform.getScaleInstance(xFactor, yFactor)102.translate(deltaX, deltaY));103};104105106/**107* Set the precomputed bounds.108* @param {goog.math.Rect?} bounds The bounds to use, or set to null to clear109* and recompute on the next call to getBoundingBox.110*/111goog.graphics.ext.Path.prototype.useBoundingBox = function(bounds) {112this.bounds_ = bounds && bounds.clone();113};114115116/**117* @return {goog.math.Rect?} The bounding box of the path, or null if the118* path is empty.119*/120goog.graphics.ext.Path.prototype.getBoundingBox = function() {121if (!this.bounds_ && !this.isEmpty()) {122var minY;123var minX = minY = Number.POSITIVE_INFINITY;124var maxY;125var maxX = maxY = Number.NEGATIVE_INFINITY;126127var simplePath =128this.isSimple() ? this : goog.graphics.Path.createSimplifiedPath(this);129simplePath.forEachSegment(function(type, points) {130for (var i = 0, len = points.length; i < len; i += 2) {131minX = Math.min(minX, points[i]);132maxX = Math.max(maxX, points[i]);133minY = Math.min(minY, points[i + 1]);134maxY = Math.max(maxY, points[i + 1]);135}136});137138this.bounds_ = new goog.math.Rect(minX, minY, maxX - minX, maxY - minY);139}140141return this.bounds_;142};143144145