mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-07 13:22:07 -05:00
merge upstream
This commit is contained in:
commit
fce29e4b75
36 changed files with 647 additions and 534 deletions
50
examples/Node.js/SVGExport.js
Normal file
50
examples/Node.js/SVGExport.js
Normal file
|
@ -0,0 +1,50 @@
|
|||
var paper = require('paper'),
|
||||
path = require('path'),
|
||||
fs = require('fs');
|
||||
|
||||
paper.setup(new paper.Canvas(300, 600));
|
||||
with (paper) {
|
||||
var stops = [new Color(1, 1, 0, 0), 'red', 'black'];
|
||||
|
||||
var radius = view.bounds.width * 0.4,
|
||||
from = new Point(view.center.x),
|
||||
to = from.add(radius, 0);
|
||||
|
||||
var circle = new Path.Circle({
|
||||
center: from,
|
||||
radius: radius,
|
||||
fillColor: {
|
||||
stops: stops,
|
||||
radial: true,
|
||||
origin: from,
|
||||
destination: to
|
||||
},
|
||||
strokeColor: 'black'
|
||||
});
|
||||
|
||||
var from = view.bounds.leftCenter,
|
||||
to = view.bounds.bottomRight;
|
||||
|
||||
var rect = new Path.Rectangle({
|
||||
from: from,
|
||||
to: to,
|
||||
fillColor: {
|
||||
stops: stops,
|
||||
radial: false,
|
||||
origin: from,
|
||||
destination: to
|
||||
},
|
||||
strokeColor: 'black'
|
||||
});
|
||||
|
||||
rect.rotate(45).scale(0.7);
|
||||
|
||||
var svg = new XMLSerializer().serializeToString(project.exportSVG());
|
||||
|
||||
console.log(svg);
|
||||
|
||||
fs.writeFile(path.resolve(__dirname, 'out.svg'),svg, function (err) {
|
||||
if (err) throw err;
|
||||
console.log('Saved!');
|
||||
});
|
||||
}
|
22
examples/Node.js/SVGImport.js
Normal file
22
examples/Node.js/SVGImport.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
var paper = require('paper'),
|
||||
path = require('path'),
|
||||
fs = require('fs');
|
||||
|
||||
paper.setup(new paper.Canvas(300, 600));
|
||||
with (paper) {
|
||||
fs.readFile('./in.svg', { encoding: 'utf8' }, function (err, data) {
|
||||
if (err)
|
||||
throw err;
|
||||
project.importSVG(data);
|
||||
paper.view.exportFrames({
|
||||
amount: 1,
|
||||
directory: __dirname,
|
||||
onComplete: function() {
|
||||
console.log('Done exporting.');
|
||||
},
|
||||
onProgress: function(event) {
|
||||
console.log(event.percentage + '% complete, frame took: ' + event.delta);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
require('../../node.js/');
|
||||
var paper = require('./Tadpoles');
|
||||
require('paper');
|
||||
var paper = require('./Tadpoles.pjs');
|
||||
|
||||
paper.view.exportFrames({
|
||||
amount: 400,
|
||||
directory: __dirname,
|
|
@ -277,4 +277,4 @@ function onFrame(event) {
|
|||
function onResize(event) {
|
||||
size = view.size;
|
||||
heartPath.position = view.center;
|
||||
}
|
||||
}
|
||||
|
|
16
examples/Node.js/in.svg
Normal file
16
examples/Node.js/in.svg
Normal file
|
@ -0,0 +1,16 @@
|
|||
<svg x="0" y="0" width="300" height="600" version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink">
|
||||
<linearGradient x1="45" y1="345" x2="255" y2="555" gradientUnits="userSpaceOnUse" id="gradient-2">
|
||||
<stop offset="0" stop-color="rgb(255, 255, 0)" stop-opacity="0"></stop>
|
||||
<stop offset="0.5" stop-color="rgb(255, 0, 0)"></stop>
|
||||
<stop offset="1" stop-color="rgb(0, 0, 0)"></stop>
|
||||
</linearGradient>
|
||||
<radialGradient cx="150" cy="150" r="120" gradientUnits="userSpaceOnUse" id="gradient-1">
|
||||
<stop offset="0" stop-color="rgb(255, 255, 0)" stop-opacity="0"></stop>
|
||||
<stop offset="0.5" stop-color="rgb(255, 0, 0)"></stop>
|
||||
<stop offset="1" stop-color="rgb(0, 0, 0)"></stop>
|
||||
</radialGradient>
|
||||
<g fill="none" stroke="rgb(0, 0, 0)" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0">
|
||||
<circle cx="150" cy="150" r="120" fill="url(#gradient-1)"></circle>
|
||||
<rect x="45" y="345" width="210" height="210" transform="rotate(45,150,450)" fill="url(#gradient-2)"></rect>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
|
@ -15,7 +15,7 @@
|
|||
var items = project.activeLayer.firstChild.children;
|
||||
var mouseIsDown = false;
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
items[i].attach({
|
||||
items[i].on({
|
||||
mousedown: function(event) {
|
||||
mouseIsDown = true;
|
||||
},
|
||||
|
|
|
@ -5,103 +5,26 @@
|
|||
<title>Gradients</title>
|
||||
<script type="text/javascript" src="../../dist/paper.js"></script>
|
||||
<script type="text/paperscript" canvas="canvas">
|
||||
project.importSVG(document.getElementById('Layer_1'));
|
||||
project.importSVG(document.getElementById('svg'));
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="500" height="1000" enable-background="new 0 0 595.28 841.89" xml:space="preserve">
|
||||
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="69" y1="239.5" x2="530" y2="239.5">
|
||||
<stop offset="0" style="stop-color:#231F20"/>
|
||||
<stop offset="0.0896" style="stop-color:#231F20;stop-opacity:0.9104"/>
|
||||
<stop offset="1" style="stop-color:#231F20;stop-opacity:0"/>
|
||||
</linearGradient>
|
||||
<rect x="69" y="210" fill="url(#SVGID_1_)" width="461" height="59"/>
|
||||
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="69" y1="162.5" x2="530" y2="162.5">
|
||||
<stop offset="0" style="stop-color:#00A14B"/>
|
||||
<stop offset="0.0031" style="stop-color:#0BA449"/>
|
||||
<stop offset="0.0203" style="stop-color:#43B13D"/>
|
||||
<stop offset="0.038" style="stop-color:#75BD33"/>
|
||||
<stop offset="0.0559" style="stop-color:#A0C72A"/>
|
||||
<stop offset="0.074" style="stop-color:#C2CF23"/>
|
||||
<stop offset="0.0922" style="stop-color:#DDD61E"/>
|
||||
<stop offset="0.1107" style="stop-color:#F0DA1A"/>
|
||||
<stop offset="0.1298" style="stop-color:#FBDD18"/>
|
||||
<stop offset="0.15" style="stop-color:#FFDE17"/>
|
||||
<stop offset="0.3" style="stop-color:#F26522"/>
|
||||
<stop offset="0.47" style="stop-color:#00A14B"/>
|
||||
<stop offset="0.64" style="stop-color:#FFDE17"/>
|
||||
<stop offset="0.8012" style="stop-color:#F26522"/>
|
||||
<stop offset="1" style="stop-color:#00A14B"/>
|
||||
</linearGradient>
|
||||
<rect x="69" y="133" fill="url(#SVGID_2_)" width="461" height="59"/>
|
||||
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="69" y1="91.5" x2="530" y2="91.5">
|
||||
<stop offset="0%" style="stop-color:#00A14B"/>
|
||||
<stop offset="0.31%" style="stop-color:#0BA449"/>
|
||||
<stop offset="2%" style="stop-color:#43B13D"/>
|
||||
<stop offset="3.8%" style="stop-color:#75BD33"/>
|
||||
<stop offset="5.59%" style="stop-color:#A0C72A"/>
|
||||
<stop offset="7.4%" style="stop-color:#C2CF23"/>
|
||||
<stop offset="9.22%" style="stop-color:#DDD61E"/>
|
||||
<stop offset="11.07%" style="stop-color:#F0DA1A"/>
|
||||
<stop offset="12.98%" style="stop-color:#FBDD18"/>
|
||||
<stop offset="15%" style="stop-color:#FFDE17"/>
|
||||
<stop offset="30%" style="stop-color:#F26522"/>
|
||||
<stop offset="47%" style="stop-color:#00A14B"/>
|
||||
<stop offset="64%" style="stop-color:#FFDE17"/>
|
||||
<stop offset="80.12%" style="stop-color:#F26522"/>
|
||||
<stop offset="100%" style="stop-color:#00A14B"/>
|
||||
</linearGradient>
|
||||
<rect x="69" y="62" fill="url(#SVGID_3_)" width="461" height="59"/>
|
||||
<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="24.6909" y1="760.1406" x2="485.6914" y2="760.1406" gradientTransform="matrix(0 1 -1 0 859.6406 264.3599)">
|
||||
<stop offset="0" style="stop-color:#231F20"/>
|
||||
<stop offset="0.0896" style="stop-color:#231F20;stop-opacity:0.9104"/>
|
||||
<stop offset="1" style="stop-color:#231F20;stop-opacity:0"/>
|
||||
</linearGradient>
|
||||
<rect x="70" y="289.051" fill="url(#SVGID_4_)" width="59" height="461"/>
|
||||
<linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="24.6909" y1="683.1396" x2="485.6914" y2="683.1396" gradientTransform="matrix(0 1 -1 0 859.6406 264.3599)">
|
||||
<stop offset="0" style="stop-color:#00A14B"/>
|
||||
<stop offset="0.0031" style="stop-color:#0BA449"/>
|
||||
<stop offset="0.0203" style="stop-color:#43B13D"/>
|
||||
<stop offset="0.038" style="stop-color:#75BD33"/>
|
||||
<stop offset="0.0559" style="stop-color:#A0C72A"/>
|
||||
<stop offset="0.074" style="stop-color:#C2CF23"/>
|
||||
<stop offset="0.0922" style="stop-color:#DDD61E"/>
|
||||
<stop offset="0.1107" style="stop-color:#F0DA1A"/>
|
||||
<stop offset="0.1298" style="stop-color:#FBDD18"/>
|
||||
<stop offset="0.15" style="stop-color:#FFDE17"/>
|
||||
<stop offset="0.3" style="stop-color:#F26522"/>
|
||||
<stop offset="0.47" style="stop-color:#00A14B"/>
|
||||
<stop offset="0.64" style="stop-color:#FFDE17"/>
|
||||
<stop offset="0.8012" style="stop-color:#F26522"/>
|
||||
<stop offset="1" style="stop-color:#00A14B"/>
|
||||
</linearGradient>
|
||||
<rect x="147.001" y="289.051" fill="url(#SVGID_5_)" width="59" height="461"/>
|
||||
<radialGradient id="SVGID_6_" cx="368.75" cy="409.5503" r="92.1995" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.1656" style="stop-color:#FFFFFF"/>
|
||||
<stop offset="0.2576" style="stop-color:#CBCBCB"/>
|
||||
<stop offset="0.3651" style="stop-color:#969696"/>
|
||||
<stop offset="0.474" style="stop-color:#686868"/>
|
||||
<stop offset="0.5821" style="stop-color:#434343"/>
|
||||
<stop offset="0.6893" style="stop-color:#252525"/>
|
||||
<stop offset="0.7953" style="stop-color:#111111"/>
|
||||
<stop offset="0.8995" style="stop-color:#040404"/>
|
||||
<stop offset="1" style="stop-color:#000000"/>
|
||||
</radialGradient>
|
||||
<circle fill="url(#SVGID_6_)" cx="368.75" cy="409.55" r="92.2"/>
|
||||
<radialGradient id="SVGID_7_" cx="368.75" cy="619.5508" r="92.1997" fx="323.3488" fy="618.7006" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.1656" style="stop-color:#FFFFFF"/>
|
||||
<stop offset="0.2576" style="stop-color:#CBCBCB"/>
|
||||
<stop offset="0.3651" style="stop-color:#969696"/>
|
||||
<stop offset="0.474" style="stop-color:#686868"/>
|
||||
<stop offset="0.5821" style="stop-color:#434343"/>
|
||||
<stop offset="0.6893" style="stop-color:#252525"/>
|
||||
<stop offset="0.7953" style="stop-color:#111111"/>
|
||||
<stop offset="0.8995" style="stop-color:#040404"/>
|
||||
<stop offset="1" style="stop-color:#000000"/>
|
||||
</radialGradient>
|
||||
<circle fill="url(#SVGID_7_)" cx="368.75" cy="619.551" r="92.2"/>
|
||||
</svg>
|
||||
<canvas id="canvas" width="500" height="1000"></canvas>
|
||||
<svg id="svg" x="0" y="0" width="300" height="600" version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink">
|
||||
<linearGradient x1="45" y1="345" x2="255" y2="555" gradientUnits="userSpaceOnUse" id="gradient-2">
|
||||
<stop offset="0" stop-color="rgb(255, 255, 0)" stop-opacity="0"></stop>
|
||||
<stop offset="0.5" stop-color="rgb(255, 0, 0)"></stop>
|
||||
<stop offset="1" stop-color="rgb(0, 0, 0)"></stop>
|
||||
</linearGradient>
|
||||
<radialGradient cx="150" cy="150" r="120" gradientUnits="userSpaceOnUse" id="gradient-1">
|
||||
<stop offset="0" stop-color="rgb(255, 255, 0)" stop-opacity="0"></stop>
|
||||
<stop offset="0.5" stop-color="rgb(255, 0, 0)"></stop>
|
||||
<stop offset="1" stop-color="rgb(0, 0, 0)"></stop>
|
||||
</radialGradient>
|
||||
<g fill="none" stroke="rgb(0, 0, 0)" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0">
|
||||
<circle cx="150" cy="150" r="120" fill="url(#gradient-1)"></circle>
|
||||
<rect x="45" y="345" width="210" height="210" transform="rotate(45,150,450)" fill="url(#gradient-2)"></rect>
|
||||
</g>
|
||||
</svg>
|
||||
<canvas id="canvas" width="300" height="600"></canvas>
|
||||
</body>
|
||||
</html>
|
107
examples/SVG Import/MoreGradients.html
Normal file
107
examples/SVG Import/MoreGradients.html
Normal file
|
@ -0,0 +1,107 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>Gradients</title>
|
||||
<script type="text/javascript" src="../../dist/paper.js"></script>
|
||||
<script type="text/paperscript" canvas="canvas">
|
||||
project.importSVG(document.getElementById('Layer_1'));
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="500" height="1000" enable-background="new 0 0 595.28 841.89" xml:space="preserve">
|
||||
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="69" y1="239.5" x2="530" y2="239.5">
|
||||
<stop offset="0" style="stop-color:#231F20"/>
|
||||
<stop offset="0.0896" style="stop-color:#231F20;stop-opacity:0.9104"/>
|
||||
<stop offset="1" style="stop-color:#231F20;stop-opacity:0"/>
|
||||
</linearGradient>
|
||||
<rect x="69" y="210" fill="url(#SVGID_1_)" width="461" height="59"/>
|
||||
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="69" y1="162.5" x2="530" y2="162.5">
|
||||
<stop offset="0" style="stop-color:#00A14B"/>
|
||||
<stop offset="0.0031" style="stop-color:#0BA449"/>
|
||||
<stop offset="0.0203" style="stop-color:#43B13D"/>
|
||||
<stop offset="0.038" style="stop-color:#75BD33"/>
|
||||
<stop offset="0.0559" style="stop-color:#A0C72A"/>
|
||||
<stop offset="0.074" style="stop-color:#C2CF23"/>
|
||||
<stop offset="0.0922" style="stop-color:#DDD61E"/>
|
||||
<stop offset="0.1107" style="stop-color:#F0DA1A"/>
|
||||
<stop offset="0.1298" style="stop-color:#FBDD18"/>
|
||||
<stop offset="0.15" style="stop-color:#FFDE17"/>
|
||||
<stop offset="0.3" style="stop-color:#F26522"/>
|
||||
<stop offset="0.47" style="stop-color:#00A14B"/>
|
||||
<stop offset="0.64" style="stop-color:#FFDE17"/>
|
||||
<stop offset="0.8012" style="stop-color:#F26522"/>
|
||||
<stop offset="1" style="stop-color:#00A14B"/>
|
||||
</linearGradient>
|
||||
<rect x="69" y="133" fill="url(#SVGID_2_)" width="461" height="59"/>
|
||||
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="69" y1="91.5" x2="530" y2="91.5">
|
||||
<stop offset="0%" style="stop-color:#00A14B"/>
|
||||
<stop offset="0.31%" style="stop-color:#0BA449"/>
|
||||
<stop offset="2%" style="stop-color:#43B13D"/>
|
||||
<stop offset="3.8%" style="stop-color:#75BD33"/>
|
||||
<stop offset="5.59%" style="stop-color:#A0C72A"/>
|
||||
<stop offset="7.4%" style="stop-color:#C2CF23"/>
|
||||
<stop offset="9.22%" style="stop-color:#DDD61E"/>
|
||||
<stop offset="11.07%" style="stop-color:#F0DA1A"/>
|
||||
<stop offset="12.98%" style="stop-color:#FBDD18"/>
|
||||
<stop offset="15%" style="stop-color:#FFDE17"/>
|
||||
<stop offset="30%" style="stop-color:#F26522"/>
|
||||
<stop offset="47%" style="stop-color:#00A14B"/>
|
||||
<stop offset="64%" style="stop-color:#FFDE17"/>
|
||||
<stop offset="80.12%" style="stop-color:#F26522"/>
|
||||
<stop offset="100%" style="stop-color:#00A14B"/>
|
||||
</linearGradient>
|
||||
<rect x="69" y="62" fill="url(#SVGID_3_)" width="461" height="59"/>
|
||||
<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="24.6909" y1="760.1406" x2="485.6914" y2="760.1406" gradientTransform="matrix(0 1 -1 0 859.6406 264.3599)">
|
||||
<stop offset="0" style="stop-color:#231F20"/>
|
||||
<stop offset="0.0896" style="stop-color:#231F20;stop-opacity:0.9104"/>
|
||||
<stop offset="1" style="stop-color:#231F20;stop-opacity:0"/>
|
||||
</linearGradient>
|
||||
<rect x="70" y="289.051" fill="url(#SVGID_4_)" width="59" height="461"/>
|
||||
<linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="24.6909" y1="683.1396" x2="485.6914" y2="683.1396" gradientTransform="matrix(0 1 -1 0 859.6406 264.3599)">
|
||||
<stop offset="0" style="stop-color:#00A14B"/>
|
||||
<stop offset="0.0031" style="stop-color:#0BA449"/>
|
||||
<stop offset="0.0203" style="stop-color:#43B13D"/>
|
||||
<stop offset="0.038" style="stop-color:#75BD33"/>
|
||||
<stop offset="0.0559" style="stop-color:#A0C72A"/>
|
||||
<stop offset="0.074" style="stop-color:#C2CF23"/>
|
||||
<stop offset="0.0922" style="stop-color:#DDD61E"/>
|
||||
<stop offset="0.1107" style="stop-color:#F0DA1A"/>
|
||||
<stop offset="0.1298" style="stop-color:#FBDD18"/>
|
||||
<stop offset="0.15" style="stop-color:#FFDE17"/>
|
||||
<stop offset="0.3" style="stop-color:#F26522"/>
|
||||
<stop offset="0.47" style="stop-color:#00A14B"/>
|
||||
<stop offset="0.64" style="stop-color:#FFDE17"/>
|
||||
<stop offset="0.8012" style="stop-color:#F26522"/>
|
||||
<stop offset="1" style="stop-color:#00A14B"/>
|
||||
</linearGradient>
|
||||
<rect x="147.001" y="289.051" fill="url(#SVGID_5_)" width="59" height="461"/>
|
||||
<radialGradient id="SVGID_6_" cx="368.75" cy="409.5503" r="92.1995" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.1656" style="stop-color:#FFFFFF"/>
|
||||
<stop offset="0.2576" style="stop-color:#CBCBCB"/>
|
||||
<stop offset="0.3651" style="stop-color:#969696"/>
|
||||
<stop offset="0.474" style="stop-color:#686868"/>
|
||||
<stop offset="0.5821" style="stop-color:#434343"/>
|
||||
<stop offset="0.6893" style="stop-color:#252525"/>
|
||||
<stop offset="0.7953" style="stop-color:#111111"/>
|
||||
<stop offset="0.8995" style="stop-color:#040404"/>
|
||||
<stop offset="1" style="stop-color:#000000"/>
|
||||
</radialGradient>
|
||||
<circle fill="url(#SVGID_6_)" cx="368.75" cy="409.55" r="92.2"/>
|
||||
<radialGradient id="SVGID_7_" cx="368.75" cy="619.5508" r="92.1997" fx="323.3488" fy="618.7006" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.1656" style="stop-color:#FFFFFF"/>
|
||||
<stop offset="0.2576" style="stop-color:#CBCBCB"/>
|
||||
<stop offset="0.3651" style="stop-color:#969696"/>
|
||||
<stop offset="0.474" style="stop-color:#686868"/>
|
||||
<stop offset="0.5821" style="stop-color:#434343"/>
|
||||
<stop offset="0.6893" style="stop-color:#252525"/>
|
||||
<stop offset="0.7953" style="stop-color:#111111"/>
|
||||
<stop offset="0.8995" style="stop-color:#040404"/>
|
||||
<stop offset="1" style="stop-color:#000000"/>
|
||||
</radialGradient>
|
||||
<circle fill="url(#SVGID_7_)" cx="368.75" cy="619.551" r="92.2"/>
|
||||
</svg>
|
||||
<canvas id="canvas" width="500" height="1000"></canvas>
|
||||
</body>
|
||||
</html>
|
2
lib/acorn-min.js
vendored
2
lib/acorn-min.js
vendored
File diff suppressed because one or more lines are too long
37
lib/acorn.js
37
lib/acorn.js
|
@ -20,12 +20,16 @@
|
|||
// [dammit]: acorn_loose.js
|
||||
// [walk]: util/walk.js
|
||||
|
||||
(function(exports) {
|
||||
(function(mod) {
|
||||
if (typeof exports == "object" && typeof module == "object") return mod(exports); // CommonJS
|
||||
if (typeof define == "function" && define.amd) return define(["exports"], mod); // AMD
|
||||
mod(this.acorn || (this.acorn = {})); // Plain browser env
|
||||
})(function(exports) {
|
||||
"use strict";
|
||||
|
||||
exports.version = "0.1.01";
|
||||
exports.version = "0.2.01";
|
||||
|
||||
// The main exported interface (under `self.acorn` when in the
|
||||
// The main exported interface (under `this.acorn` when in the
|
||||
// browser) is a `parse` function that takes a code string and
|
||||
// returns an abstract syntax tree as specified by [Mozilla parser
|
||||
// API][api], with the caveat that the SpiderMonkey-specific syntax
|
||||
|
@ -418,17 +422,17 @@
|
|||
|
||||
// Test whether a given character code starts an identifier.
|
||||
|
||||
function isIdentifierStart(code) {
|
||||
var isIdentifierStart = exports.isIdentifierStart = function(code) {
|
||||
if (code < 65) return code === 36;
|
||||
if (code < 91) return true;
|
||||
if (code < 97) return code === 95;
|
||||
if (code < 123)return true;
|
||||
return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code));
|
||||
}
|
||||
};
|
||||
|
||||
// Test whether a given character is part of an identifier.
|
||||
|
||||
function isIdentifierChar(code) {
|
||||
var isIdentifierChar = exports.isIdentifierChar = function(code) {
|
||||
if (code < 48) return code === 36;
|
||||
if (code < 58) return true;
|
||||
if (code < 65) return false;
|
||||
|
@ -436,7 +440,7 @@
|
|||
if (code < 97) return code === 95;
|
||||
if (code < 123)return true;
|
||||
return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code));
|
||||
}
|
||||
};
|
||||
|
||||
// ## Tokenizer
|
||||
|
||||
|
@ -679,7 +683,8 @@
|
|||
}
|
||||
|
||||
function readToken(forceRegexp) {
|
||||
tokStart = tokPos;
|
||||
if (!forceRegexp) tokStart = tokPos;
|
||||
else tokPos = tokStart + 1;
|
||||
if (options.locations) tokStartLoc = new line_loc_t;
|
||||
if (forceRegexp) return readRegexp();
|
||||
if (tokPos >= inputLen) return finishToken(_eof);
|
||||
|
@ -821,7 +826,7 @@
|
|||
case 85: out += String.fromCharCode(readHexChar(8)); break; // 'U'
|
||||
case 116: out += "\t"; break; // 't' -> '\t'
|
||||
case 98: out += "\b"; break; // 'b' -> '\b'
|
||||
case 118: out += "\v"; break; // 'v' -> '\u000b'
|
||||
case 118: out += "\u000b"; break; // 'v' -> '\u000b'
|
||||
case 102: out += "\f"; break; // 'f' -> '\f'
|
||||
case 48: out += "\0"; break; // 0 -> '\0'
|
||||
case 13: if (input.charCodeAt(tokPos) === 10) ++tokPos; // '\r\n'
|
||||
|
@ -940,6 +945,10 @@
|
|||
function setStrict(strct) {
|
||||
strict = strct;
|
||||
tokPos = lastEnd;
|
||||
while (tokPos < tokLineStart) {
|
||||
tokLineStart = input.lastIndexOf("\n", tokLineStart - 2) + 1;
|
||||
--tokCurLine;
|
||||
}
|
||||
skipSpace();
|
||||
readToken();
|
||||
}
|
||||
|
@ -1226,8 +1235,8 @@
|
|||
case _try:
|
||||
next();
|
||||
node.block = parseBlock();
|
||||
node.handlers = [];
|
||||
while (tokType === _catch) {
|
||||
node.handler = null;
|
||||
if (tokType === _catch) {
|
||||
var clause = startNode();
|
||||
next();
|
||||
expect(_parenL);
|
||||
|
@ -1237,10 +1246,10 @@
|
|||
expect(_parenR);
|
||||
clause.guard = null;
|
||||
clause.body = parseBlock();
|
||||
node.handlers.push(finishNode(clause, "CatchClause"));
|
||||
node.handler = finishNode(clause, "CatchClause");
|
||||
}
|
||||
node.finalizer = eat(_finally) ? parseBlock() : null;
|
||||
if (!node.handlers.length && !node.finalizer)
|
||||
if (!node.handler && !node.finalizer)
|
||||
raise(node.start, "Missing catch or finally clause");
|
||||
return finishNode(node, "TryStatement");
|
||||
|
||||
|
@ -1707,4 +1716,4 @@
|
|||
return finishNode(node, "Identifier");
|
||||
}
|
||||
|
||||
})(typeof exports === "undefined" ? (self.acorn = {}) : exports);
|
||||
});
|
||||
|
|
25
lib/bootstrap.js → lib/straps.js
Normal file → Executable file
25
lib/bootstrap.js → lib/straps.js
Normal file → Executable file
|
@ -1,14 +1,21 @@
|
|||
/**
|
||||
* Bootstrap.js JavaScript Inheritance Microframework
|
||||
* Straps.js - Inheritance library with support for bean-style accessors and
|
||||
* AOP patterns.
|
||||
*
|
||||
* Copyright (c) 2006 - 2013 Juerg Lehni
|
||||
* http://lehni.org/
|
||||
*
|
||||
* Distributed under the MIT license.
|
||||
*
|
||||
* straps.js was created by extracting and simplifying the inheritance code from
|
||||
* boostrap.js, a JavaScript DOM library, also published by Juerg Lehni:
|
||||
* https://github.com/lehni/bootstrap.js
|
||||
* The name was changed due to Twitter's introduction of their CSS framework
|
||||
* with the same name.
|
||||
*
|
||||
* Inspirations:
|
||||
* http://dean.edwards.name/weblog/2006/03/base/
|
||||
* http://dev.helma.org/Wiki/JavaScript+Inheritance+Sugar/
|
||||
* http://prototypejs.org/
|
||||
*/
|
||||
|
||||
var Base = new function() { // Bootstrap scope
|
||||
|
@ -36,7 +43,7 @@ var Base = new function() { // Bootstrap scope
|
|||
// supports the first parameter (in the emulation):
|
||||
create = Object.create || function(proto) {
|
||||
// From all browsers that do not offer Object.create(), we only
|
||||
// support Firefox 3.5 & 3.5, but luckily this hack works there:
|
||||
// support Firefox 3.5 & 3.5, and this hack works there:
|
||||
return { __proto__: proto };
|
||||
},
|
||||
_define = Object.defineProperty,
|
||||
|
@ -55,8 +62,8 @@ var Base = new function() { // Bootstrap scope
|
|||
} catch (e) {}
|
||||
}
|
||||
if ((desc.get || desc.set) && obj.__defineGetter__) {
|
||||
desc.get && obj.__defineGetter__(name, desc.get);
|
||||
desc.set && obj.__defineSetter__(name, desc.set);
|
||||
if (desc.get) obj.__defineGetter__(name, desc.get);
|
||||
if (desc.set) obj.__defineSetter__(name, desc.set);
|
||||
} else {
|
||||
obj[name] = desc.value;
|
||||
}
|
||||
|
@ -97,8 +104,12 @@ var Base = new function() { // Bootstrap scope
|
|||
// This does even work for prop: 0, as it will just be looked up
|
||||
// again through describe.
|
||||
var val = val || (val = describe(src, name))
|
||||
&& (val.get ? val : val.value),
|
||||
func = typeof val === 'function',
|
||||
&& (val.get ? val : val.value);
|
||||
// Allow aliases to properties with different names, by having
|
||||
// string values starting with '#'
|
||||
if (typeof val === 'string' && val[0] === '#')
|
||||
val = src[val.substring(1)] || val;
|
||||
var func = typeof val === 'function',
|
||||
res = val,
|
||||
// Only lookup previous value if we preserve or define a
|
||||
// function that might need it for this.base(). If we're
|
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
|
||||
* http://paperjs.org/
|
||||
*
|
||||
* Copyright (c) 2011 - 2013, Juerg Lehni & Jonathan Puckey
|
||||
* http://lehni.org/ & http://jonathanpuckey.com/
|
||||
*
|
||||
* Distributed under the MIT license. See LICENSE file for details.
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
var fs = require('fs'),
|
||||
vm = require('vm'),
|
||||
path = require('path'),
|
||||
Canvas = require('canvas');
|
||||
|
||||
__dirname = path.resolve(__dirname, '../src/');
|
||||
|
||||
// Create the context within which we will run the source files:
|
||||
var context = vm.createContext({
|
||||
options: {
|
||||
server: true,
|
||||
svg: true,
|
||||
parser: 'acorn',
|
||||
version: 'dev'
|
||||
},
|
||||
fs: fs,
|
||||
// Node Canvas library: https://github.com/learnboost/node-canvas
|
||||
Canvas: Canvas,
|
||||
HTMLCanvasElement: Canvas,
|
||||
Image: Canvas.Image,
|
||||
// Copy over global variables:
|
||||
console: console,
|
||||
require: require,
|
||||
__dirname: __dirname,
|
||||
__filename: __filename,
|
||||
// Used to load and run source files within the same context:
|
||||
include: function(uri) {
|
||||
var source = fs.readFileSync(path.resolve(__dirname, uri), 'utf8');
|
||||
// For relative includes, we save the current directory and then
|
||||
// add the uri directory to __dirname:
|
||||
var oldDirname = __dirname;
|
||||
__dirname = path.resolve(__dirname, path.dirname(uri));
|
||||
vm.runInContext(source, context, uri);
|
||||
__dirname = oldDirname;
|
||||
}
|
||||
});
|
||||
|
||||
// Load Paper.js library files:
|
||||
context.include('paper.js');
|
||||
|
||||
// Export all classes through PaperScope:
|
||||
context.Base.each(context, function(val, key) {
|
||||
if (val && val.prototype instanceof context.Base)
|
||||
context.PaperScope.prototype[key] = val;
|
||||
});
|
||||
context.PaperScope.prototype['Canvas'] = context.Canvas;
|
||||
|
||||
require.extensions['.pjs'] = function(module, uri) {
|
||||
var source = context.PaperScript.compile(fs.readFileSync(uri, 'utf8'));
|
||||
var envVars = 'var __dirname = \'' + path.dirname(uri) + '\';' +
|
||||
'var __filename = \'' + uri + '\';';
|
||||
vm.runInContext(envVars, context);
|
||||
var scope = new context.PaperScope();
|
||||
context.PaperScript.evaluate(source, scope);
|
||||
module.exports = scope;
|
||||
};
|
||||
|
||||
module.exports = new context.PaperScope();
|
2
node_modules/.gitignore
generated
vendored
Normal file
2
node_modules/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
canvas
|
||||
jsdom
|
1
node_modules/paper
generated
vendored
Symbolic link
1
node_modules/paper
generated
vendored
Symbolic link
|
@ -0,0 +1 @@
|
|||
../
|
32
package.json
32
package.json
|
@ -1,20 +1,18 @@
|
|||
{
|
||||
"name": "paper",
|
||||
"description": "Vector graphics scripting framework",
|
||||
"version": "0.2.2",
|
||||
"contributors": [{
|
||||
"name" : "Jürg Lehni",
|
||||
"url" : "http://lehni.org"
|
||||
}, {
|
||||
"name" : "Jonathan Puckey",
|
||||
"url" : "http://jonathanpuckey.com"
|
||||
}],
|
||||
"homepage": "http://paperjs.org",
|
||||
"keywords": ["canvas", "graphic", "graphics", "vector", "paper.js"],
|
||||
"repository": "git://github.com/paperjs/paper.js/",
|
||||
"dependencies": {
|
||||
"canvas": ">= 0.7.0"
|
||||
},
|
||||
"version": "0.8.3",
|
||||
"main": "./src/node/index.js",
|
||||
"engines": { "node": ">= 0.4.0" },
|
||||
"main": "./node.js/index.js"
|
||||
}
|
||||
"dependencies": {
|
||||
"canvas": ">= 0.7.0",
|
||||
"jsdom": ">= 0.6.0"
|
||||
},
|
||||
"description": "The Swiss Army Knife of Vector Graphics Scripting",
|
||||
"contributors": [
|
||||
"Jürg Lehni <juerg@lehni.org> (http://lehni.org)",
|
||||
"Jonathan Puckey <jonathan@studiomoniker.com> (http://studiomoniker.com)"
|
||||
],
|
||||
"homepage": "http://paperjs.org",
|
||||
"repository": "git://github.com/paperjs/paper.js",
|
||||
"keywords": ["vector", "graphic", "graphics", "bezier", "curve", "curves", "canvas", "svg", "paper.js"]
|
||||
}
|
||||
|
|
|
@ -18,9 +18,6 @@
|
|||
// jsdoc-toolkit will have its own project file
|
||||
"folder_exclude_patterns": ["jsdoc-toolkit"]
|
||||
},
|
||||
{
|
||||
"path": "../node.js"
|
||||
},
|
||||
{
|
||||
"path": "..",
|
||||
"name": "root",
|
||||
|
|
|
@ -265,7 +265,7 @@ var Matrix = this.Matrix = Base.extend(/** @lends Matrix# */{
|
|||
// Do not modify point, center, since that would arguments of which
|
||||
// we're reading from!
|
||||
var _point = Point.read(arguments),
|
||||
_center = Point.read(arguments);
|
||||
_center = Point.read(arguments, 0, 0, false, true); // readNull
|
||||
if (_center)
|
||||
this.translate(_center);
|
||||
var a = this._a,
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* @private
|
||||
*/
|
||||
// Extend Base with utility functions used across the library. Also set
|
||||
// this.Base on the injection scope, since bootstrap.js ommits that.
|
||||
// this.Base on the injection scope, since straps.js ommits that.
|
||||
this.Base = Base.inject(/** @lends Base# */{
|
||||
// Have generics versions of #clone() and #toString():
|
||||
generics: true,
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
/**
|
||||
* @name Callback
|
||||
* @namespace
|
||||
* @private
|
||||
*/
|
||||
var Callback = {
|
||||
attach: function(type, func) {
|
||||
|
@ -63,6 +64,13 @@ var Callback = {
|
|||
}
|
||||
},
|
||||
|
||||
once: function(type, func) {
|
||||
this.attach(type, function() {
|
||||
func.apply(this, arguments);
|
||||
this.detach(type, func);
|
||||
});
|
||||
},
|
||||
|
||||
fire: function(type, event) {
|
||||
// Returns true if fired, false otherwise
|
||||
var handlers = this._handlers && this._handlers[type];
|
||||
|
@ -82,7 +90,14 @@ var Callback = {
|
|||
return !!(this._handlers && this._handlers[type]);
|
||||
},
|
||||
|
||||
// Install jQuery-style aliases to our event handler methods
|
||||
on: '#attach',
|
||||
off: '#detach',
|
||||
trigger: '#fire',
|
||||
|
||||
statics: {
|
||||
// Override inject() so that sub-classes automatically add the accessors
|
||||
// for the event handler functions (e.g. #onMouseDown) for each property
|
||||
inject: function(/* src, ... */) {
|
||||
for (var i = 0, l = arguments.length; i < l; i++) {
|
||||
var src = arguments[i],
|
||||
|
|
|
@ -1553,9 +1553,7 @@ var Item = this.Item = Base.extend(Callback, {
|
|||
* @param {Item} item The item to be appended as a child
|
||||
* @deprecated use {@link #addChild(item)} instead.
|
||||
*/
|
||||
appendTop: function(item) {
|
||||
return this.addChild(item);
|
||||
},
|
||||
appendTop: '#addChild',
|
||||
|
||||
/**
|
||||
* Inserts the specified item as a child of this item by appending it to
|
||||
|
@ -1576,9 +1574,7 @@ var Item = this.Item = Base.extend(Callback, {
|
|||
* @return {Boolean} {@true it was moved}
|
||||
* @deprecated use {@link #insertAbove(item)} instead.
|
||||
*/
|
||||
moveAbove: function(item) {
|
||||
return this.insertAbove(item);
|
||||
},
|
||||
moveAbove: '#insertAbove',
|
||||
|
||||
/**
|
||||
* Moves the item below the specified item.
|
||||
|
@ -1587,9 +1583,7 @@ var Item = this.Item = Base.extend(Callback, {
|
|||
* @return {Boolean} {@true it was moved}
|
||||
* @deprecated use {@link #insertBelow(item)} instead.
|
||||
*/
|
||||
moveBelow: function(item) {
|
||||
return this.insertBelow(item);
|
||||
},
|
||||
moveBelow: '#insertBelow',
|
||||
|
||||
/**
|
||||
* Removes the item from its parent's named children list.
|
||||
|
@ -2660,7 +2654,7 @@ var Item = this.Item = Base.extend(Callback, {
|
|||
*
|
||||
* Attach an event handler to the item.
|
||||
*
|
||||
* @name Item#attach
|
||||
* @name Item#on
|
||||
* @function
|
||||
* @param {String('mousedown', 'mouseup', 'mousedrag', 'click',
|
||||
* 'doubleclick', 'mousemove', 'mouseenter', 'mouseleave')} type the event
|
||||
|
@ -2680,19 +2674,19 @@ var Item = this.Item = Base.extend(Callback, {
|
|||
* });
|
||||
*
|
||||
* // When the mouse enters the item, set its fill color to red:
|
||||
* path.attach('mouseenter', function() {
|
||||
* path.on('mouseenter', function() {
|
||||
* this.fillColor = 'red';
|
||||
* });
|
||||
*
|
||||
* // When the mouse leaves the item, set its fill color to black:
|
||||
* path.attach('mouseleave', function() {
|
||||
* path.on('mouseleave', function() {
|
||||
* this.fillColor = 'black';
|
||||
* });
|
||||
*/
|
||||
/**
|
||||
* Attach one or more event handlers to the item.
|
||||
*
|
||||
* @name Item#attach^2
|
||||
* @name Item#on^2
|
||||
* @function
|
||||
* @param {Object} param An object literal containing one or more of the
|
||||
* following properties: {@code mousedown, mouseup, mousedrag, click,
|
||||
|
@ -2710,7 +2704,7 @@ var Item = this.Item = Base.extend(Callback, {
|
|||
* path.fillColor = 'black';
|
||||
*
|
||||
* // When the mouse enters the item, set its fill color to red:
|
||||
* path.attach({
|
||||
* path.on({
|
||||
* mouseenter: function(event) {
|
||||
* this.fillColor = 'red';
|
||||
* },
|
||||
|
@ -2742,7 +2736,7 @@ var Item = this.Item = Base.extend(Callback, {
|
|||
* });
|
||||
*
|
||||
* // Attach the handers inside the object literal to the path:
|
||||
* path.attach(pathHandlers);
|
||||
* path.on(pathHandlers);
|
||||
* }
|
||||
*/
|
||||
|
||||
|
|
127
src/node/index.js
Normal file
127
src/node/index.js
Normal file
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
|
||||
* http://paperjs.org/
|
||||
*
|
||||
* Copyright (c) 2011 - 2013, Juerg Lehni & Jonathan Puckey
|
||||
* http://lehni.org/ & http://jonathanpuckey.com/
|
||||
*
|
||||
* Distributed under the MIT license. See LICENSE file for details.
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
var fs = require('fs'),
|
||||
vm = require('vm'),
|
||||
path = require('path'),
|
||||
// Node Canvas library: https://github.com/learnboost/node-canvas
|
||||
Canvas = require('canvas'),
|
||||
jsdom = require('jsdom'),
|
||||
domToHtml = require('jsdom/lib/jsdom/browser/domtohtml').domToHtml,
|
||||
json = require('../../package.json');
|
||||
|
||||
var options = {
|
||||
server: true,
|
||||
svg: true,
|
||||
parser: 'acorn',
|
||||
// Use 'dev' for on-the fly compilation of separate files ,but update after.
|
||||
version: 'dev'
|
||||
};
|
||||
|
||||
// Create a document and a window using jsdom, e.g. for exportSVG()
|
||||
var doc = jsdom.jsdom("<html><body></body></html>"),
|
||||
win = doc.createWindow();
|
||||
|
||||
// Define XMLSerializer.
|
||||
// TODO: Put this into a simple node module, with dependency on jsdom
|
||||
function XMLSerializer() {
|
||||
}
|
||||
|
||||
XMLSerializer.prototype.serializeToString = function(node) {
|
||||
var text = domToHtml(node);
|
||||
// Fix a jsdom issue where linearGradient gets converted to lineargradient:
|
||||
// https://github.com/tmpvar/jsdom/issues/620
|
||||
return text.replace(/(linear|radial)(gradient)/g, function(all, type) {
|
||||
return type + 'Gradient';
|
||||
});
|
||||
};
|
||||
|
||||
function DOMParser() {
|
||||
}
|
||||
|
||||
DOMParser.prototype.parseFromString = function(string, contenType) {
|
||||
var div = doc.createElement('div');
|
||||
div.innerHTML = string;
|
||||
return div.firstChild;
|
||||
};
|
||||
|
||||
// Create the context within which we will run the source files:
|
||||
var dirname = path.resolve(__dirname, '..');
|
||||
var context = vm.createContext({
|
||||
// Used to load and run source files within the same context:
|
||||
include: function(uri) {
|
||||
var source = fs.readFileSync(path.resolve(dirname, uri), 'utf8'),
|
||||
// For relative includes, we save the current directory and then
|
||||
// add the uri directory to dirname:
|
||||
prevDirname = dirname;
|
||||
dirname = path.resolve(dirname, path.dirname(uri));
|
||||
vm.runInContext(source, context, uri);
|
||||
dirname = prevDirname;
|
||||
},
|
||||
// Expose core methods and values
|
||||
__dirname: dirname,
|
||||
require: require,
|
||||
options: options,
|
||||
// Expose node modules
|
||||
fs: fs,
|
||||
Canvas: Canvas,
|
||||
// Expose global browser variables:
|
||||
HTMLCanvasElement: Canvas,
|
||||
XMLSerializer: XMLSerializer,
|
||||
DOMParser: DOMParser,
|
||||
Image: Canvas.Image,
|
||||
window: win,
|
||||
document: doc,
|
||||
navigator: win.navigator,
|
||||
console: console
|
||||
});
|
||||
|
||||
// Load Paper.js library files:
|
||||
context.include('paper.js');
|
||||
// Fix version now. Remove 2nd dot, so we can make a float out of it:
|
||||
options.version = parseFloat(json.version.replace(/(.)(\d)$/, '$2'));
|
||||
|
||||
// Since the created context fo Paper.js compilation, and the context in which
|
||||
// Node.js scripts are executed do not share the definition of Object and Array,
|
||||
// we need to redefine Base.isPlainObject() here.
|
||||
// Object(obj) === obj is a trick from underscore, but also returns true for all
|
||||
// Base objects. So we are filtering these out with an instanceof check, but
|
||||
// Include Base instances since we're using them as hashes.
|
||||
// TODO: Benchmark the speed and consider this implementation instead of the
|
||||
// current one.
|
||||
var Base = context.Base;
|
||||
Base.isPlainObject = function(obj) {
|
||||
return Object(obj) === obj && !Array.isArray(obj) && (!(obj instanceof Base)
|
||||
|| Object.getPrototypeOf(obj) === Base.prototype);
|
||||
};
|
||||
|
||||
// Expose the Canvas, XMLSerializer to paper scopes:
|
||||
Base.each({
|
||||
Canvas: Canvas,
|
||||
XMLSerializer: XMLSerializer,
|
||||
DOMParser: DOMParser
|
||||
}, function(value, key) {
|
||||
this[key] = value;
|
||||
}, context.PaperScope.prototype);
|
||||
|
||||
require.extensions['.pjs'] = function(module, uri) {
|
||||
var source = context.PaperScript.compile(fs.readFileSync(uri, 'utf8'));
|
||||
// Temporarily override __dirname and __filename
|
||||
var envVars = 'var __dirname = \'' + path.dirname(uri) + '\';'
|
||||
+ 'var __filename = \'' + uri + '\';';
|
||||
vm.runInContext(envVars, context);
|
||||
var scope = new context.PaperScope();
|
||||
context.PaperScript.evaluate(source, scope);
|
||||
module.exports = scope;
|
||||
};
|
||||
|
||||
module.exports = new context.PaperScope();
|
13
src/paper.js
13
src/paper.js
|
@ -13,7 +13,9 @@
|
|||
*
|
||||
***
|
||||
*
|
||||
* Bootstrap.js JavaScript Inheritance Micro-Framework
|
||||
* Straps.js - Inheritance library with support for bean-style accessors and
|
||||
* AOP patterns.
|
||||
*
|
||||
* Copyright (c) 2006 - 2013 Juerg Lehni
|
||||
* http://lehni.org/
|
||||
*
|
||||
|
@ -31,7 +33,7 @@
|
|||
|
||||
var paper = new function() {
|
||||
// Inline Bootstrap core (the Base class) inside the paper scope first:
|
||||
/*#*/ include('../lib/bootstrap.js');
|
||||
/*#*/ include('../lib/straps.js');
|
||||
|
||||
/*#*/ if (options.version == 'dev') {
|
||||
/*#*/ include('constants.js');
|
||||
|
@ -90,10 +92,8 @@ var paper = new function() {
|
|||
/*#*/ include('style/GradientStop.js');
|
||||
/*#*/ include('style/Style.js');
|
||||
|
||||
/*#*/ if (options.browser) {
|
||||
/*#*/ include('browser/DomElement.js');
|
||||
/*#*/ include('browser/DomEvent.js');
|
||||
/*#*/ } // options.browser
|
||||
/*#*/ include('dom/DomElement.js');
|
||||
/*#*/ include('dom/DomEvent.js');
|
||||
|
||||
/*#*/ include('ui/View.js');
|
||||
/*#*/ include('ui/CanvasView.js');
|
||||
|
@ -119,6 +119,7 @@ var paper = new function() {
|
|||
|
||||
/*#*/ if (options.svg) {
|
||||
/*#*/ include('svg/SVGStyles.js');
|
||||
/*#*/ include('svg/SVGNamespaces.js');
|
||||
/*#*/ include('svg/SVGExport.js');
|
||||
/*#*/ include('svg/SVGImport.js');
|
||||
/*#*/ } // options.svg
|
||||
|
|
|
@ -907,6 +907,44 @@ statics: {
|
|||
getLocationOf: function(point) {
|
||||
var t = this.getParameterOf.apply(this, arguments);
|
||||
return t != null ? new CurveLocation(this, t) : null;
|
||||
},
|
||||
|
||||
getNearestLocation: function(point) {
|
||||
point = Point.read(arguments);
|
||||
var values = this.getValues(),
|
||||
step = 1 / 100,
|
||||
tolerance = Numerical.TOLERANCE,
|
||||
minDist = Infinity,
|
||||
minT = 0,
|
||||
max = 1 + tolerance; // Accomodate imprecision
|
||||
|
||||
function refine(t) {
|
||||
if (t >= 0 && t <= 1) {
|
||||
var dist = point.getDistance(
|
||||
Curve.evaluate(values, t, true, 0), true);
|
||||
if (dist < minDist) {
|
||||
minDist = dist;
|
||||
minT = t;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var t = 0; t <= max; t += step)
|
||||
refine(t);
|
||||
|
||||
// Now iteratively refine solution until we reach desired precision.
|
||||
step /= 2;
|
||||
while (step > tolerance) {
|
||||
if (!refine(minT - step) && !refine(minT + step))
|
||||
step /= 2;
|
||||
}
|
||||
var pt = Curve.evaluate(values, minT, true, 0);
|
||||
return new CurveLocation(this, minT, pt, null, point.getDistance(pt));
|
||||
},
|
||||
|
||||
getNearestPoint: function(point) {
|
||||
return this.getNearestLocation.apply(this, arguments).getPoint();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1061,193 +1099,4 @@ new function() { // Scope for methods that require numerical integration
|
|||
a, b, 16, /*#=*/ Numerical.TOLERANCE);
|
||||
}
|
||||
};
|
||||
}, new function() { // Scope for nearest point on curve problem
|
||||
|
||||
// Solving the Nearest Point-on-Curve Problem and A Bezier-Based Root-Finder
|
||||
// by Philip J. Schneider from "Graphics Gems", Academic Press, 1990
|
||||
// Optimised for Paper.js
|
||||
|
||||
var maxDepth = 32,
|
||||
epsilon = Math.pow(2, -maxDepth - 1);
|
||||
|
||||
var zCubic = [
|
||||
[1.0, 0.6, 0.3, 0.1],
|
||||
[0.4, 0.6, 0.6, 0.4],
|
||||
[0.1, 0.3, 0.6, 1.0]
|
||||
];
|
||||
|
||||
var xAxis = new Line(new Point(0, 0), new Point(1, 0));
|
||||
|
||||
/**
|
||||
* Given a point and a Bezier curve, generate a 5th-degree Bezier-format
|
||||
* equation whose solution finds the point on the curve nearest the
|
||||
* user-defined point.
|
||||
*/
|
||||
function toBezierForm(v, point) {
|
||||
var n = 3, // degree of B(t)
|
||||
degree = 5, // degree of B(t) . P
|
||||
c = [],
|
||||
d = [],
|
||||
cd = [],
|
||||
w = [];
|
||||
for(var i = 0; i <= n; i++) {
|
||||
// Determine the c's -- these are vectors created by subtracting
|
||||
// point point from each of the control points
|
||||
c[i] = v[i].subtract(point);
|
||||
// Determine the d's -- these are vectors created by subtracting
|
||||
// each control point from the next
|
||||
if (i < n)
|
||||
d[i] = v[i + 1].subtract(v[i]).multiply(n);
|
||||
}
|
||||
|
||||
// Create the c,d table -- this is a table of dot products of the
|
||||
// c's and d's
|
||||
for (var row = 0; row < n; row++) {
|
||||
cd[row] = [];
|
||||
for (var column = 0; column <= n; column++)
|
||||
cd[row][column] = d[row].dot(c[column]);
|
||||
}
|
||||
|
||||
// Now, apply the z's to the dot products, on the skew diagonal
|
||||
// Also, set up the x-values, making these "points"
|
||||
for (var i = 0; i <= degree; i++)
|
||||
w[i] = new Point(i / degree, 0);
|
||||
|
||||
for (var k = 0; k <= degree; k++) {
|
||||
var lb = Math.max(0, k - n + 1),
|
||||
ub = Math.min(k, n);
|
||||
for (var i = lb; i <= ub; i++) {
|
||||
var j = k - i;
|
||||
w[k].y += cd[j][i] * zCubic[j][i];
|
||||
}
|
||||
}
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a 5th-degree equation in Bernstein-Bezier form, find all of the
|
||||
* roots in the interval [0, 1]. Return the number of roots found.
|
||||
*/
|
||||
function findRoots(w, depth) {
|
||||
switch (countCrossings(w)) {
|
||||
case 0:
|
||||
// No solutions here
|
||||
return [];
|
||||
case 1:
|
||||
// Unique solution
|
||||
// Stop recursion when the tree is deep enough
|
||||
// if deep enough, return 1 solution at midpoint
|
||||
if (depth >= maxDepth)
|
||||
return [0.5 * (w[0].x + w[5].x)];
|
||||
// Compute intersection of chord from first control point to last
|
||||
// with x-axis.
|
||||
if (isFlatEnough(w)) {
|
||||
var line = new Line(w[0], w[5], true);
|
||||
return [ Numerical.isZero(line.vector.getLength(true))
|
||||
? line.point.x
|
||||
: xAxis.intersect(line).x ];
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, solve recursively after
|
||||
// subdividing control polygon
|
||||
var p = [[]],
|
||||
left = [],
|
||||
right = [];
|
||||
for (var j = 0; j <= 5; j++)
|
||||
p[0][j] = new Point(w[j]);
|
||||
|
||||
// Triangle computation
|
||||
for (var i = 1; i <= 5; i++) {
|
||||
p[i] = [];
|
||||
for (var j = 0 ; j <= 5 - i; j++)
|
||||
p[i][j] = p[i - 1][j].add(p[i - 1][j + 1]).multiply(0.5);
|
||||
}
|
||||
for (var j = 0; j <= 5; j++) {
|
||||
left[j] = p[j][0];
|
||||
right[j] = p[5 - j][j];
|
||||
}
|
||||
|
||||
return findRoots(left, depth + 1).concat(findRoots(right, depth + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the number of times a Bezier control polygon crosses the x-axis.
|
||||
* This number is >= the number of roots.
|
||||
*/
|
||||
function countCrossings(v) {
|
||||
var crossings = 0,
|
||||
prevSign = null;
|
||||
for (var i = 0, l = v.length; i < l; i++) {
|
||||
var sign = v[i].y < 0 ? -1 : 1;
|
||||
if (prevSign != null && sign != prevSign)
|
||||
crossings++;
|
||||
prevSign = sign;
|
||||
}
|
||||
return crossings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the control polygon of a Bezier curve is flat enough for
|
||||
* recursive subdivision to bottom out.
|
||||
*/
|
||||
function isFlatEnough(v) {
|
||||
// Find the perpendicular distance from each interior control point to
|
||||
// line connecting v[0] and v[degree]
|
||||
|
||||
// Derive the implicit equation for line connecting first
|
||||
// and last control points
|
||||
var n = v.length - 1,
|
||||
a = v[0].y - v[n].y,
|
||||
b = v[n].x - v[0].x,
|
||||
c = v[0].x * v[n].y - v[n].x * v[0].y,
|
||||
maxAbove = 0,
|
||||
maxBelow = 0;
|
||||
// Find the largest distance
|
||||
for (var i = 1; i < n; i++) {
|
||||
// Compute distance from each of the points to that line
|
||||
var val = a * v[i].x + b * v[i].y + c,
|
||||
dist = val * val;
|
||||
if (val < 0 && dist > maxBelow) {
|
||||
maxBelow = dist;
|
||||
} else if (dist > maxAbove) {
|
||||
maxAbove = dist;
|
||||
}
|
||||
}
|
||||
// Compute intercepts of bounding box
|
||||
return Math.abs((maxAbove + maxBelow) / (2 * a * (a * a + b * b)))
|
||||
< epsilon;
|
||||
}
|
||||
|
||||
return {
|
||||
getNearestLocation: function(point) {
|
||||
// NOTE: If we allow #matrix on Path, we need to inverse-transform
|
||||
// point here first.
|
||||
// point = this._matrix.inverseTransform(point);
|
||||
var w = toBezierForm(this.getPoints(), point);
|
||||
// Also look at beginning and end of curve (t = 0 / 1)
|
||||
var roots = findRoots(w, 0).concat([0, 1]);
|
||||
var minDist = Infinity,
|
||||
minT,
|
||||
minPoint;
|
||||
// There are always roots, since we add [0, 1] above.
|
||||
for (var i = 0; i < roots.length; i++) {
|
||||
var pt = this.getPointAt(roots[i], true),
|
||||
dist = point.getDistance(pt, true);
|
||||
// We're comparing squared distances
|
||||
if (dist < minDist) {
|
||||
minDist = dist;
|
||||
minT = roots[i];
|
||||
minPoint = pt;
|
||||
}
|
||||
}
|
||||
return new CurveLocation(this, minT, minPoint, null,
|
||||
Math.sqrt(minDist));
|
||||
},
|
||||
|
||||
getNearestPoint: function(point) {
|
||||
return this.getNearestLocation(point).getPoint();
|
||||
}
|
||||
};
|
||||
});
|
||||
|
|
|
@ -1539,6 +1539,7 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{
|
|||
* the specified point
|
||||
*/
|
||||
getNearestLocation: function(point) {
|
||||
point = this._matrix.inverseTransform(Point.read(arguments));
|
||||
var curves = this.getCurves(),
|
||||
minDist = Infinity,
|
||||
minLoc = null;
|
||||
|
@ -2104,7 +2105,7 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{
|
|||
// and (through, to), and intersect them to get the center
|
||||
var l1 = new Line(from.add(through).divide(2),
|
||||
through.subtract(from).rotate(90)),
|
||||
l2 = new Line(through.add(to).divide(2),
|
||||
l2 = new Line(through.add(to).divide(2),
|
||||
to.subtract(through).rotate(90)),
|
||||
center = l1.intersect(l2),
|
||||
line = new Line(from, to, true),
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* performance, and has to be tested heavily for stability.
|
||||
*
|
||||
* Supported
|
||||
* - paperjs Path and CompoundPath objects
|
||||
* - Path and CompoundPath items
|
||||
* - Boolean Union
|
||||
* - Boolean Intersection
|
||||
* - Boolean Subtraction
|
||||
|
@ -97,7 +97,7 @@ PathItem.inject(new function() {
|
|||
return path;
|
||||
}
|
||||
|
||||
function computeBoolean(path1, path2, operator, subtract, _cache) {
|
||||
function computeBoolean(path1, path2, operator, subtract) {
|
||||
// We do not modify the operands themselves
|
||||
// The result might not belong to the same type
|
||||
// i.e. subtraction(A:Path, B:Path):CompoundPath etc.
|
||||
|
@ -106,13 +106,8 @@ PathItem.inject(new function() {
|
|||
var path1Clockwise = path1.isClockwise(),
|
||||
path2Clockwise = path2.isClockwise(),
|
||||
// Calculate all the intersections
|
||||
intersections = _cache && _cache.intersections
|
||||
|| path1.getIntersections(path2);
|
||||
// If we have an empty _cache object as an operand, skip calculating
|
||||
// boolean and cache the intersections.
|
||||
// if (_cache && !_cache.intersections)
|
||||
// return _cache.intersections = intersections;
|
||||
// Now split intersections on both paths, by asking the first call to
|
||||
intersections = path1.getIntersections(path2);
|
||||
// Split intersections on both paths, by asking the first call to
|
||||
// collect the intersections on the other path for us and passing the
|
||||
// result of that on to the second call.
|
||||
splitPath(splitPath(intersections, true));
|
||||
|
@ -143,8 +138,9 @@ PathItem.inject(new function() {
|
|||
&& (clockwise === path2Clockwise
|
||||
|| !testOnCurve(path2, midPoint));
|
||||
if (operator(path === path1, insidePath1, insidePath2)) {
|
||||
// Mark as invalid, but do not remove yet, so the graph
|
||||
// structure is preserved.
|
||||
// The segment is to be discarded. Don't add it to segments,
|
||||
// and mark it as invalid since it might still be found
|
||||
// through curves / intersections, see below.
|
||||
segment._invalid = true;
|
||||
} else {
|
||||
segments.push(segment);
|
||||
|
@ -160,7 +156,8 @@ PathItem.inject(new function() {
|
|||
loc = segment._intersection,
|
||||
intersection = loc && loc.getSegment(true);
|
||||
if (segment.getPrevious()._invalid)
|
||||
segment.setHandleIn(intersection ? intersection._handleIn
|
||||
segment.setHandleIn(intersection
|
||||
? intersection._handleIn
|
||||
: Point.create(0, 0));
|
||||
do {
|
||||
segment._visited = true;
|
||||
|
@ -176,7 +173,8 @@ PathItem.inject(new function() {
|
|||
segment = segment.getNext();
|
||||
} while (segment && !segment._visited && segment !== intersection);
|
||||
// Avoid stray segments and incomplete paths
|
||||
if (path._segments.length > 2) {
|
||||
var amount = path._segments.length;
|
||||
if (amount > 1 && (amount > 2 || !path.isPolygon())) {
|
||||
path.setClosed(true);
|
||||
result.addChild(path, true);
|
||||
} else {
|
||||
|
@ -219,11 +217,11 @@ PathItem.inject(new function() {
|
|||
* @param {PathItem} path the path to unite with
|
||||
* @return {PathItem} the resulting path item
|
||||
*/
|
||||
unite: function(path, _cache) {
|
||||
unite: function(path) {
|
||||
return computeBoolean(this, path,
|
||||
function(isPath1, isInPath1, isInPath2) {
|
||||
return isInPath1 || isInPath2;
|
||||
}, false, _cache);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -233,11 +231,11 @@ PathItem.inject(new function() {
|
|||
* @param {PathItem} path the path to intersect with
|
||||
* @return {PathItem} the resulting path item
|
||||
*/
|
||||
intersect: function(path, _cache) {
|
||||
intersect: function(path) {
|
||||
return computeBoolean(this, path,
|
||||
function(isPath1, isInPath1, isInPath2) {
|
||||
return !(isInPath1 || isInPath2);
|
||||
}, false, _cache);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -247,11 +245,11 @@ PathItem.inject(new function() {
|
|||
* @param {PathItem} path the path to subtract
|
||||
* @return {PathItem} the resulting path item
|
||||
*/
|
||||
subtract: function(path, _cache) {
|
||||
subtract: function(path) {
|
||||
return computeBoolean(this, path,
|
||||
function(isPath1, isInPath1, isInPath2) {
|
||||
return isPath1 && isInPath2 || !isPath1 && !isInPath1;
|
||||
}, true, _cache);
|
||||
}, true);
|
||||
},
|
||||
|
||||
// Compound boolean operators combine the basic boolean operations such
|
||||
|
|
|
@ -526,6 +526,7 @@ var Color = this.Color = Base.extend(new function() {
|
|||
? 'hsl'
|
||||
: 'hsb'
|
||||
: 'gradient' in arg || 'stops' in arg
|
||||
|| 'radial' in arg
|
||||
? 'gradient'
|
||||
: 'gray' in arg
|
||||
? 'gray'
|
||||
|
@ -580,11 +581,12 @@ var Color = this.Color = Base.extend(new function() {
|
|||
},
|
||||
|
||||
_serialize: function(options, dictionary) {
|
||||
var components = this.getComponents();
|
||||
return Base.serialize(
|
||||
// We can ommit the type for gray and rgb:
|
||||
/^(gray|rgb)$/.test(this._type)
|
||||
? this._components
|
||||
: [this._type].concat(this._components),
|
||||
? components
|
||||
: [this._type].concat(components),
|
||||
options, true, dictionary);
|
||||
},
|
||||
|
||||
|
|
|
@ -15,15 +15,12 @@
|
|||
* Paper.js DOM to a SVG DOM.
|
||||
*/
|
||||
new function() {
|
||||
var formatter = Formatter.instance,
|
||||
namespaces = {
|
||||
href: 'http://www.w3.org/1999/xlink'
|
||||
};
|
||||
var formatter = Formatter.instance;
|
||||
|
||||
function setAttributes(node, attrs) {
|
||||
for (var key in attrs) {
|
||||
var val = attrs[key],
|
||||
namespace = namespaces[key];
|
||||
namespace = SVGNamespaces[key];
|
||||
if (typeof val === 'number')
|
||||
val = formatter.number(val);
|
||||
if (namespace) {
|
||||
|
@ -346,26 +343,26 @@ new function() {
|
|||
origin = color.getOrigin().transform(matrix),
|
||||
destination = color.getDestination().transform(matrix),
|
||||
attrs;
|
||||
if (radial) {
|
||||
attrs = {
|
||||
cx: origin.x,
|
||||
cy: origin.y,
|
||||
r: origin.getDistance(destination)
|
||||
};
|
||||
var highlight = color.getHighlight();
|
||||
if (highlight) {
|
||||
highlight = highlight.transform(matrix);
|
||||
attrs.fx = highlight.x;
|
||||
attrs.fy = highlight.y;
|
||||
}
|
||||
} else {
|
||||
attrs = {
|
||||
x1: origin.x,
|
||||
y1: origin.y,
|
||||
x2: destination.x,
|
||||
y2: destination.y
|
||||
};
|
||||
if (radial) {
|
||||
attrs = {
|
||||
cx: origin.x,
|
||||
cy: origin.y,
|
||||
r: origin.getDistance(destination)
|
||||
};
|
||||
var highlight = color.getHighlight();
|
||||
if (highlight) {
|
||||
highlight = highlight.transform(matrix);
|
||||
attrs.fx = highlight.x;
|
||||
attrs.fy = highlight.y;
|
||||
}
|
||||
} else {
|
||||
attrs = {
|
||||
x1: origin.x,
|
||||
y1: origin.y,
|
||||
x2: destination.x,
|
||||
y2: destination.y
|
||||
};
|
||||
}
|
||||
attrs.gradientUnits = 'userSpaceOnUse';
|
||||
gradientNode = createElement(
|
||||
(radial ? 'radial' : 'linear') + 'Gradient', attrs);
|
||||
|
@ -462,10 +459,11 @@ new function() {
|
|||
function exportDefinitions(node) {
|
||||
if (!definitions)
|
||||
return node;
|
||||
// We can only use node nodes as defintion containers. Have the loop
|
||||
// We can only use svg nodes as defintion containers. Have the loop
|
||||
// produce one if it's a single item of another type (when calling
|
||||
// #exportSVG() on an item rather than a whole project)
|
||||
var container = node.nodeName == 'svg' && node,
|
||||
// jsdom in Node.js uses uppercase values for nodeName...
|
||||
var container = node.nodeName.toLowerCase() === 'svg' && node,
|
||||
firstChild = container ? container.firstChild : node;
|
||||
for (var i in definitions.svgs) {
|
||||
if (!container) {
|
||||
|
@ -513,10 +511,19 @@ new function() {
|
|||
*/
|
||||
exportSVG: function() {
|
||||
var node = createElement('svg'),
|
||||
layers = this.layers;
|
||||
layers = this.layers,
|
||||
size = this.view.getSize();
|
||||
for (var i = 0, l = layers.length; i < l; i++)
|
||||
node.appendChild(exportSVG(layers[i]));
|
||||
return exportDefinitions(node);
|
||||
return setAttributes(exportDefinitions(node), {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: size.width,
|
||||
height: size.height,
|
||||
version: '1.1',
|
||||
xmlns: 'http://www.w3.org/2000/svg',
|
||||
xlink: 'http://www.w3.org/1999/xlink'
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -20,22 +20,22 @@ new function() {
|
|||
// index is option, and if passed, causes a lookup in a list.
|
||||
|
||||
function getValue(node, key, allowNull, index) {
|
||||
// node[key].baseVal will even be set if the node did not define the
|
||||
// attribute, so if allowNull is true, we need to also check
|
||||
// node.getAttribute(key) == null
|
||||
var base = (!allowNull || node.getAttribute(key) != null)
|
||||
&& node[key] && node[key].baseVal;
|
||||
var namespace = SVGNamespaces[key];
|
||||
var value = namespace
|
||||
? node.getAttributeNS(namespace, key)
|
||||
: node.getAttribute(key);
|
||||
// Note: String values are unfortunately not stored in base.value, but
|
||||
// in base directly, so we need to check both, also on item lists, using
|
||||
// Base.pick(base.value, base)
|
||||
return base
|
||||
? index !== undefined
|
||||
// Item list? Look up by index:
|
||||
? index < base.numberOfItems
|
||||
? Base.pick((base = base.getItem(index)).value, base)
|
||||
: null
|
||||
: Base.pick(base.value, base)
|
||||
: null;
|
||||
if (index != null && value != null) {
|
||||
var values = value.split(',');
|
||||
value = values[index];
|
||||
if (value == null)
|
||||
value = values[values.length - 1];
|
||||
}
|
||||
if (/^[\d.+-]/.test(value))
|
||||
value = parseFloat(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
function getPoint(node, x, y, allowNull, index) {
|
||||
|
@ -68,7 +68,7 @@ new function() {
|
|||
|
||||
function importGroup(node, type) {
|
||||
var nodes = node.childNodes,
|
||||
clip = type === 'clipPath',
|
||||
clip = type === 'clippath',
|
||||
item = clip ? new CompoundPath() : new Group(),
|
||||
project = item._project,
|
||||
currentStyle = project._currentStyle;
|
||||
|
@ -142,7 +142,7 @@ new function() {
|
|||
if (child.nodeType == 1)
|
||||
stops.push(applyAttributes(new GradientStop(), child));
|
||||
}
|
||||
var isRadial = type === 'radialGradient',
|
||||
var isRadial = type === 'radialgradient',
|
||||
gradient = new Gradient(stops, isRadial),
|
||||
origin, destination, highlight;
|
||||
if (isRadial) {
|
||||
|
@ -160,12 +160,14 @@ new function() {
|
|||
return null;
|
||||
}
|
||||
|
||||
// NOTE: All importers are lowercase, since jsdom is using uppercase
|
||||
// nodeNames still.
|
||||
var importers = {
|
||||
// http://www.w3.org/TR/SVG/struct.html#Groups
|
||||
g: importGroup,
|
||||
// http://www.w3.org/TR/SVG/struct.html#NewDocument
|
||||
svg: importGroup,
|
||||
clipPath: importGroup,
|
||||
clippath: importGroup,
|
||||
// http://www.w3.org/TR/SVG/shapes.html#PolygonElement
|
||||
polygon: importPoly,
|
||||
// http://www.w3.org/TR/SVG/shapes.html#PolylineElement
|
||||
|
@ -173,9 +175,9 @@ new function() {
|
|||
// http://www.w3.org/TR/SVG/paths.html
|
||||
path: importPath,
|
||||
// http://www.w3.org/TR/SVG/pservers.html#LinearGradients
|
||||
linearGradient: importGradient,
|
||||
lineargradient: importGradient,
|
||||
// http://www.w3.org/TR/SVG/pservers.html#RadialGradients
|
||||
radialGradient: importGradient,
|
||||
radialgradient: importGradient,
|
||||
|
||||
// http://www.w3.org/TR/SVG/struct.html#ImageElement
|
||||
image: function (node) {
|
||||
|
@ -271,12 +273,42 @@ new function() {
|
|||
|
||||
function applyTransform(item, value, name, node) {
|
||||
// http://www.w3.org/TR/SVG/types.html#DataTypeTransformList
|
||||
var transforms = node[name].baseVal,
|
||||
// Parse SVG transform string. First we split at /)\s*/, to separate
|
||||
// commands
|
||||
var transforms = (node.getAttribute(name) || '').split(/\)\s*/g),
|
||||
matrix = new Matrix();
|
||||
for (var i = 0, l = transforms.numberOfItems; i < l; i++) {
|
||||
var mx = transforms.getItem(i).matrix;
|
||||
matrix.concatenate(
|
||||
new Matrix(mx.a, mx.b, mx.c, mx.d, mx.e, mx.f));
|
||||
for (var i = 0, l = transforms.length; i < l; i++) {
|
||||
var transform = transforms[i];
|
||||
if (!transform)
|
||||
break;
|
||||
// Command come before the '(', values after
|
||||
var parts = transform.split('('),
|
||||
command = parts[0],
|
||||
v = parts[1].split(/[\s,]+/g);
|
||||
// Convert values to floats
|
||||
for (var j = 0, m = v.length; j < m; j++)
|
||||
v[j] = parseFloat(v[j]);
|
||||
switch (command) {
|
||||
case 'matrix':
|
||||
matrix.concatenate(
|
||||
new Matrix(v[0], v[2], v[1], v[3], v[4], v[5]));
|
||||
break;
|
||||
case 'rotate':
|
||||
matrix.rotate(v[0], v[1], v[2]);
|
||||
break;
|
||||
case 'translate':
|
||||
matrix.translate(v[0], v[1]);
|
||||
break;
|
||||
case 'scale':
|
||||
matrix.scale(v);
|
||||
break;
|
||||
case 'skewX':
|
||||
case 'skewY':
|
||||
var value = Math.tan(v[0] * Math.PI / 180),
|
||||
isX = command == 'skewX';
|
||||
matrix.shear(isX ? value : 0, isX ? 0 : value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
item.transform(matrix);
|
||||
}
|
||||
|
@ -290,12 +322,15 @@ new function() {
|
|||
color.setAlpha(parseFloat(value));
|
||||
}
|
||||
|
||||
// Create apply-functions for attributes, and merge in those for SVGStlyes:
|
||||
var attributes = Base.each(SVGStyles, function(entry) {
|
||||
// Create apply-functions for attributes, and merge in those for SVGStlyes.
|
||||
// We need to define style attributes first, and merge in all others after,
|
||||
// since transform needs to be applied after fill color, as transformations
|
||||
// can affect gradient fills.
|
||||
var attributes = Base.merge(Base.each(SVGStyles, function(entry) {
|
||||
this[entry.attribute] = function(item, value, name, node) {
|
||||
item._style[entry.set](convertValue(value, entry.type));
|
||||
};
|
||||
}, {
|
||||
}, {}), {
|
||||
id: function(item, value) {
|
||||
definitions[value] = item;
|
||||
if (item.setName)
|
||||
|
@ -359,7 +394,9 @@ new function() {
|
|||
offset: function(item, value) {
|
||||
// http://www.w3.org/TR/SVG/pservers.html#StopElementOffsetAttribute
|
||||
var percentage = value.match(/(.*)%$/);
|
||||
item.setRampPoint(percentage ? percentage[1] / 100 : value);
|
||||
item.setRampPoint(percentage
|
||||
? percentage[1] / 100
|
||||
: parseFloat(value));
|
||||
},
|
||||
|
||||
viewBox: function(item, value, name, node, styles) {
|
||||
|
@ -449,7 +486,10 @@ new function() {
|
|||
}
|
||||
|
||||
function importSVG(node, clearDefs) {
|
||||
var type = node.nodeName,
|
||||
if (typeof node === 'string')
|
||||
node = new DOMParser().parseFromString(node, 'image/svg+xml');
|
||||
// jsdom in Node.js uses uppercase values for nodeName...
|
||||
var type = node.nodeName.toLowerCase(),
|
||||
importer = importers[type],
|
||||
item = importer && importer(node, type),
|
||||
data = node.getAttribute('data-paper-data');
|
||||
|
|
16
src/svg/SVGNamespaces.js
Normal file
16
src/svg/SVGNamespaces.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
|
||||
* http://paperjs.org/
|
||||
*
|
||||
* Copyright (c) 2011 - 2013, Juerg Lehni & Jonathan Puckey
|
||||
* http://lehni.org/ & http://jonathanpuckey.com/
|
||||
*
|
||||
* Distributed under the MIT license. See LICENSE file for details.
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
var SVGNamespaces = {
|
||||
href: 'http://www.w3.org/1999/xlink',
|
||||
xlink: 'http://www.w3.org/2000/xmlns'
|
||||
};
|
|
@ -100,23 +100,13 @@ var TextItem = this.TextItem = Item.extend(/** @lends TextItem# */{
|
|||
* @private
|
||||
* @deprecated use {@link #getStyle()} instead.
|
||||
*/
|
||||
getCharacterStyle: function() {
|
||||
return this.getStyle();
|
||||
},
|
||||
|
||||
setCharacterStyle: function(style) {
|
||||
this.setStyle(style);
|
||||
},
|
||||
getCharacterStyle: '#getStyle',
|
||||
setCharacterStyle: '#setStyle',
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @deprecated use {@link #getStyle()} instead.
|
||||
*/
|
||||
getParagraphStyle: function() {
|
||||
return this.getStyle();
|
||||
},
|
||||
|
||||
setParagraphStyle: function(style) {
|
||||
this.setStyle(style);
|
||||
}
|
||||
getParagraphStyle: '#getStyle',
|
||||
setParagraphStyle: '#setStyle'
|
||||
});
|
||||
|
|
|
@ -414,7 +414,7 @@ var Tool = this.Tool = PaperScopeItem.extend(/** @lends Tool# */{
|
|||
*
|
||||
* Attach an event handler to the tool.
|
||||
*
|
||||
* @name Tool#attach
|
||||
* @name Tool#on
|
||||
* @function
|
||||
* @param {String('mousedown', 'mouseup', 'mousedrag', 'mousemove',
|
||||
* 'keydown', 'keyup')} type the event type
|
||||
|
@ -424,7 +424,7 @@ var Tool = this.Tool = PaperScopeItem.extend(/** @lends Tool# */{
|
|||
/**
|
||||
* Attach one or more event handlers to the tool.
|
||||
*
|
||||
* @name Tool#attach^2
|
||||
* @name Tool#on^2
|
||||
* @function
|
||||
* @param {Object} param An object literal containing one or more of the
|
||||
* following properties: {@code mousedown, mouseup, mousedrag, mousemove,
|
||||
|
|
|
@ -172,7 +172,6 @@ var CanvasView = View.extend(/** @lends CanvasView# */{
|
|||
/*#*/ if (options.server) {
|
||||
// Node.js server based image exporting code.
|
||||
CanvasView.inject(new function() {
|
||||
var path = require('path');
|
||||
// Utility function that converts a number to a string with
|
||||
// x amount of padded 0 digits:
|
||||
function toPaddedString(number, length) {
|
||||
|
@ -196,7 +195,8 @@ CanvasView.inject(new function() {
|
|||
var view = this,
|
||||
count = 0,
|
||||
frameDuration = 1 / param.fps,
|
||||
lastTime = startTime = Date.now();
|
||||
startTime = Date.now(),
|
||||
lastTime = startTime;
|
||||
|
||||
// Start exporting frames by exporting the first frame:
|
||||
exportFrame(param);
|
||||
|
@ -204,8 +204,8 @@ CanvasView.inject(new function() {
|
|||
function exportFrame(param) {
|
||||
count++;
|
||||
var filename = param.prefix + toPaddedString(count, 6) + '.png',
|
||||
uri = param.directory + '/' + filename;
|
||||
var out = view.exportImage(uri, function() {
|
||||
path = param.directory + '/' + filename;
|
||||
var out = view.exportImage(path, function() {
|
||||
// When the file has been closed, export the next fame:
|
||||
var then = Date.now();
|
||||
if (param.onProgress) {
|
||||
|
@ -237,11 +237,11 @@ CanvasView.inject(new function() {
|
|||
}
|
||||
}
|
||||
},
|
||||
// DOCS: View#exportImage(uri, callback);
|
||||
exportImage: function(uri, callback) {
|
||||
|
||||
// DOCS: View#exportImage(path, callback);
|
||||
exportImage: function(path, callback) {
|
||||
this.draw();
|
||||
// TODO: is it necessary to resolve the path?
|
||||
var out = fs.createWriteStream(path.resolve(__dirname, uri)),
|
||||
var out = fs.createWriteStream(path),
|
||||
stream = this._element.createPNGStream();
|
||||
// Pipe the png stream to the write stream:
|
||||
stream.pipe(out);
|
||||
|
|
|
@ -314,8 +314,8 @@ var View = this.View = Base.extend(Callback, /** @lends View# */{
|
|||
* @type Size
|
||||
* @bean
|
||||
*/
|
||||
getSize: function() {
|
||||
return this.getBounds().getSize();
|
||||
getSize: function(/* dontLink */) {
|
||||
return this.getBounds().getSize(arguments[0]);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -324,8 +324,8 @@ var View = this.View = Base.extend(Callback, /** @lends View# */{
|
|||
* @type Point
|
||||
* @bean
|
||||
*/
|
||||
getCenter: function() {
|
||||
return this.getBounds().getCenter();
|
||||
getCenter: function(/* dontLink */) {
|
||||
return this.getBounds().getCenter(arguments[0]);
|
||||
},
|
||||
|
||||
setCenter: function(center) {
|
||||
|
@ -455,7 +455,7 @@ var View = this.View = Base.extend(Callback, /** @lends View# */{
|
|||
*
|
||||
* Attach an event handler to the view.
|
||||
*
|
||||
* @name View#attach
|
||||
* @name View#on
|
||||
* @function
|
||||
* @param {String('frame', 'resize')} type the event type
|
||||
* @param {Function} function The function to be called when the event
|
||||
|
@ -472,12 +472,12 @@ var View = this.View = Base.extend(Callback, /** @lends View# */{
|
|||
* path.rotate(3);
|
||||
* };
|
||||
*
|
||||
* view.attach('frame', frameHandler);
|
||||
* view.on('frame', frameHandler);
|
||||
*/
|
||||
/**
|
||||
* Attach one or more event handlers to the view.
|
||||
*
|
||||
* @name View#attach^2
|
||||
* @name View#on^2
|
||||
* @function
|
||||
* @param {Object} param An object literal containing one or more of the
|
||||
* following properties: {@code frame, resize}.
|
||||
|
@ -491,7 +491,7 @@ var View = this.View = Base.extend(Callback, /** @lends View# */{
|
|||
* path.rotate(3);
|
||||
* };
|
||||
*
|
||||
* view.attach({
|
||||
* view.on({
|
||||
* frame: frameHandler
|
||||
* });
|
||||
*/
|
||||
|
@ -515,7 +515,7 @@ var View = this.View = Base.extend(Callback, /** @lends View# */{
|
|||
* path.rotate(3);
|
||||
* };
|
||||
*
|
||||
* view.attach({
|
||||
* view.on({
|
||||
* frame: frameHandler
|
||||
* });
|
||||
*
|
||||
|
|
|
@ -203,3 +203,9 @@ test('Item#data', function() {
|
|||
testExportImportJSON(paper.project);
|
||||
});
|
||||
|
||||
test('Color', function() {
|
||||
var path = new Path({
|
||||
fillColor: new Color(1, 1, 0, 0.5)
|
||||
});
|
||||
testExportImportJSON(paper.project);
|
||||
});
|
Loading…
Reference in a new issue