Code cleanup

This commit is contained in:
thednp 2016-09-22 05:26:43 +03:00
parent 2960ff6d73
commit 728af0a801
17 changed files with 846 additions and 886 deletions

View file

@ -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"
}
}

View file

@ -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 ){

View file

@ -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;

View file

@ -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;
}));

View file

@ -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));

View file

@ -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;
}));

View file

@ -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}});

View file

@ -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});

File diff suppressed because one or more lines are too long

View file

@ -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

File diff suppressed because one or more lines are too long

View file

@ -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 ){

View file

@ -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;

View file

@ -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;
}));

View file

@ -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
View file

@ -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;
}));

View file

@ -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",