删除一大堆扩展
parent
78a90d987a
commit
95c922f7ea
212
src/animation.js
212
src/animation.js
|
@ -1,212 +0,0 @@
|
||||||
/**
|
|
||||||
* {}
|
|
||||||
* @author yutent<yutent.io@gmail.com>
|
|
||||||
* @date 2024/03/07 15:46:18
|
|
||||||
*/
|
|
||||||
|
|
||||||
import eve from './eve.js'
|
|
||||||
import { SnapElement } from './svg.js'
|
|
||||||
import mina from './mina.js'
|
|
||||||
import { is } from './utils.js'
|
|
||||||
|
|
||||||
let elproto = SnapElement.prototype,
|
|
||||||
Str = String,
|
|
||||||
has = 'hasOwnProperty'
|
|
||||||
|
|
||||||
function slice(from, to, f) {
|
|
||||||
return function (arr) {
|
|
||||||
let res = arr.slice(from, to)
|
|
||||||
if (res.length == 1) {
|
|
||||||
res = res[0]
|
|
||||||
}
|
|
||||||
return f ? f(res) : res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export class Animation {
|
|
||||||
constructor(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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
export function createAnimation(attr, ms, easing, callback) {
|
|
||||||
return new Animation(attr, ms, easing, callback)
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Returns a set of animations that may be able to manipulate the current element
|
|
||||||
**
|
|
||||||
= (object) in format:
|
|
||||||
{
|
|
||||||
anim (object) animation object,
|
|
||||||
mina (object) @mina object,
|
|
||||||
curStatus (number) 0..1 — status of the animation: 0 — just started, 1 — just finished,
|
|
||||||
status (function) gets or sets the status of the animation,
|
|
||||||
stop (function) stops the animation
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
elproto.inAnim = function () {
|
|
||||||
let el = this
|
|
||||||
let res = []
|
|
||||||
|
|
||||||
for (let id in el.anims) {
|
|
||||||
if (el.anims.hasOwnProperty(id)) {
|
|
||||||
let a = el.anims[id]
|
|
||||||
res.push({
|
|
||||||
anim: new Animation(a._attrs, a.dur, a.easing, a._callback),
|
|
||||||
mina: a,
|
|
||||||
curStatus: a.status(),
|
|
||||||
status(val) {
|
|
||||||
return a.status(val)
|
|
||||||
},
|
|
||||||
stop() {
|
|
||||||
a.stop()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
{
|
|
||||||
id (string) animation id, consider it read-only,
|
|
||||||
duration (function) gets or sets the duration of the animation,
|
|
||||||
easing (function) easing,
|
|
||||||
speed (function) gets or sets the speed of the animation,
|
|
||||||
status (function) gets or sets the status of the animation,
|
|
||||||
stop (function) stops the animation
|
|
||||||
}
|
|
||||||
let rect = new Snap().rect(0, 0, 10, 10);
|
|
||||||
animate(0, 10, function (val) {
|
|
||||||
rect.attr({
|
|
||||||
x: val
|
|
||||||
});
|
|
||||||
}, 1000);
|
|
||||||
// in given context is equivalent to
|
|
||||||
rect.animate({x: 10}, 1000);
|
|
||||||
*/
|
|
||||||
export function animate(from, to, setter, ms, easing, callback) {
|
|
||||||
if (typeof easing == 'function' && !easing.length) {
|
|
||||||
callback = easing
|
|
||||||
easing = mina.linear
|
|
||||||
}
|
|
||||||
let now = mina.time(),
|
|
||||||
anim = mina(from, to, now, now + ms, mina.time, setter, easing)
|
|
||||||
callback && eve.once('mina.finish.' + anim.id, callback)
|
|
||||||
return anim
|
|
||||||
}
|
|
||||||
/*\
|
|
||||||
* SnapElement.stop
|
|
||||||
[ method ]
|
|
||||||
**
|
|
||||||
* Stops all the animations for the current element
|
|
||||||
**
|
|
||||||
= (SnapElement) the current element
|
|
||||||
\*/
|
|
||||||
elproto.stop = function () {
|
|
||||||
let anims = this.inAnim()
|
|
||||||
for (let i = 0, ii = anims.length; i < ii; i++) {
|
|
||||||
anims[i].stop()
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
/*\
|
|
||||||
* SnapElement.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
|
|
||||||
= (SnapElement) 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
|
|
||||||
}
|
|
||||||
let fkeys = [],
|
|
||||||
tkeys = [],
|
|
||||||
keys = {},
|
|
||||||
from,
|
|
||||||
to,
|
|
||||||
f,
|
|
||||||
eq,
|
|
||||||
el = this
|
|
||||||
for (let 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]
|
|
||||||
}
|
|
||||||
let len = is(from, 'array') ? from.length : 1
|
|
||||||
keys[key] = slice(fkeys.length, fkeys.length + len, f)
|
|
||||||
fkeys = fkeys.concat(from)
|
|
||||||
tkeys = tkeys.concat(to)
|
|
||||||
}
|
|
||||||
let now = mina.time(),
|
|
||||||
anim = mina(
|
|
||||||
fkeys,
|
|
||||||
tkeys,
|
|
||||||
now,
|
|
||||||
now + ms,
|
|
||||||
mina.time,
|
|
||||||
function (val) {
|
|
||||||
let attr = {}
|
|
||||||
for (let 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
|
|
||||||
}
|
|
|
@ -1,80 +0,0 @@
|
||||||
/**
|
|
||||||
* {}
|
|
||||||
* @author yutent<yutent.io@gmail.com>
|
|
||||||
* @date 2024/03/07 15:17:00
|
|
||||||
*/
|
|
||||||
|
|
||||||
import eve from './eve.js'
|
|
||||||
|
|
||||||
let operators = {
|
|
||||||
'+': function (x, y) {
|
|
||||||
return x + y
|
|
||||||
},
|
|
||||||
'-': function (x, y) {
|
|
||||||
return x - y
|
|
||||||
},
|
|
||||||
'/': function (x, y) {
|
|
||||||
return x / y
|
|
||||||
},
|
|
||||||
'*': function (x, y) {
|
|
||||||
return x * y
|
|
||||||
}
|
|
||||||
},
|
|
||||||
reUnit = /[a-z]+$/i,
|
|
||||||
reAddon = /^\s*([+\-\/*])\s*=\s*([\d.eE+\-]+)\s*([^\d\s]+)?\s*$/
|
|
||||||
|
|
||||||
function getUnit(unit) {
|
|
||||||
return function (val) {
|
|
||||||
return +val.toFixed(3) + unit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
eve.on('snap.util.attr', function (val) {
|
|
||||||
let plus = String(val).match(reAddon)
|
|
||||||
if (plus) {
|
|
||||||
let evnt = eve.nt(),
|
|
||||||
name = evnt.substring(evnt.lastIndexOf('.') + 1),
|
|
||||||
a = this.attr(name),
|
|
||||||
atr = {}
|
|
||||||
eve.stop()
|
|
||||||
let unit = plus[3] || '',
|
|
||||||
aUnit = a.match(reUnit),
|
|
||||||
op = operators[plus[1]]
|
|
||||||
if (aUnit && aUnit == unit) {
|
|
||||||
val = op(+a, +plus[2])
|
|
||||||
} else {
|
|
||||||
a = this.asPX(name)
|
|
||||||
val = op(this.asPX(name), this.asPX(name, plus[2] + unit))
|
|
||||||
}
|
|
||||||
if (isNaN(a) || isNaN(val)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
atr[name] = val
|
|
||||||
this.attr(atr)
|
|
||||||
}
|
|
||||||
})(-10)
|
|
||||||
|
|
||||||
eve.on('snap.util.equal', function (name, b) {
|
|
||||||
let a = String(this.attr(name) || '')
|
|
||||||
let bplus = String(b).match(reAddon)
|
|
||||||
|
|
||||||
if (bplus) {
|
|
||||||
eve.stop()
|
|
||||||
let unit = bplus[3] || '',
|
|
||||||
aUnit = a.match(reUnit),
|
|
||||||
op = operators[bplus[1]]
|
|
||||||
if (aUnit && aUnit === unit) {
|
|
||||||
return {
|
|
||||||
from: +a,
|
|
||||||
to: op(+a, +bplus[2]),
|
|
||||||
f: getUnit(aUnit)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
a = this.asPX(name)
|
|
||||||
return {
|
|
||||||
from: a,
|
|
||||||
to: op(a, this.asPX(name, bplus[2] + unit)),
|
|
||||||
f: _ => _
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})(-10)
|
|
223
src/equal.js
223
src/equal.js
|
@ -1,223 +0,0 @@
|
||||||
// Copyright (c) 2013 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.
|
|
||||||
import eve from './eve.js'
|
|
||||||
import { Snap } from './svg.js'
|
|
||||||
import { is } from './utils.js'
|
|
||||||
import { SEPARATOR } from './lib/constants.js'
|
|
||||||
import { parseColor } from './lib/color.js'
|
|
||||||
import { Matrix } from './matrix.js'
|
|
||||||
|
|
||||||
let names = {},
|
|
||||||
reUnit = /[%a-z]+$/i,
|
|
||||||
Str = String
|
|
||||||
names.stroke = names.fill = 'colour'
|
|
||||||
function getEmpty(item) {
|
|
||||||
let l = item[0]
|
|
||||||
switch (l.toLowerCase()) {
|
|
||||||
case 't':
|
|
||||||
return [l, 0, 0]
|
|
||||||
case 'm':
|
|
||||||
return [l, 1, 0, 0, 1, 0, 0]
|
|
||||||
case 'r':
|
|
||||||
if (item.length == 4) {
|
|
||||||
return [l, 0, item[2], item[3]]
|
|
||||||
} else {
|
|
||||||
return [l, 0]
|
|
||||||
}
|
|
||||||
case 's':
|
|
||||||
if (item.length == 5) {
|
|
||||||
return [l, 1, 1, item[3], item[4]]
|
|
||||||
} else if (item.length == 3) {
|
|
||||||
return [l, 1, 1]
|
|
||||||
} else {
|
|
||||||
return [l, 1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function equaliseTransform(t1, t2, getBBox) {
|
|
||||||
t1 = t1 || new Matrix()
|
|
||||||
t2 = t2 || new Matrix()
|
|
||||||
t1 = Snap.parseTransformString(t1.toTransformString()) || []
|
|
||||||
t2 = Snap.parseTransformString(t2.toTransformString()) || []
|
|
||||||
let maxlength = Math.max(t1.length, t2.length),
|
|
||||||
from = [],
|
|
||||||
to = [],
|
|
||||||
i = 0,
|
|
||||||
j,
|
|
||||||
jj,
|
|
||||||
tt1,
|
|
||||||
tt2
|
|
||||||
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]))
|
|
||||||
) {
|
|
||||||
t1 = Snap._.transform2matrix(t1, getBBox())
|
|
||||||
t2 = Snap._.transform2matrix(t2, getBBox())
|
|
||||||
from = [['m', t1.a, t1.b, t1.c, t1.d, t1.e, t1.f]]
|
|
||||||
to = [['m', t2.a, t2.b, t2.c, t2.d, t2.e, t2.f]]
|
|
||||||
break
|
|
||||||
}
|
|
||||||
from[i] = []
|
|
||||||
to[i] = []
|
|
||||||
for (j = 0, jj = Math.max(tt1.length, tt2.length); j < jj; j++) {
|
|
||||||
j in tt1 && (from[i][j] = tt1[j])
|
|
||||||
j in tt2 && (to[i][j] = tt2[j])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
from: path2array(from),
|
|
||||||
to: path2array(to),
|
|
||||||
f: getPath(from)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function getNumber(val) {
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
function getUnit(unit) {
|
|
||||||
return function (val) {
|
|
||||||
return +val.toFixed(3) + unit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function getViewBox(val) {
|
|
||||||
return val.join(' ')
|
|
||||||
}
|
|
||||||
function getColour(clr) {
|
|
||||||
return Snap.rgb(clr[0], clr[1], clr[2], clr[3])
|
|
||||||
}
|
|
||||||
function getPath(path) {
|
|
||||||
let k = 0,
|
|
||||||
i,
|
|
||||||
ii,
|
|
||||||
j,
|
|
||||||
jj,
|
|
||||||
out,
|
|
||||||
a,
|
|
||||||
b = []
|
|
||||||
for (i = 0, ii = path.length; i < ii; i++) {
|
|
||||||
out = '['
|
|
||||||
a = ['"' + path[i][0] + '"']
|
|
||||||
for (j = 1, jj = path[i].length; j < jj; j++) {
|
|
||||||
a[j] = 'val[' + k++ + ']'
|
|
||||||
}
|
|
||||||
out += a + ']'
|
|
||||||
b[i] = out
|
|
||||||
}
|
|
||||||
return Function('val', 'return Snap.path.toString.call([' + b + '])')
|
|
||||||
}
|
|
||||||
function path2array(path) {
|
|
||||||
let out = []
|
|
||||||
for (let i = 0, ii = path.length; i < ii; i++) {
|
|
||||||
for (let j = 1, jj = path[i].length; j < jj; j++) {
|
|
||||||
out.push(path[i][j])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
function isNumeric(obj) {
|
|
||||||
return isFinite(obj)
|
|
||||||
}
|
|
||||||
function arrayEqual(arr1, arr2) {
|
|
||||||
if (!is(arr1, 'array') || !is(arr2, 'array')) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return arr1.toString() == arr2.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
eve.on('snap.util.equal', function (name, b) {
|
|
||||||
let A,
|
|
||||||
B,
|
|
||||||
a = Str(this.attr(name) || ''),
|
|
||||||
el = this
|
|
||||||
if (names[name] == 'colour') {
|
|
||||||
A = parseColor(a)
|
|
||||||
B = parseColor(b)
|
|
||||||
return {
|
|
||||||
from: [A.r, A.g, A.b, A.opacity],
|
|
||||||
to: [B.r, B.g, B.b, B.opacity],
|
|
||||||
f: getColour
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (name == 'viewBox') {
|
|
||||||
A = this.attr(name).vb.split(' ').map(Number)
|
|
||||||
B = b.split(' ').map(Number)
|
|
||||||
return {
|
|
||||||
from: A,
|
|
||||||
to: B,
|
|
||||||
f: getViewBox
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
name == 'transform' ||
|
|
||||||
name == 'gradientTransform' ||
|
|
||||||
name == 'patternTransform'
|
|
||||||
) {
|
|
||||||
if (typeof b == 'string') {
|
|
||||||
b = Str(b).replace(/\.{3}|\u2026/g, a)
|
|
||||||
}
|
|
||||||
a = this.matrix
|
|
||||||
if (!Snap._.rgTransform.test(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)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (name == 'd' || name == 'path') {
|
|
||||||
A = Snap.path.toCubic(a, b)
|
|
||||||
return {
|
|
||||||
from: path2array(A[0]),
|
|
||||||
to: path2array(A[1]),
|
|
||||||
f: getPath(A[0])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (name == 'points') {
|
|
||||||
A = Str(a).split(SEPARATOR)
|
|
||||||
B = Str(b).split(SEPARATOR)
|
|
||||||
return {
|
|
||||||
from: A,
|
|
||||||
to: B,
|
|
||||||
f: function (val) {
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isNumeric(a) && isNumeric(b)) {
|
|
||||||
return {
|
|
||||||
from: parseFloat(a),
|
|
||||||
to: parseFloat(b),
|
|
||||||
f: getNumber
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let aUnit = a.match(reUnit),
|
|
||||||
bUnit = Str(b).match(reUnit)
|
|
||||||
if (aUnit && arrayEqual(aUnit, bUnit)) {
|
|
||||||
return {
|
|
||||||
from: parseFloat(a),
|
|
||||||
to: parseFloat(b),
|
|
||||||
f: getUnit(aUnit)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
from: this.asPX(name),
|
|
||||||
to: this.asPX(name, b),
|
|
||||||
f: getNumber
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
|
@ -1,13 +1,8 @@
|
||||||
import { Snap } from './svg.js'
|
import { Snap } from './svg.js'
|
||||||
import './paper.js'
|
import './paper.js'
|
||||||
import './element.js'
|
import './element.js'
|
||||||
import { createAnimation, animate } from './animation.js'
|
|
||||||
import { Matrix } from './matrix.js'
|
import { Matrix } from './matrix.js'
|
||||||
import './attradd.js'
|
|
||||||
import './path.js'
|
import './path.js'
|
||||||
import './set.js'
|
|
||||||
import './equal.js'
|
|
||||||
import './mouse.js'
|
|
||||||
import './filter.js'
|
import './filter.js'
|
||||||
|
|
||||||
export default Snap
|
export default Snap
|
||||||
|
@ -15,5 +10,3 @@ export default Snap
|
||||||
export function createSvg(...args) {
|
export function createSvg(...args) {
|
||||||
return new Snap(...args)
|
return new Snap(...args)
|
||||||
}
|
}
|
||||||
|
|
||||||
export { Matrix, createAnimation, animate }
|
|
||||||
|
|
343
src/mina.js
343
src/mina.js
|
@ -1,343 +0,0 @@
|
||||||
/**
|
|
||||||
* {}
|
|
||||||
* @author yutent<yutent.io@gmail.com>
|
|
||||||
* @date 2024/03/08 10:20:25
|
|
||||||
*/
|
|
||||||
|
|
||||||
import eve from './eve.js'
|
|
||||||
import { uuid } from './utils.js'
|
|
||||||
|
|
||||||
let animations = {},
|
|
||||||
requestAnimFrame =
|
|
||||||
window.requestAnimationFrame ||
|
|
||||||
window.webkitRequestAnimationFrame ||
|
|
||||||
window.mozRequestAnimationFrame,
|
|
||||||
requestID,
|
|
||||||
isArray = Array.isArray,
|
|
||||||
diff = function (a, b, A, B) {
|
|
||||||
if (isArray(a)) {
|
|
||||||
res = []
|
|
||||||
for (let i = 0, ii = a.length; i < ii; i++) {
|
|
||||||
res[i] = diff(a[i], b, A[i], B)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
let dif = (A - a) / (B - b)
|
|
||||||
return function (bb) {
|
|
||||||
return a + dif * (bb - b)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
timer = Date.now,
|
|
||||||
sta = function (val) {
|
|
||||||
let a = this
|
|
||||||
if (val == null) {
|
|
||||||
return a.s
|
|
||||||
}
|
|
||||||
let ds = a.s - val
|
|
||||||
a.b += a.dur * ds
|
|
||||||
a.B += a.dur * ds
|
|
||||||
a.s = val
|
|
||||||
},
|
|
||||||
speed = function (val) {
|
|
||||||
if (val == null) {
|
|
||||||
return this.spd
|
|
||||||
}
|
|
||||||
this.spd = val
|
|
||||||
},
|
|
||||||
duration = function (val) {
|
|
||||||
if (val == null) {
|
|
||||||
return this.dur
|
|
||||||
}
|
|
||||||
this.s = (this.s * val) / this.dur
|
|
||||||
this.dur = val
|
|
||||||
},
|
|
||||||
stopit = function () {
|
|
||||||
delete animations[this.id]
|
|
||||||
this.update()
|
|
||||||
eve('mina.stop.' + this.id, a)
|
|
||||||
},
|
|
||||||
pause = function () {
|
|
||||||
let a = this
|
|
||||||
if (a.pdif) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
delete animations[a.id]
|
|
||||||
a.update()
|
|
||||||
a.pdif = a.get() - a.b
|
|
||||||
},
|
|
||||||
resume = function () {
|
|
||||||
let a = this
|
|
||||||
if (!a.pdif) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
a.b = a.get() - a.pdif
|
|
||||||
delete a.pdif
|
|
||||||
animations[a.id] = a
|
|
||||||
frame()
|
|
||||||
},
|
|
||||||
update = function () {
|
|
||||||
let a = this,
|
|
||||||
res
|
|
||||||
if (isArray(a.start)) {
|
|
||||||
res = []
|
|
||||||
for (let j = 0, jj = a.start.length; j < jj; j++) {
|
|
||||||
res[j] = +a.start[j] + (a.end[j] - a.start[j]) * a.easing(a.s)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
res = +a.start + (a.end - a.start) * a.easing(a.s)
|
|
||||||
}
|
|
||||||
a.set(res)
|
|
||||||
},
|
|
||||||
frame = function (timeStamp) {
|
|
||||||
// Manual invokation?
|
|
||||||
if (!timeStamp) {
|
|
||||||
// Frame loop stopped?
|
|
||||||
if (!requestID) {
|
|
||||||
// Start frame loop...
|
|
||||||
requestID = requestAnimFrame(frame)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let len = 0
|
|
||||||
for (let i in animations)
|
|
||||||
if (animations.hasOwnProperty(i)) {
|
|
||||||
let a = animations[i],
|
|
||||||
b = a.get(),
|
|
||||||
res
|
|
||||||
len++
|
|
||||||
a.s = (b - a.b) / (a.dur / a.spd)
|
|
||||||
if (a.s >= 1) {
|
|
||||||
delete animations[i]
|
|
||||||
a.s = 1
|
|
||||||
len--
|
|
||||||
;(function (a) {
|
|
||||||
setTimeout(function () {
|
|
||||||
eve('mina.finish.' + a.id, a)
|
|
||||||
})
|
|
||||||
})(a)
|
|
||||||
}
|
|
||||||
a.update()
|
|
||||||
}
|
|
||||||
requestID = len ? requestAnimFrame(frame) : false
|
|
||||||
}
|
|
||||||
/***
|
|
||||||
* Generic animation of numbers
|
|
||||||
**
|
|
||||||
* 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 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
|
|
||||||
= (object) animation descriptor
|
|
||||||
{
|
|
||||||
id (string) animation id,
|
|
||||||
start (number) start _slave_ number,
|
|
||||||
end (number) end _slave_ number,
|
|
||||||
b (number) start _master_ number,
|
|
||||||
s (number) animation status (0..1),
|
|
||||||
dur (number) animation duration,
|
|
||||||
spd (number) animation speed,
|
|
||||||
get (function) getter of _master_ number (see @mina.time),
|
|
||||||
set (function) setter of _slave_ number,
|
|
||||||
easing (function) easing function, default is @mina.linear,
|
|
||||||
status (function) status getter/setter,
|
|
||||||
speed (function) speed getter/setter,
|
|
||||||
duration (function) duration getter/setter,
|
|
||||||
stop (function) animation stopper
|
|
||||||
pause (function) pauses the animation
|
|
||||||
resume (function) resumes the animation
|
|
||||||
update (function) calles setter with the right value of the animation
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
export const mina = function (a, A, b, B, get, set, easing) {
|
|
||||||
let anim = {
|
|
||||||
id: uuid('M'),
|
|
||||||
start: a,
|
|
||||||
end: A,
|
|
||||||
b: b,
|
|
||||||
s: 0,
|
|
||||||
dur: B - b,
|
|
||||||
spd: 1,
|
|
||||||
get: get,
|
|
||||||
set: set,
|
|
||||||
easing: easing || mina.linear,
|
|
||||||
status: sta,
|
|
||||||
speed: speed,
|
|
||||||
duration: duration,
|
|
||||||
stop: stopit,
|
|
||||||
pause: pause,
|
|
||||||
resume: resume,
|
|
||||||
update: update
|
|
||||||
}
|
|
||||||
animations[anim.id] = anim
|
|
||||||
let len = 0,
|
|
||||||
i
|
|
||||||
for (i in animations)
|
|
||||||
if (animations.hasOwnProperty(i)) {
|
|
||||||
len++
|
|
||||||
if (len == 2) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
len == 1 && frame()
|
|
||||||
return anim
|
|
||||||
}
|
|
||||||
/*\
|
|
||||||
* mina.time
|
|
||||||
[ method ]
|
|
||||||
**
|
|
||||||
* Returns the current time. Equivalent to:
|
|
||||||
| function () {
|
|
||||||
| return (new Date).getTime();
|
|
||||||
| }
|
|
||||||
\*/
|
|
||||||
mina.time = timer
|
|
||||||
/*\
|
|
||||||
* mina.getById
|
|
||||||
[ method ]
|
|
||||||
**
|
|
||||||
* Returns an animation by its id
|
|
||||||
- id (string) animation's id
|
|
||||||
= (object) See @mina
|
|
||||||
\*/
|
|
||||||
mina.getById = function (id) {
|
|
||||||
return animations[id] || null
|
|
||||||
}
|
|
||||||
|
|
||||||
/*\
|
|
||||||
* mina.linear
|
|
||||||
[ method ]
|
|
||||||
**
|
|
||||||
* Default linear easing
|
|
||||||
- n (number) input 0..1
|
|
||||||
= (number) output 0..1
|
|
||||||
\*/
|
|
||||||
mina.linear = function (n) {
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
/*\
|
|
||||||
* mina.easeout
|
|
||||||
[ method ]
|
|
||||||
**
|
|
||||||
* Easeout easing
|
|
||||||
- n (number) input 0..1
|
|
||||||
= (number) output 0..1
|
|
||||||
\*/
|
|
||||||
mina.easeout = function (n) {
|
|
||||||
return Math.pow(n, 1.7)
|
|
||||||
}
|
|
||||||
/*\
|
|
||||||
* mina.easein
|
|
||||||
[ method ]
|
|
||||||
**
|
|
||||||
* Easein easing
|
|
||||||
- n (number) input 0..1
|
|
||||||
= (number) output 0..1
|
|
||||||
\*/
|
|
||||||
mina.easein = function (n) {
|
|
||||||
return Math.pow(n, 0.48)
|
|
||||||
}
|
|
||||||
/*\
|
|
||||||
* mina.easeinout
|
|
||||||
[ method ]
|
|
||||||
**
|
|
||||||
* Easeinout easing
|
|
||||||
- n (number) input 0..1
|
|
||||||
= (number) output 0..1
|
|
||||||
\*/
|
|
||||||
mina.easeinout = function (n) {
|
|
||||||
if (n == 1) {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
if (n == 0) {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
let q = 0.48 - n / 1.04,
|
|
||||||
Q = Math.sqrt(0.1734 + q * q),
|
|
||||||
x = Q - q,
|
|
||||||
X = Math.pow(Math.abs(x), 1 / 3) * (x < 0 ? -1 : 1),
|
|
||||||
y = -Q - q,
|
|
||||||
Y = Math.pow(Math.abs(y), 1 / 3) * (y < 0 ? -1 : 1),
|
|
||||||
t = X + Y + 0.5
|
|
||||||
return (1 - t) * 3 * t * t + t * t * t
|
|
||||||
}
|
|
||||||
/*\
|
|
||||||
* mina.backin
|
|
||||||
[ method ]
|
|
||||||
**
|
|
||||||
* Backin easing
|
|
||||||
- n (number) input 0..1
|
|
||||||
= (number) output 0..1
|
|
||||||
\*/
|
|
||||||
mina.backin = function (n) {
|
|
||||||
if (n == 1) {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
let s = 1.70158
|
|
||||||
return n * n * ((s + 1) * n - s)
|
|
||||||
}
|
|
||||||
/*\
|
|
||||||
* mina.backout
|
|
||||||
[ method ]
|
|
||||||
**
|
|
||||||
* Backout easing
|
|
||||||
- n (number) input 0..1
|
|
||||||
= (number) output 0..1
|
|
||||||
\*/
|
|
||||||
mina.backout = function (n) {
|
|
||||||
if (n == 0) {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
n = n - 1
|
|
||||||
let s = 1.70158
|
|
||||||
return n * n * ((s + 1) * n + s) + 1
|
|
||||||
}
|
|
||||||
/*\
|
|
||||||
* mina.elastic
|
|
||||||
[ method ]
|
|
||||||
**
|
|
||||||
* Elastic easing
|
|
||||||
- n (number) input 0..1
|
|
||||||
= (number) output 0..1
|
|
||||||
\*/
|
|
||||||
mina.elastic = function (n) {
|
|
||||||
if (n == !!n) {
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
Math.pow(2, -10 * n) * Math.sin(((n - 0.075) * (2 * Math.PI)) / 0.3) + 1
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/*\
|
|
||||||
* mina.bounce
|
|
||||||
[ method ]
|
|
||||||
**
|
|
||||||
* Bounce easing
|
|
||||||
- n (number) input 0..1
|
|
||||||
= (number) output 0..1
|
|
||||||
\*/
|
|
||||||
mina.bounce = function (n) {
|
|
||||||
let s = 7.5625,
|
|
||||||
p = 2.75,
|
|
||||||
l
|
|
||||||
if (n < 1 / p) {
|
|
||||||
l = s * n * n
|
|
||||||
} else {
|
|
||||||
if (n < 2 / p) {
|
|
||||||
n -= 1.5 / p
|
|
||||||
l = s * n * n + 0.75
|
|
||||||
} else {
|
|
||||||
if (n < 2.5 / p) {
|
|
||||||
n -= 2.25 / p
|
|
||||||
l = s * n * n + 0.9375
|
|
||||||
} else {
|
|
||||||
n -= 2.625 / p
|
|
||||||
l = s * n * n + 0.984375
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return l
|
|
||||||
}
|
|
||||||
export default mina
|
|
321
src/set.js
321
src/set.js
|
@ -1,321 +0,0 @@
|
||||||
/**
|
|
||||||
* {}
|
|
||||||
* @author yutent<yutent.io@gmail.com>
|
|
||||||
* @date 2024/03/07 15:33:05
|
|
||||||
*/
|
|
||||||
|
|
||||||
import eve from './eve.js'
|
|
||||||
import { Animation } from './animation.js'
|
|
||||||
import mina from './mina.js'
|
|
||||||
import { is } from './utils.js'
|
|
||||||
|
|
||||||
let mmax = Math.max,
|
|
||||||
mmin = Math.min
|
|
||||||
|
|
||||||
// Set
|
|
||||||
let Set = function (items) {
|
|
||||||
this.items = []
|
|
||||||
this.bindings = {}
|
|
||||||
this.length = 0
|
|
||||||
this.type = 'set'
|
|
||||||
if (items) {
|
|
||||||
for (let i = 0, ii = items.length; i < ii; i++) {
|
|
||||||
if (items[i]) {
|
|
||||||
this[this.items.length] = this.items[this.items.length] = items[i]
|
|
||||||
this.length++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setproto = Set.prototype
|
|
||||||
/*\
|
|
||||||
* Set.push
|
|
||||||
[ method ]
|
|
||||||
**
|
|
||||||
* Adds each argument to the current set
|
|
||||||
= (object) original element
|
|
||||||
\*/
|
|
||||||
setproto.push = function () {
|
|
||||||
let item, len
|
|
||||||
for (let i = 0, ii = arguments.length; i < ii; i++) {
|
|
||||||
item = arguments[i]
|
|
||||||
if (item) {
|
|
||||||
len = this.items.length
|
|
||||||
this[len] = this.items[len] = item
|
|
||||||
this.length++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
/*\
|
|
||||||
* Set.pop
|
|
||||||
[ method ]
|
|
||||||
**
|
|
||||||
* Removes last element and returns it
|
|
||||||
= (object) element
|
|
||||||
\*/
|
|
||||||
setproto.pop = function () {
|
|
||||||
this.length && delete this[this.length--]
|
|
||||||
return this.items.pop()
|
|
||||||
}
|
|
||||||
/*\
|
|
||||||
* Set.forEach
|
|
||||||
[ method ]
|
|
||||||
**
|
|
||||||
* Executes given function for each element in the set
|
|
||||||
*
|
|
||||||
* If the function returns `false`, the loop stops running.
|
|
||||||
**
|
|
||||||
- callback (function) function to run
|
|
||||||
- thisArg (object) context object for the callback
|
|
||||||
= (object) Set object
|
|
||||||
\*/
|
|
||||||
setproto.forEach = function (callback, thisArg) {
|
|
||||||
for (let i = 0, ii = this.items.length; i < ii; i++) {
|
|
||||||
if (callback.call(thisArg, this.items[i], i) === false) {
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Animates each element in set in sync.
|
|
||||||
*
|
|
||||||
**
|
|
||||||
- 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
|
|
||||||
* or
|
|
||||||
- animation (array) array of animation parameter for each element in set in format `[attrs, duration, easing, callback]`
|
|
||||||
> Usage
|
|
||||||
| // animate all elements in set to radius 10
|
|
||||||
| set.animate({r: 10}, 500, mina.easein);
|
|
||||||
| // or
|
|
||||||
| // animate first element to radius 10, but second to radius 20 and in different time
|
|
||||||
| set.animate([{r: 10}, 500, mina.easein], [{r: 20}, 1500, mina.easein]);
|
|
||||||
= (SnapElement) the current element
|
|
||||||
*/
|
|
||||||
setproto.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 = easing.dur
|
|
||||||
attrs = attrs.attr
|
|
||||||
}
|
|
||||||
let args = arguments
|
|
||||||
if (is(attrs, 'array') && is(args[args.length - 1], 'array')) {
|
|
||||||
let each = true
|
|
||||||
}
|
|
||||||
let begin,
|
|
||||||
handler = function () {
|
|
||||||
if (begin) {
|
|
||||||
this.b = begin
|
|
||||||
} else {
|
|
||||||
begin = this.b
|
|
||||||
}
|
|
||||||
},
|
|
||||||
cb = 0,
|
|
||||||
set = this,
|
|
||||||
callbacker =
|
|
||||||
callback &&
|
|
||||||
function () {
|
|
||||||
if (++cb == set.length) {
|
|
||||||
callback.call(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.forEach(function (el, i) {
|
|
||||||
eve.once('snap.animcreated.' + el.id, handler)
|
|
||||||
if (each) {
|
|
||||||
args[i] && el.animate.apply(el, args[i])
|
|
||||||
} else {
|
|
||||||
el.animate(attrs, ms, easing, callbacker)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Removes all children of the set.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
setproto.remove = function () {
|
|
||||||
while (this.length) {
|
|
||||||
this.pop().remove()
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Specifies how to handle a specific attribute when applied
|
|
||||||
* to a set.
|
|
||||||
*
|
|
||||||
**
|
|
||||||
- attr (string) attribute name
|
|
||||||
- callback (function) function to run
|
|
||||||
* or
|
|
||||||
- attr (string) attribute name
|
|
||||||
- element (SnapElement) specific element in the set to apply the attribute to
|
|
||||||
* or
|
|
||||||
- attr (string) attribute name
|
|
||||||
- element (SnapElement) specific element in the set to apply the attribute to
|
|
||||||
- eattr (string) attribute on the element to bind the attribute to
|
|
||||||
= (object) Set object
|
|
||||||
*/
|
|
||||||
setproto.bind = function (attr, a, b) {
|
|
||||||
let data = {}
|
|
||||||
if (typeof a == 'function') {
|
|
||||||
this.bindings[attr] = a
|
|
||||||
} else {
|
|
||||||
let aname = b || attr
|
|
||||||
this.bindings[attr] = function (v) {
|
|
||||||
data[aname] = v
|
|
||||||
a.attr(data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Equivalent of @SnapElement.attr.
|
|
||||||
*/
|
|
||||||
setproto.attr = function (value) {
|
|
||||||
let unbound = {}
|
|
||||||
for (let k in value) {
|
|
||||||
if (this.bindings[k]) {
|
|
||||||
this.bindings[k](value[k])
|
|
||||||
} else {
|
|
||||||
unbound[k] = value[k]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (let i = 0, ii = this.items.length; i < ii; i++) {
|
|
||||||
this.items[i].attr(unbound)
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Removes all elements from the set
|
|
||||||
*/
|
|
||||||
setproto.clear = function () {
|
|
||||||
while (this.length) {
|
|
||||||
this.pop()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Removes range of elements from the set
|
|
||||||
**
|
|
||||||
* index (number) position of the deletion
|
|
||||||
* count (number) number of element to remove
|
|
||||||
* insertion… (object) #optional elements to insert
|
|
||||||
*/
|
|
||||||
setproto.splice = function (index, count, insertion) {
|
|
||||||
index = index < 0 ? mmax(this.length + index, 0) : index
|
|
||||||
count = mmax(0, mmin(this.length - index, count))
|
|
||||||
let tail = [],
|
|
||||||
todel = [],
|
|
||||||
args = [],
|
|
||||||
i
|
|
||||||
for (i = 2; i < arguments.length; i++) {
|
|
||||||
args.push(arguments[i])
|
|
||||||
}
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
todel.push(this[index + i])
|
|
||||||
}
|
|
||||||
for (; i < this.length - index; i++) {
|
|
||||||
tail.push(this[index + i])
|
|
||||||
}
|
|
||||||
let arglen = args.length
|
|
||||||
for (i = 0; i < arglen + tail.length; i++) {
|
|
||||||
this.items[index + i] = this[index + i] =
|
|
||||||
i < arglen ? args[i] : tail[i - arglen]
|
|
||||||
}
|
|
||||||
i = this.items.length = this.length -= count - arglen
|
|
||||||
while (this[i]) {
|
|
||||||
delete this[i++]
|
|
||||||
}
|
|
||||||
return new Set(todel)
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Removes given element from the set
|
|
||||||
**
|
|
||||||
* element (object) element to remove
|
|
||||||
*/
|
|
||||||
setproto.exclude = function (el) {
|
|
||||||
for (let i = 0, ii = this.length; i < ii; i++)
|
|
||||||
if (this[i] == el) {
|
|
||||||
this.splice(i, 1)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Inserts set elements after given element.
|
|
||||||
**
|
|
||||||
* element (object) set will be inserted after this element
|
|
||||||
*/
|
|
||||||
setproto.insertAfter = function (el) {
|
|
||||||
let i = this.items.length
|
|
||||||
while (i--) {
|
|
||||||
this.items[i].insertAfter(el)
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Union of all bboxes of the set. See @SnapElement.getBBox.
|
|
||||||
*/
|
|
||||||
setproto.getBBox = function () {
|
|
||||||
let x = [],
|
|
||||||
y = [],
|
|
||||||
x2 = [],
|
|
||||||
y2 = []
|
|
||||||
for (let i = this.items.length; i--; )
|
|
||||||
if (!this.items[i].removed) {
|
|
||||||
let box = this.items[i].getBBox()
|
|
||||||
x.push(box.x)
|
|
||||||
y.push(box.y)
|
|
||||||
x2.push(box.x + box.width)
|
|
||||||
y2.push(box.y + box.height)
|
|
||||||
}
|
|
||||||
x = mmin.apply(0, x)
|
|
||||||
y = mmin.apply(0, y)
|
|
||||||
x2 = mmax.apply(0, x2)
|
|
||||||
y2 = mmax.apply(0, y2)
|
|
||||||
return {
|
|
||||||
x: x,
|
|
||||||
y: y,
|
|
||||||
x2: x2,
|
|
||||||
y2: y2,
|
|
||||||
width: x2 - x,
|
|
||||||
height: y2 - y,
|
|
||||||
cx: x + (x2 - x) / 2,
|
|
||||||
cy: y + (y2 - y) / 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Creates a clone of the set.
|
|
||||||
*/
|
|
||||||
setproto.clone = function (s) {
|
|
||||||
s = new Set()
|
|
||||||
for (let i = 0, ii = this.items.length; i < ii; i++) {
|
|
||||||
s.push(this.items[i].clone())
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
setproto.type = 'set'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a set and fills it with list of arguments.
|
|
||||||
**
|
|
||||||
= (object) New Set object
|
|
||||||
| let r = paper.rect(0, 0, 10, 10),
|
|
||||||
| s1 = createSet(), // empty set
|
|
||||||
| s2 = createSet(r, paper.circle(100, 100, 20)); // prefilled set
|
|
||||||
*/
|
|
||||||
export function createSet(...args) {
|
|
||||||
let set = new Set()
|
|
||||||
if (args.length) {
|
|
||||||
set.push.apply(set, args)
|
|
||||||
}
|
|
||||||
return set
|
|
||||||
}
|
|
Loading…
Reference in New Issue