/*! * version: 0.0.4 * date: 2014-12-04 * updates and docs at: http://www.greensock.com * * @license copyright (c) 2008-2015, greensock. all rights reserved. * drawsvgplugin is a club greensock membership benefit; you must have a valid membership to use * this code without violating the terms of use. visit http://greensock.com/club/ to sign up or get more details. * this work is subject to the software agreement that was issued with your membership. * * @author: jack doyle, jack@greensock.com */ var _gsscope = (typeof(module) !== "undefined" && module.exports && typeof(global) !== "undefined") ? global : this || window; //helps ensure compatibility with amd/requirejs and commonjs/node (_gsscope._gsqueue || (_gsscope._gsqueue = [])).push( function() { "use strict"; function getdistance(x1, y1, x2, y2) { x2 = parsefloat(x2) - parsefloat(x1); y2 = parsefloat(y2) - parsefloat(y1); return math.sqrt(x2 * x2 + y2 * y2); } function unwrap(element) { if (typeof(element) === "string" || !element.nodetype) { element = _gsscope.tweenlite.selector(element); if (element.length) { element = element[0]; } } return element; } //accepts values like "100%" or "20% 80%" or "20 50" and parses it into an absolute start and end position on the line/stroke based on its length. returns an an array with the start and end values, like [0, 243] function parse(value, length, defaultstart) { var i = value.indexof(" "), s, e; if (i === -1) { s = defaultstart !== undefined ? defaultstart + "" : value; e = value; } else { s = value.substr(0, i); e = value.substr(i+1); } s = (s.indexof("%") !== -1) ? (parsefloat(s) / 100) * length : parsefloat(s); e = (e.indexof("%") !== -1) ? (parsefloat(e) / 100) * length : parsefloat(e); return (s > e) ? [e, s] : [s, e]; } function getlength(element) { if (!element) { return 0; } element = unwrap(element); var type = element.tagname.tolowercase(), length, bbox, points, point, prevpoint, i, rx, ry; if (type === "path") { length = element.gettotallength() || 0; } else if (type === "rect") { bbox = element.getbbox(); length = (bbox.width + bbox.height) * 2; } else if (type === "circle") { length = math.pi * 2 * parsefloat(element.getattribute("r")); } else if (type === "line") { length = getdistance(element.getattribute("x1"), element.getattribute("y1"), element.getattribute("x2"), element.getattribute("y2")); } else if (type === "polyline" || type === "polygon") { points = element.getattribute("points").split(" "); length = 0; prevpoint = points[0].split(","); if (type === "polygon") { points.push(points[0]); if (points[0].indexof(",") === -1) { points.push(points[1]); } } for (i = 1; i < points.length; i++) { point = points[i].split(","); if (point.length === 1) { point[1] = points[i++]; } if (point.length === 2) { length += getdistance(prevpoint[0], prevpoint[1], point[0], point[1]) || 0; prevpoint = point; } } } else if (type === "ellipse") { rx = parsefloat(element.getattribute("rx")); ry = parsefloat(element.getattribute("ry")); length = math.pi * ( 3 * (rx + ry) - math.sqrt((3 * rx + ry) * (rx + 3 * ry)) ); } return length || 0; } var _getcomputedstyle = document.defaultview ? document.defaultview.getcomputedstyle : function() {}, drawsvgplugin; function getposition(element, length) { if (!element) { return [0, 0]; } element = unwrap(element); length = length || (getlength(element) + 1); var cs = _getcomputedstyle(element), dash = cs.strokedasharray || "", offset = parsefloat(cs.strokedashoffset); dash = (dash.indexof(" ") === -1) ? length : parsefloat(dash.split(" ")[0]) || 0.00001; if (dash > length) { dash = length; } return [math.max(0, -offset), dash - offset]; } drawsvgplugin = _gsscope._gsdefine.plugin({ propname: "drawsvg", api: 2, version: "0.0.4", global: true, overwriteprops: ["drawsvg"], init: function(target, value, tween) { if (!target.getbbox) { return false; } var length = getlength(target) + 1, start, end, overage; this._style = target.style; if (value === true || value === "true") { value = "0 100%"; } else if (!value) { value = "0 0"; } else if ((value + "").indexof(" ") === -1) { value = "0 " + value; } start = getposition(target, length); end = parse(value, length, start[0]); this._length = length + 10; if (start[0] === 0 && end[0] === 0) { overage = math.max(0.00001, end[1] - length); //allow people to go past the end, like values of 105% because for some paths, firefox doesn't return an accurate gettotallength(), so it could end up coming up short. this._dash = length + overage; this._offset = length - start[1] + overage; this._addtween(this, "_offset", this._offset, length - end[1] + overage, "drawsvg"); } else { this._dash = (start[1] - start[0]) || 0.000001; //some browsers render artifacts if dash is 0, so we use a very small number in that case. this._offset = -start[0]; this._addtween(this, "_dash", this._dash, (end[1] - end[0]) || 0.00001, "drawsvg"); this._addtween(this, "_offset", this._offset, -end[0], "drawsvg"); } return true; }, //called each time the values should be updated, and the ratio gets passed as the only parameter (typically it's a value between 0 and 1, but it can exceed those when using an ease like elastic.easeout or back.easeout, etc.) set: function(ratio) { if (this._firstpt) { this._super.setratio.call(this, ratio); this._style.strokedashoffset = this._offset; this._style.strokedasharray = this._dash + " " + this._length; } } }); drawsvgplugin.getlength = getlength; drawsvgplugin.getposition = getposition; }); if (_gsscope._gsdefine) { _gsscope._gsqueue.pop()(); }