Code cleanup
This commit is contained in:
parent
2960ff6d73
commit
728af0a801
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "KUTE.js",
|
||||
"version": "1.5.6",
|
||||
"version": "1.5.7",
|
||||
"homepage": "http://thednp.github.io/kute.js",
|
||||
"authors": [
|
||||
"thednp"
|
||||
|
@ -15,7 +15,8 @@
|
|||
"keywords": [
|
||||
"animations",
|
||||
"animation engine",
|
||||
"native-javascript",
|
||||
"javascript animation engine",
|
||||
"native javascript",
|
||||
"kute.js",
|
||||
"tweening",
|
||||
"engine"
|
||||
|
@ -28,5 +29,7 @@
|
|||
"test",
|
||||
"tests"
|
||||
],
|
||||
"dependencies": {}
|
||||
"dependencies": {
|
||||
"uglify-js": "^2.7.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,13 +22,13 @@
|
|||
}( function (KUTE) {
|
||||
'use strict';
|
||||
|
||||
var K = window.KUTE, DOM = K.dom, PP = K.pp, unit = K.Interpolate.unit, number = K.Interpolate.number, atts,
|
||||
var K = window.KUTE, DOM = K.dom, prepareStart = K.prS, parseProperty = K.pp, unit = K.Interpolate.unit, number = K.Interpolate.number, atts,
|
||||
getCurrentValue = function(e,a){ return e.getAttribute(a); }, // get current attribute value
|
||||
replaceUppercase = function(a) {
|
||||
return /[A-Z]/g.test(a) ? a.replace(a.match(/[A-Z]/g)[0],'-'+a.match(/[A-Z]/g)[0].toLowerCase()) : a;
|
||||
};
|
||||
|
||||
K.prS['attr'] = function(el,p,v){
|
||||
prepareStart['attr'] = function(el,p,v){
|
||||
var f = {};
|
||||
for (var a in v){
|
||||
var _a = replaceUppercase(a).replace(/_+[a-z]+/,''),
|
||||
|
@ -40,7 +40,7 @@
|
|||
|
||||
// process attributes object K.pp.attr(t[x])
|
||||
// and also register their render functions
|
||||
PP['attr'] = function(a,o,l){
|
||||
parseProperty['attr'] = function(a,o,l){
|
||||
if (!('attr' in DOM)) {
|
||||
DOM.attr = function(l,p,a,b,v) {
|
||||
for ( var o in b ){
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
throw new Error("CSS Plugin require KUTE.js.")
|
||||
}
|
||||
})(function(KUTE){
|
||||
var K = window.KUTE, p, DOM = K.dom, PP = K.pp,
|
||||
'use strict';
|
||||
var K = window.KUTE, p, DOM = K.dom, parseProperty = K.pp, prepareStart = K.prS, getComputedStyle = K.gCS,
|
||||
_br = K.property('borderRadius'), _brtl = K.property('borderTopLeftRadius'), _brtr = K.property('borderTopRightRadius'), // all radius props prefixed
|
||||
_brbl = K.property('borderBottomLeftRadius'), _brbr = K.property('borderBottomRightRadius'),
|
||||
_cls = ['borderColor', 'borderTopColor', 'borderRightColor', 'borderBottomColor', 'borderLeftColor', 'outlineColor'], // colors 'hex', 'rgb', 'rgba' -- #fff / rgb(0,0,0) / rgba(0,0,0,0)
|
||||
|
@ -49,39 +50,39 @@
|
|||
// create prepare/process/render functions for additional colors properties
|
||||
for (var i = 0, l = _cls.length; i<l; i++) {
|
||||
p = _cls[i];
|
||||
PP[p] = function(p,v) {
|
||||
parseProperty[p] = function(p,v) {
|
||||
if (!(p in DOM)) {
|
||||
DOM[p] = function(l,p,a,b,v,o) {
|
||||
l.style[p] = color(a,b,v,o.keepHex);
|
||||
};
|
||||
}
|
||||
return PP.cls(p,v);
|
||||
return parseProperty.cls(p,v);
|
||||
};
|
||||
K.prS[p] = function(el,p,v){
|
||||
return K.gCS(el,p) || _d[p];
|
||||
prepareStart[p] = function(el,p,v){
|
||||
return getComputedStyle(el,p) || _d[p];
|
||||
};
|
||||
}
|
||||
|
||||
// create prepare/process/render functions for additional box model properties
|
||||
for (var i = 0, l = _mg.length; i<l; i++) {
|
||||
p = _mg[i];
|
||||
PP[p] = function(p,v){
|
||||
parseProperty[p] = function(p,v){
|
||||
if (!(p in DOM)){
|
||||
DOM[p] = function(l,p,a,b,v){
|
||||
l.style[p] = unit(a.value,b.value,b.unit,v);
|
||||
}
|
||||
}
|
||||
return PP.box(p,v);
|
||||
return parseProperty.box(p,v);
|
||||
};
|
||||
K.prS[p] = function(el,p,v){
|
||||
return K.gCS(el,p) || _d[p];
|
||||
prepareStart[p] = function(el,p,v){
|
||||
return getComputedStyle(el,p) || _d[p];
|
||||
};
|
||||
}
|
||||
|
||||
//create prepare/process/render functions for radius properties
|
||||
for (var i = 0, l = _rd.length; i<l; i++) {
|
||||
p = _rd[i];
|
||||
PP[p] = function(p,v){
|
||||
parseProperty[p] = function(p,v){
|
||||
if ( (!(p in DOM)) ) {
|
||||
if (p === 'borderRadius') {
|
||||
DOM[p] = function(l,p,a,b,v){
|
||||
|
@ -105,15 +106,15 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
return PP.box(p,v);
|
||||
return parseProperty.box(p,v);
|
||||
};
|
||||
K.prS[p] = function(el,p,v){
|
||||
return K.gCS(el,p) || _d[p];
|
||||
prepareStart[p] = function(el,p,v){
|
||||
return getComputedStyle(el,p) || _d[p];
|
||||
};
|
||||
}
|
||||
|
||||
// clip
|
||||
PP['clip'] = function(p,v){
|
||||
parseProperty['clip'] = function(p,v){
|
||||
if ( !(p in DOM) ) {
|
||||
DOM[p] = function(l,p,a,b,v) {
|
||||
var h = 0, cl = [];
|
||||
|
@ -133,13 +134,13 @@
|
|||
}
|
||||
};
|
||||
|
||||
K.prS['clip'] = function(el,p,v){
|
||||
var c = K.gCS(el,p), w = K.gCS(el,'width'), h = K.gCS(el,'height');
|
||||
prepareStart['clip'] = function(el,p,v){
|
||||
var c = getComputedStyle(el,p), w = getComputedStyle(el,'width'), h = getComputedStyle(el,'height');
|
||||
return !/rect/.test(c) ? [0, w, h, 0] : c;
|
||||
};
|
||||
|
||||
// background position
|
||||
PP['backgroundPosition'] = function(p,v) {
|
||||
parseProperty['backgroundPosition'] = function(p,v) {
|
||||
if ( !(p in DOM) ) {
|
||||
DOM[p] = function(l,p,a,b,v) {
|
||||
l.style[p] = unit(a.x.v,b.x.v,'%',v) + ' ' + unit(a.y.v,b.y.v,'%',v);
|
||||
|
@ -154,8 +155,8 @@
|
|||
return { x: xp, y: yp };
|
||||
}
|
||||
}
|
||||
K.prS['backgroundPosition'] = function(el,p,v){
|
||||
return K.gCS(el,p) || _d[p];
|
||||
prepareStart['backgroundPosition'] = function(el,p,v){
|
||||
return getComputedStyle(el,p) || _d[p];
|
||||
}
|
||||
|
||||
return this;
|
||||
|
|
|
@ -21,12 +21,11 @@
|
|||
}
|
||||
}( function (KUTE) {
|
||||
'use strict';
|
||||
var K = window.KUTE, S = K.svg = {}, p, DOM = K.dom, PP = K.pp,
|
||||
_svg = document.querySelector('path') || document.querySelector('svg'),
|
||||
_ns = _svg && _svg.ownerSVGElement && _svg.ownerSVGElement.namespaceURI || 'http://www.w3.org/2000/svg',
|
||||
var K = window.KUTE, p, DOM = K.dom, parseProperty = K.pp, prepareStart = K.prS, getComputedStyle = K.gCS,
|
||||
_isIE = (new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})").exec(navigator.userAgent) != null) ? parseFloat( RegExp.$1 ) : false,
|
||||
_nm = ['strokeWidth', 'strokeOpacity', 'fillOpacity', 'stopOpacity'], // numeric SVG CSS props
|
||||
_cls = ['fill', 'stroke', 'stopColor'], // colors 'hex', 'rgb', 'rgba' -- #fff / rgb(0,0,0) / rgba(0,0,0,0)
|
||||
pathReg = /(m[^(h|v|l)]*|[vhl][^(v|h|l|z)]*)/gmi,
|
||||
pathReg = /(m[^(h|v|l)]*|[vhl][^(v|h|l|z)]*)/gmi, ns = 'http://www.w3.org/2000/svg',
|
||||
// interpolate functions
|
||||
number = K.Interpolate.number, color = K.Interpolate.color,
|
||||
array = function array(a,b,l,v) { // array1, array2, array2.length, progress
|
||||
|
@ -39,252 +38,300 @@
|
|||
for(i=0;i<l;i++) { s.push( array( a[i],b[i],ll,v ) ); }
|
||||
return s.join(o);
|
||||
};
|
||||
|
||||
if (_svg && !_svg.ownerSVGElement) {return;} // if SVG API is not supported, return
|
||||
|
||||
|
||||
if (_isIE&&_isIE<9) {return;} // return if SVG API is not supported
|
||||
|
||||
|
||||
// SVG MORPH
|
||||
S.gPt = function(e){ // get path d attribute or create a path from string value
|
||||
var p = {}, el = typeof e === 'object' ? e : /^\.|^\#/.test(e) ? document.querySelector(e) : null;
|
||||
if ( el && /path|glyph/.test(el.tagName) ) {
|
||||
p.e = S.fPt(el);
|
||||
p.o = el.getAttribute('d');
|
||||
var getSegments = function(s,e,r){ // getSegments returns an array of points based on a sample size morphPrecision
|
||||
var s1 = [], e1 = [], le1 = s.getTotalLength(), le2 = e.getTotalLength(), ml = Math.max(le1,le2),
|
||||
d = r, ar = ml / r, j = 0, sl = ar*r; // sl = sample length
|
||||
|
||||
} else if (!el && /[a-z][^a-z]*/ig.test(e)) { // maybe it's a string path already
|
||||
p.e = S.cP(e.trim());
|
||||
p.o = e;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
S.pCr = function(w){ // pathCross
|
||||
// path tween options
|
||||
this._mpr = w._ops.morphPrecision || 15;
|
||||
this._midx = w._ops.morphIndex;
|
||||
this._smi = w._ops.showMorphInfo;
|
||||
this._rv1 = w._ops.reverseFirstPath;
|
||||
this._rv2 = w._ops.reverseSecondPath;
|
||||
|
||||
var p1 = S.gOp(w._vS.path.o), p2 = S.gOp(w._vE.path.o), arr;
|
||||
this._isp = !/[CSQTA]/i.test(p1) && !/[CSQTA]/i.test(p2); // both shapes are polygons
|
||||
|
||||
arr = S._pCr(p1,p2,w._el.parentNode);
|
||||
|
||||
w._vS.path.d = arr[0];
|
||||
w._vE.path.d = arr[1];
|
||||
}
|
||||
|
||||
S._pCr = function(s,e,svg){ // _pathCross
|
||||
var s1, e1, arr, idx, arL, sm, lg, smp, lgp, nsm = [], sml, cl = [], len, tl, cs;
|
||||
this._sp = false;
|
||||
|
||||
if (!this._isp) {
|
||||
s = S.cP(s); e = S.cP(e);
|
||||
arr = S.gSegs(s,e,this._mpr);
|
||||
s1 = arr[0]; e1 = arr[1]; arL = e1.length;
|
||||
} else {
|
||||
s = S.pTA(s); e = S.pTA(e);
|
||||
|
||||
if ( s.length !== e.length ){
|
||||
arL = Math.max(s.length,e.length);
|
||||
if ( arL === e.length) { sm = s; lg = e; } else { sm = e; lg = s; }
|
||||
sml = sm.length;
|
||||
|
||||
smp = S.cP('M'+sm.join('L')+'z'); len = smp.getTotalLength() / arL;
|
||||
for (var i=0; i<arL; i++){
|
||||
tl = smp.getPointAtLength(len*i);
|
||||
cs = S.gCP(len,tl,sm);
|
||||
nsm.push( [ cs[0], cs[1] ] );
|
||||
}
|
||||
|
||||
if (arL === e.length) { e1 = lg; s1 = nsm; } else { s1 = lg; e1 = nsm; }
|
||||
} else {
|
||||
s1 = s; e1 = e;
|
||||
while ( (j += r) < sl ) { // populate the points arrays based on morphPrecision as sample size
|
||||
s1.push( [s.getPointAtLength(j).x, s.getPointAtLength(j).y]);
|
||||
e1.push( [e.getPointAtLength(j).x, e.getPointAtLength(j).y]);
|
||||
}
|
||||
}
|
||||
|
||||
// reverse arrays
|
||||
if (this._rv1) { s1.reverse(); }
|
||||
if (this._rv2) { e1.reverse(); }
|
||||
|
||||
// determine index for best/minimum distance between points
|
||||
if (this._smi) { idx = S.gBi(s1,e1); }
|
||||
|
||||
// shift second array to for smallest tween distance
|
||||
if (this._midx) {
|
||||
var e11 = e1.splice(this._midx,arL-this._midx);
|
||||
e1 = e11.concat(e1);
|
||||
}
|
||||
|
||||
// the console.log helper utility
|
||||
if (this._smi) {
|
||||
// also show the points
|
||||
S.shP(s1,e1,svg);
|
||||
var mpi = this._isp ? 'the polygon with the most points.\n' : (this._mpr === 25 ? 'the default' : 'your') +' morphPrecision value of '+this._mpr+'.\n';
|
||||
console.log( 'KUTE.js Path Morph Log\nThe morph used ' + arL + ' points to draw both paths based on '+mpi
|
||||
+ (this._midx ? 'You\'ve configured the morphIndex to ' + this._midx + ' while the recommended is ' + idx+ '.\n' : 'You may also consider a morphIndex for the second path. Currently the best index seems to be ' + idx + '.\n')
|
||||
+ (
|
||||
!this._rv1 && !this._rv2 ? 'If the current animation is not satisfactory, consider reversing one of the paths. Maybe the paths do not intersect or they really have different draw directions.' :
|
||||
'You\'ve chosen that the first path to have ' + ( this._rv1 ? 'REVERSED draw direction, ' : 'UNCHANGED draw direction, ') + 'while second path is to be ' + (this._rv2 ? 'REVERSED.\n' : 'UNCHANGED.\n')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
s = e = null;
|
||||
return [s1,e1]
|
||||
}
|
||||
|
||||
S.gSegs = function(s,e,r){ // getSegments returns an array of points based on a sample size morphPrecision
|
||||
var s1 = [], e1 = [], le1 = s.getTotalLength(), le2 = e.getTotalLength(), ml = Math.max(le1,le2),
|
||||
d = r, ar = ml / r, j = 0, sl = ar*r; // sl = sample length
|
||||
|
||||
while ( (j += r) < sl ) { // populate the points arrays based on morphPrecision as sample size
|
||||
s1.push( [s.getPointAtLength(j).x, s.getPointAtLength(j).y]);
|
||||
e1.push( [e.getPointAtLength(j).x, e.getPointAtLength(j).y]);
|
||||
}
|
||||
return [s1,e1];
|
||||
}
|
||||
|
||||
S.gCP = function(p,t,s){ // getClosestPoint for polygon paths it returns a close point from the original path (length,pointAtLength,smallest); // intervalLength
|
||||
var x, y, a = [], l = s.length, dx, nx, pr;
|
||||
for (i=0; i<l; i++){
|
||||
x = Math.abs(s[i][0] - t.x);
|
||||
y = Math.abs(s[i][1] - t.y);
|
||||
a.push( Math.sqrt( x * x + y * y ) );
|
||||
}
|
||||
dx = a.indexOf(Math.min.apply(null,a));
|
||||
pr = !!s[dx-1] ? dx-1 : l-1;
|
||||
nx = !!s[dx+1] ? dx+1 : 0;
|
||||
return Math.abs(s[pr][0] - t.x) < p && Math.abs(s[pr][1] - t.y) < p ? s[pr]
|
||||
: Math.abs(s[nx][0] - t.x) < p && Math.abs(s[nx][1] - t.y) < p ? s[nx]
|
||||
: Math.abs(s[dx][0] - t.x) < p && Math.abs(s[dx][1] - t.y) < p ? s[dx]
|
||||
: [t.x,t.y];
|
||||
}
|
||||
|
||||
S.shP = function(s,e,v){// showPoints helper function to visualize the points on the path
|
||||
if (!this._sp){
|
||||
var c, a = arguments, cl, p, l;
|
||||
for (var i=0; i<2; i++){
|
||||
p = a[i]; l = p.length; cl = i=== 0 ? { f: 'DeepPink', o: 'HotPink' } : { f: 'Lime', o: 'LimeGreen' };
|
||||
for (var j=0; j<l; j++) {
|
||||
c = document.createElementNS(_ns,'circle');
|
||||
c.setAttribute('cx',p[j][0]); c.setAttribute('cy',p[j][1]);
|
||||
c.setAttribute('r', j===0 ? 20 : 10 ); c.setAttribute('fill', j===0 ? cl.f : cl.o);
|
||||
if (this._isp) { v.appendChild(c); } else if (!this._isp && j===0 ) { v.appendChild(c);}
|
||||
return [s1,e1];
|
||||
},
|
||||
getClosestPoint = function(p,t,s){ // getClosestPoint for polygon paths it returns a close point from the original path (length,pointAtLength,smallest); // intervalLength
|
||||
var x, y, a = [], l = s.length, dx, nx, pr;
|
||||
for (i=0; i<l; i++){
|
||||
x = Math.abs(s[i][0] - t.x);
|
||||
y = Math.abs(s[i][1] - t.y);
|
||||
a.push( Math.sqrt( x * x + y * y ) );
|
||||
}
|
||||
dx = a.indexOf(Math.min.apply(null,a));
|
||||
pr = !!s[dx-1] ? dx-1 : l-1;
|
||||
nx = !!s[dx+1] ? dx+1 : 0;
|
||||
return Math.abs(s[pr][0] - t.x) < p && Math.abs(s[pr][1] - t.y) < p ? s[pr]
|
||||
: Math.abs(s[nx][0] - t.x) < p && Math.abs(s[nx][1] - t.y) < p ? s[nx]
|
||||
: Math.abs(s[dx][0] - t.x) < p && Math.abs(s[dx][1] - t.y) < p ? s[dx]
|
||||
: [t.x,t.y];
|
||||
},
|
||||
getBestIndex = function(s,e){ // getBestIndex for shape rotation
|
||||
var s1 = clone(s), e1 = clone(e), d = [], i, l = e.length, t, ax, ay;
|
||||
for (i=0; i<l; i++){
|
||||
t = e1.splice(i,l-i); e1 = t.concat(e1);
|
||||
ax = Math.abs(s1[i][0] - e1[i][0]);
|
||||
ay = Math.abs(s1[i][1] - e1[i][1]);
|
||||
d.push( Math.sqrt( ax * ax + ay * ay ) );
|
||||
e1 = []; e1 = clone(e); t = null;
|
||||
}
|
||||
return d.indexOf(Math.min.apply(null,d));
|
||||
},
|
||||
pathToAbsolute = function(p) { // simple pathToAbsolute for polygons | this is still BETA / a work in progress
|
||||
var np = p.match(pathReg), wp = [], l = np.length, s, c, r, x = 0, y = 0;
|
||||
for (var i = 0; i<l; i++){
|
||||
np[i] = np[i]; c = np[i][0]; r = new RegExp(c+'[^\\d|\\-]*','i');
|
||||
np[i] = np[i].replace(/(^|[^,])\s*-/g, '$1,-').replace(/(\s+\,|\s|\,)/g,',').replace(r,'').split(',');
|
||||
np[i][0] = parseFloat(np[i][0]);
|
||||
np[i][1] = parseFloat(np[i][1]);
|
||||
if (i === 0) { x+=np[i][0]; y +=np[i][1]; }
|
||||
else {
|
||||
x = np[i-1][0];
|
||||
y = np[i-1][1];
|
||||
if (/l/i.test(c)) {
|
||||
np[i][0] = c === 'l' ? np[i][0] + x : np[i][0];
|
||||
np[i][1] = c === 'l' ? np[i][1] + y : np[i][1];
|
||||
} else if (/h/i.test(c)) {
|
||||
np[i][0] = c === 'h' ? np[i][0] + x : np[i][0];
|
||||
np[i][1] = y;
|
||||
} else if (/v/i.test(c)) {
|
||||
np[i][0] = x;
|
||||
np[i][1] = c === 'v' ? np[i][0] + y : np[i][0];
|
||||
}
|
||||
}
|
||||
this._sp = true; c = null;
|
||||
}
|
||||
}
|
||||
|
||||
S.gBi = function(s,e){ // getBestIndex for shape rotation
|
||||
var s1 = S.clone(s), e1 = S.clone(e), d = [], i, l = e.length, t, ax, ay;
|
||||
for (i=0; i<l; i++){
|
||||
t = e1.splice(i,l-i); e1 = t.concat(e1);
|
||||
ax = Math.abs(s1[i][0] - e1[i][0]);
|
||||
ay = Math.abs(s1[i][1] - e1[i][1]);
|
||||
d.push( Math.sqrt( ax * ax + ay * ay ) );
|
||||
e1 = []; e1 = S.clone(e); t = null;
|
||||
}
|
||||
return d.indexOf(Math.min.apply(null,d));
|
||||
}
|
||||
|
||||
S.gOp = function(p){ // getOnePath, first path only
|
||||
return p.split(/z/i).shift() + 'z';
|
||||
}
|
||||
|
||||
S.cP = function (p){ // createPath
|
||||
var c = document.createElementNS(_ns,'path'), d = typeof p === 'object' ? p.getAttribute('d') : p;
|
||||
c.setAttribute('d',d); return c;
|
||||
}
|
||||
|
||||
S.fPt = function(p){ // forcePath for glyph elements
|
||||
if (p.tagName === 'glyph') { // perhaps we can also change other SVG tags in the future
|
||||
var c = S.cP(p); p.parentNode.appendChild(c); return c;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
S.clone = function(a) {
|
||||
var copy;
|
||||
if (a instanceof Array) {
|
||||
copy = [];
|
||||
for (var i = 0, len = a.length; i < len; i++) {
|
||||
copy[i] = S.clone(a[i]);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
S.pTA = function(p) { // simple pathToAbsolute for polygons | this is still BETA / a work in progress
|
||||
var np = p.match(pathReg), wp = [], l = np.length, s, c, r, x = 0, y = 0;
|
||||
for (var i = 0; i<l; i++){
|
||||
np[i] = np[i]; c = np[i][0]; r = new RegExp(c+'[^\\d|\\-]*','i');
|
||||
np[i] = np[i].replace(/(^|[^,])\s*-/g, '$1,-').replace(/(\s+\,|\s|\,)/g,',').replace(r,'').split(',');
|
||||
np[i][0] = parseFloat(np[i][0]);
|
||||
np[i][1] = parseFloat(np[i][1]);
|
||||
if (i === 0) { x+=np[i][0]; y +=np[i][1]; }
|
||||
else {
|
||||
x = np[i-1][0];
|
||||
y = np[i-1][1];
|
||||
if (/l/i.test(c)) {
|
||||
np[i][0] = c === 'l' ? np[i][0] + x : np[i][0];
|
||||
np[i][1] = c === 'l' ? np[i][1] + y : np[i][1];
|
||||
} else if (/h/i.test(c)) {
|
||||
np[i][0] = c === 'h' ? np[i][0] + x : np[i][0];
|
||||
np[i][1] = y;
|
||||
} else if (/v/i.test(c)) {
|
||||
np[i][0] = x;
|
||||
np[i][1] = c === 'v' ? np[i][0] + y : np[i][0];
|
||||
return np;
|
||||
},
|
||||
getOnePath = function(p){ return p.split(/z/i).shift() + 'z'; }, // getOnePath, first path only
|
||||
createPath = function (p){ // createPath
|
||||
var c = document.createElementNS(ns,'path'), d = typeof p === 'object' ? p.getAttribute('d') : p;
|
||||
c.setAttribute('d',d); return c;
|
||||
},
|
||||
forcePath = function(p){ // forcePath for glyph elements
|
||||
if (p.tagName === 'glyph') { // perhaps we can also change other SVG tags in the future
|
||||
var c = createPath(p); p.parentNode.appendChild(c); return c;
|
||||
}
|
||||
return p;
|
||||
},
|
||||
clone = function(a) {
|
||||
var copy;
|
||||
if (a instanceof Array) {
|
||||
copy = [];
|
||||
for (var i = 0, len = a.length; i < len; i++) {
|
||||
copy[i] = clone(a[i]);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
return np;
|
||||
}
|
||||
return a;
|
||||
},
|
||||
getPath = function(e){ // get path d attribute or create a path from string value
|
||||
var p = {}, el = typeof e === 'object' ? e : /^\.|^\#/.test(e) ? document.querySelector(e) : null;
|
||||
if ( el && /path|glyph/.test(el.tagName) ) {
|
||||
p.e = forcePath(el);
|
||||
p.o = el.getAttribute('d');
|
||||
|
||||
} else if (!el && /[a-z][^a-z]*/ig.test(e)) { // maybe it's a string path already
|
||||
p.e = createPath(e.trim());
|
||||
p.o = e;
|
||||
}
|
||||
return p;
|
||||
},
|
||||
showCircles = 1,
|
||||
S = K.svg = {
|
||||
showStartingPoints : function(s,e,v){ // showPoints helper function to visualize the points on the path
|
||||
if (showCircles){
|
||||
var c, a = arguments, cl, p, l;
|
||||
for (var i=0; i<2; i++){
|
||||
p = a[i]; l = p.length; cl = i=== 0 ? { f: 'DeepPink', o: 'HotPink' } : { f: 'Lime', o: 'LimeGreen' };
|
||||
for (var j=0; j<l; j++) {
|
||||
c = document.createElementNS(ns,'circle');
|
||||
c.setAttribute('cx',p[j][0]); c.setAttribute('cy',p[j][1]);
|
||||
c.setAttribute('r', j===0 ? 20 : 10 ); c.setAttribute('fill', j===0 ? cl.f : cl.o);
|
||||
if (this._isp) { v.appendChild(c); } else if (!this._isp && j===0 ) { v.appendChild(c);}
|
||||
}
|
||||
}
|
||||
showCircles = 0; c = null;
|
||||
}
|
||||
},
|
||||
_pathCross : function(s,e,svg){ // pathCross
|
||||
var s1, e1, arr, idx, arL, sm, lg, smp, lgp, nsm = [], sml, cl = [], len, tl, cs;
|
||||
|
||||
if (!this._isp) {
|
||||
s = createPath(s); e = createPath(e);
|
||||
arr = getSegments(s,e,this._mpr);
|
||||
s1 = arr[0]; e1 = arr[1]; arL = e1.length;
|
||||
} else {
|
||||
s = pathToAbsolute(s); e = pathToAbsolute(e);
|
||||
|
||||
if ( s.length !== e.length ){
|
||||
arL = Math.max(s.length,e.length);
|
||||
if ( arL === e.length) { sm = s; lg = e; } else { sm = e; lg = s; }
|
||||
sml = sm.length;
|
||||
|
||||
smp = createPath('M'+sm.join('L')+'z'); len = smp.getTotalLength() / arL;
|
||||
for (var i=0; i<arL; i++){
|
||||
tl = smp.getPointAtLength(len*i);
|
||||
cs = getClosestPoint(len,tl,sm);
|
||||
nsm.push( [ cs[0], cs[1] ] );
|
||||
}
|
||||
|
||||
if (arL === e.length) { e1 = lg; s1 = nsm; } else { s1 = lg; e1 = nsm; }
|
||||
} else {
|
||||
s1 = s; e1 = e;
|
||||
}
|
||||
}
|
||||
|
||||
// reverse arrays
|
||||
if (this._rv1) { s1.reverse(); }
|
||||
if (this._rv2) { e1.reverse(); }
|
||||
|
||||
// determine index for best/minimum distance between points
|
||||
if (this._smi) { idx = getBestIndex(s1,e1); }
|
||||
|
||||
// shift second array to for smallest tween distance
|
||||
if (this._midx) {
|
||||
var e11 = e1.splice(this._midx,arL-this._midx);
|
||||
e1 = e11.concat(e1);
|
||||
}
|
||||
|
||||
// the console.log helper utility
|
||||
if (this._smi) {
|
||||
// also show the points
|
||||
this.showStartingPoints(s1,e1,svg);
|
||||
var mpi = this._isp ? 'the polygon with the most points.\n' : (this._mpr === 25 ? 'the default' : 'your') +' morphPrecision value of '+this._mpr+'.\n';
|
||||
console.log( 'KUTE.js Path Morph Log\nThe morph used ' + arL + ' points to draw both paths based on '+mpi
|
||||
+ (this._midx ? 'You\'ve configured the morphIndex to ' + this._midx + ' while the recommended is ' + idx+ '.\n' : 'You may also consider a morphIndex for the second path. Currently the best index seems to be ' + idx + '.\n')
|
||||
+ (
|
||||
!this._rv1 && !this._rv2 ? 'If the current animation is not satisfactory, consider reversing one of the paths. Maybe the paths do not intersect or they really have different draw directions.' :
|
||||
'You\'ve chosen that the first path to have ' + ( this._rv1 ? 'REVERSED draw direction, ' : 'UNCHANGED draw direction, ') + 'while second path is to be ' + (this._rv2 ? 'REVERSED.\n' : 'UNCHANGED.\n')
|
||||
)
|
||||
);
|
||||
}
|
||||
s = e = null;
|
||||
return [s1,e1]
|
||||
},
|
||||
pathCross : function(w){ // pathCross
|
||||
// path tween options
|
||||
this._mpr = w._ops.morphPrecision || 15;
|
||||
this._midx = w._ops.morphIndex;
|
||||
this._smi = w._ops.showMorphInfo;
|
||||
this._rv1 = w._ops.reverseFirstPath;
|
||||
this._rv2 = w._ops.reverseSecondPath;
|
||||
|
||||
var p1 = getOnePath(w._vS.path.o), p2 = getOnePath(w._vE.path.o), arr;
|
||||
this._isp = !/[CSQTA]/i.test(p1) && !/[CSQTA]/i.test(p2); // both shapes are polygons
|
||||
|
||||
arr = this._pathCross(p1,p2,w._el.ownerSVGElement);
|
||||
// arr = this._pathCross(p1,p2,w._el.parentNode);
|
||||
|
||||
w._vS.path.d = arr[0];
|
||||
w._vE.path.d = arr[1];
|
||||
}
|
||||
};
|
||||
|
||||
// a shortHand pathCross && SVG transform stack
|
||||
K.svq = function(w){ if ( w._vE.path ) S.pCr(w); if ( w._vE.svgTransform ) S.sT(w); }
|
||||
K.svq = function(w){ if ( w._vE.path ) S.pathCross(w); if ( w._vE.svgTransform ) stackTransform(w); }
|
||||
|
||||
// register the render SVG path object
|
||||
// process path object and also register the render function
|
||||
K.pp['path'] = function(a,o,l) { // K.pp['path']('path',value,element);
|
||||
parseProperty['path'] = function(a,o,l) { // K.pp['path']('path',value,element);
|
||||
if (!('path' in DOM)) {
|
||||
DOM['path'] = function(l,p,a,b,v){
|
||||
l.setAttribute("d", v === 1 ? b.o : 'M' + coords( a['d'],b['d'],b['d'].length,2,'L',v ) + 'Z' );
|
||||
}
|
||||
}
|
||||
return S.gPt(o);
|
||||
return getPath(o);
|
||||
};
|
||||
|
||||
K.prS['path'] = function(el,p,v){
|
||||
prepareStart['path'] = function(el,p,v){
|
||||
return el.getAttribute('d');
|
||||
};
|
||||
|
||||
|
||||
// SVG DRAW
|
||||
S.gDr = function(e,v){
|
||||
var l = /path|glyph/.test(e.tagName) ? e.getTotalLength() : S.gL(e), start, end, d, o;
|
||||
if ( v instanceof Object ) {
|
||||
return v;
|
||||
} else if (typeof v === 'string') {
|
||||
v = v.split(/\,|\s/);
|
||||
start = /%/.test(v[0]) ? S.pc(v[0].trim(),l) : parseFloat(v[0]);
|
||||
end = /%/.test(v[1]) ? S.pc(v[1].trim(),l) : parseFloat(v[1]);
|
||||
} else if (typeof v === 'undefined') {
|
||||
o = parseFloat(K.gCS(e,'stroke-dashoffset'));
|
||||
d = K.gCS(e,'stroke-dasharray').split(/\,/);
|
||||
|
||||
start = 0-o;
|
||||
end = parseFloat(d[0]) + start || l;
|
||||
}
|
||||
|
||||
return { s: start, e: end, l: l }
|
||||
};
|
||||
var percent = function(v,l){ return parseFloat(v) / 100 * l;}, // percent
|
||||
// SVG DRAW UTILITITES
|
||||
// http://stackoverflow.com/a/30376660
|
||||
getRectLength = function(el){ // getRectLength - return the length of a Rect
|
||||
var w = el.getAttribute('width');
|
||||
var h = el.getAttribute('height');
|
||||
return (w*2)+(h*2);
|
||||
},
|
||||
getPolyLength = function(el){ // getPolygonLength / getPolylineLength - return the length of the Polygon / Polyline
|
||||
var points = el.getAttribute('points').split(' '), len = 0;
|
||||
if (points.length > 1) {
|
||||
var coord = function (p) {
|
||||
var c = p.split(',');
|
||||
if (c.length != 2) { return; } // return undefined
|
||||
if (isNaN(c[0]) || isNaN(c[1])) { return; }
|
||||
return [parseFloat(c[0]), parseFloat(c[1])];
|
||||
};
|
||||
|
||||
var dist = function (c1, c2) {
|
||||
if (c1 != undefined && c2 != undefined) {
|
||||
return Math.sqrt(Math.pow((c2[0]-c1[0]), 2) + Math.pow((c2[1]-c1[1]), 2));
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
if (points.length > 2) {
|
||||
for (var i=0; i<points.length-1; i++) {
|
||||
len += dist(coord(points[i]), coord(points[i+1]));
|
||||
}
|
||||
}
|
||||
len += dist(coord(points[0]), coord(points[points.length-1]));
|
||||
}
|
||||
return len;
|
||||
},
|
||||
getLineLength = function(el){ // getLineLength - return the length of the line
|
||||
var x1 = el.getAttribute('x1');
|
||||
var x2 = el.getAttribute('x2');
|
||||
var y1 = el.getAttribute('y1');
|
||||
var y2 = el.getAttribute('y2');
|
||||
return Math.sqrt(Math.pow((x2-x1), 2)+Math.pow((y2-y1),2));
|
||||
},
|
||||
getCircleLength = function(el){ // getCircleLength - return the length of the circle
|
||||
var r = el.getAttribute('r');
|
||||
return 2 * Math.PI * r;
|
||||
},
|
||||
getEllipseLength = function(el) { // getEllipseLength - returns the length of an ellipse
|
||||
var rx = el.getAttribute('rx'), ry = el.getAttribute('ry'),
|
||||
len = 2*rx, wid = 2*ry;
|
||||
return ((Math.sqrt(.5 * ((len * len) + (wid * wid)))) * (Math.PI * 2)) / 2;
|
||||
},
|
||||
getTotalLength = function(el){ // getLength - returns the result of any of the below functions
|
||||
if (/rect/.test(el.tagName)) {
|
||||
return getRectLength(el);
|
||||
} else if (/circle/.test(el.tagName)) {
|
||||
return getCircleLength(el);
|
||||
} else if (/ellipse/.test(el.tagName)) {
|
||||
return getEllipseLength(el);
|
||||
} else if (/polygon|polyline/.test(el.tagName)) {
|
||||
return getPolyLength(el);
|
||||
} else if (/line/.test(el.tagName)) {
|
||||
return getLineLength(el);
|
||||
}
|
||||
},
|
||||
getDraw = function(e,v){
|
||||
var l = /path|glyph/.test(e.tagName) ? e.getTotalLength() : getTotalLength(e), start, end, d, o;
|
||||
if ( v instanceof Object ) {
|
||||
return v;
|
||||
} else if (typeof v === 'string') {
|
||||
v = v.split(/\,|\s/);
|
||||
start = /%/.test(v[0]) ? percent(v[0].trim(),l) : parseFloat(v[0]);
|
||||
end = /%/.test(v[1]) ? percent(v[1].trim(),l) : parseFloat(v[1]);
|
||||
} else if (typeof v === 'undefined') {
|
||||
o = parseFloat(getComputedStyle(e,'stroke-dashoffset'));
|
||||
d = getComputedStyle(e,'stroke-dasharray').split(/\,/);
|
||||
|
||||
start = 0-o;
|
||||
end = parseFloat(d[0]) + start || l;
|
||||
}
|
||||
return { s: start, e: end, l: l }
|
||||
};
|
||||
|
||||
S.pc = function(v,l){ // percent
|
||||
return parseFloat(v) / 100 * l;
|
||||
};
|
||||
|
||||
PP['draw'] = function(a,o,f){ // register the draw property
|
||||
parseProperty['draw'] = function(a,o,f){ // register the draw property
|
||||
if (!('draw' in DOM)) {
|
||||
DOM['draw'] = function(l,p,a,b,v){
|
||||
var ll = a.l, s = number(a.s,b.s,v), e = number(a.e,b.e,v), o = 0 - s;
|
||||
|
@ -292,89 +339,18 @@
|
|||
l.style.strokeDasharray = e+o<1 ? '0px, ' + ll + 'px' : (e+o) + 'px, ' + ll + 'px';
|
||||
}
|
||||
}
|
||||
return S.gDr(f,o);
|
||||
return getDraw(f,o);
|
||||
}
|
||||
|
||||
K.prS['draw'] = function(el,p,v){
|
||||
return S.gDr(el);
|
||||
prepareStart['draw'] = function(el,p,v){
|
||||
return getDraw(el);
|
||||
}
|
||||
|
||||
// SVG DRAW UTILITITES
|
||||
// http://stackoverflow.com/a/30376660
|
||||
S.gL = function(el){ // getLength - returns the result of any of the below functions
|
||||
if (/rect/.test(el.tagName)) {
|
||||
return S.gRL(el);
|
||||
} else if (/circle/.test(el.tagName)) {
|
||||
return S.gCL(el);
|
||||
} else if (/ellipse/.test(el.tagName)) {
|
||||
return S.gEL(el);
|
||||
} else if (/polygon|polyline/.test(el.tagName)) {
|
||||
return S.gPL(el);
|
||||
} else if (/line/.test(el.tagName)) {
|
||||
return S.gLL(el);
|
||||
}
|
||||
}
|
||||
|
||||
S.gRL = function(el){ // getRectLength - return the length of a Rect
|
||||
var w = el.getAttribute('width');
|
||||
var h = el.getAttribute('height');
|
||||
return (w*2)+(h*2);
|
||||
}
|
||||
|
||||
S.gPL = function(el){ // getPolygonLength / getPolylineLength - return the length of the Polygon / Polyline
|
||||
var points = el.getAttribute('points').split(' '), len = 0;
|
||||
if (points.length > 1) {
|
||||
var coord = function (p) {
|
||||
var c = p.split(',');
|
||||
if (c.length != 2) {
|
||||
return; // return undefined
|
||||
}
|
||||
if (isNaN(c[0]) || isNaN(c[1])) {
|
||||
return;
|
||||
}
|
||||
return [parseFloat(c[0]), parseFloat(c[1])];
|
||||
};
|
||||
|
||||
var dist = function (c1, c2) {
|
||||
if (c1 != undefined && c2 != undefined) {
|
||||
return Math.sqrt(Math.pow((c2[0]-c1[0]), 2) + Math.pow((c2[1]-c1[1]), 2));
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
if (points.length > 2) {
|
||||
for (var i=0; i<points.length-1; i++) {
|
||||
len += dist(coord(points[i]), coord(points[i+1]));
|
||||
}
|
||||
}
|
||||
len += dist(coord(points[0]), coord(points[points.length-1]));
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
S.gLL = function(el){ // getLineLength - return the length of the line
|
||||
var x1 = el.getAttribute('x1');
|
||||
var x2 = el.getAttribute('x2');
|
||||
var y1 = el.getAttribute('y1');
|
||||
var y2 = el.getAttribute('y2');
|
||||
return Math.sqrt(Math.pow((x2-x1), 2)+Math.pow((y2-y1),2));
|
||||
}
|
||||
|
||||
S.gCL = function(el){ // getCircleLength - return the length of the circle
|
||||
var r = el.getAttribute('r');
|
||||
return 2 * Math.PI * r;
|
||||
}
|
||||
|
||||
S.gEL = function(el) { // getEllipseLength - returns the length of an ellipse
|
||||
var rx = el.getAttribute('rx'), ry = el.getAttribute('ry'),
|
||||
len = 2*rx, wid = 2*ry;
|
||||
return ((Math.sqrt(.5 * ((len * len) + (wid * wid)))) * (Math.PI * 2)) / 2;
|
||||
}
|
||||
|
||||
// SVG CSS Color Properties
|
||||
for ( var i = 0, l = _cls.length; i< l; i++) {
|
||||
p = _cls[i];
|
||||
PP[p] = function(p,v){
|
||||
parseProperty[p] = function(p,v){
|
||||
if (!(p in DOM)) {
|
||||
DOM[p] = function(l,p,a,b,v,o) {
|
||||
l.style[p] = color(a,b,v,o.keepHex);
|
||||
|
@ -382,26 +358,26 @@
|
|||
}
|
||||
return K.truC(v);
|
||||
}
|
||||
K.prS[p] = function(el,p,v){
|
||||
return K.gCS(el,p) || 'rgba(0,0,0,0)';
|
||||
prepareStart[p] = function(el,p,v){
|
||||
return getComputedStyle(el,p) || 'rgba(0,0,0,0)';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Other SVG related CSS props
|
||||
for ( var i = 0, l = _nm.length; i< l; i++) { // for numeric CSS props from any type of SVG shape
|
||||
p = _nm[i];
|
||||
if (p === 'strokeWidth'){ // stroke can be unitless or unit | http://stackoverflow.com/questions/1301685/fixed-stroke-width-in-svg
|
||||
PP[p] = function(p,v){
|
||||
parseProperty[p] = function(p,v){
|
||||
if (!(p in DOM)) {
|
||||
DOM[p] = function(l,p,a,b,v) {
|
||||
var _u = _u || typeof b === 'number';
|
||||
l.style[p] = !_u ? unit(a.value,b.value,b.unit,v) : number(a,b,v);
|
||||
}
|
||||
}
|
||||
return /px|%|em|vh|vw/.test(v) ? PP.box(p,v) : parseFloat(v);
|
||||
return /px|%|em|vh|vw/.test(v) ? parseProperty.box(p,v) : parseFloat(v);
|
||||
}
|
||||
} else {
|
||||
PP[p] = function(p,v){
|
||||
parseProperty[p] = function(p,v){
|
||||
if (!(p in DOM)) {
|
||||
DOM[p] = function(l,p,a,b,v) {
|
||||
l.style[p] = number(a,b,v);
|
||||
|
@ -410,13 +386,54 @@
|
|||
return parseFloat(v);
|
||||
}
|
||||
}
|
||||
K.prS[p] = function(el,p,v){
|
||||
return K.gCS(el,p) || 0;
|
||||
prepareStart[p] = function(el,p,v){
|
||||
return getComputedStyle(el,p) || 0;
|
||||
}
|
||||
}
|
||||
|
||||
// SVG Transform
|
||||
PP['svgTransform'] = function(p,v,l){
|
||||
var parseTransform = function (a){ // helper function that turns transform value from string to object
|
||||
var d = a && /\)/.test(a) ? a.split(')') : 'none', j, c ={}, p;
|
||||
|
||||
if (d instanceof Array) {
|
||||
for (j=0; j<d.length; j++){
|
||||
p = d[j].split('('); p[0] !== '' && (c[p[0].replace(/\s/,'')] = p[1] );
|
||||
}
|
||||
}
|
||||
return c;
|
||||
},
|
||||
stackTransform = function (w){ // helper function that helps preserve current transform properties into the objects
|
||||
var bb = w._el.getBBox(), ctr = parseTransform(w._el.getAttribute('transform')), r, t, i,
|
||||
cx = bb.x + bb.width/2, cy = bb.y + bb.height/2;
|
||||
|
||||
for ( i in ctr ) { // populate the valuesStart
|
||||
if (i === 'translate'){
|
||||
t = ctr[i] instanceof Array ? ctr[i] : /\,|\s/.test(ctr[i]) ? ctr[i].split(/\,|\s/) : [ctr[i]*1,0];
|
||||
w._vS.svgTransform[i] = [t[0] * 1||0, t[1] * 1||0];
|
||||
} else if (i === 'scale'){
|
||||
w._vS.svgTransform[i] = ctr[i] * 1||1;
|
||||
} else if (i === 'rotate'){
|
||||
r = ctr[i] instanceof Array ? ctr[i]
|
||||
: /\s/.test(ctr[i]) ? [ctr[i].split(' ')[0]*1, ctr[i].split(' ')[1].split(',')[0]*1, ctr[i].split(' ')[1].split(',')[1]*1]
|
||||
: [ctr[i]*1,cx,cy];
|
||||
w._vS.svgTransform[i] = r;
|
||||
} else if (/skew/.test(i)) {
|
||||
w._vS.svgTransform[i] = ctr[i] * 1||0;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i in w._vS.svgTransform) {
|
||||
if (!(i in w._vE.svgTransform)) { // copy existing and unused properties to the valuesEnd
|
||||
w._vE.svgTransform[i] = w._vS.svgTransform[i];
|
||||
}
|
||||
if (i === 'rotate' in w._vS.svgTransform && 'rotate' in w._vE.svgTransform){ // make sure to use the right transform origin when rotation is used
|
||||
w._vE.svgTransform.rotate[1] = w._vS.svgTransform.rotate[1] = cx;
|
||||
w._vE.svgTransform.rotate[2] = w._vS.svgTransform.rotate[2] = cy;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
parseProperty['svgTransform'] = function(p,v,l){
|
||||
// register the render function
|
||||
if (!('svgTransform' in DOM)) {
|
||||
DOM['svgTransform'] = function(l,p,a,b,v){
|
||||
|
@ -477,55 +494,14 @@
|
|||
return tf;
|
||||
}
|
||||
|
||||
// KUTE.prepareStart K.prS[p](el,p,to[p])
|
||||
// KUTE.prepareStart prepareStart[p](el,p,to[p])
|
||||
// returns an obect with current transform attribute value
|
||||
K.prS['svgTransform'] = function(l,p,t) {
|
||||
var tr = {}, i, ctr = S.pT(l.getAttribute('transform'));
|
||||
prepareStart['svgTransform'] = function(l,p,t) {
|
||||
var tr = {}, i, ctr = parseTransform(l.getAttribute('transform'));
|
||||
for (i in t) { tr[i] = i in ctr ? ctr[i] : (i==='scale'?1:0); } // find a value in current attribute value or add a default value
|
||||
return tr;
|
||||
}
|
||||
|
||||
S.sT = function (w){ // stackTransform - helper function that helps preserve current transform properties into the objects
|
||||
var bb = w._el.getBBox(), ctr = S.pT(w._el.getAttribute('transform')), r, t, i,
|
||||
cx = bb.x + bb.width/2, cy = bb.y + bb.height/2;
|
||||
|
||||
for ( i in ctr ) { // populate the valuesStart
|
||||
if (i === 'translate'){
|
||||
t = ctr[i] instanceof Array ? ctr[i] : /\,|\s/.test(ctr[i]) ? ctr[i].split(/\,|\s/) : [ctr[i]*1,0];
|
||||
w._vS.svgTransform[i] = [t[0] * 1||0, t[1] * 1||0];
|
||||
} else if (i === 'scale'){
|
||||
w._vS.svgTransform[i] = ctr[i] * 1||1;
|
||||
} else if (i === 'rotate'){
|
||||
r = ctr[i] instanceof Array ? ctr[i]
|
||||
: /\s/.test(ctr[i]) ? [ctr[i].split(' ')[0]*1, ctr[i].split(' ')[1].split(',')[0]*1, ctr[i].split(' ')[1].split(',')[1]*1]
|
||||
: [ctr[i]*1,cx,cy];
|
||||
w._vS.svgTransform[i] = r;
|
||||
} else if (/skew/.test(i)) {
|
||||
w._vS.svgTransform[i] = ctr[i] * 1||0;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i in w._vS.svgTransform) {
|
||||
if (!(i in w._vE.svgTransform)) { // copy existing and unused properties to the valuesEnd
|
||||
w._vE.svgTransform[i] = w._vS.svgTransform[i];
|
||||
}
|
||||
if (i === 'rotate' in w._vS.svgTransform && 'rotate' in w._vE.svgTransform){ // make sure to use the right transform origin when rotation is used
|
||||
w._vE.svgTransform.rotate[1] = w._vS.svgTransform.rotate[1] = cx;
|
||||
w._vE.svgTransform.rotate[2] = w._vS.svgTransform.rotate[2] = cy;
|
||||
}
|
||||
}
|
||||
}
|
||||
S.pT = function (a){ // parseTransform - helper function that turns transform value from string to object
|
||||
var d = a && /\)/.test(a) ? a.split(')') : 'none', j, c ={}, p;
|
||||
|
||||
if (d instanceof Array) {
|
||||
for (j=0; j<d.length; j++){
|
||||
p = d[j].split('('); p[0] !== '' && (c[p[0].replace(/\s/,'')] = p[1] );
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
return S;
|
||||
|
||||
}));
|
|
@ -9,31 +9,33 @@
|
|||
define(["./kute.js"], function(KUTE){ factory(KUTE); return KUTE; });
|
||||
} else if(typeof module == "object" && typeof require == "function") {
|
||||
var KUTE = require("./kute.js");
|
||||
module.exports = factory(KUTE);
|
||||
module.exports = factory();
|
||||
} else if ( typeof window.KUTE !== 'undefined' ) {
|
||||
factory();
|
||||
} else {
|
||||
throw new Error("Text-Plugin requires KUTE.js.");
|
||||
}
|
||||
}( function () {
|
||||
var K = window.KUTE, DOM = K.dom, PP = K.pp, number = K.Interpolate.number,
|
||||
}( function (KUTE) {
|
||||
'use strict';
|
||||
var K = window.KUTE, DOM = K.dom, prepareStart = K.prS,
|
||||
parseProperty = K.pp, number = K.Interpolate.number,
|
||||
_s = String("abcdefghijklmnopqrstuvwxyz").split(""), // lowercase
|
||||
_S = String("abcdefghijklmnopqrstuvwxyz".toUpperCase()).split(""), // uppercase
|
||||
_S = String("abcdefghijklmnopqrstuvwxyz".toUpperCase()).split(""), // uparsePropertyercase
|
||||
_sb = String("~!@#$%^&*()_+{}[];'<>,./?\=-").split(""), // symbols
|
||||
_n = String("0123456789").split(""), // numeric
|
||||
_a = _s.concat(_S,_n), // alpha numeric
|
||||
_all = _a.concat(_sb), // all caracters
|
||||
random = Math.random, floor = Math.floor, min = Math.min;
|
||||
|
||||
K.prS['text'] = K.prS['number'] = function(l,p,v){
|
||||
prepareStart['text'] = prepareStart['number'] = function(l,p,v){
|
||||
return l.innerHTML;
|
||||
}
|
||||
|
||||
PP['text'] = function(p,v,l) {
|
||||
parseProperty['text'] = function(p,v,l) {
|
||||
if ( !( 'text' in DOM ) ) {
|
||||
DOM['text'] = function(l,p,a,b,v,o) {
|
||||
var tp = tp || o.textChars === 'alpha' ? _s // textChars is alpha
|
||||
: o.textChars === 'upper' ? _S // textChars is numeric
|
||||
: o.textChars === 'uparsePropertyer' ? _S // textChars is numeric
|
||||
: o.textChars === 'numeric' ? _n // textChars is numeric
|
||||
: o.textChars === 'alphanumeric' ? _a // textChars is alphanumeric
|
||||
: o.textChars === 'symbols' ? _sb // textChars is symbols
|
||||
|
@ -50,7 +52,7 @@
|
|||
return v;
|
||||
}
|
||||
|
||||
PP['number'] = function(p,v,l) {
|
||||
parseProperty['number'] = function(p,v,l) {
|
||||
if ( !( 'number' in DOM ) ) {
|
||||
DOM['number'] = function(l,p,a,b,v) {
|
||||
l.innerHTML = parseInt( number(a, b, v));
|
||||
|
|
107
demo/src/kute.js
107
demo/src/kute.js
|
@ -512,8 +512,43 @@
|
|||
};
|
||||
easing.easingBounceInOut = function(t) { if ( t < 0.5 ) return easing.easingBounceIn( t * 2 ) * 0.5; return easing.easingBounceOut( t * 2 - 1 ) * 0.5 + 0.5;};
|
||||
|
||||
var start = function (t) { // move functions that use the ticker outside the prototype to be in the same scope with it
|
||||
this.scrollIn();
|
||||
|
||||
perspective(this._el,this); // apply the perspective and transform origin
|
||||
if ( this._rpr ) { this.stack(); } // on start we reprocess the valuesStart for TO() method
|
||||
|
||||
for ( var e in this._vE ) {
|
||||
this._vSR[e] = this._vS[e];
|
||||
}
|
||||
|
||||
// now it's a good time to start
|
||||
add(this);
|
||||
this.playing = true;
|
||||
this.paused = false;
|
||||
this._sCF = false;
|
||||
this._sT = t || window.performance.now();
|
||||
this._sT += this._dl;
|
||||
|
||||
if (!this._sCF) {
|
||||
if (this._sC) { this._sC.call(); }
|
||||
this._sCF = true;
|
||||
}
|
||||
if (!_t) _tk();
|
||||
return this;
|
||||
},
|
||||
play = function () {
|
||||
if (this.paused && this.playing) {
|
||||
this.paused = false;
|
||||
if (this._rC !== null) { this._rC.call(); }
|
||||
this._sT += window.performance.now() - this._pST;
|
||||
add(this);
|
||||
if (!_t) _tk(); // restart ticking if stopped
|
||||
}
|
||||
return this;
|
||||
},
|
||||
// single Tween object construct
|
||||
var Tween = function (_el, _vS, _vE, _o) {
|
||||
Tween = function (_el, _vS, _vE, _o) {
|
||||
this._el = _el; // element animation is applied to
|
||||
this._vSR = {}; // internal valuesStartRepeat
|
||||
this._vS = _vS; // valuesStart
|
||||
|
@ -546,6 +581,8 @@
|
|||
this._stC = _o.stop || null; // _on StopCallback
|
||||
this.repeat = this._r; // we cache the number of repeats to be able to put it back after all cycles finish
|
||||
this._ops = {};
|
||||
this.start = Tween.prototype.start = start;
|
||||
this.play = Tween.prototype.play = this.resume = Tween.prototype.resume = play;
|
||||
|
||||
//also add plugins options or transform perspective
|
||||
for (var o in _o) { if (!(o in this) && !/delay|duration|repeat|origin|start|stop|update|complete|pause|play|yoyo|easing/i.test(o) ) { this._ops[o] = _o[o]; } }
|
||||
|
@ -717,61 +754,24 @@
|
|||
_o[i].delay = i>0 ? o.delay + (o.offset||0) : o.delay;
|
||||
this.tweens.push( fromTo(els[i], vS, vE, _o[i]) );
|
||||
}
|
||||
};
|
||||
|
||||
var ws = TweensTO.prototype = TweensFT.prototype;
|
||||
ws.start = function(t){
|
||||
t = t || window.performance.now();
|
||||
var i, tl = this.tweens.length;
|
||||
for ( i = 0; i < tl; i++ ) {
|
||||
this.tweens[i].start(t);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
ws.stop = function(){ for ( var i = 0; i < this.tweens.length; i++ ) { this.tweens[i].stop(); } return this; }
|
||||
ws.pause = function(){ for ( var i = 0; i < this.tweens.length; i++ ) { this.tweens[i].pause(); } return this; }
|
||||
ws.chain = function(){ this.tweens[this.tweens.length-1]._cT = arguments; return this; }
|
||||
ws.play = ws.resume = function(){ for ( var i = 0; i < this.tweens.length; i++ ) { this.tweens[i].play(); } return this; }
|
||||
|
||||
var start = function (t) { // move functions that use the ticker outside the prototype to be in the same scope with it
|
||||
this.scrollIn();
|
||||
|
||||
perspective(this._el,this); // apply the perspective and transform origin
|
||||
if ( this._rpr ) { this.stack(); } // on start we reprocess the valuesStart for TO() method
|
||||
|
||||
for ( var e in this._vE ) {
|
||||
this._vSR[e] = this._vS[e];
|
||||
}
|
||||
|
||||
// now it's a good time to start
|
||||
add(this);
|
||||
this.playing = true;
|
||||
this.paused = false;
|
||||
this._sCF = false;
|
||||
this._sT = t || window.performance.now();
|
||||
this._sT += this._dl;
|
||||
|
||||
if (!this._sCF) {
|
||||
if (this._sC) { this._sC.call(); }
|
||||
this._sCF = true;
|
||||
}
|
||||
if (!_t) _tk();
|
||||
return this;
|
||||
},
|
||||
play = function () {
|
||||
if (this.paused && this.playing) {
|
||||
this.paused = false;
|
||||
if (this._rC !== null) { this._rC.call(); }
|
||||
this._sT += window.performance.now() - this._pST;
|
||||
add(this);
|
||||
if (!_t) _tk(); // restart ticking if stopped
|
||||
}
|
||||
return this;
|
||||
ws = TweensTO.prototype = TweensFT.prototype = {
|
||||
start : function(t){
|
||||
t = t || window.performance.now();
|
||||
var i, tl = this.tweens.length;
|
||||
for ( i = 0; i < tl; i++ ) {
|
||||
this.tweens[i].start(t);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
stop : function(){ for ( var i = 0; i < this.tweens.length; i++ ) { this.tweens[i].stop(); } return this; },
|
||||
pause : function(){ for ( var i = 0; i < this.tweens.length; i++ ) { this.tweens[i].pause(); } return this; },
|
||||
chain : function(){ this.tweens[this.tweens.length-1]._cT = arguments; return this; },
|
||||
play : function(){ for ( var i = 0; i < this.tweens.length; i++ ) { this.tweens[i].play(); } return this; },
|
||||
resume :function() {return this.play()}
|
||||
};
|
||||
Tween.prototype.start = start;
|
||||
Tween.prototype.play = Tween.prototype.resume = play;
|
||||
|
||||
K = { // export core methods to public for plugins
|
||||
return K = { // export core methods to public for plugins
|
||||
property: property, getPrefix: getPrefix, selector: selector, pe : pe, // utils
|
||||
to: to, fromTo: fromTo, allTo: allTo, allFromTo: allFromTo, // main methods
|
||||
Interpolate: {number: number, unit: unit, color: color }, // interpolators ?? move array & coords to svg and leave color
|
||||
|
@ -781,5 +781,4 @@
|
|||
Easing: easing,
|
||||
Tween: Tween, TweensTO: TweensTO, TweensFT: TweensFT // constructors
|
||||
};
|
||||
return K;
|
||||
}));
|
2
dist/kute-attr.min.js
vendored
2
dist/kute-attr.min.js
vendored
|
@ -1 +1 @@
|
|||
!function(t){if("function"==typeof define&&define.amd)define(["./kute.js"],function(e){return t(e),e});else if("object"==typeof module&&"function"==typeof require){var e=require("./kute.js");module.exports=t(e)}else{if("undefined"==typeof window.KUTE)throw new Error("Attributes Plugin require KUTE.js.");t(e)}}(function(t){"use strict";var e,r=window.KUTE,n=r.dom,i=r.pp,u=r.Interpolate.unit,a=r.Interpolate.number,o=function(t,e){return t.getAttribute(e)},f=function(t){return/[A-Z]/g.test(t)?t.replace(t.match(/[A-Z]/g)[0],"-"+t.match(/[A-Z]/g)[0].toLowerCase()):t};r.prS.attr=function(t,e,r){var n={};for(var i in r){var u=f(i).replace(/_+[a-z]+/,""),a=o(t,u);n[u]=a||(/opacity/i.test(i)?1:0)}return n},i.attr=function(t,i,c){"attr"in n||(n.attr=function(t,e,r,i,u){for(var a in i)n.attributes[a](t,a,r[a],i[a],u)},e=n.attributes={});var s,p={};for(s in i){var l=f(s),v=o(c,l.replace(/_+[a-z]+/,""));if(/(%|[a-z]+)$/.test(i[s])||/(%|[a-z]+)$/.test(v)){var d=r.truD(v).u||r.truD(i[s]).u,b=/%/.test(d)?"_percent":"_"+d;s+b in e||(e[s+b]=function(t,e,r,n,i){var a=a||f(e).replace(b,"");t.setAttribute(a,u(r.v,n.v,n.u,i))}),p[s+b]=r.truD(i[s])}else s in e||(e[s]=function(t,e,r,n,i){var u=u||f(e);t.setAttribute(u,a(r,n,i))}),p[s]=parseFloat(i[s])}return p}});
|
||||
!function(t){if("function"==typeof define&&define.amd)define(["./kute.js"],function(e){return t(e),e});else if("object"==typeof module&&"function"==typeof require){var e=require("./kute.js");module.exports=t(e)}else{if("undefined"==typeof window.KUTE)throw new Error("Attributes Plugin require KUTE.js.");t(e)}}(function(t){"use strict";var e,r=window.KUTE,n=r.dom,i=r.prS,u=r.pp,a=r.Interpolate.unit,o=r.Interpolate.number,f=function(t,e){return t.getAttribute(e)},c=function(t){return/[A-Z]/g.test(t)?t.replace(t.match(/[A-Z]/g)[0],"-"+t.match(/[A-Z]/g)[0].toLowerCase()):t};i.attr=function(t,e,r){var n={};for(var i in r){var u=c(i).replace(/_+[a-z]+/,""),a=f(t,u);n[u]=a||(/opacity/i.test(i)?1:0)}return n},u.attr=function(t,i,u){"attr"in n||(n.attr=function(t,e,r,i,u){for(var a in i)n.attributes[a](t,a,r[a],i[a],u)},e=n.attributes={});var s,p={};for(s in i){var l=c(s),v=f(u,l.replace(/_+[a-z]+/,""));if(/(%|[a-z]+)$/.test(i[s])||/(%|[a-z]+)$/.test(v)){var d=r.truD(v).u||r.truD(i[s]).u,b=/%/.test(d)?"_percent":"_"+d;s+b in e||(e[s+b]=function(t,e,r,n,i){var u=u||c(e).replace(b,"");t.setAttribute(u,a(r.v,n.v,n.u,i))}),p[s+b]=r.truD(i[s])}else s in e||(e[s]=function(t,e,r,n,i){var u=u||c(e);t.setAttribute(u,o(r,n,i))}),p[s]=parseFloat(i[s])}return p}});
|
||||
|
|
2
dist/kute-css.min.js
vendored
2
dist/kute-css.min.js
vendored
|
@ -1 +1 @@
|
|||
!function(t){if("function"==typeof define&&define.amd)define(["./kute.js"],function(r){return t(r),r});else if("object"==typeof module&&"function"==typeof require){var r=require("./kute.js");module.exports=t(r)}else{if("undefined"==typeof window.KUTE)throw new Error("CSS Plugin require KUTE.js.");t(r)}}(function(t){for(var r,e=window.KUTE,o=e.dom,i=e.pp,n=e.property("borderRadius"),u=e.property("borderTopLeftRadius"),d=e.property("borderTopRightRadius"),a=e.property("borderBottomLeftRadius"),l=e.property("borderBottomRightRadius"),f=["borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","outlineColor"],p=["borderRadius","borderTopLeftRadius","borderTopRightRadius","borderBottomLeftRadius","borderBottomRightRadius"],g=["right","bottom","minWidth","minHeight","maxWidth","maxHeight","padding","margin","paddingTop","paddingBottom","paddingLeft","paddingRight","marginTop","marginBottom","marginLeft","marginRight","borderWidth","borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth","outlineWidth"],c=["fontSize","lineHeight","letterSpacing","wordSpacing"],s=["clip"],b=["backgroundPosition"],h=p.concat(g,c),v=f.concat(s,p,g,c,b),m=v.length,R=(e.Interpolate.number,e.Interpolate.unit),y=e.Interpolate.color,S=S||{},x=0;x<m;x++)r=v[x],f.indexOf(r)!==-1?S[r]="rgba(0,0,0,0)":h.indexOf(r)!==-1?S[r]=0:b.indexOf(r)!==-1?S[r]=[50,50]:"clip"===r&&(S[r]=[0,0,0,0]);for(var x=0,C=f.length;x<C;x++)r=f[x],i[r]=function(t,r){return t in o||(o[t]=function(t,r,e,o,i,n){t.style[r]=y(e,o,i,n.keepHex)}),i.cls(t,r)},e.prS[r]=function(t,r,o){return e.gCS(t,r)||S[r]};for(var x=0,C=h.length;x<C;x++)r=h[x],i[r]=function(t,r){return t in o||(o[t]=function(t,r,e,o,i){t.style[r]=R(e.value,o.value,o.unit,i)}),i.box(t,r)},e.prS[r]=function(t,r,o){return e.gCS(t,r)||S[r]};for(var x=0,C=p.length;x<C;x++)r=p[x],i[r]=function(t,r){return t in o||("borderRadius"===t?o[t]=function(t,r,e,o,i){t.style[n]=R(e.value,o.value,o.unit,i)}:"borderTopLeftRadius"===t?o[t]=function(t,r,e,o,i){t.style[u]=R(e.value,o.value,o.unit,i)}:"borderTopRightRadius"===t?o[t]=function(t,r,e,o,i){t.style[d]=R(e.value,o.value,o.unit,i)}:"borderBottomLeftRadius"===t?o[t]=function(t,r,e,o,i){t.style[a]=R(e.value,o.value,o.unit,i)}:"borderBottomRightRadius"===t&&(o[t]=function(t,r,e,o,i){t.style[l]=R(e.value,o.value,o.unit,i)})),i.box(t,r)},e.prS[r]=function(t,r,o){return e.gCS(t,r)||S[r]};return i.clip=function(t,r){if(t in o||(o[t]=function(t,r,e,o,i){var n=0,u=[];for(n;n<4;n++){var d=e[n].v,a=o[n].v,l=o[n].u||"px";u[n]=R(d,a,l,i)}t.style[r]="rect("+u+")"}),r instanceof Array)return[e.truD(r[0]),e.truD(r[1]),e.truD(r[2]),e.truD(r[3])];var i=r.replace(/rect|\(|\)/g,"");return i=/\,/g.test(i)?i.split(/\,/g):i.split(/\s/g),[e.truD(i[0]),e.truD(i[1]),e.truD(i[2]),e.truD(i[3])]},e.prS.clip=function(t,r,o){var i=e.gCS(t,r),n=e.gCS(t,"width"),u=e.gCS(t,"height");return/rect/.test(i)?i:[0,n,u,0]},i.backgroundPosition=function(t,r){if(t in o||(o[t]=function(t,r,e,o,i){t.style[r]=R(e.x.v,o.x.v,"%",i)+" "+R(e.y.v,o.y.v,"%",i)}),r instanceof Array)return{x:e.truD(r[0])||{v:50,u:"%"},y:e.truD(r[1])||{v:50,u:"%"}};var i,n,u=r.replace(/top|left/g,0).replace(/right|bottom/g,100).replace(/center|middle/g,50);return u=/\,/g.test(u)?u.split(/\,/g):u.split(/\s/g),u=2===u.length?u:[u[0],50],i=e.truD(u[0]),n=e.truD(u[1]),{x:i,y:n}},e.prS.backgroundPosition=function(t,r,o){return e.gCS(t,r)||S[r]},this});
|
||||
!function(t){if("function"==typeof define&&define.amd)define(["./kute.js"],function(r){return t(r),r});else if("object"==typeof module&&"function"==typeof require){var r=require("./kute.js");module.exports=t(r)}else{if("undefined"==typeof window.KUTE)throw new Error("CSS Plugin require KUTE.js.");t(r)}}(function(t){"use strict";for(var r,e=window.KUTE,o=e.dom,i=e.pp,n=e.prS,u=e.gCS,d=e.property("borderRadius"),a=e.property("borderTopLeftRadius"),l=e.property("borderTopRightRadius"),f=e.property("borderBottomLeftRadius"),p=e.property("borderBottomRightRadius"),c=["borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","outlineColor"],g=["borderRadius","borderTopLeftRadius","borderTopRightRadius","borderBottomLeftRadius","borderBottomRightRadius"],s=["right","bottom","minWidth","minHeight","maxWidth","maxHeight","padding","margin","paddingTop","paddingBottom","paddingLeft","paddingRight","marginTop","marginBottom","marginLeft","marginRight","borderWidth","borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth","outlineWidth"],b=["fontSize","lineHeight","letterSpacing","wordSpacing"],h=["clip"],v=["backgroundPosition"],m=g.concat(s,b),R=c.concat(h,g,s,b,v),y=R.length,x=(e.Interpolate.number,e.Interpolate.unit),T=e.Interpolate.color,D=D||{},B=0;B<y;B++)r=R[B],c.indexOf(r)!==-1?D[r]="rgba(0,0,0,0)":m.indexOf(r)!==-1?D[r]=0:v.indexOf(r)!==-1?D[r]=[50,50]:"clip"===r&&(D[r]=[0,0,0,0]);for(var B=0,L=c.length;B<L;B++)r=c[B],i[r]=function(t,r){return t in o||(o[t]=function(t,r,e,o,i,n){t.style[r]=T(e,o,i,n.keepHex)}),i.cls(t,r)},n[r]=function(t,r,e){return u(t,r)||D[r]};for(var B=0,L=m.length;B<L;B++)r=m[B],i[r]=function(t,r){return t in o||(o[t]=function(t,r,e,o,i){t.style[r]=x(e.value,o.value,o.unit,i)}),i.box(t,r)},n[r]=function(t,r,e){return u(t,r)||D[r]};for(var B=0,L=g.length;B<L;B++)r=g[B],i[r]=function(t,r){return t in o||("borderRadius"===t?o[t]=function(t,r,e,o,i){t.style[d]=x(e.value,o.value,o.unit,i)}:"borderTopLeftRadius"===t?o[t]=function(t,r,e,o,i){t.style[a]=x(e.value,o.value,o.unit,i)}:"borderTopRightRadius"===t?o[t]=function(t,r,e,o,i){t.style[l]=x(e.value,o.value,o.unit,i)}:"borderBottomLeftRadius"===t?o[t]=function(t,r,e,o,i){t.style[f]=x(e.value,o.value,o.unit,i)}:"borderBottomRightRadius"===t&&(o[t]=function(t,r,e,o,i){t.style[p]=x(e.value,o.value,o.unit,i)})),i.box(t,r)},n[r]=function(t,r,e){return u(t,r)||D[r]};return i.clip=function(t,r){if(t in o||(o[t]=function(t,r,e,o,i){var n=0,u=[];for(n;n<4;n++){var d=e[n].v,a=o[n].v,l=o[n].u||"px";u[n]=x(d,a,l,i)}t.style[r]="rect("+u+")"}),r instanceof Array)return[e.truD(r[0]),e.truD(r[1]),e.truD(r[2]),e.truD(r[3])];var i=r.replace(/rect|\(|\)/g,"");return i=/\,/g.test(i)?i.split(/\,/g):i.split(/\s/g),[e.truD(i[0]),e.truD(i[1]),e.truD(i[2]),e.truD(i[3])]},n.clip=function(t,r,e){var o=u(t,r),i=u(t,"width"),n=u(t,"height");return/rect/.test(o)?o:[0,i,n,0]},i.backgroundPosition=function(t,r){if(t in o||(o[t]=function(t,r,e,o,i){t.style[r]=x(e.x.v,o.x.v,"%",i)+" "+x(e.y.v,o.y.v,"%",i)}),r instanceof Array)return{x:e.truD(r[0])||{v:50,u:"%"},y:e.truD(r[1])||{v:50,u:"%"}};var i,n,u=r.replace(/top|left/g,0).replace(/right|bottom/g,100).replace(/center|middle/g,50);return u=/\,/g.test(u)?u.split(/\,/g):u.split(/\s/g),u=2===u.length?u:[u[0],50],i=e.truD(u[0]),n=e.truD(u[1]),{x:i,y:n}},n.backgroundPosition=function(t,r,e){return u(t,r)||D[r]},this});
|
||||
|
|
2
dist/kute-svg.min.js
vendored
2
dist/kute-svg.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/kute-text.min.js
vendored
2
dist/kute-text.min.js
vendored
|
@ -1 +1 @@
|
|||
!function(t){if("function"==typeof define&&define.amd)define(["./kute.js"],function(n){return t(n),n});else if("object"==typeof module&&"function"==typeof require){var n=require("./kute.js");module.exports=t(n)}else{if("undefined"==typeof window.KUTE)throw new Error("Text-Plugin requires KUTE.js.");t()}}(function(){var t=window.KUTE,n=t.dom,e=t.pp,r=t.Interpolate.number,i=String("abcdefghijklmnopqrstuvwxyz").split(""),u=String("abcdefghijklmnopqrstuvwxyz".toUpperCase()).split(""),s=String("~!@#$%^&*()_+{}[];'<>,./?=-").split(""),o=String("0123456789").split(""),a=i.concat(u,o),p=(a.concat(s),Math.random),f=Math.floor,l=Math.min;return t.prS.text=t.prS.number=function(t,n,e){return t.innerHTML},e.text=function(t,e,r){return"text"in n||(n.text=function(t,n,e,r,h,c){var g=g||"alpha"===c.textChars?i:"upper"===c.textChars?u:"numeric"===c.textChars?o:"alphanumeric"===c.textChars?a:"symbols"===c.textChars?s:c.textChars?c.textChars.split(""):i,m=g.length,x=g[f(p()*m)],d="",b="",w=e.substring(0),C=r.substring(0);d=""!==e?w.substring(w.length,f(l(h*w.length,w.length))):"",b=C.substring(0,f(l(h*C.length,C.length))),t.innerHTML=h<1?b+x+d:r}),e},e.number=function(t,e,i){return"number"in n||(n.number=function(t,n,e,i,u){t.innerHTML=parseInt(r(e,i,u))}),parseInt(e)||0},this});
|
||||
!function(t){if("function"==typeof define&&define.amd)define(["./kute.js"],function(e){return t(e),e});else if("object"==typeof module&&"function"==typeof require){require("./kute.js");module.exports=t()}else{if("undefined"==typeof window.KUTE)throw new Error("Text-Plugin requires KUTE.js.");t()}}(function(t){"use strict";var e=window.KUTE,n=e.dom,r=e.prS,i=e.pp,u=e.Interpolate.number,s=String("abcdefghijklmnopqrstuvwxyz").split(""),o=String("abcdefghijklmnopqrstuvwxyz".toUpperCase()).split(""),a=String("~!@#$%^&*()_+{}[];'<>,./?=-").split(""),f=String("0123456789").split(""),p=s.concat(o,f),l=(p.concat(a),Math.random),h=Math.floor,c=Math.min;return r.text=r.number=function(t,e,n){return t.innerHTML},i.text=function(t,e,r){return"text"in n||(n.text=function(t,e,n,r,i,u){var g=g||"alpha"===u.textChars?s:"uparsePropertyer"===u.textChars?o:"numeric"===u.textChars?f:"alphanumeric"===u.textChars?p:"symbols"===u.textChars?a:u.textChars?u.textChars.split(""):s,m=g.length,x=g[h(l()*m)],d="",b="",w=n.substring(0),y=r.substring(0);d=""!==n?w.substring(w.length,h(c(i*w.length,w.length))):"",b=y.substring(0,h(c(i*y.length,y.length))),t.innerHTML=i<1?b+x+d:r}),e},i.number=function(t,e,r){return"number"in n||(n.number=function(t,e,n,r,i){t.innerHTML=parseInt(u(n,r,i))}),parseInt(e)||0},this});
|
||||
|
|
2
dist/kute.min.js
vendored
2
dist/kute.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -22,13 +22,13 @@
|
|||
}( function (KUTE) {
|
||||
'use strict';
|
||||
|
||||
var K = window.KUTE, DOM = K.dom, PP = K.pp, unit = K.Interpolate.unit, number = K.Interpolate.number, atts,
|
||||
var K = window.KUTE, DOM = K.dom, prepareStart = K.prS, parseProperty = K.pp, unit = K.Interpolate.unit, number = K.Interpolate.number, atts,
|
||||
getCurrentValue = function(e,a){ return e.getAttribute(a); }, // get current attribute value
|
||||
replaceUppercase = function(a) {
|
||||
return /[A-Z]/g.test(a) ? a.replace(a.match(/[A-Z]/g)[0],'-'+a.match(/[A-Z]/g)[0].toLowerCase()) : a;
|
||||
};
|
||||
|
||||
K.prS['attr'] = function(el,p,v){
|
||||
prepareStart['attr'] = function(el,p,v){
|
||||
var f = {};
|
||||
for (var a in v){
|
||||
var _a = replaceUppercase(a).replace(/_+[a-z]+/,''),
|
||||
|
@ -40,7 +40,7 @@
|
|||
|
||||
// process attributes object K.pp.attr(t[x])
|
||||
// and also register their render functions
|
||||
PP['attr'] = function(a,o,l){
|
||||
parseProperty['attr'] = function(a,o,l){
|
||||
if (!('attr' in DOM)) {
|
||||
DOM.attr = function(l,p,a,b,v) {
|
||||
for ( var o in b ){
|
||||
|
|
39
kute-css.js
39
kute-css.js
|
@ -16,7 +16,8 @@
|
|||
throw new Error("CSS Plugin require KUTE.js.")
|
||||
}
|
||||
})(function(KUTE){
|
||||
var K = window.KUTE, p, DOM = K.dom, PP = K.pp,
|
||||
'use strict';
|
||||
var K = window.KUTE, p, DOM = K.dom, parseProperty = K.pp, prepareStart = K.prS, getComputedStyle = K.gCS,
|
||||
_br = K.property('borderRadius'), _brtl = K.property('borderTopLeftRadius'), _brtr = K.property('borderTopRightRadius'), // all radius props prefixed
|
||||
_brbl = K.property('borderBottomLeftRadius'), _brbr = K.property('borderBottomRightRadius'),
|
||||
_cls = ['borderColor', 'borderTopColor', 'borderRightColor', 'borderBottomColor', 'borderLeftColor', 'outlineColor'], // colors 'hex', 'rgb', 'rgba' -- #fff / rgb(0,0,0) / rgba(0,0,0,0)
|
||||
|
@ -49,39 +50,39 @@
|
|||
// create prepare/process/render functions for additional colors properties
|
||||
for (var i = 0, l = _cls.length; i<l; i++) {
|
||||
p = _cls[i];
|
||||
PP[p] = function(p,v) {
|
||||
parseProperty[p] = function(p,v) {
|
||||
if (!(p in DOM)) {
|
||||
DOM[p] = function(l,p,a,b,v,o) {
|
||||
l.style[p] = color(a,b,v,o.keepHex);
|
||||
};
|
||||
}
|
||||
return PP.cls(p,v);
|
||||
return parseProperty.cls(p,v);
|
||||
};
|
||||
K.prS[p] = function(el,p,v){
|
||||
return K.gCS(el,p) || _d[p];
|
||||
prepareStart[p] = function(el,p,v){
|
||||
return getComputedStyle(el,p) || _d[p];
|
||||
};
|
||||
}
|
||||
|
||||
// create prepare/process/render functions for additional box model properties
|
||||
for (var i = 0, l = _mg.length; i<l; i++) {
|
||||
p = _mg[i];
|
||||
PP[p] = function(p,v){
|
||||
parseProperty[p] = function(p,v){
|
||||
if (!(p in DOM)){
|
||||
DOM[p] = function(l,p,a,b,v){
|
||||
l.style[p] = unit(a.value,b.value,b.unit,v);
|
||||
}
|
||||
}
|
||||
return PP.box(p,v);
|
||||
return parseProperty.box(p,v);
|
||||
};
|
||||
K.prS[p] = function(el,p,v){
|
||||
return K.gCS(el,p) || _d[p];
|
||||
prepareStart[p] = function(el,p,v){
|
||||
return getComputedStyle(el,p) || _d[p];
|
||||
};
|
||||
}
|
||||
|
||||
//create prepare/process/render functions for radius properties
|
||||
for (var i = 0, l = _rd.length; i<l; i++) {
|
||||
p = _rd[i];
|
||||
PP[p] = function(p,v){
|
||||
parseProperty[p] = function(p,v){
|
||||
if ( (!(p in DOM)) ) {
|
||||
if (p === 'borderRadius') {
|
||||
DOM[p] = function(l,p,a,b,v){
|
||||
|
@ -105,15 +106,15 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
return PP.box(p,v);
|
||||
return parseProperty.box(p,v);
|
||||
};
|
||||
K.prS[p] = function(el,p,v){
|
||||
return K.gCS(el,p) || _d[p];
|
||||
prepareStart[p] = function(el,p,v){
|
||||
return getComputedStyle(el,p) || _d[p];
|
||||
};
|
||||
}
|
||||
|
||||
// clip
|
||||
PP['clip'] = function(p,v){
|
||||
parseProperty['clip'] = function(p,v){
|
||||
if ( !(p in DOM) ) {
|
||||
DOM[p] = function(l,p,a,b,v) {
|
||||
var h = 0, cl = [];
|
||||
|
@ -133,13 +134,13 @@
|
|||
}
|
||||
};
|
||||
|
||||
K.prS['clip'] = function(el,p,v){
|
||||
var c = K.gCS(el,p), w = K.gCS(el,'width'), h = K.gCS(el,'height');
|
||||
prepareStart['clip'] = function(el,p,v){
|
||||
var c = getComputedStyle(el,p), w = getComputedStyle(el,'width'), h = getComputedStyle(el,'height');
|
||||
return !/rect/.test(c) ? [0, w, h, 0] : c;
|
||||
};
|
||||
|
||||
// background position
|
||||
PP['backgroundPosition'] = function(p,v) {
|
||||
parseProperty['backgroundPosition'] = function(p,v) {
|
||||
if ( !(p in DOM) ) {
|
||||
DOM[p] = function(l,p,a,b,v) {
|
||||
l.style[p] = unit(a.x.v,b.x.v,'%',v) + ' ' + unit(a.y.v,b.y.v,'%',v);
|
||||
|
@ -154,8 +155,8 @@
|
|||
return { x: xp, y: yp };
|
||||
}
|
||||
}
|
||||
K.prS['backgroundPosition'] = function(el,p,v){
|
||||
return K.gCS(el,p) || _d[p];
|
||||
prepareStart['backgroundPosition'] = function(el,p,v){
|
||||
return getComputedStyle(el,p) || _d[p];
|
||||
}
|
||||
|
||||
return this;
|
||||
|
|
684
kute-svg.js
684
kute-svg.js
|
@ -21,12 +21,11 @@
|
|||
}
|
||||
}( function (KUTE) {
|
||||
'use strict';
|
||||
var K = window.KUTE, S = K.svg = {}, p, DOM = K.dom, PP = K.pp,
|
||||
_svg = document.querySelector('path') || document.querySelector('svg'),
|
||||
_ns = _svg && _svg.ownerSVGElement && _svg.ownerSVGElement.namespaceURI || 'http://www.w3.org/2000/svg',
|
||||
var K = window.KUTE, p, DOM = K.dom, parseProperty = K.pp, prepareStart = K.prS, getComputedStyle = K.gCS,
|
||||
_isIE = (new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})").exec(navigator.userAgent) != null) ? parseFloat( RegExp.$1 ) : false,
|
||||
_nm = ['strokeWidth', 'strokeOpacity', 'fillOpacity', 'stopOpacity'], // numeric SVG CSS props
|
||||
_cls = ['fill', 'stroke', 'stopColor'], // colors 'hex', 'rgb', 'rgba' -- #fff / rgb(0,0,0) / rgba(0,0,0,0)
|
||||
pathReg = /(m[^(h|v|l)]*|[vhl][^(v|h|l|z)]*)/gmi,
|
||||
pathReg = /(m[^(h|v|l)]*|[vhl][^(v|h|l|z)]*)/gmi, ns = 'http://www.w3.org/2000/svg',
|
||||
// interpolate functions
|
||||
number = K.Interpolate.number, color = K.Interpolate.color,
|
||||
array = function array(a,b,l,v) { // array1, array2, array2.length, progress
|
||||
|
@ -39,252 +38,300 @@
|
|||
for(i=0;i<l;i++) { s.push( array( a[i],b[i],ll,v ) ); }
|
||||
return s.join(o);
|
||||
};
|
||||
|
||||
if (_svg && !_svg.ownerSVGElement) {return;} // if SVG API is not supported, return
|
||||
|
||||
|
||||
if (_isIE&&_isIE<9) {return;} // return if SVG API is not supported
|
||||
|
||||
|
||||
// SVG MORPH
|
||||
S.gPt = function(e){ // get path d attribute or create a path from string value
|
||||
var p = {}, el = typeof e === 'object' ? e : /^\.|^\#/.test(e) ? document.querySelector(e) : null;
|
||||
if ( el && /path|glyph/.test(el.tagName) ) {
|
||||
p.e = S.fPt(el);
|
||||
p.o = el.getAttribute('d');
|
||||
var getSegments = function(s,e,r){ // getSegments returns an array of points based on a sample size morphPrecision
|
||||
var s1 = [], e1 = [], le1 = s.getTotalLength(), le2 = e.getTotalLength(), ml = Math.max(le1,le2),
|
||||
d = r, ar = ml / r, j = 0, sl = ar*r; // sl = sample length
|
||||
|
||||
} else if (!el && /[a-z][^a-z]*/ig.test(e)) { // maybe it's a string path already
|
||||
p.e = S.cP(e.trim());
|
||||
p.o = e;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
S.pCr = function(w){ // pathCross
|
||||
// path tween options
|
||||
this._mpr = w._ops.morphPrecision || 15;
|
||||
this._midx = w._ops.morphIndex;
|
||||
this._smi = w._ops.showMorphInfo;
|
||||
this._rv1 = w._ops.reverseFirstPath;
|
||||
this._rv2 = w._ops.reverseSecondPath;
|
||||
|
||||
var p1 = S.gOp(w._vS.path.o), p2 = S.gOp(w._vE.path.o), arr;
|
||||
this._isp = !/[CSQTA]/i.test(p1) && !/[CSQTA]/i.test(p2); // both shapes are polygons
|
||||
|
||||
arr = S._pCr(p1,p2,w._el.parentNode);
|
||||
|
||||
w._vS.path.d = arr[0];
|
||||
w._vE.path.d = arr[1];
|
||||
}
|
||||
|
||||
S._pCr = function(s,e,svg){ // _pathCross
|
||||
var s1, e1, arr, idx, arL, sm, lg, smp, lgp, nsm = [], sml, cl = [], len, tl, cs;
|
||||
this._sp = false;
|
||||
|
||||
if (!this._isp) {
|
||||
s = S.cP(s); e = S.cP(e);
|
||||
arr = S.gSegs(s,e,this._mpr);
|
||||
s1 = arr[0]; e1 = arr[1]; arL = e1.length;
|
||||
} else {
|
||||
s = S.pTA(s); e = S.pTA(e);
|
||||
|
||||
if ( s.length !== e.length ){
|
||||
arL = Math.max(s.length,e.length);
|
||||
if ( arL === e.length) { sm = s; lg = e; } else { sm = e; lg = s; }
|
||||
sml = sm.length;
|
||||
|
||||
smp = S.cP('M'+sm.join('L')+'z'); len = smp.getTotalLength() / arL;
|
||||
for (var i=0; i<arL; i++){
|
||||
tl = smp.getPointAtLength(len*i);
|
||||
cs = S.gCP(len,tl,sm);
|
||||
nsm.push( [ cs[0], cs[1] ] );
|
||||
}
|
||||
|
||||
if (arL === e.length) { e1 = lg; s1 = nsm; } else { s1 = lg; e1 = nsm; }
|
||||
} else {
|
||||
s1 = s; e1 = e;
|
||||
while ( (j += r) < sl ) { // populate the points arrays based on morphPrecision as sample size
|
||||
s1.push( [s.getPointAtLength(j).x, s.getPointAtLength(j).y]);
|
||||
e1.push( [e.getPointAtLength(j).x, e.getPointAtLength(j).y]);
|
||||
}
|
||||
}
|
||||
|
||||
// reverse arrays
|
||||
if (this._rv1) { s1.reverse(); }
|
||||
if (this._rv2) { e1.reverse(); }
|
||||
|
||||
// determine index for best/minimum distance between points
|
||||
if (this._smi) { idx = S.gBi(s1,e1); }
|
||||
|
||||
// shift second array to for smallest tween distance
|
||||
if (this._midx) {
|
||||
var e11 = e1.splice(this._midx,arL-this._midx);
|
||||
e1 = e11.concat(e1);
|
||||
}
|
||||
|
||||
// the console.log helper utility
|
||||
if (this._smi) {
|
||||
// also show the points
|
||||
S.shP(s1,e1,svg);
|
||||
var mpi = this._isp ? 'the polygon with the most points.\n' : (this._mpr === 25 ? 'the default' : 'your') +' morphPrecision value of '+this._mpr+'.\n';
|
||||
console.log( 'KUTE.js Path Morph Log\nThe morph used ' + arL + ' points to draw both paths based on '+mpi
|
||||
+ (this._midx ? 'You\'ve configured the morphIndex to ' + this._midx + ' while the recommended is ' + idx+ '.\n' : 'You may also consider a morphIndex for the second path. Currently the best index seems to be ' + idx + '.\n')
|
||||
+ (
|
||||
!this._rv1 && !this._rv2 ? 'If the current animation is not satisfactory, consider reversing one of the paths. Maybe the paths do not intersect or they really have different draw directions.' :
|
||||
'You\'ve chosen that the first path to have ' + ( this._rv1 ? 'REVERSED draw direction, ' : 'UNCHANGED draw direction, ') + 'while second path is to be ' + (this._rv2 ? 'REVERSED.\n' : 'UNCHANGED.\n')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
s = e = null;
|
||||
return [s1,e1]
|
||||
}
|
||||
|
||||
S.gSegs = function(s,e,r){ // getSegments returns an array of points based on a sample size morphPrecision
|
||||
var s1 = [], e1 = [], le1 = s.getTotalLength(), le2 = e.getTotalLength(), ml = Math.max(le1,le2),
|
||||
d = r, ar = ml / r, j = 0, sl = ar*r; // sl = sample length
|
||||
|
||||
while ( (j += r) < sl ) { // populate the points arrays based on morphPrecision as sample size
|
||||
s1.push( [s.getPointAtLength(j).x, s.getPointAtLength(j).y]);
|
||||
e1.push( [e.getPointAtLength(j).x, e.getPointAtLength(j).y]);
|
||||
}
|
||||
return [s1,e1];
|
||||
}
|
||||
|
||||
S.gCP = function(p,t,s){ // getClosestPoint for polygon paths it returns a close point from the original path (length,pointAtLength,smallest); // intervalLength
|
||||
var x, y, a = [], l = s.length, dx, nx, pr;
|
||||
for (i=0; i<l; i++){
|
||||
x = Math.abs(s[i][0] - t.x);
|
||||
y = Math.abs(s[i][1] - t.y);
|
||||
a.push( Math.sqrt( x * x + y * y ) );
|
||||
}
|
||||
dx = a.indexOf(Math.min.apply(null,a));
|
||||
pr = !!s[dx-1] ? dx-1 : l-1;
|
||||
nx = !!s[dx+1] ? dx+1 : 0;
|
||||
return Math.abs(s[pr][0] - t.x) < p && Math.abs(s[pr][1] - t.y) < p ? s[pr]
|
||||
: Math.abs(s[nx][0] - t.x) < p && Math.abs(s[nx][1] - t.y) < p ? s[nx]
|
||||
: Math.abs(s[dx][0] - t.x) < p && Math.abs(s[dx][1] - t.y) < p ? s[dx]
|
||||
: [t.x,t.y];
|
||||
}
|
||||
|
||||
S.shP = function(s,e,v){// showPoints helper function to visualize the points on the path
|
||||
if (!this._sp){
|
||||
var c, a = arguments, cl, p, l;
|
||||
for (var i=0; i<2; i++){
|
||||
p = a[i]; l = p.length; cl = i=== 0 ? { f: 'DeepPink', o: 'HotPink' } : { f: 'Lime', o: 'LimeGreen' };
|
||||
for (var j=0; j<l; j++) {
|
||||
c = document.createElementNS(_ns,'circle');
|
||||
c.setAttribute('cx',p[j][0]); c.setAttribute('cy',p[j][1]);
|
||||
c.setAttribute('r', j===0 ? 20 : 10 ); c.setAttribute('fill', j===0 ? cl.f : cl.o);
|
||||
if (this._isp) { v.appendChild(c); } else if (!this._isp && j===0 ) { v.appendChild(c);}
|
||||
return [s1,e1];
|
||||
},
|
||||
getClosestPoint = function(p,t,s){ // getClosestPoint for polygon paths it returns a close point from the original path (length,pointAtLength,smallest); // intervalLength
|
||||
var x, y, a = [], l = s.length, dx, nx, pr;
|
||||
for (i=0; i<l; i++){
|
||||
x = Math.abs(s[i][0] - t.x);
|
||||
y = Math.abs(s[i][1] - t.y);
|
||||
a.push( Math.sqrt( x * x + y * y ) );
|
||||
}
|
||||
dx = a.indexOf(Math.min.apply(null,a));
|
||||
pr = !!s[dx-1] ? dx-1 : l-1;
|
||||
nx = !!s[dx+1] ? dx+1 : 0;
|
||||
return Math.abs(s[pr][0] - t.x) < p && Math.abs(s[pr][1] - t.y) < p ? s[pr]
|
||||
: Math.abs(s[nx][0] - t.x) < p && Math.abs(s[nx][1] - t.y) < p ? s[nx]
|
||||
: Math.abs(s[dx][0] - t.x) < p && Math.abs(s[dx][1] - t.y) < p ? s[dx]
|
||||
: [t.x,t.y];
|
||||
},
|
||||
getBestIndex = function(s,e){ // getBestIndex for shape rotation
|
||||
var s1 = clone(s), e1 = clone(e), d = [], i, l = e.length, t, ax, ay;
|
||||
for (i=0; i<l; i++){
|
||||
t = e1.splice(i,l-i); e1 = t.concat(e1);
|
||||
ax = Math.abs(s1[i][0] - e1[i][0]);
|
||||
ay = Math.abs(s1[i][1] - e1[i][1]);
|
||||
d.push( Math.sqrt( ax * ax + ay * ay ) );
|
||||
e1 = []; e1 = clone(e); t = null;
|
||||
}
|
||||
return d.indexOf(Math.min.apply(null,d));
|
||||
},
|
||||
pathToAbsolute = function(p) { // simple pathToAbsolute for polygons | this is still BETA / a work in progress
|
||||
var np = p.match(pathReg), wp = [], l = np.length, s, c, r, x = 0, y = 0;
|
||||
for (var i = 0; i<l; i++){
|
||||
np[i] = np[i]; c = np[i][0]; r = new RegExp(c+'[^\\d|\\-]*','i');
|
||||
np[i] = np[i].replace(/(^|[^,])\s*-/g, '$1,-').replace(/(\s+\,|\s|\,)/g,',').replace(r,'').split(',');
|
||||
np[i][0] = parseFloat(np[i][0]);
|
||||
np[i][1] = parseFloat(np[i][1]);
|
||||
if (i === 0) { x+=np[i][0]; y +=np[i][1]; }
|
||||
else {
|
||||
x = np[i-1][0];
|
||||
y = np[i-1][1];
|
||||
if (/l/i.test(c)) {
|
||||
np[i][0] = c === 'l' ? np[i][0] + x : np[i][0];
|
||||
np[i][1] = c === 'l' ? np[i][1] + y : np[i][1];
|
||||
} else if (/h/i.test(c)) {
|
||||
np[i][0] = c === 'h' ? np[i][0] + x : np[i][0];
|
||||
np[i][1] = y;
|
||||
} else if (/v/i.test(c)) {
|
||||
np[i][0] = x;
|
||||
np[i][1] = c === 'v' ? np[i][0] + y : np[i][0];
|
||||
}
|
||||
}
|
||||
this._sp = true; c = null;
|
||||
}
|
||||
}
|
||||
|
||||
S.gBi = function(s,e){ // getBestIndex for shape rotation
|
||||
var s1 = S.clone(s), e1 = S.clone(e), d = [], i, l = e.length, t, ax, ay;
|
||||
for (i=0; i<l; i++){
|
||||
t = e1.splice(i,l-i); e1 = t.concat(e1);
|
||||
ax = Math.abs(s1[i][0] - e1[i][0]);
|
||||
ay = Math.abs(s1[i][1] - e1[i][1]);
|
||||
d.push( Math.sqrt( ax * ax + ay * ay ) );
|
||||
e1 = []; e1 = S.clone(e); t = null;
|
||||
}
|
||||
return d.indexOf(Math.min.apply(null,d));
|
||||
}
|
||||
|
||||
S.gOp = function(p){ // getOnePath, first path only
|
||||
return p.split(/z/i).shift() + 'z';
|
||||
}
|
||||
|
||||
S.cP = function (p){ // createPath
|
||||
var c = document.createElementNS(_ns,'path'), d = typeof p === 'object' ? p.getAttribute('d') : p;
|
||||
c.setAttribute('d',d); return c;
|
||||
}
|
||||
|
||||
S.fPt = function(p){ // forcePath for glyph elements
|
||||
if (p.tagName === 'glyph') { // perhaps we can also change other SVG tags in the future
|
||||
var c = S.cP(p); p.parentNode.appendChild(c); return c;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
S.clone = function(a) {
|
||||
var copy;
|
||||
if (a instanceof Array) {
|
||||
copy = [];
|
||||
for (var i = 0, len = a.length; i < len; i++) {
|
||||
copy[i] = S.clone(a[i]);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
S.pTA = function(p) { // simple pathToAbsolute for polygons | this is still BETA / a work in progress
|
||||
var np = p.match(pathReg), wp = [], l = np.length, s, c, r, x = 0, y = 0;
|
||||
for (var i = 0; i<l; i++){
|
||||
np[i] = np[i]; c = np[i][0]; r = new RegExp(c+'[^\\d|\\-]*','i');
|
||||
np[i] = np[i].replace(/(^|[^,])\s*-/g, '$1,-').replace(/(\s+\,|\s|\,)/g,',').replace(r,'').split(',');
|
||||
np[i][0] = parseFloat(np[i][0]);
|
||||
np[i][1] = parseFloat(np[i][1]);
|
||||
if (i === 0) { x+=np[i][0]; y +=np[i][1]; }
|
||||
else {
|
||||
x = np[i-1][0];
|
||||
y = np[i-1][1];
|
||||
if (/l/i.test(c)) {
|
||||
np[i][0] = c === 'l' ? np[i][0] + x : np[i][0];
|
||||
np[i][1] = c === 'l' ? np[i][1] + y : np[i][1];
|
||||
} else if (/h/i.test(c)) {
|
||||
np[i][0] = c === 'h' ? np[i][0] + x : np[i][0];
|
||||
np[i][1] = y;
|
||||
} else if (/v/i.test(c)) {
|
||||
np[i][0] = x;
|
||||
np[i][1] = c === 'v' ? np[i][0] + y : np[i][0];
|
||||
return np;
|
||||
},
|
||||
getOnePath = function(p){ return p.split(/z/i).shift() + 'z'; }, // getOnePath, first path only
|
||||
createPath = function (p){ // createPath
|
||||
var c = document.createElementNS(ns,'path'), d = typeof p === 'object' ? p.getAttribute('d') : p;
|
||||
c.setAttribute('d',d); return c;
|
||||
},
|
||||
forcePath = function(p){ // forcePath for glyph elements
|
||||
if (p.tagName === 'glyph') { // perhaps we can also change other SVG tags in the future
|
||||
var c = createPath(p); p.parentNode.appendChild(c); return c;
|
||||
}
|
||||
return p;
|
||||
},
|
||||
clone = function(a) {
|
||||
var copy;
|
||||
if (a instanceof Array) {
|
||||
copy = [];
|
||||
for (var i = 0, len = a.length; i < len; i++) {
|
||||
copy[i] = clone(a[i]);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
return np;
|
||||
}
|
||||
return a;
|
||||
},
|
||||
getPath = function(e){ // get path d attribute or create a path from string value
|
||||
var p = {}, el = typeof e === 'object' ? e : /^\.|^\#/.test(e) ? document.querySelector(e) : null;
|
||||
if ( el && /path|glyph/.test(el.tagName) ) {
|
||||
p.e = forcePath(el);
|
||||
p.o = el.getAttribute('d');
|
||||
|
||||
} else if (!el && /[a-z][^a-z]*/ig.test(e)) { // maybe it's a string path already
|
||||
p.e = createPath(e.trim());
|
||||
p.o = e;
|
||||
}
|
||||
return p;
|
||||
},
|
||||
showCircles = 1,
|
||||
S = K.svg = {
|
||||
showStartingPoints : function(s,e,v){ // showPoints helper function to visualize the points on the path
|
||||
if (showCircles){
|
||||
var c, a = arguments, cl, p, l;
|
||||
for (var i=0; i<2; i++){
|
||||
p = a[i]; l = p.length; cl = i=== 0 ? { f: 'DeepPink', o: 'HotPink' } : { f: 'Lime', o: 'LimeGreen' };
|
||||
for (var j=0; j<l; j++) {
|
||||
c = document.createElementNS(ns,'circle');
|
||||
c.setAttribute('cx',p[j][0]); c.setAttribute('cy',p[j][1]);
|
||||
c.setAttribute('r', j===0 ? 20 : 10 ); c.setAttribute('fill', j===0 ? cl.f : cl.o);
|
||||
if (this._isp) { v.appendChild(c); } else if (!this._isp && j===0 ) { v.appendChild(c);}
|
||||
}
|
||||
}
|
||||
showCircles = 0; c = null;
|
||||
}
|
||||
},
|
||||
_pathCross : function(s,e,svg){ // pathCross
|
||||
var s1, e1, arr, idx, arL, sm, lg, smp, lgp, nsm = [], sml, cl = [], len, tl, cs;
|
||||
|
||||
if (!this._isp) {
|
||||
s = createPath(s); e = createPath(e);
|
||||
arr = getSegments(s,e,this._mpr);
|
||||
s1 = arr[0]; e1 = arr[1]; arL = e1.length;
|
||||
} else {
|
||||
s = pathToAbsolute(s); e = pathToAbsolute(e);
|
||||
|
||||
if ( s.length !== e.length ){
|
||||
arL = Math.max(s.length,e.length);
|
||||
if ( arL === e.length) { sm = s; lg = e; } else { sm = e; lg = s; }
|
||||
sml = sm.length;
|
||||
|
||||
smp = createPath('M'+sm.join('L')+'z'); len = smp.getTotalLength() / arL;
|
||||
for (var i=0; i<arL; i++){
|
||||
tl = smp.getPointAtLength(len*i);
|
||||
cs = getClosestPoint(len,tl,sm);
|
||||
nsm.push( [ cs[0], cs[1] ] );
|
||||
}
|
||||
|
||||
if (arL === e.length) { e1 = lg; s1 = nsm; } else { s1 = lg; e1 = nsm; }
|
||||
} else {
|
||||
s1 = s; e1 = e;
|
||||
}
|
||||
}
|
||||
|
||||
// reverse arrays
|
||||
if (this._rv1) { s1.reverse(); }
|
||||
if (this._rv2) { e1.reverse(); }
|
||||
|
||||
// determine index for best/minimum distance between points
|
||||
if (this._smi) { idx = getBestIndex(s1,e1); }
|
||||
|
||||
// shift second array to for smallest tween distance
|
||||
if (this._midx) {
|
||||
var e11 = e1.splice(this._midx,arL-this._midx);
|
||||
e1 = e11.concat(e1);
|
||||
}
|
||||
|
||||
// the console.log helper utility
|
||||
if (this._smi) {
|
||||
// also show the points
|
||||
this.showStartingPoints(s1,e1,svg);
|
||||
var mpi = this._isp ? 'the polygon with the most points.\n' : (this._mpr === 25 ? 'the default' : 'your') +' morphPrecision value of '+this._mpr+'.\n';
|
||||
console.log( 'KUTE.js Path Morph Log\nThe morph used ' + arL + ' points to draw both paths based on '+mpi
|
||||
+ (this._midx ? 'You\'ve configured the morphIndex to ' + this._midx + ' while the recommended is ' + idx+ '.\n' : 'You may also consider a morphIndex for the second path. Currently the best index seems to be ' + idx + '.\n')
|
||||
+ (
|
||||
!this._rv1 && !this._rv2 ? 'If the current animation is not satisfactory, consider reversing one of the paths. Maybe the paths do not intersect or they really have different draw directions.' :
|
||||
'You\'ve chosen that the first path to have ' + ( this._rv1 ? 'REVERSED draw direction, ' : 'UNCHANGED draw direction, ') + 'while second path is to be ' + (this._rv2 ? 'REVERSED.\n' : 'UNCHANGED.\n')
|
||||
)
|
||||
);
|
||||
}
|
||||
s = e = null;
|
||||
return [s1,e1]
|
||||
},
|
||||
pathCross : function(w){ // pathCross
|
||||
// path tween options
|
||||
this._mpr = w._ops.morphPrecision || 15;
|
||||
this._midx = w._ops.morphIndex;
|
||||
this._smi = w._ops.showMorphInfo;
|
||||
this._rv1 = w._ops.reverseFirstPath;
|
||||
this._rv2 = w._ops.reverseSecondPath;
|
||||
|
||||
var p1 = getOnePath(w._vS.path.o), p2 = getOnePath(w._vE.path.o), arr;
|
||||
this._isp = !/[CSQTA]/i.test(p1) && !/[CSQTA]/i.test(p2); // both shapes are polygons
|
||||
|
||||
arr = this._pathCross(p1,p2,w._el.ownerSVGElement);
|
||||
// arr = this._pathCross(p1,p2,w._el.parentNode);
|
||||
|
||||
w._vS.path.d = arr[0];
|
||||
w._vE.path.d = arr[1];
|
||||
}
|
||||
};
|
||||
|
||||
// a shortHand pathCross && SVG transform stack
|
||||
K.svq = function(w){ if ( w._vE.path ) S.pCr(w); if ( w._vE.svgTransform ) S.sT(w); }
|
||||
K.svq = function(w){ if ( w._vE.path ) S.pathCross(w); if ( w._vE.svgTransform ) stackTransform(w); }
|
||||
|
||||
// register the render SVG path object
|
||||
// process path object and also register the render function
|
||||
K.pp['path'] = function(a,o,l) { // K.pp['path']('path',value,element);
|
||||
parseProperty['path'] = function(a,o,l) { // K.pp['path']('path',value,element);
|
||||
if (!('path' in DOM)) {
|
||||
DOM['path'] = function(l,p,a,b,v){
|
||||
l.setAttribute("d", v === 1 ? b.o : 'M' + coords( a['d'],b['d'],b['d'].length,2,'L',v ) + 'Z' );
|
||||
}
|
||||
}
|
||||
return S.gPt(o);
|
||||
return getPath(o);
|
||||
};
|
||||
|
||||
K.prS['path'] = function(el,p,v){
|
||||
prepareStart['path'] = function(el,p,v){
|
||||
return el.getAttribute('d');
|
||||
};
|
||||
|
||||
|
||||
// SVG DRAW
|
||||
S.gDr = function(e,v){
|
||||
var l = /path|glyph/.test(e.tagName) ? e.getTotalLength() : S.gL(e), start, end, d, o;
|
||||
if ( v instanceof Object ) {
|
||||
return v;
|
||||
} else if (typeof v === 'string') {
|
||||
v = v.split(/\,|\s/);
|
||||
start = /%/.test(v[0]) ? S.pc(v[0].trim(),l) : parseFloat(v[0]);
|
||||
end = /%/.test(v[1]) ? S.pc(v[1].trim(),l) : parseFloat(v[1]);
|
||||
} else if (typeof v === 'undefined') {
|
||||
o = parseFloat(K.gCS(e,'stroke-dashoffset'));
|
||||
d = K.gCS(e,'stroke-dasharray').split(/\,/);
|
||||
|
||||
start = 0-o;
|
||||
end = parseFloat(d[0]) + start || l;
|
||||
}
|
||||
|
||||
return { s: start, e: end, l: l }
|
||||
};
|
||||
var percent = function(v,l){ return parseFloat(v) / 100 * l;}, // percent
|
||||
// SVG DRAW UTILITITES
|
||||
// http://stackoverflow.com/a/30376660
|
||||
getRectLength = function(el){ // getRectLength - return the length of a Rect
|
||||
var w = el.getAttribute('width');
|
||||
var h = el.getAttribute('height');
|
||||
return (w*2)+(h*2);
|
||||
},
|
||||
getPolyLength = function(el){ // getPolygonLength / getPolylineLength - return the length of the Polygon / Polyline
|
||||
var points = el.getAttribute('points').split(' '), len = 0;
|
||||
if (points.length > 1) {
|
||||
var coord = function (p) {
|
||||
var c = p.split(',');
|
||||
if (c.length != 2) { return; } // return undefined
|
||||
if (isNaN(c[0]) || isNaN(c[1])) { return; }
|
||||
return [parseFloat(c[0]), parseFloat(c[1])];
|
||||
};
|
||||
|
||||
var dist = function (c1, c2) {
|
||||
if (c1 != undefined && c2 != undefined) {
|
||||
return Math.sqrt(Math.pow((c2[0]-c1[0]), 2) + Math.pow((c2[1]-c1[1]), 2));
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
if (points.length > 2) {
|
||||
for (var i=0; i<points.length-1; i++) {
|
||||
len += dist(coord(points[i]), coord(points[i+1]));
|
||||
}
|
||||
}
|
||||
len += dist(coord(points[0]), coord(points[points.length-1]));
|
||||
}
|
||||
return len;
|
||||
},
|
||||
getLineLength = function(el){ // getLineLength - return the length of the line
|
||||
var x1 = el.getAttribute('x1');
|
||||
var x2 = el.getAttribute('x2');
|
||||
var y1 = el.getAttribute('y1');
|
||||
var y2 = el.getAttribute('y2');
|
||||
return Math.sqrt(Math.pow((x2-x1), 2)+Math.pow((y2-y1),2));
|
||||
},
|
||||
getCircleLength = function(el){ // getCircleLength - return the length of the circle
|
||||
var r = el.getAttribute('r');
|
||||
return 2 * Math.PI * r;
|
||||
},
|
||||
getEllipseLength = function(el) { // getEllipseLength - returns the length of an ellipse
|
||||
var rx = el.getAttribute('rx'), ry = el.getAttribute('ry'),
|
||||
len = 2*rx, wid = 2*ry;
|
||||
return ((Math.sqrt(.5 * ((len * len) + (wid * wid)))) * (Math.PI * 2)) / 2;
|
||||
},
|
||||
getTotalLength = function(el){ // getLength - returns the result of any of the below functions
|
||||
if (/rect/.test(el.tagName)) {
|
||||
return getRectLength(el);
|
||||
} else if (/circle/.test(el.tagName)) {
|
||||
return getCircleLength(el);
|
||||
} else if (/ellipse/.test(el.tagName)) {
|
||||
return getEllipseLength(el);
|
||||
} else if (/polygon|polyline/.test(el.tagName)) {
|
||||
return getPolyLength(el);
|
||||
} else if (/line/.test(el.tagName)) {
|
||||
return getLineLength(el);
|
||||
}
|
||||
},
|
||||
getDraw = function(e,v){
|
||||
var l = /path|glyph/.test(e.tagName) ? e.getTotalLength() : getTotalLength(e), start, end, d, o;
|
||||
if ( v instanceof Object ) {
|
||||
return v;
|
||||
} else if (typeof v === 'string') {
|
||||
v = v.split(/\,|\s/);
|
||||
start = /%/.test(v[0]) ? percent(v[0].trim(),l) : parseFloat(v[0]);
|
||||
end = /%/.test(v[1]) ? percent(v[1].trim(),l) : parseFloat(v[1]);
|
||||
} else if (typeof v === 'undefined') {
|
||||
o = parseFloat(getComputedStyle(e,'stroke-dashoffset'));
|
||||
d = getComputedStyle(e,'stroke-dasharray').split(/\,/);
|
||||
|
||||
start = 0-o;
|
||||
end = parseFloat(d[0]) + start || l;
|
||||
}
|
||||
return { s: start, e: end, l: l }
|
||||
};
|
||||
|
||||
S.pc = function(v,l){ // percent
|
||||
return parseFloat(v) / 100 * l;
|
||||
};
|
||||
|
||||
PP['draw'] = function(a,o,f){ // register the draw property
|
||||
parseProperty['draw'] = function(a,o,f){ // register the draw property
|
||||
if (!('draw' in DOM)) {
|
||||
DOM['draw'] = function(l,p,a,b,v){
|
||||
var ll = a.l, s = number(a.s,b.s,v), e = number(a.e,b.e,v), o = 0 - s;
|
||||
|
@ -292,89 +339,18 @@
|
|||
l.style.strokeDasharray = e+o<1 ? '0px, ' + ll + 'px' : (e+o) + 'px, ' + ll + 'px';
|
||||
}
|
||||
}
|
||||
return S.gDr(f,o);
|
||||
return getDraw(f,o);
|
||||
}
|
||||
|
||||
K.prS['draw'] = function(el,p,v){
|
||||
return S.gDr(el);
|
||||
prepareStart['draw'] = function(el,p,v){
|
||||
return getDraw(el);
|
||||
}
|
||||
|
||||
// SVG DRAW UTILITITES
|
||||
// http://stackoverflow.com/a/30376660
|
||||
S.gL = function(el){ // getLength - returns the result of any of the below functions
|
||||
if (/rect/.test(el.tagName)) {
|
||||
return S.gRL(el);
|
||||
} else if (/circle/.test(el.tagName)) {
|
||||
return S.gCL(el);
|
||||
} else if (/ellipse/.test(el.tagName)) {
|
||||
return S.gEL(el);
|
||||
} else if (/polygon|polyline/.test(el.tagName)) {
|
||||
return S.gPL(el);
|
||||
} else if (/line/.test(el.tagName)) {
|
||||
return S.gLL(el);
|
||||
}
|
||||
}
|
||||
|
||||
S.gRL = function(el){ // getRectLength - return the length of a Rect
|
||||
var w = el.getAttribute('width');
|
||||
var h = el.getAttribute('height');
|
||||
return (w*2)+(h*2);
|
||||
}
|
||||
|
||||
S.gPL = function(el){ // getPolygonLength / getPolylineLength - return the length of the Polygon / Polyline
|
||||
var points = el.getAttribute('points').split(' '), len = 0;
|
||||
if (points.length > 1) {
|
||||
var coord = function (p) {
|
||||
var c = p.split(',');
|
||||
if (c.length != 2) {
|
||||
return; // return undefined
|
||||
}
|
||||
if (isNaN(c[0]) || isNaN(c[1])) {
|
||||
return;
|
||||
}
|
||||
return [parseFloat(c[0]), parseFloat(c[1])];
|
||||
};
|
||||
|
||||
var dist = function (c1, c2) {
|
||||
if (c1 != undefined && c2 != undefined) {
|
||||
return Math.sqrt(Math.pow((c2[0]-c1[0]), 2) + Math.pow((c2[1]-c1[1]), 2));
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
if (points.length > 2) {
|
||||
for (var i=0; i<points.length-1; i++) {
|
||||
len += dist(coord(points[i]), coord(points[i+1]));
|
||||
}
|
||||
}
|
||||
len += dist(coord(points[0]), coord(points[points.length-1]));
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
S.gLL = function(el){ // getLineLength - return the length of the line
|
||||
var x1 = el.getAttribute('x1');
|
||||
var x2 = el.getAttribute('x2');
|
||||
var y1 = el.getAttribute('y1');
|
||||
var y2 = el.getAttribute('y2');
|
||||
return Math.sqrt(Math.pow((x2-x1), 2)+Math.pow((y2-y1),2));
|
||||
}
|
||||
|
||||
S.gCL = function(el){ // getCircleLength - return the length of the circle
|
||||
var r = el.getAttribute('r');
|
||||
return 2 * Math.PI * r;
|
||||
}
|
||||
|
||||
S.gEL = function(el) { // getEllipseLength - returns the length of an ellipse
|
||||
var rx = el.getAttribute('rx'), ry = el.getAttribute('ry'),
|
||||
len = 2*rx, wid = 2*ry;
|
||||
return ((Math.sqrt(.5 * ((len * len) + (wid * wid)))) * (Math.PI * 2)) / 2;
|
||||
}
|
||||
|
||||
// SVG CSS Color Properties
|
||||
for ( var i = 0, l = _cls.length; i< l; i++) {
|
||||
p = _cls[i];
|
||||
PP[p] = function(p,v){
|
||||
parseProperty[p] = function(p,v){
|
||||
if (!(p in DOM)) {
|
||||
DOM[p] = function(l,p,a,b,v,o) {
|
||||
l.style[p] = color(a,b,v,o.keepHex);
|
||||
|
@ -382,26 +358,26 @@
|
|||
}
|
||||
return K.truC(v);
|
||||
}
|
||||
K.prS[p] = function(el,p,v){
|
||||
return K.gCS(el,p) || 'rgba(0,0,0,0)';
|
||||
prepareStart[p] = function(el,p,v){
|
||||
return getComputedStyle(el,p) || 'rgba(0,0,0,0)';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Other SVG related CSS props
|
||||
for ( var i = 0, l = _nm.length; i< l; i++) { // for numeric CSS props from any type of SVG shape
|
||||
p = _nm[i];
|
||||
if (p === 'strokeWidth'){ // stroke can be unitless or unit | http://stackoverflow.com/questions/1301685/fixed-stroke-width-in-svg
|
||||
PP[p] = function(p,v){
|
||||
parseProperty[p] = function(p,v){
|
||||
if (!(p in DOM)) {
|
||||
DOM[p] = function(l,p,a,b,v) {
|
||||
var _u = _u || typeof b === 'number';
|
||||
l.style[p] = !_u ? unit(a.value,b.value,b.unit,v) : number(a,b,v);
|
||||
}
|
||||
}
|
||||
return /px|%|em|vh|vw/.test(v) ? PP.box(p,v) : parseFloat(v);
|
||||
return /px|%|em|vh|vw/.test(v) ? parseProperty.box(p,v) : parseFloat(v);
|
||||
}
|
||||
} else {
|
||||
PP[p] = function(p,v){
|
||||
parseProperty[p] = function(p,v){
|
||||
if (!(p in DOM)) {
|
||||
DOM[p] = function(l,p,a,b,v) {
|
||||
l.style[p] = number(a,b,v);
|
||||
|
@ -410,13 +386,54 @@
|
|||
return parseFloat(v);
|
||||
}
|
||||
}
|
||||
K.prS[p] = function(el,p,v){
|
||||
return K.gCS(el,p) || 0;
|
||||
prepareStart[p] = function(el,p,v){
|
||||
return getComputedStyle(el,p) || 0;
|
||||
}
|
||||
}
|
||||
|
||||
// SVG Transform
|
||||
PP['svgTransform'] = function(p,v,l){
|
||||
var parseTransform = function (a){ // helper function that turns transform value from string to object
|
||||
var d = a && /\)/.test(a) ? a.split(')') : 'none', j, c ={}, p;
|
||||
|
||||
if (d instanceof Array) {
|
||||
for (j=0; j<d.length; j++){
|
||||
p = d[j].split('('); p[0] !== '' && (c[p[0].replace(/\s/,'')] = p[1] );
|
||||
}
|
||||
}
|
||||
return c;
|
||||
},
|
||||
stackTransform = function (w){ // helper function that helps preserve current transform properties into the objects
|
||||
var bb = w._el.getBBox(), ctr = parseTransform(w._el.getAttribute('transform')), r, t, i,
|
||||
cx = bb.x + bb.width/2, cy = bb.y + bb.height/2;
|
||||
|
||||
for ( i in ctr ) { // populate the valuesStart
|
||||
if (i === 'translate'){
|
||||
t = ctr[i] instanceof Array ? ctr[i] : /\,|\s/.test(ctr[i]) ? ctr[i].split(/\,|\s/) : [ctr[i]*1,0];
|
||||
w._vS.svgTransform[i] = [t[0] * 1||0, t[1] * 1||0];
|
||||
} else if (i === 'scale'){
|
||||
w._vS.svgTransform[i] = ctr[i] * 1||1;
|
||||
} else if (i === 'rotate'){
|
||||
r = ctr[i] instanceof Array ? ctr[i]
|
||||
: /\s/.test(ctr[i]) ? [ctr[i].split(' ')[0]*1, ctr[i].split(' ')[1].split(',')[0]*1, ctr[i].split(' ')[1].split(',')[1]*1]
|
||||
: [ctr[i]*1,cx,cy];
|
||||
w._vS.svgTransform[i] = r;
|
||||
} else if (/skew/.test(i)) {
|
||||
w._vS.svgTransform[i] = ctr[i] * 1||0;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i in w._vS.svgTransform) {
|
||||
if (!(i in w._vE.svgTransform)) { // copy existing and unused properties to the valuesEnd
|
||||
w._vE.svgTransform[i] = w._vS.svgTransform[i];
|
||||
}
|
||||
if (i === 'rotate' in w._vS.svgTransform && 'rotate' in w._vE.svgTransform){ // make sure to use the right transform origin when rotation is used
|
||||
w._vE.svgTransform.rotate[1] = w._vS.svgTransform.rotate[1] = cx;
|
||||
w._vE.svgTransform.rotate[2] = w._vS.svgTransform.rotate[2] = cy;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
parseProperty['svgTransform'] = function(p,v,l){
|
||||
// register the render function
|
||||
if (!('svgTransform' in DOM)) {
|
||||
DOM['svgTransform'] = function(l,p,a,b,v){
|
||||
|
@ -477,55 +494,14 @@
|
|||
return tf;
|
||||
}
|
||||
|
||||
// KUTE.prepareStart K.prS[p](el,p,to[p])
|
||||
// KUTE.prepareStart prepareStart[p](el,p,to[p])
|
||||
// returns an obect with current transform attribute value
|
||||
K.prS['svgTransform'] = function(l,p,t) {
|
||||
var tr = {}, i, ctr = S.pT(l.getAttribute('transform'));
|
||||
prepareStart['svgTransform'] = function(l,p,t) {
|
||||
var tr = {}, i, ctr = parseTransform(l.getAttribute('transform'));
|
||||
for (i in t) { tr[i] = i in ctr ? ctr[i] : (i==='scale'?1:0); } // find a value in current attribute value or add a default value
|
||||
return tr;
|
||||
}
|
||||
|
||||
S.sT = function (w){ // stackTransform - helper function that helps preserve current transform properties into the objects
|
||||
var bb = w._el.getBBox(), ctr = S.pT(w._el.getAttribute('transform')), r, t, i,
|
||||
cx = bb.x + bb.width/2, cy = bb.y + bb.height/2;
|
||||
|
||||
for ( i in ctr ) { // populate the valuesStart
|
||||
if (i === 'translate'){
|
||||
t = ctr[i] instanceof Array ? ctr[i] : /\,|\s/.test(ctr[i]) ? ctr[i].split(/\,|\s/) : [ctr[i]*1,0];
|
||||
w._vS.svgTransform[i] = [t[0] * 1||0, t[1] * 1||0];
|
||||
} else if (i === 'scale'){
|
||||
w._vS.svgTransform[i] = ctr[i] * 1||1;
|
||||
} else if (i === 'rotate'){
|
||||
r = ctr[i] instanceof Array ? ctr[i]
|
||||
: /\s/.test(ctr[i]) ? [ctr[i].split(' ')[0]*1, ctr[i].split(' ')[1].split(',')[0]*1, ctr[i].split(' ')[1].split(',')[1]*1]
|
||||
: [ctr[i]*1,cx,cy];
|
||||
w._vS.svgTransform[i] = r;
|
||||
} else if (/skew/.test(i)) {
|
||||
w._vS.svgTransform[i] = ctr[i] * 1||0;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i in w._vS.svgTransform) {
|
||||
if (!(i in w._vE.svgTransform)) { // copy existing and unused properties to the valuesEnd
|
||||
w._vE.svgTransform[i] = w._vS.svgTransform[i];
|
||||
}
|
||||
if (i === 'rotate' in w._vS.svgTransform && 'rotate' in w._vE.svgTransform){ // make sure to use the right transform origin when rotation is used
|
||||
w._vE.svgTransform.rotate[1] = w._vS.svgTransform.rotate[1] = cx;
|
||||
w._vE.svgTransform.rotate[2] = w._vS.svgTransform.rotate[2] = cy;
|
||||
}
|
||||
}
|
||||
}
|
||||
S.pT = function (a){ // parseTransform - helper function that turns transform value from string to object
|
||||
var d = a && /\)/.test(a) ? a.split(')') : 'none', j, c ={}, p;
|
||||
|
||||
if (d instanceof Array) {
|
||||
for (j=0; j<d.length; j++){
|
||||
p = d[j].split('('); p[0] !== '' && (c[p[0].replace(/\s/,'')] = p[1] );
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
return S;
|
||||
|
||||
}));
|
18
kute-text.js
18
kute-text.js
|
@ -9,31 +9,33 @@
|
|||
define(["./kute.js"], function(KUTE){ factory(KUTE); return KUTE; });
|
||||
} else if(typeof module == "object" && typeof require == "function") {
|
||||
var KUTE = require("./kute.js");
|
||||
module.exports = factory(KUTE);
|
||||
module.exports = factory();
|
||||
} else if ( typeof window.KUTE !== 'undefined' ) {
|
||||
factory();
|
||||
} else {
|
||||
throw new Error("Text-Plugin requires KUTE.js.");
|
||||
}
|
||||
}( function () {
|
||||
var K = window.KUTE, DOM = K.dom, PP = K.pp, number = K.Interpolate.number,
|
||||
}( function (KUTE) {
|
||||
'use strict';
|
||||
var K = window.KUTE, DOM = K.dom, prepareStart = K.prS,
|
||||
parseProperty = K.pp, number = K.Interpolate.number,
|
||||
_s = String("abcdefghijklmnopqrstuvwxyz").split(""), // lowercase
|
||||
_S = String("abcdefghijklmnopqrstuvwxyz".toUpperCase()).split(""), // uppercase
|
||||
_S = String("abcdefghijklmnopqrstuvwxyz".toUpperCase()).split(""), // uparsePropertyercase
|
||||
_sb = String("~!@#$%^&*()_+{}[];'<>,./?\=-").split(""), // symbols
|
||||
_n = String("0123456789").split(""), // numeric
|
||||
_a = _s.concat(_S,_n), // alpha numeric
|
||||
_all = _a.concat(_sb), // all caracters
|
||||
random = Math.random, floor = Math.floor, min = Math.min;
|
||||
|
||||
K.prS['text'] = K.prS['number'] = function(l,p,v){
|
||||
prepareStart['text'] = prepareStart['number'] = function(l,p,v){
|
||||
return l.innerHTML;
|
||||
}
|
||||
|
||||
PP['text'] = function(p,v,l) {
|
||||
parseProperty['text'] = function(p,v,l) {
|
||||
if ( !( 'text' in DOM ) ) {
|
||||
DOM['text'] = function(l,p,a,b,v,o) {
|
||||
var tp = tp || o.textChars === 'alpha' ? _s // textChars is alpha
|
||||
: o.textChars === 'upper' ? _S // textChars is numeric
|
||||
: o.textChars === 'uparsePropertyer' ? _S // textChars is numeric
|
||||
: o.textChars === 'numeric' ? _n // textChars is numeric
|
||||
: o.textChars === 'alphanumeric' ? _a // textChars is alphanumeric
|
||||
: o.textChars === 'symbols' ? _sb // textChars is symbols
|
||||
|
@ -50,7 +52,7 @@
|
|||
return v;
|
||||
}
|
||||
|
||||
PP['number'] = function(p,v,l) {
|
||||
parseProperty['number'] = function(p,v,l) {
|
||||
if ( !( 'number' in DOM ) ) {
|
||||
DOM['number'] = function(l,p,a,b,v) {
|
||||
l.innerHTML = parseInt( number(a, b, v));
|
||||
|
|
107
kute.js
107
kute.js
|
@ -512,8 +512,43 @@
|
|||
};
|
||||
easing.easingBounceInOut = function(t) { if ( t < 0.5 ) return easing.easingBounceIn( t * 2 ) * 0.5; return easing.easingBounceOut( t * 2 - 1 ) * 0.5 + 0.5;};
|
||||
|
||||
var start = function (t) { // move functions that use the ticker outside the prototype to be in the same scope with it
|
||||
this.scrollIn();
|
||||
|
||||
perspective(this._el,this); // apply the perspective and transform origin
|
||||
if ( this._rpr ) { this.stack(); } // on start we reprocess the valuesStart for TO() method
|
||||
|
||||
for ( var e in this._vE ) {
|
||||
this._vSR[e] = this._vS[e];
|
||||
}
|
||||
|
||||
// now it's a good time to start
|
||||
add(this);
|
||||
this.playing = true;
|
||||
this.paused = false;
|
||||
this._sCF = false;
|
||||
this._sT = t || window.performance.now();
|
||||
this._sT += this._dl;
|
||||
|
||||
if (!this._sCF) {
|
||||
if (this._sC) { this._sC.call(); }
|
||||
this._sCF = true;
|
||||
}
|
||||
if (!_t) _tk();
|
||||
return this;
|
||||
},
|
||||
play = function () {
|
||||
if (this.paused && this.playing) {
|
||||
this.paused = false;
|
||||
if (this._rC !== null) { this._rC.call(); }
|
||||
this._sT += window.performance.now() - this._pST;
|
||||
add(this);
|
||||
if (!_t) _tk(); // restart ticking if stopped
|
||||
}
|
||||
return this;
|
||||
},
|
||||
// single Tween object construct
|
||||
var Tween = function (_el, _vS, _vE, _o) {
|
||||
Tween = function (_el, _vS, _vE, _o) {
|
||||
this._el = _el; // element animation is applied to
|
||||
this._vSR = {}; // internal valuesStartRepeat
|
||||
this._vS = _vS; // valuesStart
|
||||
|
@ -546,6 +581,8 @@
|
|||
this._stC = _o.stop || null; // _on StopCallback
|
||||
this.repeat = this._r; // we cache the number of repeats to be able to put it back after all cycles finish
|
||||
this._ops = {};
|
||||
this.start = Tween.prototype.start = start;
|
||||
this.play = Tween.prototype.play = this.resume = Tween.prototype.resume = play;
|
||||
|
||||
//also add plugins options or transform perspective
|
||||
for (var o in _o) { if (!(o in this) && !/delay|duration|repeat|origin|start|stop|update|complete|pause|play|yoyo|easing/i.test(o) ) { this._ops[o] = _o[o]; } }
|
||||
|
@ -717,61 +754,24 @@
|
|||
_o[i].delay = i>0 ? o.delay + (o.offset||0) : o.delay;
|
||||
this.tweens.push( fromTo(els[i], vS, vE, _o[i]) );
|
||||
}
|
||||
};
|
||||
|
||||
var ws = TweensTO.prototype = TweensFT.prototype;
|
||||
ws.start = function(t){
|
||||
t = t || window.performance.now();
|
||||
var i, tl = this.tweens.length;
|
||||
for ( i = 0; i < tl; i++ ) {
|
||||
this.tweens[i].start(t);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
ws.stop = function(){ for ( var i = 0; i < this.tweens.length; i++ ) { this.tweens[i].stop(); } return this; }
|
||||
ws.pause = function(){ for ( var i = 0; i < this.tweens.length; i++ ) { this.tweens[i].pause(); } return this; }
|
||||
ws.chain = function(){ this.tweens[this.tweens.length-1]._cT = arguments; return this; }
|
||||
ws.play = ws.resume = function(){ for ( var i = 0; i < this.tweens.length; i++ ) { this.tweens[i].play(); } return this; }
|
||||
|
||||
var start = function (t) { // move functions that use the ticker outside the prototype to be in the same scope with it
|
||||
this.scrollIn();
|
||||
|
||||
perspective(this._el,this); // apply the perspective and transform origin
|
||||
if ( this._rpr ) { this.stack(); } // on start we reprocess the valuesStart for TO() method
|
||||
|
||||
for ( var e in this._vE ) {
|
||||
this._vSR[e] = this._vS[e];
|
||||
}
|
||||
|
||||
// now it's a good time to start
|
||||
add(this);
|
||||
this.playing = true;
|
||||
this.paused = false;
|
||||
this._sCF = false;
|
||||
this._sT = t || window.performance.now();
|
||||
this._sT += this._dl;
|
||||
|
||||
if (!this._sCF) {
|
||||
if (this._sC) { this._sC.call(); }
|
||||
this._sCF = true;
|
||||
}
|
||||
if (!_t) _tk();
|
||||
return this;
|
||||
},
|
||||
play = function () {
|
||||
if (this.paused && this.playing) {
|
||||
this.paused = false;
|
||||
if (this._rC !== null) { this._rC.call(); }
|
||||
this._sT += window.performance.now() - this._pST;
|
||||
add(this);
|
||||
if (!_t) _tk(); // restart ticking if stopped
|
||||
}
|
||||
return this;
|
||||
ws = TweensTO.prototype = TweensFT.prototype = {
|
||||
start : function(t){
|
||||
t = t || window.performance.now();
|
||||
var i, tl = this.tweens.length;
|
||||
for ( i = 0; i < tl; i++ ) {
|
||||
this.tweens[i].start(t);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
stop : function(){ for ( var i = 0; i < this.tweens.length; i++ ) { this.tweens[i].stop(); } return this; },
|
||||
pause : function(){ for ( var i = 0; i < this.tweens.length; i++ ) { this.tweens[i].pause(); } return this; },
|
||||
chain : function(){ this.tweens[this.tweens.length-1]._cT = arguments; return this; },
|
||||
play : function(){ for ( var i = 0; i < this.tweens.length; i++ ) { this.tweens[i].play(); } return this; },
|
||||
resume :function() {return this.play()}
|
||||
};
|
||||
Tween.prototype.start = start;
|
||||
Tween.prototype.play = Tween.prototype.resume = play;
|
||||
|
||||
K = { // export core methods to public for plugins
|
||||
return K = { // export core methods to public for plugins
|
||||
property: property, getPrefix: getPrefix, selector: selector, pe : pe, // utils
|
||||
to: to, fromTo: fromTo, allTo: allTo, allFromTo: allFromTo, // main methods
|
||||
Interpolate: {number: number, unit: unit, color: color }, // interpolators ?? move array & coords to svg and leave color
|
||||
|
@ -781,5 +781,4 @@
|
|||
Easing: easing,
|
||||
Tween: Tween, TweensTO: TweensTO, TweensFT: TweensFT // constructors
|
||||
};
|
||||
return K;
|
||||
}));
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "kute.js",
|
||||
"version": "1.5.6",
|
||||
"version": "1.5.7",
|
||||
"description": "A minimal Native Javascript animation engine.",
|
||||
"main": "kute.js",
|
||||
"scripts": {
|
||||
|
@ -14,8 +14,9 @@
|
|||
"keywords": [
|
||||
"kute.js",
|
||||
"animation engine",
|
||||
"javascript animation engine",
|
||||
"animations",
|
||||
"native-javascript"
|
||||
"native javascript"
|
||||
],
|
||||
"author": "thednp",
|
||||
"license": "MIT",
|
||||
|
|
Loading…
Reference in a new issue