Merge branch 'dev'

master
Dmitry Baranovskiy 2017-02-05 13:23:31 +11:00
commit b1ff04a2e0
35 changed files with 12399 additions and 15462 deletions

16
.travis.yml Normal file
View File

@ -0,0 +1,16 @@
language: node_js
node_js:
- "node"
sudo: true
before_script:
- npm install -g grunt-cli
- npm install
- grunt
- cd test
script: phantomjs test.js
notifications:
slack: snapsvg:1zY6dZQuE1vhnug8pLSbbYMv

View File

@ -1,3 +1,3 @@
Contributions to this code are covered by the Adobe contributors
license agreeent. Developers must sign and submit the Adobe CLA in
license agreement. Developers must sign and submit the Adobe CLA in
order to contribute to this project.

View File

@ -1,7 +1,31 @@
module.exports = function(grunt) {
var pkg = grunt.file.readJSON("package.json");
var pkg = grunt.file.readJSON("package.json"),
core = [
"./src/mina.js",
"./src/svg.js",
"./src/element.js",
"./src/animation.js",
"./src/matrix.js",
"./src/attr.js",
"./src/class.js",
"./src/attradd.js",
"./src/paper.js",
"./src/path.js",
"./src/set.js",
"./src/equal.js",
"./src/mouse.js",
"./src/filter.js",
"./src/align.js",
"./src/colors.js"
],
src = [
"./node_modules/eve/eve.js",
"./src/amd-banner.js",
"./src/amd-footer.js"
];
src.splice(2, 0, core);
// Project configuration.
grunt.initConfig({
// Metadata.
@ -26,30 +50,31 @@ module.exports = function(grunt) {
},
target: {
dest: "dist/snap.svg.js",
src: [
"./node_modules/eve/eve.js",
"./src/amd-banner.js",
"./src/mina.js",
"./src/svg.js",
"./src/element.js",
"./src/matrix.js",
"./src/attr.js",
"./src/class.js",
"./src/attradd.js",
"./src/paper.js",
"./src/path.js",
"./src/set.js",
"./src/equal.js",
"./src/mouse.js",
"./src/filter.js",
"./src/align.js",
"./src/amd-footer.js"
]
src: src
}
},
exec: {
dr: {
command: "node node_modules/dr.js/dr dr.json"
},
test: {
command: "cd test; phantomjs test.js"
},
eslint: {
command: "./node_modules/eslint/bin/eslint.js " + core.join(" ")
},
},
prettify: {
options: {
indent: 4,
indent_char: " ",
wrap_line_length: 80,
brace_style: "expand",
unformatted: ["code", "pre", "script"]
},
one: {
src: "./doc/reference.html",
dest: "./doc/reference.html"
}
}
});
@ -57,6 +82,9 @@ module.exports = function(grunt) {
grunt.loadNpmTasks("grunt-contrib-concat");
grunt.loadNpmTasks("grunt-contrib-uglify");
grunt.loadNpmTasks("grunt-exec");
grunt.loadNpmTasks("grunt-prettify");
grunt.registerTask("default", ["concat", "uglify", "exec"]);
grunt.registerTask("default", ["exec:eslint", "concat", "uglify", "exec:dr", "prettify"]);
grunt.registerTask("lint", ["exec:eslint"]);
grunt.registerTask("test", ["exec:test"]);
};

View File

