- added `precision()` method to round numeric element attributes -> __TODO!__
- added a linter during the npm build process
- added `npm build:dev` to let you develop without getting too annoyed
+- added `beziere()` and `steps()` to generate easing functions
### Removed
- removed `SVG.Array.split()` function
- The whole lib is now splitted into es6 modules (#875)
- `Element.svg()` now can can replace the current node, can export the children of a node and can take an export modifier to change/replace the exported nodes
- `ungroup()` now breaks off one container and not more
+- `clone()` does not add the clone to the dom anymore
### Fixed
- fixed a bug in clipping and masking where empty nodes persists after removal -> __TODO!__
* @copyright Wout Fierens <wout@mick-wout.com>
* @license MIT
*
-* BUILT: Wed Nov 07 2018 16:59:53 GMT+0100 (GMT+01:00)
+* BUILT: Wed Nov 07 2018 22:39:24 GMT+0100 (GMT+01:00)
*/;
var SVG = (function () {
'use strict';
} else if (val == null) {
// act as a getter if the first and only argument is not an object
val = this.node.getAttribute(attr);
- return val == null ? attrs[attr] // FIXME: do we need to return defaults?
- : isNumber.test(val) ? parseFloat(val) : val;
+ return val == null ? attrs[attr] : isNumber.test(val) ? parseFloat(val) : val;
} else {
// convert image fill and stroke to patterns
if (attr === 'fill' || attr === 'stroke') {
}, {
key: "clone",
- value: function clone(parent) {
+ value: function clone() {
// write dom data to the dom so the clone can pickup the data
this.writeDataToDom(); // clone element and assign new id
- var clone = assignNewId(this.node.cloneNode(true)); // insert the clone in the given parent or after myself
-
- if (parent) parent.add(clone); // FIXME: after might not be available here
- else this.after(clone);
- return clone;
+ return assignNewId(this.node.cloneNode(true));
} // Iterates over all children and invokes a given block
}, {
'<': function _(pos) {
return -Math.cos(pos * Math.PI / 2) + 1;
},
- bezier: function bezier(t0, x0, t1, x1) {
- return function (t) {// TODO: FINISH
+ bezier: function bezier(x1, y1, x2, y2) {
+ // see https://www.w3.org/TR/css-easing-1/#cubic-bezier-algo
+ return function (t) {
+ if (t < 0) {
+ if (x1 > 0) {
+ return y1 / x1 * t;
+ } else if (x2 > 0) {
+ return y2 / x2 * t;
+ } else {
+ return 0;
+ }
+ } else if (t > 1) {
+ if (x2 < 1) {
+ return (1 - y2) / (1 - x2) * t + (y2 - x2) / (1 - x2);
+ } else if (x1 < 1) {
+ return (1 - y1) / (1 - x1) * t + (y1 - x1) / (1 - x1);
+ } else {
+ return 1;
+ }
+ } else {
+ return 3 * t * Math.pow(1 - t, 2) * y1 + 3 * Math.pow(t, 2) * (1 - t) * y2 + Math.pow(t, 3);
+ }
+ };
+ },
+ // https://www.w3.org/TR/css-easing-1/#step-timing-function-algo
+ steps: function steps(_steps) {
+ var stepPosition = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'end';
+ // deal with "jump-" prefix
+ stepPosition = stepPosition.split('-').reverse()[0];
+ var jumps = _steps;
+
+ if (stepPosition === 'none') {
+ --jumps;
+ } else if (stepPosition === 'both') {
+ ++jumps;
+ } // The beforeFlag is essentially useless
+
+
+ return function (t) {
+ var beforeFlag = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
+ // Step is called currentStep in referenced url
+ var step = Math.floor(t * _steps);
+ var jumping = t * step % 1 === 0;
+
+ if (stepPosition === 'start' || stepPosition === 'both') {
+ ++step;
+ }
+
+ if (beforeFlag && jumping) {
+ --step;
+ }
+
+ if (t >= 0 && step < 0) {
+ step = 0;
+ }
+
+ if (t <= 1 && step > jumps) {
+ step = jumps;
+ }
+
+ return step / jumps;
};
}
};
}
} catch (e) {
try {
- var clone = this.clone(parser().svg).show();
+ var clone = this.clone().addTo(parser().svg).show();
box = cb(clone.node);
clone.remove();
} catch (e) {
value: function _step() {
// If the timeline is paused, just do nothing
if (this._paused) return; // Get the time delta from the last time and update the time
- // TODO: Deal with window.blur window.focus to pause animations
var time = this._timeSource();
expect(clone.get(0).id()).not.toBe(group.get(0).id())
expect(clone.get(1).id()).not.toBe(group.get(1).id())
})
- it('inserts the clone after the cloned element', function() {
- clone = rect.clone()
- expect(rect.next()).toBe(clone)
- })
- it('inserts the clone in the specified parent', function() {
- var g = draw.group()
- clone = rect.clone(g)
- expect(g.get(0)).toBe(clone)
- })
it('deep copies over dom data', function() {
group.dom = {'foo':'bar'}
rect.dom = {'foo':'baz'}
'<>': function (pos) { return -Math.cos(pos * Math.PI) / 2 + 0.5 },
'>': function (pos) { return Math.sin(pos * Math.PI / 2) },
'<': function (pos) { return -Math.cos(pos * Math.PI / 2) + 1 },
- bezier: function (t0, x0, t1, x1) {
+ bezier: function (x1, y1, x2, y2) {
+ // see https://www.w3.org/TR/css-easing-1/#cubic-bezier-algo
return function (t) {
- // TODO: FINISH
+ if (t < 0) {
+ if (x1 > 0) {
+ return y1 / x1 * t
+ } else if (x2 > 0) {
+ return y2 / x2 * t
+ } else {
+ return 0
+ }
+ } else if (t > 1) {
+ if (x2 < 1) {
+ return (1 - y2) / (1 - x2) * t + (y2 - x2) / (1 - x2)
+ } else if (x1 < 1) {
+ return (1 - y1) / (1 - x1) * t + (y1 - x1) / (1 - x1)
+ } else {
+ return 1
+ }
+ } else {
+ return 3 * t * (1 - t) ** 2 * y1 + 3 * t ** 2 * (1 - t) * y2 + t ** 3
+ }
+ }
+ },
+ // https://www.w3.org/TR/css-easing-1/#step-timing-function-algo
+ steps: function (steps, stepPosition = 'end') {
+ // deal with "jump-" prefix
+ stepPosition = stepPosition.split('-').reverse()[0]
+
+ let jumps = steps
+ if (stepPosition === 'none') {
+ --jumps
+ } else if (stepPosition === 'both') {
+ ++jumps
+ }
+
+ // The beforeFlag is essentially useless
+ return (t, beforeFlag = false) => {
+ // Step is called currentStep in referenced url
+ let step = Math.floor(t * steps)
+ const jumping = (t * step) % 1 === 0
+
+ if (stepPosition === 'start' || stepPosition === 'both') {
+ ++step
+ }
+
+ if (beforeFlag && jumping) {
+ --step
+ }
+
+ if (t >= 0 && step < 0) {
+ step = 0
+ }
+
+ if (t <= 1 && step > jumps) {
+ step = jumps
+ }
+
+ return step / jumps
}
}
}
if (this._paused) return
// Get the time delta from the last time and update the time
- // TODO: Deal with window.blur window.focus to pause animations
var time = this._timeSource()
var dtSource = time - this._lastSourceTime
var dtTime = this._speed * dtSource + (this._time - this._lastStepTime)
}
// Clone element
- clone (parent) {
+ clone () {
// write dom data to the dom so the clone can pickup the data
this.writeDataToDom()
// clone element and assign new id
- let clone = assignNewId(this.node.cloneNode(true))
-
- // insert the clone in the given parent or after myself
- if (parent) parent.add(clone)
- // FIXME: after might not be available here
- else this.after(clone)
-
- return clone
+ return assignNewId(this.node.cloneNode(true))
}
// Iterates over all children and invokes a given block
} else if (val == null) {
// act as a getter if the first and only argument is not an object
val = this.node.getAttribute(attr)
- return val == null ? defaults[attr] // FIXME: do we need to return defaults?
+ return val == null ? defaults[attr]
: isNumber.test(val) ? parseFloat(val)
: val
} else {
}
} catch (e) {
try {
- let clone = this.clone(parser().svg).show()
+ let clone = this.clone().addTo(parser().svg).show()
box = cb(clone.node)
clone.remove()
} catch (e) {