Skip to content

Instantly share code, notes, and snippets.

@sfpgmr sfpgmr/README.md
Last active Oct 23, 2016

Embed
What would you like to do?
SVGからthree.jsのshapeへの変換(3)

SVGからthree.jsのshapeへの変換(3)

エドワード・マイブリッジの「Horse in motion」をInkscapeでトレースし、各馬をセル化したものをthree.jsのshapeに変換し表示しています。

3Dっぽく回転させてみてます。

下記のURLから動くデモが見れます。Windows 10 Tech Preview 9926 のIE11では動作しませんでした。ひょっとするとIE11ではそもそも動作しないのかもしれません。原因は不明ですが。。

http://bl.ocks.org/sfpgmr/afe9d11885e81086fa80

Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
<!DOCTYPE html>
<html vocab="http://schema.org" lang="ja">
<head>
<title>Three.jsによる馬のアニメーション</title>
<meta charset="utf-8" />
<meta name="description" content="SVGアニメーションのテスト" />
<meta name="keywords" content="Youtube,d3.js,Q.js,jquery" />
<meta name="author" content="sfpgmr" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<script type="text/javascript" src="./pathseg.js"></script>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/d3/3.5.2/d3.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r70/three.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/q.js/1.1.2/q.min.js" ></script>
<!--<script type="text/javascript" src="./graphics.js"></script> -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.2/normalize.min.css" />
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
}
#svg {
display:none;
}
</style>
</head>
<body>
<div id="content"></div>
<div id="svg"></div>
<div id="svgcell"></div>
<script type="text/javascript" src="index.js"></script>
<script>
</script>
</body>
</html>
//The MIT License (MIT)
//
//Copyright (c) 2015 Satoshi Fujiwara
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
/// <reference path="http://cdnjs.cloudflare.com/ajax/libs/d3/3.5.2/d3.js" />
/// <reference path="http://cdnjs.cloudflare.com/ajax/libs/three.js/r70/three.js" />
/// <reference path="..\intellisense\q.intellisense.js" />
// stackoverflowより
// 絶対座標から相対座標への変換
// http://stackoverflow.com/questions/14179333/convert-svg-path-to-relative-commands
function convertToRelative(path) {
function set(type) {
var args = [].slice.call(arguments, 1)
, rcmd = 'createSVGPathSeg'+ type +'Rel'
, rseg = path[rcmd].apply(path, args);
segs.replaceItem(rseg, i);
}
var dx, dy, x0, y0, x1, y1, x2, y2, segs = path.pathSegList;
for (var x = 0, y = 0, i = 0, len = segs.numberOfItems; i < len; i++) {
var seg = segs.getItem(i)
, c = seg.pathSegTypeAsLetter;
if (/[MLHVCSQTAZz]/.test(c)) {
if ('x1' in seg) x1 = seg.x1 - x;
if ('x2' in seg) x2 = seg.x2 - x;
if ('y1' in seg) y1 = seg.y1 - y;
if ('y2' in seg) y2 = seg.y2 - y;
if ('x' in seg) dx = -x + (x = seg.x);
if ('y' in seg) dy = -y + (y = seg.y);
switch (c) {
case 'M': set('Moveto',dx,dy); break;
case 'L': set('Lineto',dx,dy); break;
case 'H': set('LinetoHorizontal',dx); break;
case 'V': set('LinetoVertical',dy); break;
case 'C': set('CurvetoCubic',dx,dy,x1,y1,x2,y2); break;
case 'S': set('CurvetoCubicSmooth',dx,dy,x2,y2); break;
case 'Q': set('CurvetoQuadratic',dx,dy,x1,y1); break;
case 'T': set('CurvetoQuadraticSmooth',dx,dy); break;
case 'A': set('Arc',dx,dy,seg.r1,seg.r2,seg.angle,
seg.largeArcFlag,seg.sweepFlag); break;
case 'Z': case 'z': x = x0; y = y0; break;
}
}
else {
if ('x' in seg) x += seg.x;
if ('y' in seg) y += seg.y;
}
// store the start of a subpath
if (c == 'M' || c == 'm') {
x0 = x;
y0 = y;
}
}
path.setAttribute('d', path.getAttribute('d').replace(/Z/g, 'z'));
}
// svg pathをthree.jsのshapeに変換する
// スペースの処理とy座標を反転するように修正
// From d3-threeD.js
// https://github.com/asutherland/d3-threeD
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
var DEGS_TO_RADS = Math.PI / 180, UNIT_SIZE = 100;
var DIGIT_0 = 48, DIGIT_9 = 57, COMMA = 44, SPACE = 32, PERIOD = 46, MINUS = 45;
function transformSVGPath(pathStr,obj) {
var path = obj ? new obj() : new THREE.Shape();
var idx = 1, len = pathStr.length, activeCmd,
x = 0, y = 0, nx = 0, ny = 0, firstX = null, firstY = null,
x1 = 0, x2 = 0, y1 = 0, y2 = 0,
rx = 0, ry = 0, xar = 0, laf = 0, sf = 0, cx, cy;
function eatNum() {
var sidx, c, isFloat = false, s;
// eat delims
while (idx < len) {
c = pathStr.charCodeAt(idx);
if (c !== COMMA && c !== SPACE)
break;
idx++;
}
if (c === MINUS)
sidx = idx++;
else
sidx = idx;
// eat number
while (idx < len) {
c = pathStr.charCodeAt(idx);
if (DIGIT_0 <= c && c <= DIGIT_9) {
idx++;
continue;
}
else if (c === PERIOD) {
idx++;
isFloat = true;
continue;
}
s = pathStr.substring(sidx, idx);
return isFloat ? parseFloat(s) : parseInt(s);
}
s = pathStr.substring(sidx);
return isFloat ? parseFloat(s) : parseInt(s);
}
function nextIsNum() {
var c;
// do permanently eat any delims...
while (idx < len) {
c = pathStr.charCodeAt(idx);
if (c !== COMMA && c !== SPACE)
break;
idx++;
}
c = pathStr.charCodeAt(idx);
return (c === MINUS || (DIGIT_0 <= c && c <= DIGIT_9));
}
var canRepeat;
activeCmd = pathStr[0];
while (idx <= len) {
canRepeat = true;
switch (activeCmd) {
// moveto commands, become lineto's if repeated
case 'M':
x = eatNum();
y = -eatNum();
path.moveTo(x, y);
activeCmd = 'L';
firstX = x;
firstY = y;
break;
case 'm':
x += eatNum();
y += -eatNum();
path.moveTo(x, y);
activeCmd = 'l';
firstX = x;
firstY = y;
break;
case 'Z':
case 'z':
canRepeat = false;
if (x !== firstX || y !== firstY)
path.lineTo(firstX, firstY);
break;
// - lines!
case 'L':
case 'H':
case 'V':
nx = (activeCmd === 'V') ? x : eatNum();
ny = (activeCmd === 'H') ? y : -eatNum();
path.lineTo(nx, ny);
x = nx;
y = ny;
break;
case 'l':
case 'h':
case 'v':
nx = (activeCmd === 'v') ? x : (x + eatNum());
ny = (activeCmd === 'h') ? y : (y + -eatNum());
path.lineTo(nx, ny);
x = nx;
y = ny;
break;
// - cubic bezier
case 'C':
x1 = eatNum(); y1 = -eatNum();
case 'S':
if (activeCmd === 'S') {
x1 = 2 * x - x2; y1 = 2 * y - y2;
}
x2 = eatNum();
y2 = -eatNum();
nx = eatNum();
ny = -eatNum();
path.bezierCurveTo(x1, y1, x2, y2, nx, ny);
x = nx; y = ny;
break;
case 'c':
x1 = x + eatNum();
y1 = y + -eatNum();
case 's':
if (activeCmd === 's') {
x1 = 2 * x - x2;
y1 = 2 * y - y2;
}
x2 = x + eatNum();
y2 = y + -eatNum();
nx = x + eatNum();
ny = y + -eatNum();
path.bezierCurveTo(x1, y1, x2, y2, nx, ny);
x = nx; y = ny;
break;
// - quadratic bezier
case 'Q':
x1 = eatNum(); y1 = -eatNum();
case 'T':
if (activeCmd === 'T') {
x1 = 2 * x - x1;
y1 = 2 * y - y1;
}
nx = eatNum();
ny = -eatNum();
path.quadraticCurveTo(x1, y1, nx, ny);
x = nx;
y = ny;
break;
case 'q':
x1 = x + eatNum();
y1 = y + -eatNum();
case 't':
if (activeCmd === 't') {
x1 = 2 * x - x1;
y1 = 2 * y - y1;
}
nx = x + eatNum();
ny = y + -eatNum();
path.quadraticCurveTo(x1, y1, nx, ny);
x = nx; y = ny;
break;
// - elliptical arc
case 'A':
rx = eatNum();
ry = eatNum();
xar = eatNum() * DEGS_TO_RADS;
laf = eatNum();
sf = eatNum();
nx = eatNum();
ny = -eatNum();
if (rx !== ry) {
console.warn("Forcing elliptical arc to be a circular one :(",
rx, ry);
}
// SVG implementation notes does all the math for us! woo!
// http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes
// step1, using x1 as x1'
x1 = Math.cos(xar) * (x - nx) / 2 + Math.sin(xar) * (y - ny) / 2;
y1 = -Math.sin(xar) * (x - nx) / 2 + Math.cos(xar) * (y - ny) / 2;
// step 2, using x2 as cx'
var norm = Math.sqrt(
(rx*rx * ry*ry - rx*rx * y1*y1 - ry*ry * x1*x1) /
(rx*rx * y1*y1 + ry*ry * x1*x1));
if (laf === sf)
norm = -norm;
x2 = norm * rx * y1 / ry;
y2 = norm * -ry * x1 / rx;
// step 3
cx = Math.cos(xar) * x2 - Math.sin(xar) * y2 + (x + nx) / 2;
cy = Math.sin(xar) * x2 + Math.cos(xar) * y2 + (y + ny) / 2;
var u = new THREE.Vector2(1, 0),
v = new THREE.Vector2((x1 - x2) / rx,
(y1 - y2) / ry);
var startAng = Math.acos(u.dot(v) / u.length() / v.length());
if (u.x * v.y - u.y * v.x < 0)
startAng = -startAng;
// we can reuse 'v' from start angle as our 'u' for delta angle
u.x = (-x1 - x2) / rx;
u.y = (-y1 - y2) / ry;
var deltaAng = Math.acos(v.dot(u) / v.length() / u.length());
// This normalization ends up making our curves fail to triangulate...
if (v.x * u.y - v.y * u.x < 0)
deltaAng = -deltaAng;
if (!sf && deltaAng > 0)
deltaAng -= Math.PI * 2;
if (sf && deltaAng < 0)
deltaAng += Math.PI * 2;
path.absarc(cx, cy, rx, startAng, startAng + deltaAng, sf);
x = nx;
y = ny;
break;
default:
throw new Error("weird path command: " + activeCmd);
}
// just reissue the command
if (canRepeat && nextIsNum())
continue;
activeCmd = pathStr[idx++];
}
return path;
}
// from gist
// https://gist.github.com/gabrielflorit/3758456
function createShape( geometry, color, x, y, z, rx, ry, rz, s ) {
// flat shape
// var geometry = new THREE.ShapeGeometry( shape );
var material = new THREE.MeshBasicMaterial({
color: color,
side: THREE.DoubleSide,
overdraw: true
});
var mesh = new THREE.Mesh( geometry, material );
mesh.position.set( x, y, z );
mesh.rotation.set( rx, ry, rz );
mesh.scale.set( s, s, s );
return mesh;
}
// メイン
window.addEventListener('load',function(){
var WIDTH = window.innerWidth, HEIGHT = window.innerHeight;
var renderer = new THREE.WebGLRenderer({ antialias: false, sortObjects: true });
renderer.setSize(WIDTH, HEIGHT);
renderer.setClearColor(0x000000, 1);
renderer.domElement.id = 'console';
renderer.domElement.className = 'console';
renderer.domElement.style.zIndex = 0;
d3.select('#content').node().appendChild(renderer.domElement);
renderer.clear();
// シーンの作成
var scene = new THREE.Scene();
// カメラの作成
var camera = new THREE.PerspectiveCamera(90.0, WIDTH / HEIGHT);
camera.position.x = 0.0;
camera.position.y = 0.0;
camera.position.z = (WIDTH / 2.0) * HEIGHT / WIDTH;
camera.lookAt(new THREE.Vector3(0.0, 0.0, 0.0));
var horseGroups = [];
window.addEventListener('resize',function()
{
WIDTH = window.innerWidth;
HEIGHT = window.innerHeight;
renderer.setSize(WIDTH,HEIGHT);
camera.aspect = WIDTH / HEIGHT;
camera.position.z = (WIDTH / 2.0) * HEIGHT / WIDTH;
camera.updateProjectionMatrix();
});
var xml = Q.nfbind(d3.xml);
var gto;
// SVGファイルから馬のメッシュを作る
xml('./horse03.svg','image/svg+xml')
.then(function(svg){
try {
document.querySelector('#svg').appendChild(svg.firstChild);
var shapes = [];
d3.select('#svg').selectAll('g').each(function(){
var g = d3.select(this);
var boundingBox = g.select('rect').node();
var paths = g.selectAll('path');
var holes = [];
var shape = null;
var shapeId = null;
paths.each(function(){
// 馬セルの取り出しと座標補正
var path = d3.select(this);
convertToRelative(path.node());
var m = path.node().createSVGPathSegMovetoRel
(path.node().pathSegList.getItem(0).x - boundingBox.x.baseVal.value - boundingBox.width.baseVal.value / 2.0,
path.node().pathSegList.getItem(0).y - boundingBox.y.baseVal.value - boundingBox.height.baseVal.value / 2.0
);
path.node().pathSegList.replaceItem(m,0);
path.attr('d',path.attr('d'));
// svg pathからthree.js shape Meshへの変換
if(path.attr('id').match(/hole/)){
holes.push(transformSVGPath(path.attr('d'),THREE.Path));
} else {
shape = transformSVGPath(path.attr('d'));
shapeId = path.attr('id');
}
});
holes.forEach(function(d){
shape.holes.push(d);
});
shapes.push({name:shapeId,shape:new THREE.ShapeGeometry( shape )});
});
var ggroup = new THREE.Group();
for(var i = 0; i < 100;++i){
var group = new THREE.Group();
shapes.forEach(function(sm){
var shapeMesh = createShape(sm.shape,0xFFFF00,0,0,0,0,0,0,1.0);
shapeMesh.visible = false;
shapeMesh.name = sm.name;
group.add(shapeMesh);
});
group.position.x = Math.random() * WIDTH * 2 - WIDTH * 2 / 2;
group.position.y = Math.random() * HEIGHT * 2 - HEIGHT *2 / 2;
group.position.z = 2000.0 * Math.random() - 1000.0;
horseGroups.push(group);
ggroup.add(group);
}
scene.add(ggroup);
ggroup.name = 'world';
d3.select('#svg').remove();
} catch (e) {
console.log(e + '\n' + e.stack);
}
//レンダリング
var r = 0.0;
(function render(index){
if(index > 10.0) index = 0.0;
var idx = parseInt(index,10);
for(var i = 0,end = horseGroups.length;i< end;++i){
var g = horseGroups[i];
g.getObjectByName('horse' + ('00' + idx.toString(10)).slice(-2)).visible = true;
if(idx == 0){
g.getObjectByName('horse10').visible = false;
} else {
g.getObjectByName('horse' + ('00' + (idx - 1).toString(10)).slice(-2)).visible = false;
}
}
scene.getObjectByName('world').rotateX(0.005);
scene.getObjectByName('world').rotateY(0.005);
scene.getObjectByName('world').rotateZ(0.005);
renderer.render(scene,camera);
index += 0.25;
r += 0.001;
requestAnimationFrame(render.bind(null,index));
})(0);
// console.log(d3.select('#svg').html());
});
});
// SVGPathSeg API polyfill
// https://github.com/progers/pathseg
//
// This is a drop-in replacement for the SVGPathSeg and SVGPathSegList APIs that were removed from
// SVG2 (https://lists.w3.org/Archives/Public/www-svg/2015Jun/0044.html), including the latest spec
// changes which were implemented in Firefox 43 and Chrome 46.
(function() { "use strict";
if (!("SVGPathSeg" in window)) {
// Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSeg
window.SVGPathSeg = function(type, typeAsLetter, owningPathSegList) {
this.pathSegType = type;
this.pathSegTypeAsLetter = typeAsLetter;
this._owningPathSegList = owningPathSegList;
}
window.SVGPathSeg.prototype.classname = "SVGPathSeg";
window.SVGPathSeg.PATHSEG_UNKNOWN = 0;
window.SVGPathSeg.PATHSEG_CLOSEPATH = 1;
window.SVGPathSeg.PATHSEG_MOVETO_ABS = 2;
window.SVGPathSeg.PATHSEG_MOVETO_REL = 3;
window.SVGPathSeg.PATHSEG_LINETO_ABS = 4;
window.SVGPathSeg.PATHSEG_LINETO_REL = 5;
window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS = 6;
window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL = 7;
window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS = 8;
window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL = 9;
window.SVGPathSeg.PATHSEG_ARC_ABS = 10;
window.SVGPathSeg.PATHSEG_ARC_REL = 11;
window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS = 12;
window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL = 13;
window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS = 14;
window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL = 15;
window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS = 16;
window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL = 17;
window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS = 18;
window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL = 19;
// Notify owning PathSegList on any changes so they can be synchronized back to the path element.
window.SVGPathSeg.prototype._segmentChanged = function() {
if (this._owningPathSegList)
this._owningPathSegList.segmentChanged(this);
}
window.SVGPathSegClosePath = function(owningPathSegList) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CLOSEPATH, "z", owningPathSegList);
}
window.SVGPathSegClosePath.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegClosePath.prototype.toString = function() { return "[object SVGPathSegClosePath]"; }
window.SVGPathSegClosePath.prototype._asPathString = function() { return this.pathSegTypeAsLetter; }
window.SVGPathSegClosePath.prototype.clone = function() { return new window.SVGPathSegClosePath(undefined); }
window.SVGPathSegMovetoAbs = function(owningPathSegList, x, y) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_ABS, "M", owningPathSegList);
this._x = x;
this._y = y;
}
window.SVGPathSegMovetoAbs.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegMovetoAbs.prototype.toString = function() { return "[object SVGPathSegMovetoAbs]"; }
window.SVGPathSegMovetoAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; }
window.SVGPathSegMovetoAbs.prototype.clone = function() { return new window.SVGPathSegMovetoAbs(undefined, this._x, this._y); }
Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegMovetoRel = function(owningPathSegList, x, y) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_REL, "m", owningPathSegList);
this._x = x;
this._y = y;
}
window.SVGPathSegMovetoRel.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegMovetoRel.prototype.toString = function() { return "[object SVGPathSegMovetoRel]"; }
window.SVGPathSegMovetoRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; }
window.SVGPathSegMovetoRel.prototype.clone = function() { return new window.SVGPathSegMovetoRel(undefined, this._x, this._y); }
Object.defineProperty(window.SVGPathSegMovetoRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegMovetoRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegLinetoAbs = function(owningPathSegList, x, y) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_ABS, "L", owningPathSegList);
this._x = x;
this._y = y;
}
window.SVGPathSegLinetoAbs.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegLinetoAbs.prototype.toString = function() { return "[object SVGPathSegLinetoAbs]"; }
window.SVGPathSegLinetoAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; }
window.SVGPathSegLinetoAbs.prototype.clone = function() { return new window.SVGPathSegLinetoAbs(undefined, this._x, this._y); }
Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegLinetoRel = function(owningPathSegList, x, y) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_REL, "l", owningPathSegList);
this._x = x;
this._y = y;
}
window.SVGPathSegLinetoRel.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegLinetoRel.prototype.toString = function() { return "[object SVGPathSegLinetoRel]"; }
window.SVGPathSegLinetoRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; }
window.SVGPathSegLinetoRel.prototype.clone = function() { return new window.SVGPathSegLinetoRel(undefined, this._x, this._y); }
Object.defineProperty(window.SVGPathSegLinetoRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegLinetoRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegCurvetoCubicAbs = function(owningPathSegList, x, y, x1, y1, x2, y2) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS, "C", owningPathSegList);
this._x = x;
this._y = y;
this._x1 = x1;
this._y1 = y1;
this._x2 = x2;
this._y2 = y2;
}
window.SVGPathSegCurvetoCubicAbs.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegCurvetoCubicAbs.prototype.toString = function() { return "[object SVGPathSegCurvetoCubicAbs]"; }
window.SVGPathSegCurvetoCubicAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; }
window.SVGPathSegCurvetoCubicAbs.prototype.clone = function() { return new window.SVGPathSegCurvetoCubicAbs(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2); }
Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x1", { get: function() { return this._x1; }, set: function(x1) { this._x1 = x1; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y1", { get: function() { return this._y1; }, set: function(y1) { this._y1 = y1; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x2", { get: function() { return this._x2; }, set: function(x2) { this._x2 = x2; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y2", { get: function() { return this._y2; }, set: function(y2) { this._y2 = y2; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegCurvetoCubicRel = function(owningPathSegList, x, y, x1, y1, x2, y2) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL, "c", owningPathSegList);
this._x = x;
this._y = y;
this._x1 = x1;
this._y1 = y1;
this._x2 = x2;
this._y2 = y2;
}
window.SVGPathSegCurvetoCubicRel.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegCurvetoCubicRel.prototype.toString = function() { return "[object SVGPathSegCurvetoCubicRel]"; }
window.SVGPathSegCurvetoCubicRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; }
window.SVGPathSegCurvetoCubicRel.prototype.clone = function() { return new window.SVGPathSegCurvetoCubicRel(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2); }
Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x1", { get: function() { return this._x1; }, set: function(x1) { this._x1 = x1; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y1", { get: function() { return this._y1; }, set: function(y1) { this._y1 = y1; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x2", { get: function() { return this._x2; }, set: function(x2) { this._x2 = x2; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y2", { get: function() { return this._y2; }, set: function(y2) { this._y2 = y2; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegCurvetoQuadraticAbs = function(owningPathSegList, x, y, x1, y1) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS, "Q", owningPathSegList);
this._x = x;
this._y = y;
this._x1 = x1;
this._y1 = y1;
}
window.SVGPathSegCurvetoQuadraticAbs.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegCurvetoQuadraticAbs.prototype.toString = function() { return "[object SVGPathSegCurvetoQuadraticAbs]"; }
window.SVGPathSegCurvetoQuadraticAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x + " " + this._y; }
window.SVGPathSegCurvetoQuadraticAbs.prototype.clone = function() { return new window.SVGPathSegCurvetoQuadraticAbs(undefined, this._x, this._y, this._x1, this._y1); }
Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "x1", { get: function() { return this._x1; }, set: function(x1) { this._x1 = x1; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "y1", { get: function() { return this._y1; }, set: function(y1) { this._y1 = y1; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegCurvetoQuadraticRel = function(owningPathSegList, x, y, x1, y1) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL, "q", owningPathSegList);
this._x = x;
this._y = y;
this._x1 = x1;
this._y1 = y1;
}
window.SVGPathSegCurvetoQuadraticRel.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegCurvetoQuadraticRel.prototype.toString = function() { return "[object SVGPathSegCurvetoQuadraticRel]"; }
window.SVGPathSegCurvetoQuadraticRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x + " " + this._y; }
window.SVGPathSegCurvetoQuadraticRel.prototype.clone = function() { return new window.SVGPathSegCurvetoQuadraticRel(undefined, this._x, this._y, this._x1, this._y1); }
Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "x1", { get: function() { return this._x1; }, set: function(x1) { this._x1 = x1; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "y1", { get: function() { return this._y1; }, set: function(y1) { this._y1 = y1; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegArcAbs = function(owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_ABS, "A", owningPathSegList);
this._x = x;
this._y = y;
this._r1 = r1;
this._r2 = r2;
this._angle = angle;
this._largeArcFlag = largeArcFlag;
this._sweepFlag = sweepFlag;
}
window.SVGPathSegArcAbs.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegArcAbs.prototype.toString = function() { return "[object SVGPathSegArcAbs]"; }
window.SVGPathSegArcAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._r1 + " " + this._r2 + " " + this._angle + " " + (this._largeArcFlag ? "1" : "0") + " " + (this._sweepFlag ? "1" : "0") + " " + this._x + " " + this._y; }
window.SVGPathSegArcAbs.prototype.clone = function() { return new window.SVGPathSegArcAbs(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag); }
Object.defineProperty(window.SVGPathSegArcAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegArcAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegArcAbs.prototype, "r1", { get: function() { return this._r1; }, set: function(r1) { this._r1 = r1; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegArcAbs.prototype, "r2", { get: function() { return this._r2; }, set: function(r2) { this._r2 = r2; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegArcAbs.prototype, "angle", { get: function() { return this._angle; }, set: function(angle) { this._angle = angle; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegArcAbs.prototype, "largeArcFlag", { get: function() { return this._largeArcFlag; }, set: function(largeArcFlag) { this._largeArcFlag = largeArcFlag; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegArcAbs.prototype, "sweepFlag", { get: function() { return this._sweepFlag; }, set: function(sweepFlag) { this._sweepFlag = sweepFlag; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegArcRel = function(owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_REL, "a", owningPathSegList);
this._x = x;
this._y = y;
this._r1 = r1;
this._r2 = r2;
this._angle = angle;
this._largeArcFlag = largeArcFlag;
this._sweepFlag = sweepFlag;
}
window.SVGPathSegArcRel.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegArcRel.prototype.toString = function() { return "[object SVGPathSegArcRel]"; }
window.SVGPathSegArcRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._r1 + " " + this._r2 + " " + this._angle + " " + (this._largeArcFlag ? "1" : "0") + " " + (this._sweepFlag ? "1" : "0") + " " + this._x + " " + this._y; }
window.SVGPathSegArcRel.prototype.clone = function() { return new window.SVGPathSegArcRel(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag); }
Object.defineProperty(window.SVGPathSegArcRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegArcRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegArcRel.prototype, "r1", { get: function() { return this._r1; }, set: function(r1) { this._r1 = r1; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegArcRel.prototype, "r2", { get: function() { return this._r2; }, set: function(r2) { this._r2 = r2; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegArcRel.prototype, "angle", { get: function() { return this._angle; }, set: function(angle) { this._angle = angle; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegArcRel.prototype, "largeArcFlag", { get: function() { return this._largeArcFlag; }, set: function(largeArcFlag) { this._largeArcFlag = largeArcFlag; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegArcRel.prototype, "sweepFlag", { get: function() { return this._sweepFlag; }, set: function(sweepFlag) { this._sweepFlag = sweepFlag; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegLinetoHorizontalAbs = function(owningPathSegList, x) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS, "H", owningPathSegList);
this._x = x;
}
window.SVGPathSegLinetoHorizontalAbs.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegLinetoHorizontalAbs.prototype.toString = function() { return "[object SVGPathSegLinetoHorizontalAbs]"; }
window.SVGPathSegLinetoHorizontalAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x; }
window.SVGPathSegLinetoHorizontalAbs.prototype.clone = function() { return new window.SVGPathSegLinetoHorizontalAbs(undefined, this._x); }
Object.defineProperty(window.SVGPathSegLinetoHorizontalAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegLinetoHorizontalRel = function(owningPathSegList, x) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL, "h", owningPathSegList);
this._x = x;
}
window.SVGPathSegLinetoHorizontalRel.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegLinetoHorizontalRel.prototype.toString = function() { return "[object SVGPathSegLinetoHorizontalRel]"; }
window.SVGPathSegLinetoHorizontalRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x; }
window.SVGPathSegLinetoHorizontalRel.prototype.clone = function() { return new window.SVGPathSegLinetoHorizontalRel(undefined, this._x); }
Object.defineProperty(window.SVGPathSegLinetoHorizontalRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegLinetoVerticalAbs = function(owningPathSegList, y) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS, "V", owningPathSegList);
this._y = y;
}
window.SVGPathSegLinetoVerticalAbs.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegLinetoVerticalAbs.prototype.toString = function() { return "[object SVGPathSegLinetoVerticalAbs]"; }
window.SVGPathSegLinetoVerticalAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._y; }
window.SVGPathSegLinetoVerticalAbs.prototype.clone = function() { return new window.SVGPathSegLinetoVerticalAbs(undefined, this._y); }
Object.defineProperty(window.SVGPathSegLinetoVerticalAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegLinetoVerticalRel = function(owningPathSegList, y) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL, "v", owningPathSegList);
this._y = y;
}
window.SVGPathSegLinetoVerticalRel.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegLinetoVerticalRel.prototype.toString = function() { return "[object SVGPathSegLinetoVerticalRel]"; }
window.SVGPathSegLinetoVerticalRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._y; }
window.SVGPathSegLinetoVerticalRel.prototype.clone = function() { return new window.SVGPathSegLinetoVerticalRel(undefined, this._y); }
Object.defineProperty(window.SVGPathSegLinetoVerticalRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegCurvetoCubicSmoothAbs = function(owningPathSegList, x, y, x2, y2) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS, "S", owningPathSegList);
this._x = x;
this._y = y;
this._x2 = x2;
this._y2 = y2;
}
window.SVGPathSegCurvetoCubicSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegCurvetoCubicSmoothAbs.prototype.toString = function() { return "[object SVGPathSegCurvetoCubicSmoothAbs]"; }
window.SVGPathSegCurvetoCubicSmoothAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; }
window.SVGPathSegCurvetoCubicSmoothAbs.prototype.clone = function() { return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, this._x, this._y, this._x2, this._y2); }
Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "x2", { get: function() { return this._x2; }, set: function(x2) { this._x2 = x2; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "y2", { get: function() { return this._y2; }, set: function(y2) { this._y2 = y2; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegCurvetoCubicSmoothRel = function(owningPathSegList, x, y, x2, y2) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL, "s", owningPathSegList);
this._x = x;
this._y = y;
this._x2 = x2;
this._y2 = y2;
}
window.SVGPathSegCurvetoCubicSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegCurvetoCubicSmoothRel.prototype.toString = function() { return "[object SVGPathSegCurvetoCubicSmoothRel]"; }
window.SVGPathSegCurvetoCubicSmoothRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; }
window.SVGPathSegCurvetoCubicSmoothRel.prototype.clone = function() { return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, this._x, this._y, this._x2, this._y2); }
Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "x2", { get: function() { return this._x2; }, set: function(x2) { this._x2 = x2; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "y2", { get: function() { return this._y2; }, set: function(y2) { this._y2 = y2; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegCurvetoQuadraticSmoothAbs = function(owningPathSegList, x, y) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS, "T", owningPathSegList);
this._x = x;
this._y = y;
}
window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.toString = function() { return "[object SVGPathSegCurvetoQuadraticSmoothAbs]"; }
window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; }
window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.clone = function() { return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, this._x, this._y); }
Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegCurvetoQuadraticSmoothRel = function(owningPathSegList, x, y) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL, "t", owningPathSegList);
this._x = x;
this._y = y;
}
window.SVGPathSegCurvetoQuadraticSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.toString = function() { return "[object SVGPathSegCurvetoQuadraticSmoothRel]"; }
window.SVGPathSegCurvetoQuadraticSmoothRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; }
window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.clone = function() { return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, this._x, this._y); }
Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
// Add createSVGPathSeg* functions to window.SVGPathElement.
// Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-Interfacewindow.SVGPathElement.
window.SVGPathElement.prototype.createSVGPathSegClosePath = function() { return new window.SVGPathSegClosePath(undefined); }
window.SVGPathElement.prototype.createSVGPathSegMovetoAbs = function(x, y) { return new window.SVGPathSegMovetoAbs(undefined, x, y); }
window.SVGPathElement.prototype.createSVGPathSegMovetoRel = function(x, y) { return new window.SVGPathSegMovetoRel(undefined, x, y); }
window.SVGPathElement.prototype.createSVGPathSegLinetoAbs = function(x, y) { return new window.SVGPathSegLinetoAbs(undefined, x, y); }
window.SVGPathElement.prototype.createSVGPathSegLinetoRel = function(x, y) { return new window.SVGPathSegLinetoRel(undefined, x, y); }
window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicAbs = function(x, y, x1, y1, x2, y2) { return new window.SVGPathSegCurvetoCubicAbs(undefined, x, y, x1, y1, x2, y2); }
window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicRel = function(x, y, x1, y1, x2, y2) { return new window.SVGPathSegCurvetoCubicRel(undefined, x, y, x1, y1, x2, y2); }
window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticAbs = function(x, y, x1, y1) { return new window.SVGPathSegCurvetoQuadraticAbs(undefined, x, y, x1, y1); }
window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticRel = function(x, y, x1, y1) { return new window.SVGPathSegCurvetoQuadraticRel(undefined, x, y, x1, y1); }
window.SVGPathElement.prototype.createSVGPathSegArcAbs = function(x, y, r1, r2, angle, largeArcFlag, sweepFlag) { return new window.SVGPathSegArcAbs(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag); }
window.SVGPathElement.prototype.createSVGPathSegArcRel = function(x, y, r1, r2, angle, largeArcFlag, sweepFlag) { return new window.SVGPathSegArcRel(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag); }
window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalAbs = function(x) { return new window.SVGPathSegLinetoHorizontalAbs(undefined, x); }
window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalRel = function(x) { return new window.SVGPathSegLinetoHorizontalRel(undefined, x); }
window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalAbs = function(y) { return new window.SVGPathSegLinetoVerticalAbs(undefined, y); }
window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalRel = function(y) { return new window.SVGPathSegLinetoVerticalRel(undefined, y); }
window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothAbs = function(x, y, x2, y2) { return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, x, y, x2, y2); }
window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothRel = function(x, y, x2, y2) { return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, x, y, x2, y2); }
window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothAbs = function(x, y) { return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, x, y); }
window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothRel = function(x, y) { return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, x, y); }
}
if (!("SVGPathSegList" in window)) {
// Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSegList
window.SVGPathSegList = function(pathElement) {
this._pathElement = pathElement;
this._list = this._parsePath(this._pathElement.getAttribute("d"));
// Use a MutationObserver to catch changes to the path's "d" attribute.
this._mutationObserverConfig = { "attributes": true, "attributeFilter": ["d"] };
this._pathElementMutationObserver = new MutationObserver(this._updateListFromPathMutations.bind(this));
this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig);
}
window.SVGPathSegList.prototype.classname = "SVGPathSegList";
Object.defineProperty(window.SVGPathSegList.prototype, "numberOfItems", {
get: function() {
this._checkPathSynchronizedToList();
return this._list.length;
},
enumerable: true
});
// Add the pathSegList accessors to window.SVGPathElement.
// Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGAnimatedPathData
Object.defineProperty(window.SVGPathElement.prototype, "pathSegList", {
get: function() {
if (!this._pathSegList)
this._pathSegList = new window.SVGPathSegList(this);
return this._pathSegList;
},
enumerable: true
});
// FIXME: The following are not implemented and simply return window.SVGPathElement.pathSegList.
Object.defineProperty(window.SVGPathElement.prototype, "normalizedPathSegList", { get: function() { return this.pathSegList; }, enumerable: true });
Object.defineProperty(window.SVGPathElement.prototype, "animatedPathSegList", { get: function() { return this.pathSegList; }, enumerable: true });
Object.defineProperty(window.SVGPathElement.prototype, "animatedNormalizedPathSegList", { get: function() { return this.pathSegList; }, enumerable: true });
// Process any pending mutations to the path element and update the list as needed.
// This should be the first call of all public functions and is needed because
// MutationObservers are not synchronous so we can have pending asynchronous mutations.
window.SVGPathSegList.prototype._checkPathSynchronizedToList = function() {
this._updateListFromPathMutations(this._pathElementMutationObserver.takeRecords());
}
window.SVGPathSegList.prototype._updateListFromPathMutations = function(mutationRecords) {
if (!this._pathElement)
return;
var hasPathMutations = false;
mutationRecords.forEach(function(record) {
if (record.attributeName == "d")
hasPathMutations = true;
});
if (hasPathMutations)
this._list = this._parsePath(this._pathElement.getAttribute("d"));
}
// Serialize the list and update the path's 'd' attribute.
window.SVGPathSegList.prototype._writeListToPath = function() {
this._pathElementMutationObserver.disconnect();
this._pathElement.setAttribute("d", window.SVGPathSegList._pathSegArrayAsString(this._list));
this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig);
}
// When a path segment changes the list needs to be synchronized back to the path element.
window.SVGPathSegList.prototype.segmentChanged = function(pathSeg) {
this._writeListToPath();
}
window.SVGPathSegList.prototype.clear = function() {
this._checkPathSynchronizedToList();
this._list.forEach(function(pathSeg) {
pathSeg._owningPathSegList = null;
});
this._list = [];
this._writeListToPath();
}
window.SVGPathSegList.prototype.initialize = function(newItem) {
this._checkPathSynchronizedToList();
this._list = [newItem];
newItem._owningPathSegList = this;
this._writeListToPath();
return newItem;
}
window.SVGPathSegList.prototype._checkValidIndex = function(index) {
if (isNaN(index) || index < 0 || index >= this.numberOfItems)
throw "INDEX_SIZE_ERR";
}
window.SVGPathSegList.prototype.getItem = function(index) {
this._checkPathSynchronizedToList();
this._checkValidIndex(index);
return this._list[index];
}
window.SVGPathSegList.prototype.insertItemBefore = function(newItem, index) {
this._checkPathSynchronizedToList();
// Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list.
if (index > this.numberOfItems)
index = this.numberOfItems;
if (newItem._owningPathSegList) {
// SVG2 spec says to make a copy.
newItem = newItem.clone();
}
this._list.splice(index, 0, newItem);
newItem._owningPathSegList = this;
this._writeListToPath();
return newItem;
}
window.SVGPathSegList.prototype.replaceItem = function(newItem, index) {
this._checkPathSynchronizedToList();
if (newItem._owningPathSegList) {
// SVG2 spec says to make a copy.
newItem = newItem.clone();
}
this._checkValidIndex(index);
this._list[index] = newItem;
newItem._owningPathSegList = this;
this._writeListToPath();
return newItem;
}
window.SVGPathSegList.prototype.removeItem = function(index) {
this._checkPathSynchronizedToList();
this._checkValidIndex(index);
var item = this._list[index];
this._list.splice(index, 1);
this._writeListToPath();
return item;
}
window.SVGPathSegList.prototype.appendItem = function(newItem) {
this._checkPathSynchronizedToList();
if (newItem._owningPathSegList) {
// SVG2 spec says to make a copy.
newItem = newItem.clone();
}
this._list.push(newItem);
newItem._owningPathSegList = this;
// TODO: Optimize this to just append to the existing attribute.
this._writeListToPath();
return newItem;
}
window.SVGPathSegList._pathSegArrayAsString = function(pathSegArray) {
var string = "";
var first = true;
pathSegArray.forEach(function(pathSeg) {
if (first) {
first = false;
string += pathSeg._asPathString();
} else {
string += " " + pathSeg._asPathString();
}
});
return string;
}
// This closely follows SVGPathParser::parsePath from Source/core/svg/SVGPathParser.cpp.
window.SVGPathSegList.prototype._parsePath = function(string) {
if (!string || string.length == 0)
return [];
var owningPathSegList = this;
var Builder = function() {
this.pathSegList = [];
}
Builder.prototype.appendSegment = function(pathSeg) {
this.pathSegList.push(pathSeg);
}
var Source = function(string) {
this._string = string;
this._currentIndex = 0;
this._endIndex = this._string.length;
this._previousCommand = window.SVGPathSeg.PATHSEG_UNKNOWN;
this._skipOptionalSpaces();
}
Source.prototype._isCurrentSpace = function() {
var character = this._string[this._currentIndex];
return character <= " " && (character == " " || character == "\n" || character == "\t" || character == "\r" || character == "\f");
}
Source.prototype._skipOptionalSpaces = function() {
while (this._currentIndex < this._endIndex && this._isCurrentSpace())
this._currentIndex++;
return this._currentIndex < this._endIndex;
}
Source.prototype._skipOptionalSpacesOrDelimiter = function() {
if (this._currentIndex < this._endIndex && !this._isCurrentSpace() && this._string.charAt(this._currentIndex) != ",")
return false;
if (this._skipOptionalSpaces()) {
if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ",") {
this._currentIndex++;
this._skipOptionalSpaces();
}
}
return this._currentIndex < this._endIndex;
}
Source.prototype.hasMoreData = function() {
return this._currentIndex < this._endIndex;
}
Source.prototype.peekSegmentType = function() {
var lookahead = this._string[this._currentIndex];
return this._pathSegTypeFromChar(lookahead);
}
Source.prototype._pathSegTypeFromChar = function(lookahead) {
switch (lookahead) {
case "Z":
case "z":
return window.SVGPathSeg.PATHSEG_CLOSEPATH;
case "M":
return window.SVGPathSeg.PATHSEG_MOVETO_ABS;
case "m":
return window.SVGPathSeg.PATHSEG_MOVETO_REL;
case "L":
return window.SVGPathSeg.PATHSEG_LINETO_ABS;
case "l":
return window.SVGPathSeg.PATHSEG_LINETO_REL;
case "C":
return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS;
case "c":
return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL;
case "Q":
return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS;
case "q":
return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL;
case "A":
return window.SVGPathSeg.PATHSEG_ARC_ABS;
case "a":
return window.SVGPathSeg.PATHSEG_ARC_REL;
case "H":
return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS;
case "h":
return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL;
case "V":
return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS;
case "v":
return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL;
case "S":
return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS;
case "s":
return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL;
case "T":
return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS;
case "t":
return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL;
default:
return window.SVGPathSeg.PATHSEG_UNKNOWN;
}
}
Source.prototype._nextCommandHelper = function(lookahead, previousCommand) {
// Check for remaining coordinates in the current command.
if ((lookahead == "+" || lookahead == "-" || lookahead == "." || (lookahead >= "0" && lookahead <= "9")) && previousCommand != window.SVGPathSeg.PATHSEG_CLOSEPATH) {
if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_ABS)
return window.SVGPathSeg.PATHSEG_LINETO_ABS;
if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_REL)
return window.SVGPathSeg.PATHSEG_LINETO_REL;
return previousCommand;
}
return window.SVGPathSeg.PATHSEG_UNKNOWN;
}
Source.prototype.initialCommandIsMoveTo = function() {
// If the path is empty it is still valid, so return true.
if (!this.hasMoreData())
return true;
var command = this.peekSegmentType();
// Path must start with moveTo.
return command == window.SVGPathSeg.PATHSEG_MOVETO_ABS || command == window.SVGPathSeg.PATHSEG_MOVETO_REL;
}
// Parse a number from an SVG path. This very closely follows genericParseNumber(...) from Source/core/svg/SVGParserUtilities.cpp.
// Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-PathDataBNF
Source.prototype._parseNumber = function() {
var exponent = 0;
var integer = 0;
var frac = 1;
var decimal = 0;
var sign = 1;
var expsign = 1;
var startIndex = this._currentIndex;
this._skipOptionalSpaces();
// Read the sign.
if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == "+")
this._currentIndex++;
else if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == "-") {
this._currentIndex++;
sign = -1;
}
if (this._currentIndex == this._endIndex || ((this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") && this._string.charAt(this._currentIndex) != "."))
// The first character of a number must be one of [0-9+-.].
return undefined;
// Read the integer part, build right-to-left.
var startIntPartIndex = this._currentIndex;
while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9")
this._currentIndex++; // Advance to first non-digit.
if (this._currentIndex != startIntPartIndex) {
var scanIntPartIndex = this._currentIndex - 1;
var multiplier = 1;
while (scanIntPartIndex >= startIntPartIndex) {
integer += multiplier * (this._string.charAt(scanIntPartIndex--) - "0");
multiplier *= 10;
}
}
// Read the decimals.
if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ".") {
this._currentIndex++;
// There must be a least one digit following the .
if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9")
return undefined;
while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") {
frac *= 10;
decimal += (this._string.charAt(this._currentIndex) - "0") / frac;
this._currentIndex += 1;
}
}
// Read the exponent part.
if (this._currentIndex != startIndex && this._currentIndex + 1 < this._endIndex && (this._string.charAt(this._currentIndex) == "e" || this._string.charAt(this._currentIndex) == "E") && (this._string.charAt(this._currentIndex + 1) != "x" && this._string.charAt(this._currentIndex + 1) != "m")) {
this._currentIndex++;
// Read the sign of the exponent.
if (this._string.charAt(this._currentIndex) == "+") {
this._currentIndex++;
} else if (this._string.charAt(this._currentIndex) == "-") {
this._currentIndex++;
expsign = -1;
}
// There must be an exponent.
if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9")
return undefined;
while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") {
exponent *= 10;
exponent += (this._string.charAt(this._currentIndex) - "0");
this._currentIndex++;
}
}
var number = integer + decimal;
number *= sign;
if (exponent)
number *= Math.pow(10, expsign * exponent);
if (startIndex == this._currentIndex)
return undefined;
this._skipOptionalSpacesOrDelimiter();
return number;
}
Source.prototype._parseArcFlag = function() {
if (this._currentIndex >= this._endIndex)
return undefined;
var flag = false;
var flagChar = this._string.charAt(this._currentIndex++);
if (flagChar == "0")
flag = false;
else if (flagChar == "1")
flag = true;
else
return undefined;
this._skipOptionalSpacesOrDelimiter();
return flag;
}
Source.prototype.parseSegment = function() {
var lookahead = this._string[this._currentIndex];
var command = this._pathSegTypeFromChar(lookahead);
if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) {
// Possibly an implicit command. Not allowed if this is the first command.
if (this._previousCommand == window.SVGPathSeg.PATHSEG_UNKNOWN)
return null;
command = this._nextCommandHelper(lookahead, this._previousCommand);
if (command == window.SVGPathSeg.PATHSEG_UNKNOWN)
return null;
} else {
this._currentIndex++;
}
this._previousCommand = command;
switch (command) {
case window.SVGPathSeg.PATHSEG_MOVETO_REL:
return new window.SVGPathSegMovetoRel(owningPathSegList, this._parseNumber(), this._parseNumber());
case window.SVGPathSeg.PATHSEG_MOVETO_ABS:
return new window.SVGPathSegMovetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
case window.SVGPathSeg.PATHSEG_LINETO_REL:
return new window.SVGPathSegLinetoRel(owningPathSegList, this._parseNumber(), this._parseNumber());
case window.SVGPathSeg.PATHSEG_LINETO_ABS:
return new window.SVGPathSegLinetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:
return new window.SVGPathSegLinetoHorizontalRel(owningPathSegList, this._parseNumber());
case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:
return new window.SVGPathSegLinetoHorizontalAbs(owningPathSegList, this._parseNumber());
case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL:
return new window.SVGPathSegLinetoVerticalRel(owningPathSegList, this._parseNumber());
case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS:
return new window.SVGPathSegLinetoVerticalAbs(owningPathSegList, this._parseNumber());
case window.SVGPathSeg.PATHSEG_CLOSEPATH:
this._skipOptionalSpaces();
return new window.SVGPathSegClosePath(owningPathSegList);
case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL:
var points = {x1: this._parseNumber(), y1: this._parseNumber(), x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
return new window.SVGPathSegCurvetoCubicRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2);
case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS:
var points = {x1: this._parseNumber(), y1: this._parseNumber(), x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
return new window.SVGPathSegCurvetoCubicAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2);
case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
var points = {x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
return new window.SVGPathSegCurvetoCubicSmoothRel(owningPathSegList, points.x, points.y, points.x2, points.y2);
case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
var points = {x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
return new window.SVGPathSegCurvetoCubicSmoothAbs(owningPathSegList, points.x, points.y, points.x2, points.y2);
case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:
var points = {x1: this._parseNumber(), y1: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
return new window.SVGPathSegCurvetoQuadraticRel(owningPathSegList, points.x, points.y, points.x1, points.y1);
case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:
var points = {x1: this._parseNumber(), y1: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
return new window.SVGPathSegCurvetoQuadraticAbs(owningPathSegList, points.x, points.y, points.x1, points.y1);
case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:
return new window.SVGPathSegCurvetoQuadraticSmoothRel(owningPathSegList, this._parseNumber(), this._parseNumber());
case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:
return new window.SVGPathSegCurvetoQuadraticSmoothAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
case window.SVGPathSeg.PATHSEG_ARC_REL:
var points = {x1: this._parseNumber(), y1: this._parseNumber(), arcAngle: this._parseNumber(), arcLarge: this._parseArcFlag(), arcSweep: this._parseArcFlag(), x: this._parseNumber(), y: this._parseNumber()};
return new window.SVGPathSegArcRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep);
case window.SVGPathSeg.PATHSEG_ARC_ABS:
var points = {x1: this._parseNumber(), y1: this._parseNumber(), arcAngle: this._parseNumber(), arcLarge: this._parseArcFlag(), arcSweep: this._parseArcFlag(), x: this._parseNumber(), y: this._parseNumber()};
return new window.SVGPathSegArcAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep);
default:
throw "Unknown path seg type."
}
}
var builder = new Builder();
var source = new Source(string);
if (!source.initialCommandIsMoveTo())
return [];
while (source.hasMoreData()) {
var pathSeg = source.parseSegment();
if (!pathSeg)
return [];
builder.appendSegment(pathSeg);
}
return builder.pathSegList;
}
}
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.