@ -1,4 +1,4 @@
[Snap.svg](http://snapsvg.io)
[Snap.svg](http://snapsvg.io) · [![Build Status](https://travis-ci.org/adobe-webplatform/Snap.svg.svg?branch=dev)](https://travis-ci.org/adobe-webplatform/Snap.svg) [![CDNJS](https://img.shields.io/cdnjs/v/snap.svg.svg)](https://cdnjs.com/libraries/snap.svg/) [![GitHub Tag](https://img.shields.io/github/tag/adobe-webplatform/snap.svg.svg)](https://github.com/adobe-webplatform/Snap.svg/releases) [![License](https://img.shields.io/npm/l/snapsvg.svg)](https://github.com/adobe-webplatform/Snap.svg/blob/master/LICENSE)
======
A JavaScript SVG library for the modern web. Learn more at [snapsvg.io](http://snapsvg.io).
@ -6,7 +6,8 @@ A JavaScript SVG library for the modern web. Learn more at [snapsvg.io](http://s
[Follow us on Twitter.](https://twitter.com/snapsvg)
### Install
* [Bower](http://bower.io/) - `bower install snap.svg`
* [Bower](http://bower.io/) - `bower install snap.svg` ![Bower](https://img.shields.io/bower/v/snap.svg.svg)
* [npm](http://npmjs.com/) - `npm install snapsvg` [![npm version](https://img.shields.io/npm/v/snapsvg.svg?style=flat)](https://www.npmjs.com/package/snapsvg) [![Downloads](https://img.shields.io/npm/dt/snapsvg.svg)](https://www.npmjs.com/package/snapsvg)
* Manual Minified - https://github.com/adobe-webplatform/Snap.svg/raw/master/dist/snap.svg-min.js
* Manual Unminified - https://raw.githubusercontent.com/adobe-webplatform/Snap.svg/master/dist/snap.svg.js
@ -16,6 +17,7 @@ A JavaScript SVG library for the modern web. Learn more at [snapsvg.io](http://s
* [About Snap.svg](http://snapsvg.io/about/)
* [Getting Started](http://snapsvg.io/start/)
* [API Reference](http://snapsvg.io/docs/)
* [Slack Room](https://snapsvg.slack.com/). [Invite](https://snapsvg.slack.com/shared_invite/MTM2NTE4MTk3MDYwLTE0ODYwODgzNzUtYjQ0YmM1N2U0Mg)
### Use
@ -31,6 +33,7 @@ const Snap = require(`imports-loader?this=>window,fix=>module.exports=0!snapsvg/
```
### Build
[![Build Status](https://travis-ci.org/adobe-webplatform/Snap.svg.svg?branch=dev)](https://travis-ci.org/adobe-webplatform/Snap.svg)
Snap.svg uses [Grunt](http://gruntjs.com/) to build.
@ -50,10 +53,22 @@ npm install
```
_*Snap.svg uses Grunt 0.4.0. You might want to [read](http://gruntjs.com/getting-started) more on their website if you havent upgraded since a lot has changed._
* Type `grunt` in the command line to build the files.
* The results will be built into the release folder.
* To build the files run
```sh
grunt
```
* The results will be built into the `dist` folder.
* Alternatively type `grunt watch` to have the build run automatically when you make changes to source files.
### Testing
Tests are located in `test` folder. To run tests, simply open `test.html` in there. Automatic tests use PhantomJS to scrap this file, so you can use it as a reference.
Alternatively, install [PhantomJS](http://phantomjs.org) and run command
```sh
grunt test
```
### Contribute
* [Fill out the CLA](http://snapsvg.io/contributions/).
@ -63,6 +78,7 @@ _*Snap.svg uses Grunt 0.4.0. You might want to [read](http://gruntjs.com/getting
git checkout -b my_branch
```
* Add your changes.
* Check that tests are passing
* Commit your changes:
```sh
git commit -am "Added some awesome stuff"

View File

@ -1,6 +1,6 @@
{
"name": "Snap.svg",
"version": "0.4.1",
"version": "0.5.0",
"homepage": "http://snapsvg.io",
"authors": [
"Dmitry Baranovskiy <dmitry@baranovskiy.com>"

View File

@ -2,7 +2,7 @@
"name": "Snap.svg",
"repo": "adobe-webplatform/Snap.svg",
"description": "The JavaScript library for modern SVG graphics.",
"version": "0.3.0",
"version": "0.5.0",
"keywords": ["svg", "snap", "js", "javascript"],
"dependencies": {},
"development": {},

12
dist/snap.svg-min.js vendored

File diff suppressed because one or more lines are too long

1055
dist/snap.svg.js vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -8,6 +8,12 @@
}, {
"url": "src/element.js",
"link": "https://github.com/adobe-webplatform/Snap.svg/blob/master/src/element.js"
}, {
"url": "src/attr.js",
"link": "https://github.com/adobe-webplatform/Snap.svg/blob/master/src/attr.js"
}, {
"url": "src/animation.js",
"link": "https://github.com/adobe-webplatform/Snap.svg/blob/master/src/animation.js"
}, {
"url": "src/matrix.js",
"link": "https://github.com/adobe-webplatform/Snap.svg/blob/master/src/matrix.js"
@ -35,5 +41,8 @@
}, {
"url": "src/set.js",
"link": "https://github.com/adobe-webplatform/Snap.svg/blob/master/src/set.js"
}, {
"url": "src/colors.js",
"link": "https://github.com/adobe-webplatform/Snap.svg/blob/master/src/colors.js"
}]
}

View File

@ -1,3 +1,11 @@
#0.5.0
* Added color palettes for Material and FlatUI
* Added methods for gradients: `Element.stops()`, `Element.addStop()`, `Element.setStops()`
* Fixed matrix splitting for better animation of matrices`
* Various bug fixes
* Better integration of tests and ESlint
#0.4.1
* Bug fixes.

View File

@ -1,6 +1,6 @@
{
"name": "snapsvg",
"version": "0.4.1",
"version": "0.5.0",
"description": "JavaScript Vector Library",
"main": "./dist/snap.svg.js",
"repository": {
@ -8,17 +8,51 @@
"url": "git@github.com:adobe-webplatform/Snap.svg.git"
},
"author": "Dmitry Baranovskiy",
"license": "Apache License v2",
"license": "Apache-2.0",
"dependencies": {
"eve": "~0.4.2"
"eve": "~0.5.1"
},
"devDependencies": {
"grunt": "~0.4.1",
"grunt-contrib-uglify": "~0.2.0",
"grunt-contrib-concat": "~0.3.0",
"grunt-exec": "~0.4.2",
"grunt-prettify": "0.4.0",
"mocha": "*",
"expect.js": "*",
"eslint": "*",
"dr.js": "~0.1.0"
},
"eslintConfig": {
"globals": {
"window": true,
"console": true
},
"rules": {
"block-scoped-var": 0,
"comma-dangle": 0,
"no-extra-parens": 1,
"no-shadow": 0,
"consistent-return": 0,
"eqeqeq": 0,
"no-new-wrappers": 0,
"no-sequences": 1,
"radix": 2,
"new-parens": 0,
"no-underscore-dangle": 0,
"no-path-concat": 0,
"strict": 0,
"camelcase": 0,
"no-extend-native": 0,
"no-loop-func": 0,
"new-cap": 0,
"no-unused-expressions": 0,
"no-mixed-requires": 0,
"quotes": [
1,
"double",
"avoid-escape"
]
}
}
}

View File

@ -5,9 +5,9 @@
define(["eve"], function (eve) {
return factory(glob, eve);
});
} else if (typeof exports != 'undefined') {
} else if (typeof exports != "undefined") {
// Next for Node.js or CommonJS
var eve = require('eve');
var eve = require("eve");
module.exports = factory(glob, eve);
} else {
// Browser globals (glob is window)

207
src/animation.js Normal file
View File

@ -0,0 +1,207 @@
// Copyright (c) 2016 Adobe Systems Incorporated. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
var elproto = Element.prototype,
is = Snap.is,
Str = String,
has = "hasOwnProperty";
function slice(from, to, f) {
return function (arr) {
var res = arr.slice(from, to);
if (res.length == 1) {
res = res[0];
}
return f ? f(res) : res;
};
}
var Animation = function (attr, ms, easing, callback) {
if (typeof easing == "function" && !easing.length) {
callback = easing;
easing = mina.linear;
}
this.attr = attr;
this.dur = ms;
easing && (this.easing = easing);
callback && (this.callback = callback);
};
Snap._.Animation = Animation;
/*\
* Snap.animation
[ method ]
**
* Creates an animation object
**
- attr (object) attributes of final destination
- duration (number) duration of the animation, in milliseconds
- easing (function) #optional one of easing functions of @mina or custom one
- callback (function) #optional callback function that fires when animation ends
= (object) animation object
\*/
Snap.animation = function (attr, ms, easing, callback) {
return new Animation(attr, ms, easing, callback);
};
/*\
* Element.inAnim
[ method ]
**
* Returns a set of animations that may be able to manipulate the current element
**
= (object) in format:
o {
o anim (object) animation object,
o mina (object) @mina object,
o curStatus (number) 0..1 status of the animation: 0 just started, 1 just finished,
o status (function) gets or sets the status of the animation,
o stop (function) stops the animation
o }
\*/
elproto.inAnim = function () {
var el = this,
res = [];
for (var id in el.anims) if (el.anims[has](id)) {
(function (a) {
res.push({
anim: new Animation(a._attrs, a.dur, a.easing, a._callback),
mina: a,
curStatus: a.status(),
status: function (val) {
return a.status(val);
},
stop: function () {
a.stop();
}
});
}(el.anims[id]));
}
return res;
};
/*\
* Snap.animate
[ method ]
**
* Runs generic animation of one number into another with a caring function
**
- from (number|array) number or array of numbers
- to (number|array) number or array of numbers
- setter (function) caring function that accepts one number argument
- duration (number) duration, in milliseconds
- easing (function) #optional easing function from @mina or custom
- callback (function) #optional callback function to execute when animation ends
= (object) animation object in @mina format
o {
o id (string) animation id, consider it read-only,
o duration (function) gets or sets the duration of the animation,
o easing (function) easing,
o speed (function) gets or sets the speed of the animation,
o status (function) gets or sets the status of the animation,
o stop (function) stops the animation
o }
| var rect = Snap().rect(0, 0, 10, 10);
| Snap.animate(0, 10, function (val) {
| rect.attr({
| x: val
| });
| }, 1000);
| // in given context is equivalent to
| rect.animate({x: 10}, 1000);
\*/
Snap.animate = function (from, to, setter, ms, easing, callback) {
if (typeof easing == "function" && !easing.length) {
callback = easing;
easing = mina.linear;
}
var now = mina.time(),
anim = mina(from, to, now, now + ms, mina.time, setter, easing);
callback && eve.once("mina.finish." + anim.id, callback);
return anim;
};
/*\
* Element.stop
[ method ]
**
* Stops all the animations for the current element
**
= (Element) the current element
\*/
elproto.stop = function () {
var anims = this.inAnim();
for (var i = 0, ii = anims.length; i < ii; i++) {
anims[i].stop();
}
return this;
};
/*\
* Element.animate
[ method ]
**
* Animates the given attributes of the element
**
- attrs (object) key-value pairs of destination attributes
- duration (number) duration of the animation in milliseconds
- easing (function) #optional easing function from @mina or custom
- callback (function) #optional callback function that executes when the animation ends
= (Element) the current element
\*/
elproto.animate = function (attrs, ms, easing, callback) {
if (typeof easing == "function" && !easing.length) {
callback = easing;
easing = mina.linear;
}
if (attrs instanceof Animation) {
callback = attrs.callback;
easing = attrs.easing;
ms = attrs.dur;
attrs = attrs.attr;
}
var fkeys = [], tkeys = [], keys = {}, from, to, f, eq,
el = this;
for (var key in attrs) if (attrs[has](key)) {
if (el.equal) {
eq = el.equal(key, Str(attrs[key]));
from = eq.from;
to = eq.to;
f = eq.f;
} else {
from = +el.attr(key);
to = +attrs[key];
}
var len = is(from, "array") ? from.length : 1;
keys[key] = slice(fkeys.length, fkeys.length + len, f);
fkeys = fkeys.concat(from);
tkeys = tkeys.concat(to);
}
var now = mina.time(),
anim = mina(fkeys, tkeys, now, now + ms, mina.time, function (val) {
var attr = {};
for (var key in keys) if (keys[has](key)) {
attr[key] = keys[key](val);
}
el.attr(attr);
}, easing);
el.anims[anim.id] = anim;
anim._attrs = attrs;
anim._callback = callback;
eve("snap.animcreated." + el.id, anim);
eve.once("mina.finish." + anim.id, function () {
eve.off("mina.*." + anim.id);
delete el.anims[anim.id];
callback && callback.call(el);
});
eve.once("mina.stop." + anim.id, function () {
eve.off("mina.*." + anim.id);
delete el.anims[anim.id];
});
return el;
};
});

View File

@ -17,12 +17,23 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
wrap = Snap._.wrap,
is = Snap.is,
getSomeDefs = Snap._.getSomeDefs,
reURLValue = /^url\(#?([^)]+)\)$/,
reURLValue = /^url\((['"]?)([^)]+)\1\)$/,
$ = Snap._.$,
URL = Snap.url,
Str = String,
separator = Snap._.separator,
E = "";
/*\
* Snap.deurl
[ method ]
**
* Unwraps path from `"url(<path>)"`.
- value (string) url path
= (string) unwrapped path
\*/
Snap.deurl = function (value) {
return String(value).match(reURLValue)[2];
}
// Attributes event handlers
eve.on("snap.util.attr.mask", function (value) {
if (value instanceof Element || value instanceof Fragment) {
@ -53,9 +64,20 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
}(function (value) {
if (value instanceof Element || value instanceof Fragment) {
eve.stop();
if (value.type == "clipPath") {
var clip = value;
} else {
var clip,
node = value.node;
while (node) {
if (node.nodeName === "clipPath") {
clip = new Element(node);
break;
}
if (node.nodeName === "svg") {
clip = undefined;
break;
}
node = node.parentNode;
}
if (!clip) {
clip = make("clipPath", getSomeDefs(this));
clip.node.appendChild(value.node);
!clip.node.id && $(clip.node, {
@ -143,6 +165,23 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
}
return out;
});
var len = stops.length,
start = 0,
j = 0;
function seed(i, end) {
var step = (end - start) / (i - j);
for (var k = j; k < i; k++) {
stops[k].offset = +(+start + step * (k - j)).toFixed(2);
}
j = i;
start = end;
}
len--;
for (var i = 0; i < len; i++) if ("offset" in stops[i]) {
seed(i, stops[i].offset);
}
stops[len].offset = stops[len].offset || 100;
seed(len, stops[len].offset);
return {
type: type,
params: params,
@ -375,6 +414,22 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
eve.on("snap.util.getattr.#text", function () {
return this.node.textContent;
})(-1);
eve.on("snap.util.getattr.fill", function (internal) {
if (internal) {
return;
}
eve.stop();
var value = eve("snap.util.getattr.fill", this, true).firstDefined();
return Snap(Snap.deurl(value)) || value;
})(-1);
eve.on("snap.util.getattr.stroke", function (internal) {
if (internal) {
return;
}
eve.stop();
var value = eve("snap.util.getattr.stroke", this, true).firstDefined();
return Snap(Snap.deurl(value)) || value;
})(-1);
eve.on("snap.util.getattr.viewBox", function () {
eve.stop();
var vb = $(this.node, "viewBox");

View File

@ -38,7 +38,7 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
if (classes.length) {
j = 0;
while ((clazz = classes[j++])) {
while (clazz = classes[j++]) {
pos = curClasses.indexOf(clazz);
if (!~pos) {
curClasses.push(clazz);
@ -72,7 +72,7 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
finalValue;
if (curClasses.length) {
j = 0;
while ((clazz = classes[j++])) {
while (clazz = classes[j++]) {
pos = curClasses.indexOf(clazz);
if (~pos) {
curClasses.splice(pos, 1);
@ -129,7 +129,7 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
clazz,
finalValue;
j = 0;
while ((clazz = classes[j++])) {
while (clazz = classes[j++]) {
pos = curClasses.indexOf(clazz);
if (~pos) {
curClasses.splice(pos, 1);

129
src/colors.js Normal file
View File

@ -0,0 +1,129 @@
// Copyright (c) 2017 Adobe Systems Incorporated. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
Snap.plugin(function (Snap, Element, Paper, glob) {
// Colours are from https://www.materialui.co
var red = "#ffebee#ffcdd2#ef9a9a#e57373#ef5350#f44336#e53935#d32f2f#c62828#b71c1c#ff8a80#ff5252#ff1744#d50000",
pink = "#FCE4EC#F8BBD0#F48FB1#F06292#EC407A#E91E63#D81B60#C2185B#AD1457#880E4F#FF80AB#FF4081#F50057#C51162",
purple = "#F3E5F5#E1BEE7#CE93D8#BA68C8#AB47BC#9C27B0#8E24AA#7B1FA2#6A1B9A#4A148C#EA80FC#E040FB#D500F9#AA00FF",
deeppurple = "#EDE7F6#D1C4E9#B39DDB#9575CD#7E57C2#673AB7#5E35B1#512DA8#4527A0#311B92#B388FF#7C4DFF#651FFF#6200EA",
indigo = "#E8EAF6#C5CAE9#9FA8DA#7986CB#5C6BC0#3F51B5#3949AB#303F9F#283593#1A237E#8C9EFF#536DFE#3D5AFE#304FFE",
blue = "#E3F2FD#BBDEFB#90CAF9#64B5F6#64B5F6#2196F3#1E88E5#1976D2#1565C0#0D47A1#82B1FF#448AFF#2979FF#2962FF",
lightblue = "#E1F5FE#B3E5FC#81D4FA#4FC3F7#29B6F6#03A9F4#039BE5#0288D1#0277BD#01579B#80D8FF#40C4FF#00B0FF#0091EA",
cyan = "#E0F7FA#B2EBF2#80DEEA#4DD0E1#26C6DA#00BCD4#00ACC1#0097A7#00838F#006064#84FFFF#18FFFF#00E5FF#00B8D4",
teal = "#E0F2F1#B2DFDB#80CBC4#4DB6AC#26A69A#009688#00897B#00796B#00695C#004D40#A7FFEB#64FFDA#1DE9B6#00BFA5",
green = "#E8F5E9#C8E6C9#A5D6A7#81C784#66BB6A#4CAF50#43A047#388E3C#2E7D32#1B5E20#B9F6CA#69F0AE#00E676#00C853",
lightgreen = "#F1F8E9#DCEDC8#C5E1A5#AED581#9CCC65#8BC34A#7CB342#689F38#558B2F#33691E#CCFF90#B2FF59#76FF03#64DD17",
lime = "#F9FBE7#F0F4C3#E6EE9C#DCE775#D4E157#CDDC39#C0CA33#AFB42B#9E9D24#827717#F4FF81#EEFF41#C6FF00#AEEA00",
yellow = "#FFFDE7#FFF9C4#FFF59D#FFF176#FFEE58#FFEB3B#FDD835#FBC02D#F9A825#F57F17#FFFF8D#FFFF00#FFEA00#FFD600",
amber = "#FFF8E1#FFECB3#FFE082#FFD54F#FFCA28#FFC107#FFB300#FFA000#FF8F00#FF6F00#FFE57F#FFD740#FFC400#FFAB00",
orange = "#FFF3E0#FFE0B2#FFCC80#FFB74D#FFA726#FF9800#FB8C00#F57C00#EF6C00#E65100#FFD180#FFAB40#FF9100#FF6D00",
deeporange = "#FBE9E7#FFCCBC#FFAB91#FF8A65#FF7043#FF5722#F4511E#E64A19#D84315#BF360C#FF9E80#FF6E40#FF3D00#DD2C00",
brown = "#EFEBE9#D7CCC8#BCAAA4#A1887F#8D6E63#795548#6D4C41#5D4037#4E342E#3E2723",
grey = "#FAFAFA#F5F5F5#EEEEEE#E0E0E0#BDBDBD#9E9E9E#757575#616161#424242#212121",
bluegrey = "#ECEFF1#CFD8DC#B0BEC5#90A4AE#78909C#607D8B#546E7A#455A64#37474F#263238";
/*\
* Snap.mui
[ property ]
**
* Contain Material UI colours.
| Snap().rect(0, 0, 10, 10).attr({fill: Snap.mui.deeppurple, stroke: Snap.mui.amber[600]});
# For colour reference: <a href="https://www.materialui.co">https://www.materialui.co</a>.
\*/
Snap.mui = {};
/*\
* Snap.flat
[ property ]
**
* Contain Flat UI colours.
| Snap().rect(0, 0, 10, 10).attr({fill: Snap.flat.carrot, stroke: Snap.flat.wetasphalt});
# For colour reference: <a href="https://www.materialui.co">https://www.materialui.co</a>.
\*/
Snap.flat = {};
function saveColor(colors) {
colors = colors.split(/(?=#)/);
var color = new String(colors[5]);
color[50] = colors[0];
color[100] = colors[1];
color[200] = colors[2];
color[300] = colors[3];
color[400] = colors[4];
color[500] = colors[5];
color[600] = colors[6];
color[700] = colors[7];
color[800] = colors[8];
color[900] = colors[9];
if (colors[10]) {
color.A100 = colors[10];
color.A200 = colors[11];
color.A400 = colors[12];
color.A700 = colors[13];
}
return color;
}
Snap.mui.red = saveColor(red);
Snap.mui.pink = saveColor(pink);
Snap.mui.purple = saveColor(purple);
Snap.mui.deeppurple = saveColor(deeppurple);
Snap.mui.indigo = saveColor(indigo);
Snap.mui.blue = saveColor(blue);
Snap.mui.lightblue = saveColor(lightblue);
Snap.mui.cyan = saveColor(cyan);
Snap.mui.teal = saveColor(teal);
Snap.mui.green = saveColor(green);
Snap.mui.lightgreen = saveColor(lightgreen);
Snap.mui.lime = saveColor(lime);
Snap.mui.yellow = saveColor(yellow);
Snap.mui.amber = saveColor(amber);
Snap.mui.orange = saveColor(orange);
Snap.mui.deeporange = saveColor(deeporange);
Snap.mui.brown = saveColor(brown);
Snap.mui.grey = saveColor(grey);
Snap.mui.bluegrey = saveColor(bluegrey);
Snap.flat.turquoise = "#1abc9c";
Snap.flat.greensea = "#16a085";
Snap.flat.sunflower = "#f1c40f";
Snap.flat.orange = "#f39c12";
Snap.flat.emerland = "#2ecc71";
Snap.flat.nephritis = "#27ae60";
Snap.flat.carrot = "#e67e22";
Snap.flat.pumpkin = "#d35400";
Snap.flat.peterriver = "#3498db";
Snap.flat.belizehole = "#2980b9";
Snap.flat.alizarin = "#e74c3c";
Snap.flat.pomegranate = "#c0392b";
Snap.flat.amethyst = "#9b59b6";
Snap.flat.wisteria = "#8e44ad";
Snap.flat.clouds = "#ecf0f1";
Snap.flat.silver = "#bdc3c7";
Snap.flat.wetasphalt = "#34495e";
Snap.flat.midnightblue = "#2c3e50";
Snap.flat.concrete = "#95a5a6";
Snap.flat.asbestos = "#7f8c8d";
/*\
* Snap.importMUIColors
[ method ]
**
* Imports Material UI colours into global object.
| Snap.importMUIColors();
| Snap().rect(0, 0, 10, 10).attr({fill: deeppurple, stroke: amber[600]});
# For colour reference: <a href="https://www.materialui.co">https://www.materialui.co</a>.
\*/
Snap.importMUIColors = function () {
for (var color in Snap.mui) {
if (Snap.mui.hasOwnProperty(color)) {
window[color] = Snap.mui[color];
}
}
};
});

View File

@ -1,6 +1,6 @@
// Snap.svg @VERSION
//
// Copyright (c) 2013 2015 Adobe Systems Incorporated. All rights reserved.
// Copyright (c) 2013 2017 Adobe Systems Incorporated. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.

View File

@ -47,6 +47,9 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
o }
\*/
elproto.getBBox = function (isWithoutTransform) {
if (this.type == "tspan") {
return Snap._.box(this.node.getClientRects().item(0));
}
if (!Snap.Matrix || !Snap.path) {
return this.node.getBBox();
}
@ -487,7 +490,7 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
if (val) {
uses[val] = (uses[val] || []).concat(function (id) {
var attr = {};
attr[name] = URL(id);
attr[name] = Snap.url(id);
$(it.node, attr);
});
}
@ -651,193 +654,6 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
p.node.appendChild(this.node);
return p;
};
// animation
function slice(from, to, f) {
return function (arr) {
var res = arr.slice(from, to);
if (res.length == 1) {
res = res[0];
}
return f ? f(res) : res;
};
}
var Animation = function (attr, ms, easing, callback) {
if (typeof easing == "function" && !easing.length) {
callback = easing;
easing = mina.linear;
}
this.attr = attr;
this.dur = ms;
easing && (this.easing = easing);
callback && (this.callback = callback);
};
Snap._.Animation = Animation;
/*\
* Snap.animation
[ method ]
**
* Creates an animation object
**
- attr (object) attributes of final destination
- duration (number) duration of the animation, in milliseconds
- easing (function) #optional one of easing functions of @mina or custom one
- callback (function) #optional callback function that fires when animation ends
= (object) animation object
\*/
Snap.animation = function (attr, ms, easing, callback) {
return new Animation(attr, ms, easing, callback);
};
/*\
* Element.inAnim
[ method ]
**
* Returns a set of animations that may be able to manipulate the current element
**
= (object) in format:
o {
o anim (object) animation object,
o mina (object) @mina object,
o curStatus (number) 0..1 status of the animation: 0 just started, 1 just finished,
o status (function) gets or sets the status of the animation,
o stop (function) stops the animation
o }
\*/
elproto.inAnim = function () {
var el = this,
res = [];
for (var id in el.anims) if (el.anims[has](id)) {
(function (a) {
res.push({
anim: new Animation(a._attrs, a.dur, a.easing, a._callback),
mina: a,
curStatus: a.status(),
status: function (val) {
return a.status(val);
},
stop: function () {
a.stop();
}
});
}(el.anims[id]));
}
return res;
};
/*\
* Snap.animate
[ method ]
**
* Runs generic animation of one number into another with a caring function
**
- from (number|array) number or array of numbers
- to (number|array) number or array of numbers
- setter (function) caring function that accepts one number argument
- duration (number) duration, in milliseconds
- easing (function) #optional easing function from @mina or custom
- callback (function) #optional callback function to execute when animation ends
= (object) animation object in @mina format
o {
o id (string) animation id, consider it read-only,
o duration (function) gets or sets the duration of the animation,
o easing (function) easing,
o speed (function) gets or sets the speed of the animation,
o status (function) gets or sets the status of the animation,
o stop (function) stops the animation
o }
| var rect = Snap().rect(0, 0, 10, 10);
| Snap.animate(0, 10, function (val) {
| rect.attr({
| x: val
| });
| }, 1000);
| // in given context is equivalent to
| rect.animate({x: 10}, 1000);
\*/
Snap.animate = function (from, to, setter, ms, easing, callback) {
if (typeof easing == "function" && !easing.length) {
callback = easing;
easing = mina.linear;
}
var now = mina.time(),
anim = mina(from, to, now, now + ms, mina.time, setter, easing);
callback && eve.once("mina.finish." + anim.id, callback);
return anim;
};
/*\
* Element.stop
[ method ]
**
* Stops all the animations for the current element
**
= (Element) the current element
\*/
elproto.stop = function () {
var anims = this.inAnim();
for (var i = 0, ii = anims.length; i < ii; i++) {
anims[i].stop();
}
return this;
};
/*\
* Element.animate
[ method ]
**
* Animates the given attributes of the element
**
- attrs (object) key-value pairs of destination attributes
- duration (number) duration of the animation in milliseconds
- easing (function) #optional easing function from @mina or custom
- callback (function) #optional callback function that executes when the animation ends
= (Element) the current element
\*/
elproto.animate = function (attrs, ms, easing, callback) {
if (typeof easing == "function" && !easing.length) {
callback = easing;
easing = mina.linear;
}
if (attrs instanceof Animation) {
callback = attrs.callback;
easing = attrs.easing;
ms = attrs.dur;
attrs = attrs.attr;
}
var fkeys = [], tkeys = [], keys = {}, from, to, f, eq,
el = this;
for (var key in attrs) if (attrs[has](key)) {
if (el.equal) {
eq = el.equal(key, Str(attrs[key]));
from = eq.from;
to = eq.to;
f = eq.f;
} else {
from = +el.attr(key);
to = +attrs[key];
}
var len = is(from, "array") ? from.length : 1;
keys[key] = slice(fkeys.length, fkeys.length + len, f);
fkeys = fkeys.concat(from);
tkeys = tkeys.concat(to);
}
var now = mina.time(),
anim = mina(fkeys, tkeys, now, now + ms, mina.time, function (val) {
var attr = {};
for (var key in keys) if (keys[has](key)) {
attr[key] = keys[key](val);
}
el.attr(attr);
}, easing);
el.anims[anim.id] = anim;
anim._attrs = attrs;
anim._callback = callback;
eve("snap.animcreated." + el.id, anim);
eve.once("mina.finish." + anim.id, function () {
delete el.anims[anim.id];
callback && callback.call(el);
});
eve.once("mina.stop." + anim.id, function () {
delete el.anims[anim.id];
});
return el;
};
var eldata = {};
/*\
* Element.data

View File

@ -13,7 +13,7 @@
// limitations under the License.
Snap.plugin(function (Snap, Element, Paper, glob) {
var names = {},
reUnit = /[a-z]+$/i,
reUnit = /[%a-z]+$/i,
Str = String;
names.stroke = names.fill = "colour";
function getEmpty(item) {
@ -36,9 +36,10 @@ Snap.plugin(function (Snap, Element, Paper, glob) {
}
}
function equaliseTransform(t1, t2, getBBox) {
t2 = Str(t2).replace(/\.{3}|\u2026/g, t1);
t1 = Snap.parseTransformString(t1) || [];
t2 = Snap.parseTransformString(t2) || [];
t1 = t1 || new Snap.Matrix;
t2 = t2 || new Snap.Matrix;
t1 = Snap.parseTransformString(t1.toTransformString()) || [];
t2 = Snap.parseTransformString(t2.toTransformString()) || [];
var maxlength = Math.max(t1.length, t2.length),
from = [],
to = [],
@ -47,9 +48,9 @@ Snap.plugin(function (Snap, Element, Paper, glob) {
for (; i < maxlength; i++) {
tt1 = t1[i] || getEmpty(t2[i]);
tt2 = t2[i] || getEmpty(tt1);
if ((tt1[0] != tt2[0]) ||
(tt1[0].toLowerCase() == "r" && (tt1[2] != tt2[2] || tt1[3] != tt2[3])) ||
(tt1[0].toLowerCase() == "s" && (tt1[3] != tt2[3] || tt1[4] != tt2[4]))
if (tt1[0] != tt2[0] ||
tt1[0].toLowerCase() == "r" && (tt1[2] != tt2[2] || tt1[3] != tt2[3]) ||
tt1[0].toLowerCase() == "s" && (tt1[3] != tt2[3] || tt1[4] != tt2[4])
) {
t1 = Snap._.transform2matrix(t1, getBBox());
t2 = Snap._.transform2matrix(t2, getBBox());
@ -82,7 +83,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) {
return val.join(" ");
}
function getColour(clr) {
return Snap.rgb(clr[0], clr[1], clr[2]);
return Snap.rgb(clr[0], clr[1], clr[2], clr[3]);
}
function getPath(path) {
var k = 0, i, ii, j, jj, out, a, b = [];
@ -90,7 +91,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) {
out = "[";
a = ['"' + path[i][0] + '"'];
for (j = 1, jj = path[i].length; j < jj; j++) {
a[j] = "val[" + (k++) + "]";
a[j] = "val[" + k++ + "]";
}
out += a + "]";
b[i] = out;
@ -107,7 +108,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) {
return out;
}
function isNumeric(obj) {
return isFinite(parseFloat(obj));
return isFinite(obj);
}
function arrayEqual(arr1, arr2) {
if (!Snap.is(arr1, "array") || !Snap.is(arr2, "array")) {
@ -121,13 +122,6 @@ Snap.plugin(function (Snap, Element, Paper, glob) {
eve.on("snap.util.equal", function (name, b) {
var A, B, a = Str(this.attr(name) || ""),
el = this;
if (isNumeric(a) && isNumeric(b)) {
return {
from: parseFloat(a),
to: parseFloat(b),
f: getNumber
};
}
if (names[name] == "colour") {
A = Snap.color(a);
B = Snap.color(b);
@ -147,11 +141,14 @@ Snap.plugin(function (Snap, Element, Paper, glob) {
};
}
if (name == "transform" || name == "gradientTransform" || name == "patternTransform") {
if (b instanceof Snap.Matrix) {
b = b.toTransformString();
if (typeof b == "string") {
b = Str(b).replace(/\.{3}|\u2026/g, a);
}
a = this.matrix;
if (!Snap._.rgTransform.test(b)) {
b = Snap._.svgTransform2string(b);
b = Snap._.transform2matrix(Snap._.svgTransform2string(b), this.getBBox());
} else {
b = Snap._.transform2matrix(b, this.getBBox());
}
return equaliseTransform(a, b, function () {
return el.getBBox(1);
@ -174,6 +171,13 @@ Snap.plugin(function (Snap, Element, Paper, glob) {
f: function (val) { return val; }
};
}
if (isNumeric(a) && isNumeric(b)) {
return {
from: parseFloat(a),
to: parseFloat(b),
f: getNumber
};
}
var aUnit = a.match(reUnit),
bUnit = Str(b).match(reUnit);
if (aUnit && arrayEqual(aUnit, bUnit)) {

View File

@ -126,22 +126,23 @@ Snap.plugin(function (Snap, Element, Paper, glob) {
- opacity (number) #optional `0..1` opacity of the shadow
= (string) filter representation
> Usage
| var f = paper.filter(Snap.filter.shadow(0, 2, 3)),
| var f = paper.filter(Snap.filter.shadow(0, 2, .3)),
| c = paper.circle(10, 10, 10).attr({
| filter: f
| });
\*/
Snap.filter.shadow = function (dx, dy, blur, color, opacity) {
if (typeof blur == "string") {
color = blur;
opacity = color;
blur = 4;
if (opacity == null) {
if (color == null) {
opacity = blur;
blur = 4;
color = "#000";
} else {
opacity = color;
color = blur;
blur = 4;
}
}
if (typeof color != "string") {
opacity = color;
color = "#000";
}
color = color || "#000";
if (blur == null) {
blur = 4;
}

View File

@ -58,30 +58,48 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
- matrix (object) @Matrix
\*/
matrixproto.add = function (a, b, c, d, e, f) {
var out = [[], [], []],
m = [[this.a, this.c, this.e], [this.b, this.d, this.f], [0, 0, 1]],
matrix = [[a, c, e], [b, d, f], [0, 0, 1]],
x, y, z, res;
if (a && a instanceof Matrix) {
matrix = [[a.a, a.c, a.e], [a.b, a.d, a.f], [0, 0, 1]];
return this.add(a.a, a.b, a.c, a.d, a.e, a.f);
}
var aNew = a * this.a + b * this.c,
bNew = a * this.b + b * this.d;
this.e += e * this.a + f * this.c;
this.f += e * this.b + f * this.d;
this.c = c * this.a + d * this.c;
this.d = c * this.b + d * this.d;
for (x = 0; x < 3; x++) {
for (y = 0; y < 3; y++) {
res = 0;
for (z = 0; z < 3; z++) {
res += m[x][z] * matrix[z][y];
}
out[x][y] = res;
}
this.a = aNew;
this.b = bNew;
return this;
};
/*\
* Matrix.multLeft
[ method ]
**
* Multiplies a passed affine transform to the left: M * this.
- a (number)
- b (number)
- c (number)
- d (number)
- e (number)
- f (number)
* or
- matrix (object) @Matrix
\*/
Matrix.prototype.multLeft = function (a, b, c, d, e, f) {
if (a && a instanceof Matrix) {
return this.multLeft(a.a, a.b, a.c, a.d, a.e, a.f);
}
this.a = out[0][0];
this.b = out[1][0];
this.c = out[0][1];
this.d = out[1][1];
this.e = out[0][2];
this.f = out[1][2];
var aNew = a * this.a + c * this.b,
cNew = a * this.c + c * this.d,
eNew = a * this.e + c * this.f + e;
this.b = b * this.a + d * this.b;
this.d = b * this.c + d * this.d;
this.f = b * this.e + d * this.f + f;
this.a = aNew;
this.c = cNew;
this.e = eNew;
return this;
};
/*\
@ -115,7 +133,9 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
- y (number) vertical offset distance
\*/
matrixproto.translate = function (x, y) {
return this.add(1, 0, 0, 1, x, y);
this.e += x * this.a + y * this.c;
this.f += x * this.b + y * this.d;
return this;
};
/*\
* Matrix.scale
@ -130,9 +150,12 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
\*/
matrixproto.scale = function (x, y, cx, cy) {
y == null && (y = x);
(cx || cy) && this.add(1, 0, 0, 1, cx, cy);
this.add(x, 0, 0, y, 0, 0);
(cx || cy) && this.add(1, 0, 0, 1, -cx, -cy);
(cx || cy) && this.translate(cx, cy);
this.a *= x;
this.b *= x;
this.c *= y;
this.d *= y;
(cx || cy) && this.translate(-cx, -cy);
return this;
};
/*\
@ -153,6 +176,43 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
this.add(cos, sin, -sin, cos, x, y);
return this.add(1, 0, 0, 1, -x, -y);
};
/*\
* Matrix.skewX
[ method ]
**
* Skews the matrix along the x-axis
- x (number) Angle to skew along the x-axis (in degrees).
\*/
matrixproto.skewX = function (x) {
return this.skew(x, 0);
};
/*\
* Matrix.skewY
[ method ]
**
* Skews the matrix along the y-axis
- y (number) Angle to skew along the y-axis (in degrees).
\*/
matrixproto.skewY = function (y) {
return this.skew(0, y);
};
/*\
* Matrix.skew
[ method ]
**
* Skews the matrix
- y (number) Angle to skew along the y-axis (in degrees).
- x (number) Angle to skew along the x-axis (in degrees).
\*/
matrixproto.skew = function (x, y) {
x = x || 0;
y = y || 0;
x = Snap.rad(x);
y = Snap.rad(y);
var c = math.tan(x).toFixed(9);
var b = math.tan(y).toFixed(9);
return this.add(1, b, c, 1, 0, 0);
};
/*\
* Matrix.x
[ method ]
@ -225,7 +285,7 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
out.dy = this.f;
// scale and shear
var row = [[this.a, this.c], [this.b, this.d]];
var row = [[this.a, this.b], [this.c, this.d]];
out.scalex = math.sqrt(norm(row[0]));
normalize(row[0]);
@ -241,7 +301,7 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
}
// rotation
var sin = -row[0][1],
var sin = row[0][1],
cos = row[1][1];
if (cos < 0) {
out.rotate = Snap.deg(math.acos(cos));
@ -271,8 +331,8 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
s.scaley = +s.scaley.toFixed(4);
s.rotate = +s.rotate.toFixed(4);
return (s.dx || s.dy ? "t" + [+s.dx.toFixed(4), +s.dy.toFixed(4)] : E) +
(s.scalex != 1 || s.scaley != 1 ? "s" + [s.scalex, s.scaley, 0, 0] : E) +
(s.rotate ? "r" + [+s.rotate.toFixed(4), 0, 0] : E);
(s.rotate ? "r" + [+s.rotate.toFixed(4), 0, 0] : E) +
(s.scalex != 1 || s.scaley != 1 ? "s" + [s.scalex, s.scaley, 0, 0] : E);
} else {
return "m" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)];
}

View File

@ -1,4 +1,4 @@
// Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
// Copyright (c) 2017 Adobe Systems Incorporated. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -19,8 +19,10 @@ var mina = (function (eve) {
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
setTimeout(callback, 16);
setTimeout(callback, 16, new Date().getTime());
return true;
},
requestID,
isArray = Array.isArray || function (a) {
return a instanceof Array ||
Object.prototype.toString.call(a) == "[object Array]";
@ -94,6 +96,7 @@ var mina = (function (eve) {
a.b = a.get() - a.pdif;
delete a.pdif;
animations[a.id] = a;
frame();
},
update = function () {
var a = this,
@ -109,7 +112,16 @@ var mina = (function (eve) {
}
a.set(res);
},
frame = function () {
frame = function (timeStamp) {
// Manual invokation?
if (!timeStamp) {
// Frame loop stopped?
if (!requestID) {
// Start frame loop...
requestID = requestAnimFrame(frame);
}
return;
}
var len = 0;
for (var i in animations) if (animations.hasOwnProperty(i)) {
var a = animations[i],
@ -129,7 +141,7 @@ var mina = (function (eve) {
}
a.update();
}
len && requestAnimFrame(frame);
requestID = len ? requestAnimFrame(frame) : false;
},
/*\
* mina
@ -140,7 +152,7 @@ var mina = (function (eve) {
- a (number) start _slave_ number
- A (number) end _slave_ number
- b (number) start _master_ number (start time in general case)
- B (number) end _master_ number (end time in gereal case)
- B (number) end _master_ number (end time in general case)
- get (function) getter of _master_ number (see @mina.time)
- set (function) setter of _slave_ number
- easing (function) #optional easing function, default is @mina.linear
@ -193,7 +205,7 @@ var mina = (function (eve) {
break;
}
}
len == 1 && requestAnimFrame(frame);
len == 1 && frame();
return anim;
};
/*\
@ -333,18 +345,18 @@ var mina = (function (eve) {
var s = 7.5625,
p = 2.75,
l;
if (n < (1 / p)) {
if (n < 1 / p) {
l = s * n * n;
} else {
if (n < (2 / p)) {
n -= (1.5 / p);
if (n < 2 / p) {
n -= 1.5 / p;
l = s * n * n + .75;
} else {
if (n < (2.5 / p)) {
n -= (2.25 / p);
if (n < 2.5 / p) {
n -= 2.25 / p;
l = s * n * n + .9375;
} else {
n -= (2.625 / p);
n -= 2.625 / p;
l = s * n * n + .984375;
}
}

View File

@ -512,9 +512,27 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
(function () {
var $ = Snap._.$;
// gradients' helpers
/*\
* Element.stops
[ method ]
**
* Only for gradients!
* Returns array of gradient stops elements.
= (array) the stops array.
\*/
function Gstops() {
return this.selectAll("stop");
}
/*\
* Element.addStop
[ method ]
**
* Only for gradients!
* Adds another stop to the gradient.
- color (string) stops color
- offset (number) stops offset 0..100
= (object) gradient element
\*/
function GaddStop(color, offset) {
var stop = $("stop"),
attr = {
@ -526,7 +544,19 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
attr["stop-opacity"] = color.opacity;
}
$(stop, attr);
this.node.appendChild(stop);
var stops = this.stops(),
inserted;
for (var i = 0; i < stops.length; i++) {
var stopOffset = parseFloat(stops[i].attr("offset"));
if (stopOffset > offset) {
this.node.insertBefore(stop, stops[i].node);
inserted = true;
break;
}
}
if (!inserted) {
this.node.appendChild(stop);
}
return this;
}
function GgetBBox() {
@ -543,6 +573,44 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
return Snap._.box(cx - r, cy - r, r * 2, r * 2);
}
}
/*\
* Element.setStops
[ method ]
**
* Only for gradients!
* Updates stops of the gradient based on passed gradient descriptor. See @Ppaer.gradient
- str (string) gradient descriptor part after `()`.
= (object) gradient element
| var g = paper.gradient("l(0, 0, 1, 1)#000-#f00-#fff");
| g.setStops("#fff-#000-#f00-#fc0");
\*/
function GsetStops(str) {
var grad = str,
stops = this.stops();
if (typeof str == "string") {
grad = eve("snap.util.grad.parse", null, "l(0,0,0,1)" + str).firstDefined().stops;
}
if (!Snap.is(grad, "array")) {
return;
}
for (var i = 0; i < stops.length; i++) {
if (grad[i]) {
var color = Snap.color(grad[i].color),
attr = {"offset": grad[i].offset + "%"};
attr["stop-color"] = color.hex;
if (color.opacity < 1) {
attr["stop-opacity"] = color.opacity;
}
stops[i].attr(attr);
} else {
stops[i].remove();
}
}
for (i = stops.length; i < grad.length; i++) {
this.addStop(grad[i].color, grad[i].offset);
}
return this;
}
function gradient(defs, str) {
var grad = eve("snap.util.grad.parse", null, str).firstDefined(),
el;
@ -561,24 +629,8 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
});
}
var stops = grad.stops,
len = stops.length,
start = 0,
j = 0;
function seed(i, end) {
var step = (end - start) / (i - j);
for (var k = j; k < i; k++) {
stops[k].offset = +(+start + step * (k - j)).toFixed(2);
}
j = i;
start = end;
}
len--;
for (var i = 0; i < len; i++) if ("offset" in stops[i]) {
seed(i, stops[i].offset);
}
stops[len].offset = stops[len].offset || 100;
seed(len, stops[len].offset);
for (i = 0; i <= len; i++) {
len = stops.length;
for (var i = 0; i < len; i++) {
var stop = stops[i];
el.addStop(stop.color, stop.offset);
}
@ -589,6 +641,7 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
el.stops = Gstops;
el.addStop = GaddStop;
el.getBBox = GgetBBox;
el.setStops = GsetStops;
if (x1 != null) {
$(el.node, {
x1: x1,

View File

@ -165,7 +165,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) {
ay = t1 * p1y + t * c1y,
cx = t1 * c2x + t * p2x,
cy = t1 * c2y + t * p2y,
alpha = (90 - math.atan2(mx - nx, my - ny) * 180 / PI);
alpha = 90 - math.atan2(mx - nx, my - ny) * 180 / PI;
// (mx > nx || my < ny) && (alpha += 180);
return {
x: x,
@ -451,7 +451,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) {
function rectPath(x, y, w, h, r) {
if (r) {
return [
["M", +x + (+r), y],
["M", +x + +r, y],
["l", w - r * 2, 0],
["a", r, r, 0, 0, 1, r, r],
["l", 0, h - r * 2],
@ -575,7 +575,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) {
my = pa[2];
default:
for (var j = 1, jj = pa.length; j < jj; j++) {
r[j] = +(pa[j] - ((j % 2) ? x : y)).toFixed(3);
r[j] = +(pa[j] - (j % 2 ? x : y)).toFixed(3);
}
}
} else {
@ -686,7 +686,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) {
my = +pa[2] + y;
default:
for (j = 1, jj = pa.length; j < jj; j++) {
r[j] = +pa[j] + ((j % 2) ? x : y);
r[j] = +pa[j] + (j % 2 ? x : y);
}
}
} else if (pa0 == "R") {
@ -761,6 +761,9 @@ Snap.plugin(function (Snap, Element, Paper, glob) {
Y = x * math.sin(rad) + y * math.cos(rad);
return {x: X, y: Y};
});
if (!rx || !ry) {
return [x1, y1, x2, y2, x2, y2];
}
if (!recursive) {
xy = rotate(x1, y1, -rad);
x1 = xy.x;
@ -772,7 +775,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) {
sin = math.sin(PI / 180 * angle),
x = (x1 - x2) / 2,
y = (y1 - y2) / 2;
var h = (x * x) / (rx * rx) + (y * y) / (ry * ry);
var h = x * x / (rx * rx) + y * y / (ry * ry);
if (h > 1) {
h = math.sqrt(h);
rx = h * rx;
@ -895,8 +898,8 @@ Snap.plugin(function (Snap, Element, Paper, glob) {
while (j--) {
t = tvalues[j];
mt = 1 - t;
bounds[0][j] = (mt * mt * mt * x0) + (3 * mt * mt * t * x1) + (3 * mt * t * t * x2) + (t * t * t * x3);
bounds[1][j] = (mt * mt * mt * y0) + (3 * mt * mt * t * y1) + (3 * mt * t * t * y2) + (t * t * t * y3);
bounds[0][j] = mt * mt * mt * x0 + 3 * mt * mt * t * x1 + 3 * mt * t * t * x2 + t * t * t * x3;
bounds[1][j] = mt * mt * mt * y0 + 3 * mt * mt * t * y1 + 3 * mt * t * t * y2 + t * t * t * y3;
}
bounds[0][jlen] = x0;

View File

@ -142,6 +142,14 @@ Snap.plugin(function (Snap, Element, Paper, glob) {
}
});
};
/*\
* Set.remove
[ method ]
**
* Removes all children of the set.
*
= (object) Set object
\*/
setproto.remove = function () {
while (this.length) {
this.pop().remove();
@ -180,6 +188,13 @@ Snap.plugin(function (Snap, Element, Paper, glob) {
}
return this;
};
/*\
* Set.attr
[ method ]
**
* Equivalent of @Element.attr.
= (object) Set object
\*/
setproto.attr = function (value) {
var unbound = {};
for (var k in value) {
@ -258,6 +273,15 @@ Snap.plugin(function (Snap, Element, Paper, glob) {
}
return false;
};
/*\
* Set.insertAfter
[ method ]
**
* Inserts set elements after given element.
**
- element (object) set will be inserted after this element
= (object) Set object
\*/
setproto.insertAfter = function (el) {
var i = this.items.length;
while (i--) {
@ -265,6 +289,13 @@ Snap.plugin(function (Snap, Element, Paper, glob) {
}
return this;
};
/*\
* Set.getBBox
[ method ]
**
* Union of all bboxes of the set. See @Element.getBBox.
= (object) bounding box descriptor. See @Element.getBBox.
\*/
setproto.getBBox = function () {
var x = [],
y = [],
@ -292,6 +323,14 @@ Snap.plugin(function (Snap, Element, Paper, glob) {
cy: y + (y2 - y) / 2
};
};
/*\
* Set.insertAfter
[ method ]
**
* Creates a clone of the set.
**
= (object) New Set object
\*/
setproto.clone = function (s) {
s = new Set;
for (var i = 0, ii = this.items.length; i < ii; i++) {
@ -304,7 +343,24 @@ Snap.plugin(function (Snap, Element, Paper, glob) {
};
setproto.type = "set";
// export
/*\
* Snap.Set
[ property ]
**
* Set constructor.
\*/
Snap.Set = Set;
/*\
* Snap.set
[ method ]
**
* Creates a set and fills it with list of arguments.
**
= (object) New Set object
| var r = paper.rect(0, 0, 10, 10),
| s1 = Snap.set(), // empty set
| s2 = Snap.set(r, paper.circle(100, 100, 20)); // prefilled set
\*/
Snap.set = function () {
var set = new Set;
if (arguments.length) {

View File

@ -1,4 +1,4 @@
// Copyright (c) 2013 - 2015 Adobe Systems Incorporated. All rights reserved.
// Copyright (c) 2013 - 2017 Adobe Systems Incorporated. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -13,7 +13,7 @@
// limitations under the License.
var Snap = (function(root) {
Snap.version = "0.4.1";
Snap.version = "0.5.0";
/*\
* Snap
[ method ]
@ -76,14 +76,13 @@ var has = "hasOwnProperty",
ISURL = /^url\(['"]?([^\)]+?)['"]?\)$/i,
colourRegExp = /^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+%?)?)\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\))\s*$/i,
bezierrg = /^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/,
reURLValue = /^url\(#?([^)]+)\)$/,
separator = Snap._.separator = /[,\s]+/,
whitespace = /[\s]/g,
commaSpaces = /[\s]*,[\s]*/,
hsrg = {hs: 1, rg: 1},
pathCommand = /([a-z])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\s]*,?[\s]*)+)/ig,
tCommand = /([rstm])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\s]*,?[\s]*)+)/ig,
pathValues = /(-?\d*\.?\d*(?:e[\-+]?\\d+)?)[\s]*,?[\s]*/ig,
pathValues = /(-?\d*\.?\d*(?:e[\-+]?\d+)?)[\s]*,?[\s]*/ig,
idgen = 0,
idprefix = "S" + (+new Date).toString(36),
ID = function (el) {
@ -92,6 +91,14 @@ var has = "hasOwnProperty",
xlink = "http://www.w3.org/1999/xlink",
xmlns = "http://www.w3.org/2000/svg",
hub = {},
/*\
* Snap.url
[ method ]
**
* Wraps path into `"url('<path>')"`.
- value (string) path
= (string) wrapped path
\*/
URL = Snap.url = function (url) {
return "url('#" + url + "')";
};
@ -171,9 +178,9 @@ function is(o, type) {
(o instanceof Array || Array.isArray && Array.isArray(o))) {
return true;
}
return (type == "null" && o === null) ||
(type == typeof o && o !== null) ||
(type == "object" && o === Object(o)) ||
return type == "null" && o === null ||
type == typeof o && o !== null ||
type == "object" && o === Object(o) ||
objectToString.call(o).slice(8, -1).toLowerCase() == type;
}
/*\
@ -379,7 +386,6 @@ Snap.atan2 = function (num) {
[ method ]
**
* Returns an angle between two or three points
> Parameters
- x1 (number) x coord of first point
- y1 (number) y coord of first point
- x2 (number) x coord of second point
@ -394,7 +400,6 @@ Snap.angle = angle;
[ method ]
**
* Returns distance between two points
> Parameters
- x1 (number) x coord of first point
- y1 (number) y coord of first point
- x2 (number) x coord of second point
@ -409,7 +414,6 @@ Snap.len = function (x1, y1, x2, y2) {
[ method ]
**
* Returns squared distance between two points
> Parameters
- x1 (number) x coord of first point
- y1 (number) y coord of first point
- x2 (number) x coord of second point
@ -424,7 +428,6 @@ Snap.len2 = function (x1, y1, x2, y2) {
[ method ]
**
* Returns closest point to a given one on a given path.
> Parameters
- path (Element) path element
- x (number) x coord of a point
- y (number) y coord of a point
@ -453,7 +456,9 @@ Snap.closestPoint = function (path, x, y) {
// linear scan for coarse approximation
for (var scan, scanLength = 0, scanDistance; scanLength <= pathLength; scanLength += precision) {
if ((scanDistance = distance2(scan = pathNode.getPointAtLength(scanLength))) < bestDistance) {
best = scan, bestLength = scanLength, bestDistance = scanDistance;
best = scan;
bestLength = scanLength;
bestDistance = scanDistance;
}
}
@ -467,9 +472,13 @@ Snap.closestPoint = function (path, x, y) {
beforeDistance,
afterDistance;
if ((beforeLength = bestLength - precision) >= 0 && (beforeDistance = distance2(before = pathNode.getPointAtLength(beforeLength))) < bestDistance) {
best = before, bestLength = beforeLength, bestDistance = beforeDistance;
best = before;
bestLength = beforeLength;
bestDistance = beforeDistance;
} else if ((afterLength = bestLength + precision) <= pathLength && (afterDistance = distance2(after = pathNode.getPointAtLength(afterLength))) < bestDistance) {
best = after, bestLength = afterLength, bestDistance = afterDistance;
best = after;
bestLength = afterLength;
bestDistance = afterDistance;
} else {
precision *= .5;
}
@ -628,7 +637,7 @@ Snap.getRGB = cacher(function (colour) {
blue = mmin(math.round(blue), 255);
opacity = mmin(mmax(opacity, 0), 1);
rgb = {r: red, g: green, b: blue, toString: rgbtoString};
rgb.hex = "#" + (16777216 | blue | (green << 8) | (red << 16)).toString(16).slice(1);
rgb.hex = "#" + (16777216 | blue | green << 8 | red << 16).toString(16).slice(1);
rgb.opacity = is(opacity, "finite") ? opacity : 1;
return rgb;
}
@ -675,7 +684,7 @@ Snap.rgb = cacher(function (r, g, b, o) {
var round = math.round;
return "rgba(" + [round(r), round(g), round(b), +o.toFixed(2)] + ")";
}
return "#" + (16777216 | b | (g << 8) | (r << 16)).toString(16).slice(1);
return "#" + (16777216 | b | g << 8 | r << 16).toString(16).slice(1);
});
var toHex = function (color) {
var i = glob.doc.getElementsByTagName("head")[0] || glob.doc.getElementsByTagName("svg")[0],
@ -817,7 +826,7 @@ Snap.hsb2rgb = function (h, s, v, o) {
}
h *= 360;
var R, G, B, X, C;
h = (h % 360) / 60;
h = h % 360 / 60;
C = v * s;
X = C * (1 - abs(h % 2 - 1));
R = G = B = v - C;
@ -857,7 +866,7 @@ Snap.hsl2rgb = function (h, s, l, o) {
}
h *= 360;
var R, G, B, X, C;
h = (h % 360) / 60;
h = h % 360 / 60;
C = 2 * s * (l < .5 ? l : 1 - l);
X = C * (1 - abs(h % 2 - 1));
R = G = B = l - C / 2;
@ -892,12 +901,11 @@ Snap.rgb2hsb = function (r, g, b) {
var H, S, V, C;
V = mmax(r, g, b);
C = V - mmin(r, g, b);
H = (C == 0 ? null :
V == r ? (g - b) / C :
V == g ? (b - r) / C + 2 :
(r - g) / C + 4
);
H = ((H + 360) % 6) * 60 / 360;
H = C == 0 ? null :
V == r ? (g - b) / C :
V == g ? (b - r) / C + 2 :
(r - g) / C + 4;
H = (H + 360) % 6 * 60 / 360;
S = C == 0 ? 0 : C / V;
return {h: H, s: S, b: V, toString: hsbtoString};
};
@ -926,15 +934,15 @@ Snap.rgb2hsl = function (r, g, b) {
M = mmax(r, g, b);
m = mmin(r, g, b);
C = M - m;
H = (C == 0 ? null :
M == r ? (g - b) / C :
M == g ? (b - r) / C + 2 :
(r - g) / C + 4);
H = ((H + 360) % 6) * 60 / 360;
H = C == 0 ? null :
M == r ? (g - b) / C :
M == g ? (b - r) / C + 2 :
(r - g) / C + 4;
H = (H + 360) % 6 * 60 / 360;
L = (M + m) / 2;
S = (C == 0 ? 0 :
S = C == 0 ? 0 :
L < .5 ? C / (2 * L) :
C / (2 - 2 * L));
C / (2 - 2 * L);
return {h: H, s: S, l: L, toString: hsltoString};
};
@ -1146,8 +1154,8 @@ var contains = glob.doc.contains || glob.doc.compareDocumentPosition ?
return false;
};
function getSomeDefs(el) {
var p = (el.node.ownerSVGElement && wrap(el.node.ownerSVGElement)) ||
(el.node.parentNode && wrap(el.node.parentNode)) ||
var p = el.node.ownerSVGElement && wrap(el.node.ownerSVGElement) ||
el.node.parentNode && wrap(el.node.parentNode) ||
Snap.select("svg") ||
Snap(0, 0),
pdefs = p.select("defs"),
@ -1492,7 +1500,7 @@ function Paper(w, h) {
desc,
defs,
proto = Paper.prototype;
if (w && w.tagName == "svg") {
if (w && w.tagName && w.tagName.toLowerCase() == "svg") {
if (w.snap in hub) {
return hub[w.snap];
}
@ -1744,7 +1752,7 @@ Snap.ajax = function (url, postData, callback, scope){
}
postData = pd.join("&");
}
req.open((postData ? "POST" : "GET"), url, true);
req.open(postData ? "POST" : "GET", url, true);
if (postData) {
req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

View File

@ -8,7 +8,6 @@
<link rel="shortcut icon" href="/assets/favicon.ico?v=1">
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
<link rel="stylesheet" href="/assets/docs/fonts/stylesheet.css?v=201311041519">
<link rel="stylesheet" href="/assets/docs/css/topcoat-desktop-light.css?v=201311041519">
<link rel="stylesheet" href="/assets/docs/css/main.css?v=201311041519">
<link rel="stylesheet" href="/assets/docs/css/dr.css?v=201311041519">
<link rel="stylesheet" href="/assets/docs/css/prism.css?v=201311041519">
@ -50,7 +49,7 @@
<a href="/docs/" class="mobile-hide selected">Docs</a>
<a href="/support/">Support</a>
<a href="/demos/" class="mobile-hide">Demos</a>
<a class="bt" href="/assets/downloads/Snap.svg-0.1.0.zip" onclick="trackOutboundLink(this, 'Download', '0.1');return false;">Download</a>
<a class="bt" href="/assets/downloads/Snap.svg-0.5.0.zip" onclick="trackOutboundLink(this, 'Download', '0.5.0');return false;">Download</a>
</nav>
</div>
</header>
@ -62,7 +61,7 @@
<div class="max-width">
<div id="sideNav">
<div class="combo">
<input type="search" id="dr-filter" value="" placeholder="search" class="topcoat-search-input">
<input type="search" id="dr-filter" value="" placeholder="search">
</div>
<div id="pageNav">
<ol id="dr-toc">
@ -80,7 +79,7 @@
{{~it.out :item:index}}
<article id="{{=item[0].title}}">
<header>
<h3 class="{{=item[0].clas}}">{{=item[0].name}}<a href="#{{=item[0].title}}" title="Link to this section" class="dr-hash">&#x2693;</a><a class="dr-sourceline" title="Go to line {{=item[0].line}} in the source" href="https://github.com/adobe-webplatform/Snap.svg/blob/master/src/svg.js#L{{=item[0].line}}">&#x27ad;</a></h3>
<h2 class="{{=item[0].clas}}">{{=item[0].name}}<a href="#{{=item[0].title}}" title="Link to this section" class="dr-hash">&#x2693;</a><a class="dr-sourceline" title="Go to line {{=item[0].line}} in the source" href="https://github.com/adobe-webplatform/Snap.svg/blob/master/src/svg.js#L{{=item[0].line}}">&#x27ad;</a></h2>
</header>
<section>
<div class="extra" id="{{=item[0].title}}-extra"></div>
@ -88,10 +87,10 @@
{{~item :line:i}}
{{ if (i > 0) { }}
{{ if (line.text) { }}<p>{{=line.text.join("</p><p>")}}</p>{{ } }}
{{ if (line.attr) { }}<div class="topcoat-list__container">
<h3 class="topcoat-list__header">Parameters</h3>
<ol class="topcoat-list">
{{~line.attr :attr:j}}<li class="topcoat-list__item"><span class="dr-param">{{=attr.name}}</span>
{{ if (line.attr) { }}<div class="params">
<h3 class="params">Parameters</h3>
<ol class="params-list">
{{~line.attr :attr:j}}<li><span class="dr-param">{{=attr.name}}</span>
<span class="dr-type">{{~attr.type :type:k}}<em class="dr-type-{{=type}}">{{=type}}</em> {{~}}</span>
<span class="dr-description">{{=attr.desc}}</span></li>
{{~}}

View File

@ -1,17 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Test</title>
<script src="dist/snap.svg.js"></script>
</head>
<body>
<script>
var s = Snap();
Snap.load("inkscape.svg", function (f) {
console.log(f.select('path[sodipodi:nodetypes="cc"]'));
});
</script>
</body>
</html>

View File

@ -59,24 +59,24 @@ describe("Filter methods", function () {
str = Snap.filter.shadow(-1, 3);
expect(str).to.be('<feGaussianBlur in="SourceAlpha" stdDeviation="4"/><feOffset dx="-1" dy="3" result="offsetblur"/><feFlood flood-color="#000000"/><feComposite in2="offsetblur" operator="in"/><feComponentTransfer><feFuncA type="linear" slope="1"/></feComponentTransfer><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>');
});
it("Snap.filter.shadow - dx & dy, blur", function() {
it("Snap.filter.shadow - dx & dy, opacity", function() {
var str = Snap.filter.shadow(5, 5, 5);
expect(str).to.be('<feGaussianBlur in="SourceAlpha" stdDeviation="5"/><feOffset dx="5" dy="5" result="offsetblur"/><feFlood flood-color="#000000"/><feComposite in2="offsetblur" operator="in"/><feComponentTransfer><feFuncA type="linear" slope="1"/></feComponentTransfer><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>');
expect(str).to.be('<feGaussianBlur in="SourceAlpha" stdDeviation="4"/><feOffset dx="5" dy="5" result="offsetblur"/><feFlood flood-color="#000000"/><feComposite in2="offsetblur" operator="in"/><feComponentTransfer><feFuncA type="linear" slope="5"/></feComponentTransfer><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>');
str = Snap.filter.shadow(-1, 3, 10);
expect(str).to.be('<feGaussianBlur in="SourceAlpha" stdDeviation="10"/><feOffset dx="-1" dy="3" result="offsetblur"/><feFlood flood-color="#000000"/><feComposite in2="offsetblur" operator="in"/><feComponentTransfer><feFuncA type="linear" slope="1"/></feComponentTransfer><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>');
expect(str).to.be('<feGaussianBlur in="SourceAlpha" stdDeviation="4"/><feOffset dx="-1" dy="3" result="offsetblur"/><feFlood flood-color="#000000"/><feComposite in2="offsetblur" operator="in"/><feComponentTransfer><feFuncA type="linear" slope="10"/></feComponentTransfer><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>');
});
it("Snap.filter.shadow - dx & dy, color", function() {
var str = Snap.filter.shadow(5, 5, '#F00');
expect(str).to.be('<feGaussianBlur in="SourceAlpha" stdDeviation="4"/><feOffset dx="5" dy="5" result="offsetblur"/><feFlood flood-color="#ff0000"/><feComposite in2="offsetblur" operator="in"/><feComponentTransfer><feFuncA type="linear" slope="#F00"/></feComponentTransfer><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>');
str = Snap.filter.shadow(-1, 3, 'hsla(128deg, 50%, 50%, 0.8)');
expect(str).to.be('<feGaussianBlur in="SourceAlpha" stdDeviation="4"/><feOffset dx="-1" dy="3" result="offsetblur"/><feFlood flood-color="rgba(64,191,81,0.8)"/><feComposite in2="offsetblur" operator="in"/><feComponentTransfer><feFuncA type="linear" slope="hsla(128deg, 50%, 50%, 0.8)"/></feComponentTransfer><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>');
it("Snap.filter.shadow - dx & dy, color, opacity", function() {
var str = Snap.filter.shadow(5, 5, '#F00', 1);
expect(str).to.be('<feGaussianBlur in="SourceAlpha" stdDeviation="4"/><feOffset dx="5" dy="5" result="offsetblur"/><feFlood flood-color="#ff0000"/><feComposite in2="offsetblur" operator="in"/><feComponentTransfer><feFuncA type="linear" slope="1"/></feComponentTransfer><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>');
str = Snap.filter.shadow(-1, 3, 'hsla(128deg, 50%, 50%, 0.8)', .5);
expect(str).to.be('<feGaussianBlur in="SourceAlpha" stdDeviation="4"/><feOffset dx="-1" dy="3" result="offsetblur"/><feFlood flood-color="rgba(64,191,81,0.8)"/><feComposite in2="offsetblur" operator="in"/><feComponentTransfer><feFuncA type="linear" slope="0.5"/></feComponentTransfer><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>');
});
it("Snap.filter.shadow - dx & dy, blur & color", function() {
var str = Snap.filter.shadow(5, 5, 5, '#F00');
it("Snap.filter.shadow - dx & dy, blur, color, opacity", function() {
var str = Snap.filter.shadow(5, 5, 5, '#F00', 1);
expect(str).to.be('<feGaussianBlur in="SourceAlpha" stdDeviation="5"/><feOffset dx="5" dy="5" result="offsetblur"/><feFlood flood-color="#ff0000"/><feComposite in2="offsetblur" operator="in"/><feComponentTransfer><feFuncA type="linear" slope="1"/></feComponentTransfer><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>');
str = Snap.filter.shadow(-1, 3, 10, 'hsla(128deg, 50%, 50%, 0.8)');
expect(str).to.be('<feGaussianBlur in="SourceAlpha" stdDeviation="10"/><feOffset dx="-1" dy="3" result="offsetblur"/><feFlood flood-color="rgba(64,191,81,0.8)"/><feComposite in2="offsetblur" operator="in"/><feComponentTransfer><feFuncA type="linear" slope="1"/></feComponentTransfer><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>');
str = Snap.filter.shadow(-1, 3, 10, 'hsla(128deg, 50%, 50%, 0.8)', .5);
expect(str).to.be('<feGaussianBlur in="SourceAlpha" stdDeviation="10"/><feOffset dx="-1" dy="3" result="offsetblur"/><feFlood flood-color="rgba(64,191,81,0.8)"/><feComposite in2="offsetblur" operator="in"/><feComponentTransfer><feFuncA type="linear" slope="0.5"/></feComponentTransfer><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>');
});

78
test/gradients.js Normal file
View File

@ -0,0 +1,78 @@
describe("Gradients", function () {
var s,
r;
beforeEach(function () {
s = Snap(100, 100);
r = s.rect(0, 0, 100, 100);
});
afterEach(function () {
s.remove();
});
function getGrad(el) {
if (!el) {
el = r;
}
var id = el.node.getAttribute("fill");
id = Snap.deurl(id);
return s.select(id);
}
it("creates simple gradient", function () {
r.attr({fill: "l(0,0,1,0)#fff-#000"});
var g = getGrad();
expect(g).to.not.be(null);
expect(g.stops().length).to.be(2);
expect(g.stops()[0].attr("stop-color")).to.be("rgb(255, 255, 255)");
});
it("creates radial gradient", function () {
r.attr({fill: "r()#fff-#000"});
var g = getGrad();
expect(g).to.not.be(null);
expect(g.stops().length).to.be(2);
expect(g.stops()[0].attr("stop-color")).to.be("rgb(255, 255, 255)");
});
it("returns gradient for .attr(\"fill\") call", function () {
r.attr({fill: "l(0,0,1,0)#fff-#fc0:20-#000"});
var g = getGrad(),
g2 = r.attr("fill");
expect(g).to.be(g2);
});
it("creates complex gradient", function () {
r.attr({fill: "l(0,0,1,0)#fff-#fc0:20-#000"});
var g = getGrad();
expect(g).to.not.be(null);
expect(g.stops().length).to.be(3);
expect(g.stops()[0].attr("stop-color")).to.be("rgb(255, 255, 255)");
expect(g.stops()[1].attr("offset")).to.be("20%");
});
it("updates simple gradient", function () {
r.attr({fill: "l(0,0,1,0)#fff-#000"});
var g = getGrad();
expect(g).to.not.be(null);
expect(g.stops().length).to.be(2);
expect(g.stops()[0].attr("stop-color")).to.be("rgb(255, 255, 255)");
g.setStops("#000-#fff");
expect(g.stops().length).to.be(2);
expect(g.stops()[0].attr("stop-color")).to.be("rgb(0, 0, 0)");
g.setStops("#000-red-#fff");
expect(g.stops().length).to.be(3);
expect(g.stops()[1].attr("stop-color")).to.be("rgb(255, 0, 0)");
});
it("adds stops to the gradient", function () {
r.attr({fill: "l(0,0,1,0)#fff-#000"});
var g = getGrad();
expect(g).to.not.be(null);
expect(g.stops().length).to.be(2);
expect(g.stops()[0].attr("stop-color")).to.be("rgb(255, 255, 255)");
g.addStop("red", 20);
expect(g.stops().length).to.be(3);
expect(g.stops()[1].attr("stop-color")).to.be("rgb(255, 0, 0)");
expect(g.stops()[1].attr("offset")).to.be("20%");
});
});

View File

@ -183,6 +183,42 @@ describe("Matrix methods", function () {
f: 18
});
});
it("Matrix.skewX", function() {
var matrix = new Snap.Matrix(1, 0, 0, 1, 20, 30);
matrix.skewX(45);
expect(matrix).to.eql({
a: 1,
b: 0,
c: 1,
d: 1,
e: 20,
f: 30
});
});
it("Matrix.skewY", function() {
var matrix = new Snap.Matrix(1, 0, 0, 1, 20, 30);
matrix.skewY(45);
expect(matrix).to.eql({
a: 1,
b: 1,
c: 0,
d: 1,
e: 20,
f: 30
});
});
it("Matrix.skew", function() {
var matrix = new Snap.Matrix(1, 0, 0, 1, 20, 30);
matrix.skew(45, -45);
expect(matrix).to.eql({
a: 1,
b: -1,
c: 1,
d: 1,
e: 20,
f: 30
});
});
it("Matrix.x", function() {
var matrix = new Snap.Matrix(1, 0, 0, 1, 20, 30);
var result = matrix.x(10, -10);

View File

@ -41,16 +41,15 @@
<script src="attradd.js"></script>
<script src="path.js"></script>
<script src="element.js"></script>
<script src="gradients.js"></script>
<script src="set.js"></script>
<script src="filter.js"></script>
<script src="matrix.js"></script>
<script src="mina.js"></script>
<svg id="svgroot"></svg>
<script>
mocha.checkLeaks();
window.onload = function () {
mocha.run();
};
mocha.run();
</script>
<svg id="svgroot"></svg>
</body>
</html>

12
test/test.js Normal file
View File

@ -0,0 +1,12 @@
var page = require("webpage").create();
page.open("test.html", function (status) {
var errors = 0;
if (status === "success") {
errors = page.evaluate(function () {
return +document.querySelector("li.failures em").innerText;
});
console.log(errors);
}
phantom.exit(errors);
});