エドワード・マイブリッジの「Horse in motion」をInkscapeでトレースし、各馬をセル化したものをthree.jsのshapeに変換し表示しています。
3Dっぽく回転させてみてます。
下記のURLから動くデモが見れます。Windows 10 Tech Preview 9926 のIE11では動作しませんでした。ひょっとするとIE11ではそもそも動作しないのかもしれません。原因は不明ですが。。
エドワード・マイブリッジの「Horse in motion」をInkscapeでトレースし、各馬をセル化したものをthree.jsのshapeに変換し表示しています。
3Dっぽく回転させてみてます。
下記のURLから動くデモが見れます。Windows 10 Tech Preview 9926 のIE11では動作しませんでした。ひょっとするとIE11ではそもそも動作しないのかもしれません。原因は不明ですが。。
<!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; | |
} | |
} | |
}()); |