Improved overall performance https://github.com/thednp/kute.js/issues/34
Fixed some issues with SVG Plugin https://github.com/thednp/kute.js/issues/33
Documentation updates
This commit is contained in:
thednp 2016-09-03 18:35:49 +03:00
parent 3e1eb06d26
commit a30eab2ff9
29 changed files with 1749 additions and 1656 deletions

View file

@ -96,17 +96,18 @@ footer p {margin: 0 0 10px}
/* example box */
.example-box {
font-size: 40px; line-height: 150px; text-align:center; font-weight: bold;
width: 150px; height: 150px; float: left; position:relative;
float: left; position:relative;
width: 150px; height: 150px;
border-radius: 5px; margin: 0 20px 20px 0;
/* easy hack to improve box model properties performance on modern browsers only ofc */
transform: translate3d(0px,0px,0px); -webkit-transform: translate3d(0px,0px,0px);
}
.example-box-model {
font-size: 40px; text-align:center; font-weight: bold;
/*.example-box-model {
font-size: 40px; text-align:center; font-weight: bold;
float: left; position:relative;
border-radius: 5px; margin: 0 20px 20px 0;
}
svg.example-box { width: auto; height: auto; }*/
.easing-example {float: none; font-size: 24px; width: 320px}
.example-buttons {position: absolute; top: 18px; right:0}
@ -114,7 +115,7 @@ footer p {margin: 0 0 10px}
h1.example-item {
font-size: 50px;
line-height:50px;
color: #fff;
color: #333;
}
h1.example-item span {

View file

@ -25,7 +25,7 @@ var boxModel = document.getElementById('boxModel'),
// built the tween objects
var bm1 = KUTE.to(box,{marginTop:50},{ yoyo: true, repeat: 1, duration: 1500, update: onMarginTop});
var bm2 = KUTE.to(box,{marginBottom:50},{ yoyo: true, repeat: 1, duration: 1500, update: onMarginBottom});
var bm3 = KUTE.to(box,{padding:30},{ yoyo: true, repeat: 1, duration: 1500, update: onPadding});
var bm3 = KUTE.to(box,{paddingTop:15},{ yoyo: true, repeat: 1, duration: 1500, update: onPadding});
var bm4 = KUTE.to(box,{marginTop:50,marginLeft:50,marginBottom:70},{ yoyo: true, repeat: 1, duration: 1500, update: onMargin, complete: onComplete});
// chain the bms
@ -37,7 +37,7 @@ bm3.chain(bm4);
//callback functions
function onMarginTop() { var css = KUTE.gCS(box,'marginTop'); box.innerHTML = parseInt(css)+'px'+'<br>MARGIN'; }
function onMarginBottom() { var css = KUTE.gCS(box,'marginBottom'); box.innerHTML = 'MARGIN<br>'+parseInt(css)+'px'; }
function onPadding() { var css = KUTE.gCS(box,'paddingTop'); box.innerHTML = 'PADDING<br>'+parseInt(css)+'px'; }
function onPadding() { var css = KUTE.gCS(box,'paddingTop'); box.innerHTML = parseInt(css)+'px<br>PADDING'; }
function onMargin() { var css = KUTE.gCS(box,'marginTop'); box.innerHTML = 'MARGIN<br>'+parseInt(css)+'px'; }
function onComplete() { box.innerHTML = 'BOX<br>&nbsp;MODEL&nbsp;'; }
@ -115,16 +115,18 @@ var colTween2 = KUTE.to(colBoxElement, {borderTopColor: '#9C27B0'}, {duration: 1
var colTween3 = KUTE.to(colBoxElement, {borderRightColor: '#9C27B0'}, {duration: 1000});
var colTween4 = KUTE.to(colBoxElement, {borderBottomColor: '#9C27B0'}, {duration: 1000});
var colTween5 = KUTE.to(colBoxElement, {borderLeftColor: '#9C27B0'}, {duration: 1000});
var colTween6 = KUTE.to(colBoxElement, {outlineColor: '#9C27B0'}, {duration: 1000, repeat: 1, yoyo: true});
colTween1.chain(colTween2);
colTween2.chain(colTween3);
colTween3.chain(colTween4);
colTween4.chain(colTween5);
colTween5.chain(colTween6);
colbtn.addEventListener('click', function(e){
e.preventDefault();
!colTween1.playing && !colTween2.playing && !colTween3.playing && !colTween4.playing && !colTween5.playing && colTween1.start();
!colTween1.playing && !colTween2.playing && !colTween3.playing && !colTween4.playing && !colTween5.playing && !colTween6.playing && colTween1.start();
},false);
/* COLORS EXAMPLE */

View file

@ -39,7 +39,7 @@ for (var j=0; j<l; j++) {
} else if (es === 'multiPointBezier') {
tweenEasing2[_j]._e = KUTE.Physics.bezier({points: [{"x":0,"y":0,"cp":[{"x":0.387,"y":0.007}]},{"x":0.509,"y":0.48,"cp":[{"x":0.069,"y":0.874},{"x":0.928,"y":0.139}]},{"x":1,"y":1,"cp":[{"x":0.639,"y":0.988}]}] });
} else {
tweenEasing2[_j]._e = KUTE.pe(es);
tweenEasing2[_j]._e = KUTE.pe(es) || KUTE.Easing.linear;
}
}

View file

@ -60,8 +60,8 @@ var mixTransforms = document.getElementById('mixTransforms'),
mt1Tween = KUTE.to(mt1, {translateX:200,rotateX:360,rotateY:15,rotateZ:5}, { perspective:400, easing:'easingCubicInOut', yoyo:true, repeat: 1, duration:1500}),
mt2Tween = KUTE.to(mt2, {translateX:-200,rotateX:360,rotateY:15,rotateZ:5}, { easing:'easingCubicInOut', yoyo:true, repeat: 1, duration:1500});
mt1.style[tfo] = '50% 50% 50px'; mt1.style[tfp] = 'perspective(400px) translateX(0px) rotateX(0deg) rotateY(0deg) rotateZ(0deg)';
mt2.style[tfo] = '50% 50% 50px'; mt2.parentNode.style[pp] = '400px';
mt1.style[tfo] = '50% 50% 0px'; mt1.style[tfp] = 'perspective(400px) translateX(0px) rotateX(0deg) rotateY(0deg) rotateZ(0deg)';
mt2.style[tfo] = '50% 50% -200px'; mt2.parentNode.style[pp] = '400px';
skewBtn.addEventListener('click', function(){
!mt1Tween.playing && mt1Tween.start();
!mt2Tween.playing && mt2Tween.start();
@ -151,9 +151,9 @@ var colBox = document.getElementById('colBox'),
colbtn = colBox.querySelector('.btn');
var colTween1 = KUTE.to(colBoxElement, {color: '#9C27B0'}, {duration: 1000});
var colTween2 = KUTE.to(colBoxElement, {backgroundColor: '#069'}, {duration: 1000});
var colTween2 = KUTE.to(colBoxElement, {backgroundColor: '#069'}, {duration: 1000, keepHex: true});
var colTween3 = KUTE.to(colBoxElement, {color: '#fff'}, {duration: 1000});
var colTween4 = KUTE.to(colBoxElement, {backgroundColor: '#9C27B0'}, {duration: 1000});
var colTween4 = KUTE.to(colBoxElement, {backgroundColor: '#9C27B0'}, {duration: 1000, keepHex: true});
colTween1.chain(colTween2);
colTween2.chain(colTween3);
@ -272,7 +272,7 @@ easings.addEventListener('click',function(e){
} else if (es === 'multiPointBezier') {
tweenEasing2._e = KUTE.Physics.bezier({points: [{"x":0,"y":0,"cp":[{"x":0.387,"y":0.007}]},{"x":0.509,"y":0.48,"cp":[{"x":0.069,"y":0.874},{"x":0.928,"y":0.139}]},{"x":1,"y":1,"cp":[{"x":0.639,"y":0.988}]}] });
} else {
tweenEasing2._e = KUTE.pe(es);
tweenEasing2._e = KUTE.Easing[es] || KUTE.Easing.linear;
}
}
},false);

View file

@ -24,9 +24,8 @@
// filter unsupported browsers
if (!('boxShadow' in document.body.style)) {return;}
// add a reference to KUTE object
var K = window.KUTE;
var K = window.KUTE, unit = K.Interpolate.unit, colr = K.Interpolate.color;
// the preffixed boxShadow property, mostly for legacy browsers
// maybe the browser is supporting the property with its vendor preffix
@ -37,8 +36,8 @@
// for the .to() method, you need to prepareStart the boxShadow property
// which means you need to read the current computed value
K.prS['boxShadow'] = function(element,property,value){
var cssBoxShadow = K.gCS(element,'boxShadow');
return /^none$|^initial$|^inherit$|^inset$/.test(cssBoxShadow) ? '0px 0px 0px 0px rgb(0,0,0)' : cssBoxShadow;
var cssBoxShadow = K.gCS(element,_boxShadow);
return /^none$|^initial$|^inherit$|^inset$/.test(cssBoxShadow) ? '0px 0px 0px 0px rgb(0,0,0)' : cssBoxShadow;
}
// the processProperty for boxShadow
@ -50,23 +49,20 @@
// the DOM update function for boxShadow registers here
// we only enqueue it if the boxShadow property is used to tween
K.dom['boxShadow'] = function(w,p,v) {
K.dom['boxShadow'] = function(l,p,a,b,v) {
// let's start with the numbers | set unit | also determine inset
var numbers = [], unit = 'px', // the unit is always px
inset = w._vS[p][5] !== 'none' || w._vE[p][5] !== 'none' ? ' inset' : false;
var numbers = [], px = 'px', // the unit is always px
inset = a[5] !== 'none' || b[5] !== 'none' ? ' inset' : false;
for (var i=0; i<4; i++){
numbers.push( (w._vS[p][i] + (w._vE[p][i] - w._vS[p][i]) * v ) + unit);
numbers.push( unit( a[i], b[i], px, v ) );
}
// now we handle the color
var color, _color = {};
for (var c in w._vE[p][4]) {
_color[c] = parseInt(w._vS[p][4][c] + (w._vE[p][4][c] - w._vS[p][4][c]) * v )||0;
}
color = 'rgb(' + _color.r + ',' + _color.g + ',' + _color.b + ') ';
var colorValue = colr(a[4],b[4],v);
// the final piece of the puzzle, the DOM update
w._el.style[_boxShadow] = inset ? color + numbers.join(' ') + inset : color + numbers.join(' ');
l.style[_boxShadow] = inset ? colorValue + numbers.join(' ') + inset : colorValue + numbers.join(' ');
};
}

View file

@ -98,14 +98,14 @@ drawBtn.addEventListener('click', function(){
}, false);
// svgTransform examples
// // svgTransform examples
var svgRotate = document.getElementById('svgRotate');
var rotateBtn = document.getElementById('rotateBtn');
var svgr1 = svgRotate.getElementsByTagName('path')[0];
var svgr2 = svgRotate.getElementsByTagName('path')[1];
var svgTween11 = KUTE.to(svgr1, {svgTransform: { rotate: [-360,0,0] } }, {yoyo: true, repeat: 1, duration: 1500, easing: "easingCubicOut"});
var svgTween12 = KUTE.to(svgr2, {svgTransform: { translate: 580 , rotate: 360 } }, {yoyo: true, repeat: 1, duration: 1500, easing: "easingCubicOut"});
var svgTween11 = KUTE.to(svgr1, { rotate: 360 }, {transformOrigin: '50% 50%', yoyo: true, repeat: 1, duration: 1500, easing: "easingCubicOut"});
var svgTween12 = KUTE.to(svgr2, { svgTransform: { translate: 580, rotate: 360 } }, {yoyo: true, repeat: 1, duration: 1500, easing: "easingCubicOut"});
rotateBtn.addEventListener('click', function(){
!svgTween11.playing && svgTween11.start();
@ -116,8 +116,8 @@ var svgTranslate = document.getElementById('svgTranslate');
var translateBtn = document.getElementById('translateBtn');
var svgt1 = svgTranslate.getElementsByTagName('path')[0];
var svgt2 = svgTranslate.getElementsByTagName('path')[1];
var svgTween21 = KUTE.to(svgt1, {svgTransform: { translate: 580 } }, {yoyo: true, repeat: 1, duration: 1500, easing: "easingCubicOut"});
var svgTween22 = KUTE.to(svgt2, {svgTransform: { translate: 0 } }, {yoyo: true, repeat: 1, duration: 1500, easing: "easingCubicOut"});
var svgTween21 = KUTE.to(svgt1, { translate: 580 }, {yoyo: true, repeat: 1, duration: 1500, easing: "easingCubicOut"});
var svgTween22 = KUTE.to(svgt2, {svgTransform: { translate: [0,0] } }, {yoyo: true, repeat: 1, duration: 1500, easing: "easingCubicOut"});
translateBtn.addEventListener('click', function(){
!svgTween21.playing && svgTween21.start();
@ -128,26 +128,81 @@ var svgSkew = document.getElementById('svgSkew');
var skewBtn = document.getElementById('skewBtn');
var svgsk1 = svgSkew.getElementsByTagName('path')[0];
var svgsk2 = svgSkew.getElementsByTagName('path')[1];
var svgTween31 = KUTE.to(svgsk1, {svgTransform: { skewX: -15 } }, {yoyo: true, repeat: 1, duration: 1500, easing: "easingCubicOut"});
var svgTween32 = KUTE.to(svgsk2, {svgTransform: { translate: 580, skewY: 15 } }, {yoyo: true, repeat: 1, duration: 1500, easing: "easingCubicOut"});
var svgTween31 = KUTE.to(svgsk1, { skewX: -15 }, {transformOrigin: '0px 0px 0px',
// yoyo: true, repeat: 1,
duration: 1500, easing: "easingCubicOut"});
var svgTween311 = KUTE.to(svgsk1, { skewY: 15 }, {
// yoyo: true, repeat: 1,
duration: 1500, easing: "easingCubicOut"});
var svgTween313 = KUTE.to(svgsk1, { skewX: 0, skewY: 0 }, {
// yoyo: true, repeat: 1,
duration: 1500, easing: "easingCubicOut"});
var svgTween32 = KUTE.to(svgsk2, {svgTransform: { translate: 580, skewX: -15 } }, {
// yoyo: true, repeat: 1,
duration: 1500, easing: "easingCubicOut"});
var svgTween322 = KUTE.to(svgsk2, {svgTransform: { translate: 580, skewY: 15 } }, {
// yoyo: true, repeat: 1,
duration: 1500, easing: "easingCubicOut"});
var svgTween323 = KUTE.to(svgsk2, {svgTransform: { translate: 580, skewY: 0, skewX: 0 } }, {
// yoyo: true, repeat: 1,
duration: 1500, easing: "easingCubicOut"});
svgTween31.chain(svgTween311);
svgTween311.chain(svgTween313);
svgTween32.chain(svgTween322);
svgTween322.chain(svgTween323);
skewBtn.addEventListener('click', function(){
!svgTween31.playing && svgTween31.start();
!svgTween32.playing && svgTween32.start();
!svgTween31.playing && !svgTween311.playing && !svgTween313.playing && svgTween31.start();
!svgTween32.playing && !svgTween322.playing && !svgTween323.playing && svgTween32.start();
}, false);
var svgScale = document.getElementById('svgScale');
var scaleBtn = document.getElementById('scaleBtn');
var svgs1 = svgScale.getElementsByTagName('path')[0];
var svgs2 = svgScale.getElementsByTagName('path')[1];
var svgTween41 = KUTE.to(svgs1, {svgTransform: { scale: 1.5 } }, {yoyo: true, repeat: 1, duration: 1500, easing: "easingCubicOut"});
var svgTween42 = KUTE.to(svgs2, {svgTransform: { translate: 580, scale: 0.5 } }, {yoyo: true, repeat: 1, duration: 1500, easing: "easingCubicOut"});
var svgTween41 = KUTE.to(svgs1, { scale: 1.5 }, {transformOrigin: '50% 50%', yoyo: true, repeat: 1, duration: 1500, easing: "easingCubicOut"});
var svgTween42 = KUTE.to(svgs2, {svgTransform: {
translate: 580,
scale: 0.5,
} }, {yoyo: true, repeat: 1, duration: 1500, easing: "easingCubicOut"});
scaleBtn.addEventListener('click', function(){
!svgTween41.playing && svgTween41.start();
!svgTween42.playing && svgTween42.start();
}, false);
var svgMixed = document.getElementById('svgMixed');
var mixedBtn = document.getElementById('mixedBtn');
var svgm1 = svgMixed.getElementsByTagName('path')[0];
var svgm2 = svgMixed.getElementsByTagName('path')[1];
var svgTween51 = KUTE.to(svgm1, { // a regular transform without svg plugin
// svgTransform: {
translate: 250,
rotate: 360,
skewX: -25,
// skewY: 25,
scale: 1.5,
// }
}, {transformOrigin: "50% 50%", yoyo: true, repeat: 1, duration: 1500, easing: "easingCubicOut"});
var svgTween52 = KUTE.to(svgm2, {
svgTransform: {
translate: 580+250,
scale: 1.5,
rotate: 360,
skewX: -25,
// skewY: 25,
}
}, {yoyo: true, repeat: 1, duration: 1500, easing: "easingCubicOut"});
mixedBtn.addEventListener('click', function(){
!svgTween51.playing && svgTween51.start();
!svgTween52.playing && svgTween52.start();
}, false);
// fill HEX/RGBa
var tween1 = KUTE.to('#fillSVG', {fill: '#069'}, {duration: 1500, yoyo:true, repeat: 1});
@ -162,7 +217,7 @@ var tween3 = KUTE.to('#fillSVG',{strokeOpacity: 0.6}, {duration: 1500, yoyo:true
var tween4 = KUTE.to('#fillSVG',{fillOpacity: 0.2}, {yoyo:true, repeat: 1});
// strokeWidth Number
var tween5 = KUTE.to('#fillSVG',{strokeWidth: 0}, {duration: 1500, yoyo:true, repeat: 1});
var tween5 = KUTE.to('#fillSVG',{strokeWidth: '0px'}, {duration: 1500, yoyo:true, repeat: 1});
tween1.chain(tween4);
tween2.chain(tween3,tween5);

View file

@ -13,7 +13,7 @@ numBtn.addEventListener('click', function(){
// write text
var headText = document.getElementById('headText'),
headBtn = document.getElementById('headBtn'),
headTween = KUTE.to(headText, {text: "This is a <strong>super simple</strong> write text demo."}, {duration: 3000, easing: 'easingBounceOut'});
headTween = KUTE.to(headText, {text: "This is a <strong>super simple</strong> write text demo."}, {repeat: 1, yoyo: true, duration: 5000, easing: 'easingBounceOut'});
headBtn.addEventListener('click', function(){
!headTween.playing && headTween.start();
}, false);

View file

@ -118,7 +118,7 @@ var tween4 = KUTE.to('selector1',{margin:'5%'});
</code></pre>
<p>We're gonna chain these tweens and start the animation. You can download this example <a href='http://codepen.io/thednp/share/zip/xwqYbX/'>here</a>.</p>
<div id="boxModel" class="featurettes">
<div class="example-item example-box-model bg-lime" style="padding: 15px; font-size:26px">BOX<br>&nbsp;MODEL&nbsp;</div>
<div class="example-box example-box-model bg-lime" style="padding: 0; font-size:26px; line-height: 70px;">BOX<br>&nbsp;MODEL&nbsp;</div>
<div class="example-buttons">
<a class="btn btn-orange" href="#">Start</a>
@ -159,7 +159,7 @@ KUTE.to('selector1',{outlineColor:'#069'}).start();
<p>Let's get some animation going. Download the example <a href='http://codepen.io/thednp/share/zip/OypvNR/'>here</a>.</p>
<div id="colBox" class="featurettes">
<div class="example-item example-box bg-olive" style="outline: #222 solid 5px; width: 135px; height: 135px; border:15px solid #9C27B0; line-height: 105px; font-size:30px">Colors</div>
<div class="example-item example-box bg-olive" style="outline: #eee solid 5px; width: 135px; height: 135px; border:15px solid #9C27B0; line-height: 105px; font-size:30px">Colors</div>
<div class="example-buttons">
<a class="btn btn-blue" href="#">Start</a>

View file

@ -213,23 +213,29 @@ K.pp['boxShadow'] = function(property,value,element){
// the DOM update function for boxShadow registers here
// we only enqueue it if the boxShadow property is used to tween
if ( !('boxShadow' in K.dom) ) {
K.dom['boxShadow'] = function(w,p,v) {
K.dom['boxShadow'] = function(l,p,a,b,v) { // element, propertyName, valuesStart.boxShadow, valuesEnd.boxShadow, progress
// let's start with the numbers | set unit | also determine inset
var numbers = [], unit = 'px', // the unit is always px
inset = w._vS[p][5] !== 'none' || w._vE[p][5] !== 'none' ? ' inset' : false;
for (var i=0; i&lt;4; i++){
numbers.push( (w._vS[p][i] + (w._vE[p][i] - w._vS[p][i]) * v ) + unit);
var numbers = [], px = 'px', // the unit is always px
inset = a[5] !== 'none' || w._vE[p][5] !== 'none' ? ' inset' : false;
for (var i=0; i&lt;4; i++){ // for boxShadow coordinates we do the math for an array of numbers
numbers.push( (a[i] + (b[i] - a[i]) * v ) + px);
// we can also write this like this now, starting 1.5.3
// numbers.push( K.Interpolate.unit(a[i], b[i], px, v) );
}
// now we handle the color
var color, _color = {};
var colorValue, _color = {};
for (var c in w._vE[p][4]) {
_color[c] = parseInt(w._vS[p][4][c] + (w._vE[p][4][c] - w._vS[p][4][c]) * v )||0;
}
color = 'rgb(' + _color.r + ',' + _color.g + ',' + _color.b + ') ';
colorValue = 'rgb(' + _color.r + ',' + _color.g + ',' + _color.b + ') ';
// for color interpolation, starting with v1.5.3 we can cut it short to this
// var colorValue = K.Interpolate.color(a[5],b[5],v);
// last piece of the puzzle, the DOM update
w._el.style[_boxShadow] = inset ? color + numbers.join(' ') + inset : color + numbers.join(' ');
l.style[_boxShadow] = inset ? colorValue + numbers.join(' ') + inset : colorValue + numbers.join(' ');
};
}
@ -305,12 +311,15 @@ var myBSTween3 = KUTE.fromTo('selector', {boxShadow: [5, 5, 0, '#069', 'inset']}
<li><kbd class="bg-lime">KUTE.property(propertyName)</kbd> is the <strong>autoPrefix</strong> function that returns the property with the right vendor prefix, but only if required; on legacy browsers that don't support the property, the function returns <strong>undefinedPropertyName</strong> and that would be an easy way to detect support for that property on most legacy browsers: <pre><code class="language-javascript">if (/undefined/.test(KUTE.property('propertyName')) ) { /* legacy browsers */ } else { /* modern browsers */ }</code></pre></li>
<li><kbd class="bg-lime">KUTE.getPrefix()</kbd> returns a vendor preffix even if the browser supports a specific preffixed property or not.</li>
<li><kbd class="bg-lime">KUTE.gCS(element,property)</kbd> a hybrid <code>getComputedStyle</code> function to get the current value of the property required for the <code>.to()</code> method; it actually checks in <code>element.style</code>, <code>element.currentStyle</code> and <code>window.getComputedStyle(element,null)</code> to make sure it won't miss the property value;</li>
<li><kbd class="bg-lime">KUTE.gIS()</kbd> a <code>getInlineStyle</code> function to read the current inline style, very useful for transform, because decomposing a computed <strong>matrix</strong> would require a ton lot more code;</li>
<li><kbd class="bg-lime">KUTE.truD(value)</kbd> a function that accepts String and Number and returns a <code>{v: 150, u: 'px'}</code> object for any box model or a single numeric value based property and make it ready to tween.</li>
<li><kbd class="bg-lime">KUTE.truD(value)</kbd> a function that accepts String and Number and returns a <code>{v: 150, u: 'px'}</code> object for any box model or a single numeric value based property and make it ready to tween. When a second parameter is set to <i>true</i> it will return an object with value and unit specific for rotation angles and skews.</li>
<li><kbd class="bg-lime">KUTE.truC(color)</kbd> a function that returns an <code>{r: 150, g: 150, b: 0}</code> color object ready to tween; if the color value is a <a href="http://www.w3schools.com/colors/colors_names.asp" target="_blank">web safe color</a>, the IE9+ browsers will be able to return the rgb object we need.</li>
<li><kbd class="bg-lime">KUTE.htr(hex)</kbd> a function that accepts HEX formatted colors and returns an <code>{r: 150, g: 150, b: 0}</code> color object;</li>
<li><kbd class="bg-lime">KUTE.rth(r,g,b)</kbd> a function that accepts numeric values for red, blue and green and returns a HEX format <code>#006699</code> color string.</li>
</ul>
<li><kbd class="bg-lime">KUTE.Interpolate.number</kbd> is most essential interpolation tool when developing plugins for various properties not supported in the core.</li>
<li><kbd class="bg-lime">KUTE.Interpolate.unit</kbd> is used mainly for box model properties, text properties, and generally anything that's a string based valued. Like <code>width: 250px</code></li>
<li><kbd class="bg-lime">KUTE.Interpolate.color</kbd> is a very fast interpolation function for colors, as used in the above example.</li>
<li><kbd class="bg-lime">KUTE.Interpolate.array</kbd> and <kbd class="bg-lime">KUTE.Interpolate.coords</kbd> are SVG Plugin only, but you can have a look anytime when you're out of ideas.</li>
</ul>
<ul id="share" class="nav">
<li>Share </li>

View file

@ -119,6 +119,21 @@
<li><kbd class="bg-olive">scale</kbd> sub-property used to apply a single value size transformation. When using this sub-property, the <kbd class="bg-olive">translate</kbd> will be automatically adjusted to make sure the animation looks as you would expect it from a regular HTML5 element. Eg. <code>scale:0.5</code> will scale down a shape to half of it's initial size. <kbd class="bg-lime">IE9+</kbd></li>
</ul>
<h3>SVG Properties</h3>
<p>The <a href="svg.html">SVG Plugin</a> can animate the <code>d</code> attribute of a given <code>&lt;path&gt;</code> or <code>&lt;glyph&gt;</code> element with the tween property called <kbd class="bg-olive">path</kbd>. The animation effect is widelly known as morph SVG and implemented in various scripts, but the KUTE.js implementation is similar to <a href="http://bl.ocks.org/mbostock/3081153" target="_blank">the D3.js examples</a> for wider usability.</p>
<p>Further more, the SVG Plugin can animate the stroke in a way that you probably know as <code>drawSVG</code>. KUTE.js implements it as <kbd class="bg-olive">draw</kbd> tween property that deals with the well known CSS properties: <kbd>strokeDasharray</kbd> and <kbd>strokeDashoffset</kbd>.
<p>The SVG Plugin also manages animation for most useful CSS properties that are specific to SVG elements, since SMIL animations tend to go extinct, this plugin can get quite useful.</p>
<ul>
<li><kbd class="bg-olive">strokeWidth</kbd> allows you to animate the <code>stroke-width</code> for a given SVG element.</li>
<li><kbd class="bg-olive">strokeOpacity</kbd> allows you to animate the <code>stroke-opacity</code> for a given SVG element.</li>
<li><kbd class="bg-olive">fillOpacity</kbd> allows you to animate the <code>fill-opacity</code> for a given SVG element.</li>
<li><kbd class="bg-olive">stopOpacity</kbd> allows you to animate the <code>stop-opacity</code> for a given gradient SVG element.</li>
<li><kbd class="bg-olive">fill</kbd> allows you to animate the <code>fill</code> color property for a given SVG element.</li>
<li><kbd class="bg-olive">stroke</kbd> allows you to animate the <code>stroke</code> color for a given SVG element.</li>
<li><kbd class="bg-olive">stopColor</kbd> allows you to animate the <code>stop-color</code> for a given gradient SVG element.</li>
</ul>
<h3>Box Model Properties</h3>
<p>The core engine supports <code>width</code>, <code>height</code>, <code>left</code> and <code>top</code> while the <a href="css.html">CSS Plugin</a> adds support for all other box-model properties.</p>
<ul>
@ -152,21 +167,6 @@
<li><kbd class="bg-olive">borderTopColor</kbd>, <kbd class="bg-olive">borderRightColor</kbd>, <kbd class="bg-olive">borderBottomColor</kbd> and <kbd class="bg-olive">borderLeftColor</kbd> properties allow you to animate the color of the border on each side of a given element.</li>
</ul>
<p><strong>Remember</strong>: shorthands for <code>borderColor</code> property are not supported.</p>
<h3>SVG Properties</h3>
<p>The <a href="svg.html">SVG Plugin</a> can animate the <code>d</code> attribute of a given <code>&lt;path&gt;</code> or <code>&lt;glyph&gt;</code> element with the tween property called <kbd class="bg-olive">path</kbd>. The animation effect is widelly known as morph SVG and implemented in various scripts, but the KUTE.js implementation is similar to <a href="http://bl.ocks.org/mbostock/3081153" target="_blank">the D3.js examples</a> for wider usability.</p>
<p>Further more, the SVG Plugin can animate the stroke in a way that you probably know as <code>drawSVG</code>. KUTE.js implements it as <kbd class="bg-olive">draw</kbd> tween property that deals with the well known CSS properties: <kbd>strokeDasharray</kbd> and <kbd>strokeDashoffset</kbd>.
<p>The SVG Plugin also manages animation for most useful CSS properties that are specific to SVG elements, since SMIL animations tend to go extinct, this plugin can get quite useful.</p>
<ul>
<li><kbd class="bg-olive">strokeWidth</kbd> allows you to animate the <code>stroke-width</code> for a given SVG element.</li>
<li><kbd class="bg-olive">strokeOpacity</kbd> allows you to animate the <code>stroke-opacity</code> for a given SVG element.</li>
<li><kbd class="bg-olive">fillOpacity</kbd> allows you to animate the <code>fill-opacity</code> for a given SVG element.</li>
<li><kbd class="bg-olive">stopOpacity</kbd> allows you to animate the <code>stop-opacity</code> for a given gradient SVG element.</li>
<li><kbd class="bg-olive">fill</kbd> allows you to animate the <code>fill</code> color property for a given SVG element.</li>
<li><kbd class="bg-olive">stroke</kbd> allows you to animate the <code>stroke</code> color for a given SVG element.</li>
<li><kbd class="bg-olive">stopColor</kbd> allows you to animate the <code>stop-color</code> for a given gradient SVG element.</li>
</ul>
<h3>Presentation Attributes</h3>
<p>The <a href="attr.html">Attributes Plugin</a> can animate any numerical presentation attribute such as <kbd class="bg-olive">width</kbd>, <kbd class="bg-olive">cx</kbd> or <kbd class="bg-olive">stop-opacity</kbd>, but the values can be also suffixed: <code>150px</code> or <code>50%</code>, and for that you must always provide a string value that include the measurement unit, and that, of course, depends on the attribute. This plugin can be a great addition to the above SVG Plugin for specific gradient attributes or specific geometric shapes' attributes.</p>

View file

@ -21,7 +21,8 @@
}
}( function (KUTE) {
'use strict';
var K = window.KUTE;
var K = window.KUTE, DOM = K.dom, PP = K.pp, unit = K.Interpolate.unit, number = K.Interpolate.number;
// get current attribute value
K.gCA = function(e,a){
@ -35,35 +36,35 @@
}
return f;
};
// register the render attributes object
if (!('attr' in K.dom)) {
K.dom.attr = function(w,p,v){
for ( var o in w._vE[p] ){
K.dom.attr.prototype[o](w,o,v);
if (!('attr' in DOM)) {
DOM.attr = function(l,p,a,b,v) {
for ( var o in b ){
DOM.attr.prototype[o](l,o,a[o],b[o],v);
}
};
}
var ra = K.dom.attr.prototype;
var ra = DOM.attr.prototype;
// process attributes object K.pp.attr(t[x])
// and also register their render functions
K.pp['attr'] = function(a,o){
PP['attr'] = function(a,o){
var ats = {}, p;
for ( p in o ) {
if ( /%|px/.test(o[p]) ) {
var u = K.truD(o[p]).u, s = /%/.test(u) ? '_percent' : '_'+u;
if (!(p+s in ra)) {
ra[p+s] = function(w,p,v){
w._el.setAttribute(p.replace(s,''), (w._vS.attr[p].v + (w._vE.attr[p].v - w._vS.attr[p].v) * v) + w._vE.attr[p].u);
ra[p+s] = function(l,p,a,b,v) {
var _p = p.replace(s,'');
l.setAttribute(_p, unit(a.v,b.v,b.u,v) );
}
}
ats[p+s] = K.truD(o[p]);
} else {
if (!(p in ra)) {
ra[p] = function(w,p,v){
w._el.setAttribute(p, w._vS.attr[p] + (w._vE.attr[p]- w._vS.attr[p]) * v);
ra[p] = function(l,o,a,b,v) {
l.setAttribute(o, number(a,b,v));
}
}
ats[p] = o[p] * 1;

View file

@ -5,26 +5,6 @@
* optimized by dnp_theme 2015 MIT License
* Licensed under MIT-License
*/
// /* THIS IS THE OLD CODE */
// (function(kute_ea){
// // Obtain a reference to the base KUTE.
// // Since KUTE supports a variety of module systems,
// // we need to pick up which one to use.
// if(define == "function") {
// define(["./kute.js"], function(KUTE){ kute_ea(KUTE); return KUTE; });
// } else if(typeof module == "object" && typeof require == "function") {
// // We assume, that require() is sync.
// var KUTE = require("./kute.js");
// kute_ea(KUTE);
// // Export the modified one. Not really required, but convenient.
// module.exports = KUTE;
// } else if(typeof window.KUTE != "undefined") {
// kute_ea(window.KUTE);
// } else {
// throw new Error("KUTE.js Bezier/Easing depends on KUTE.js. Read the docs for more info.")
// }
// })(function(KUTE){
(function (factory) {
if (typeof define === 'function' && define.amd) {

View file

@ -16,7 +16,7 @@
throw new Error("CSS Plugin require KUTE.js.")
}
})(function(KUTE){
var K = window.KUTE, p,
var K = window.KUTE, p, DOM = K.dom, PP = K.pp,
_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)
@ -28,7 +28,8 @@
_clp = ['clip'], _bg = ['backgroundPosition'], // clip | background position
_mg = _rd.concat(_bm,_tp), // a merge of all properties with px|%|em|rem|etc unit
_all = _cls.concat(_clp, _rd, _bm, _tp, _bg), al = _all.length,
_all = _cls.concat(_clp, _rd, _bm, _tp, _bg), al = _all.length,
number = K.Interpolate.number, unit = K.Interpolate.unit, color = K.Interpolate.color,
_d = _d || {}; //all properties default values
//populate default values object
@ -48,26 +49,13 @@
// create prepare/process/render functions for additional colors properties
for (var i = 0, l = _cls.length; i<l; i++) {
p = _cls[i];
K.pp[p] = function(p,v) {
if ( (!(p in K.dom)) ) {
K.dom[p] = function(w,p,v) {
var _c = {};
for (var c in w._vE[p].value) {
if ( c !== 'a' ){
_c[c] = parseInt(w._vS[p].value[c] + (w._vE[p].value[c] - w._vS[p].value[c]) * v )||0;
} else {
_c[c] = (w._vS[p].value[c] && w._vE[p].value[c]) ? parseFloat(w._vS[p].value[c] + (w._vE[p].value[c] - w._vS[p].value[c]) * v) : null;
}
}
if ( w._hex ) {
w._el.style[p] = K.rth( _c.r, _c.g, _c.b );
} else {
w._el.style[p] = !_c.a || _isIE8 ? 'rgb(' + _c.r + ',' + _c.g + ',' + _c.b + ')' : 'rgba(' + _c.r + ',' + _c.g + ',' + _c.b + ',' + _c.a + ')';
}
PP[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 K.pp.cls(p,v);
return PP.cls(p,v);
};
K.prS[p] = function(el,p,v){
return K.gCS(el,p) || _d[p];
@ -77,13 +65,13 @@
// create prepare/process/render functions for additional box model properties
for (var i = 0, l = _mg.length; i<l; i++) {
p = _mg[i];
K.pp[p] = function(p,v){
if ( (!(p in K.dom)) ) {
K.dom[p] = function(w,p,v) {
w._el.style[p] = (w._vS[p].value + (w._vE[p].value - w._vS[p].value) * v ) + w._vE[p].unit;
};
}
return K.pp.box(p,v);
PP[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);
};
K.prS[p] = function(el,p,v){
return K.gCS(el,p) || _d[p];
@ -93,31 +81,31 @@
//create prepare/process/render functions for radius properties
for (var i = 0, l = _rd.length; i<l; i++) {
p = _rd[i];
K.pp[p] = function(p,v){
if ( (!(p in K.dom)) ) {
PP[p] = function(p,v){
if ( (!(p in DOM)) ) {
if (p === 'borderRadius') {
K.dom[p] = function(w,p,v) {
w._el.style[_br] = (w._vS[p].value + (w._vE[p].value - w._vS[p].value) * v ) + w._vE[p].unit;
};
DOM[p] = function(l,p,a,b,v){
l.style[_br] = unit(a.value,b.value,b.unit,v);
}
} else if (p === 'borderTopLeftRadius') {
K.dom[p] = function(w,p,v) {
w._el.style[_brtl] = (w._vS[p].value + (w._vE[p].value - w._vS[p].value) * v ) + w._vE[p].unit;
};
DOM[p] = function(l,p,a,b,v){
l.style[_brtl] = unit(a.value,b.value,b.unit,v);
}
} else if (p === 'borderTopRightRadius') {
K.dom[p] = function(w,p,v) {
w._el.style[_brtr] = (w._vS[p].value + (w._vE[p].value - w._vS[p].value) * v ) + w._vE[p].unit;
};
DOM[p] = function(l,p,a,b,v){
l.style[_brtr] = unit(a.value,b.value,b.unit,v);
}
} else if (p === 'borderBottomLeftRadius') {
K.dom[p] = function(w,p,v) {
w._el.style[_brbl] = (w._vS[p].value + (w._vE[p].value - w._vS[p].value) * v ) + w._vE[p].unit;
};
DOM[p] = function(l,p,a,b,v){
l.style[_brbl] = unit(a.value,b.value,b.unit,v);
}
} else if (p === 'borderBottomRightRadius') {
K.dom[p] = function(w,p,v) {
w._el.style[_brbr] = (w._vS[p].value + (w._vE[p].value - w._vS[p].value) * v ) + w._vE[p].unit;
};
DOM[p] = function(l,p,a,b,v){
l.style[_brbr] = unit(a.value,b.value,b.unit,v);
}
}
}
return K.pp.box(p,v);
return PP.box(p,v);
};
K.prS[p] = function(el,p,v){
return K.gCS(el,p) || _d[p];
@ -125,15 +113,15 @@
}
// clip
K.pp['clip'] = function(p,v){
if ( !(p in K.dom) ) {
K.dom[p] = function(w,p,v) {
PP['clip'] = function(p,v){
if ( !(p in DOM) ) {
DOM[p] = function(l,p,a,b,v) {
var h = 0, cl = [];
for (h;h<4;h++){
var c1 = w._vS[p][h].v, c2 = w._vE[p][h].v, cu = w._vE[p][h].u || 'px';
cl[h] = ((c1 + ( c2 - c1 ) * v)) + cu;
var c1 = a[h].v, c2 = b[h].v, cu = b[h].u || 'px';
cl[h] = unit(c1,c2,cu,v);
}
w._el.style[p] = 'rect('+cl+')';
l.style[p] = 'rect('+cl+')';
};
}
if ( v instanceof Array ){
@ -151,12 +139,10 @@
};
// background position
K.pp['backgroundPosition'] = function(p,v) {
if ( !(p in K.dom) ) {
K.dom[p] = function(w,p,v) {
var px1 = w._vS[p].x.v, px2 = w._vE[p].x.v, py1 = w._vS[p].y.v, py2 = w._vE[p].y.v,
px = (px1 + ( px2 - px1 ) * v), pxu = '%', py = (py1 + ( py2 - py1 ) * v), pyu = '%';
w._el.style[p] = px + pxu + ' ' + py + pyu;
PP['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);
};
}
if ( v instanceof Array ){

View file

@ -21,13 +21,24 @@
}
}( function (KUTE) {
'use strict';
var K = window.KUTE, S = S || {}, p,
var K = window.KUTE, S = S || {}, 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',
_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,
// interpolate functions
number = K.Interpolate.number, color = K.Interpolate.color,
array = function array(a,b,l,v) { // array1, array2, array2.length, progress
var na = [], i;
for(i=0;i<l;i++) { na.push( a[i] === b[i] ? b[i] : number(a[i],b[i],v) ); } // don't do math if not needed
return na;
},
coords = function coords(a,b,l,ll,o,v) { // array1, array2, array2.length, coordinates.length, joiner, progress for SVG stuff
var s = [], i;
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
@ -39,8 +50,7 @@
p.o = el.getAttribute('d');
} else if (!el && /[a-z][^a-z]*/ig.test(e)) { // maybe it's a string path already
var np = S.cP(e.trim());
p.e = np;
p.e = S.cP(e.trim());
p.o = e;
}
return p;
@ -48,11 +58,11 @@
S.pCr = function(w){ // pathCross
// path tween options
this._mpr = w.morphPrecision || 25;
this._midx = w.morphIndex;
this._smi = w.showMorphInfo;
this._rv1 = w.reverseFirstPath;
this._rv2 = w.reverseSecondPath;
this._mpr = w._ops.morphPrecision || 25;
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
@ -179,10 +189,7 @@
}
S.gOp = function(p){ // getOnePath, first path only
var a = p.split(/z/i);
if (a.length > 2) {
return a[0].trim() + 'z';
} else { return p.trim(); }
return p.split(/z/i).shift() + 'z';
}
S.cP = function (p){ // createPath
@ -216,7 +223,7 @@
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]; }
if (i === 0) { x+=np[i][0]; y +=np[i][1]; }
else {
x = np[i-1][0];
y = np[i-1][1];
@ -234,23 +241,16 @@
}
return np;
}
// a shortHand pathCross
K.svq = function(w){ if ( w._vE.path ) S.pCr(w); }
// a shortHand pathCross && SVG transform stack
K.svq = function(w){ if ( w._vE.path ) S.pCr(w); if ( w._vE.svgTransform ) S.sT(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);
if (!('path' in K.dom)) {
K.dom['path'] = function(w,p,v){
var points =[], i, l;
for(i=0,l=w._vE.path.d.length;i<l;i++) { // for each point
points[i] = [];
for(var j=0;j<2;j++) { // each point coordinate
points[i].push(w._vS.path.d[i][j]+(w._vE.path.d[i][j]-w._vS.path.d[i][j])*v);
}
}
w._el.setAttribute("d", v === 1 ? w._vE.path.o : 'M' + points.join('L') + 'Z' );
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);
@ -270,8 +270,8 @@
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,'strokeDashoffset'));
d = K.gCS(e,'strokeDasharray').split(/\,/);
o = parseFloat(K.gCS(e,'stroke-dashoffset'));
d = K.gCS(e,'stroke-dasharray').split(/\,/);
start = 0-o;
end = parseFloat(d[0]) + start || l;
@ -280,31 +280,27 @@
return { s: start, e: end, l: l }
};
S.pc = function(v,l){
S.pc = function(v,l){ // percent
return parseFloat(v) / 100 * l;
};
K.pp['draw'] = function(a,o,l){ // register the draw property
if (!('draw' in K.dom)) {
K.dom['draw'] = function(w,p,v){
var l, s, e, o;
l = w._vS.draw.l;
s = w._vS.draw.s+(w._vE.draw.s-w._vS.draw.s)*v;
e = w._vS.draw.e+(w._vE.draw.e-w._vS.draw.e)*v;
o = 0 - s;
w._el.style.strokeDashoffset = o +'px';
w._el.style.strokeDasharray = e+o<1 ? '0px, ' + l + 'px' : (e+o) + 'px, ' + l + 'px';
PP['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;
l.style.strokeDashoffset = o +'px';
l.style.strokeDasharray = e+o<1 ? '0px, ' + ll + 'px' : (e+o) + 'px, ' + ll + 'px';
}
}
return S.gDr(l,o);
return S.gDr(f,o);
}
K.prS['draw'] = function(el,p,v){
return S.gDr(el)
return S.gDr(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);
@ -325,7 +321,7 @@
return (w*2)+(h*2);
}
S.gPL = function(el){ // getPolygonLength - return the length of the Polygon / Polyline
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) {
@ -373,30 +369,16 @@
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];
K.pp[p] = function(p,v){
if (!(p in K.dom)) {
K.dom[p] = function(w,p,v){
var _c = {};
for (var c in w._vE[p]) {
if ( c !== 'a' ){
_c[c] = parseInt(w._vS[p][c] + (w._vE[p][c] - w._vS[p][c]) * v )||0;
} else {
_c[c] = (w._vS[p][c] && w._vE[p][c]) ? parseFloat(w._vS[p][c] + (w._vE[p][c] - w._vS[p][c]) * v) : null;
}
}
if ( w._hex ) {
w._el.style[p] = K.rth( _c.r, _c.g, _c.b );
} else {
w._el.style[p] = !_c.a ? 'rgb(' + _c.r + ',' + _c.g + ',' + _c.b + ')' : 'rgba(' + _c.r + ',' + _c.g + ',' + _c.b + ',' + _c.a + ')';
}
}
PP[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 K.truC(v);
}
@ -404,23 +386,25 @@
return K.gCS(el,p) || 'rgba(0,0,0,0)';
}
}
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'){
K.pp[p] = function(p,v){
if (!(p in K.dom)) {
K.dom[p] = function(w,p,v) {
w._el.style[p] = (w._vS[p].value + (w._vE[p].value - w._vS[p].value) * v) + w._vS[p].unit;
if (p === 'strokeWidth'){ // stroke can be unitless or unit | http://stackoverflow.com/questions/1301685/fixed-stroke-width-in-svg
PP[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 K.pp.box(p,v);
return /px|%|em|vh|vw/.test(v) ? PP.box(p,v) : parseFloat(v);
}
} else {
K.pp[p] = function(p,v){
if (!(p in K.dom)) {
K.dom[p] = function(w,p,v) {
w._el.style[p] = w._vS[p] + (w._vE[p] - w._vS[p]) * v;
PP[p] = function(p,v){
if (!(p in DOM)) {
DOM[p] = function(l,p,a,b,v) {
l.style[p] = number(a,b,v);
}
}
return parseFloat(v);
@ -432,72 +416,115 @@
}
// SVG Transform
K.pp['svgTransform'] = function(p,v,l){
PP['svgTransform'] = function(p,v,l){
// register the render function
if (!('svgTransform' in K.dom)) {
K.dom['svgTransform'] = function(w,p,v) {
if (!('svgTransform' in DOM)) {
DOM['svgTransform'] = function(l,p,a,b,v){
var tr = '', i;
for (i in w._vE[p]){
for (i in b){
tr += i + '('; // start string
if ( i === 'translate'){ // translate
tr += (w._vS[p][i][1] === w._vE[p][i][1] && w._vE[p][i][1] === 0 )
? (w._vS[p][i][0] + (w._vE[p][i][0] - w._vS[p][i][0]) * v )
: (w._vS[p][i][0] + (w._vE[p][i][0] - w._vS[p][i][0]) * v ) + ' ' + (w._vS[p][i][1] + (w._vE[p][i][1] - w._vS[p][i][1]) * v );
tr += (a[i][1] === b[i][1] && b[i][1] === 0 )
? number(a[i][0],b[i][0],v)
: number(a[i][0],b[i][0],v) + ' ' + number(a[i][1],b[i][1],v);
} else if ( i === 'rotate'){ // rotate
tr += w._vS[p][i][0] + (w._vE[p][i][0] - w._vS[p][i][0]) * v + ' ';
tr += !w.reversed ? w._vE[p][i][1] + ',' + w._vE[p][i][2] : w._vS[p][i][1] + ',' + w._vS[p][i][2]; // make sure to always use the right transform-origin
tr += number(a[i][0],b[i][0],v) + ' ';
tr += b[i][1] + ',' + b[i][2];
} else { // scale, skewX or skewY
tr += w._vS[p][i] + (w._vE[p][i] - w._vS[p][i]) * v;
tr += number(a[i],b[i],v);
}
tr += ') '; // end string
}
w._el.setAttributeNS(null,'transform', tr.replace(/\)\s$/,')') );
l.setAttribute('transform', tr.trim() );
}
}
// return transform object
var tf = {}, bb = l.getBBox(), cx = bb.x + bb.width/2, cy = bb.y + bb.height/2, i, r, t;
for ( i in v ) {
// now prepare transform
var tf = {}, bb = l.getBBox(), cx = bb.x + bb.width/2, cy = bb.y + bb.height/2, r, cr, t, ct;
for ( i in v ) { // populate the valuesStart and / or valuesEnd
if (i === 'rotate'){
r = v[i] instanceof Array ? v[i]
r = v[i] instanceof Array ? v[i]
: /\s/.test(v[i]) ? [v[i].split(' ')[0]*1, v[i].split(' ')[1].split(',')[0]*1, v[i].split(' ')[1].split(',')[1]*1]
: [v[i],cx,cy];
: [v[i]*1,cx,cy];
tf[i] = r;
} else if (i === 'translate'){
t = v[i] instanceof Array ? v[i] : /\s/.test(v[i]) ? v[i].split(' ') : [v[i],0];
tf[i] = [t[0] * 1||0, t[1] * 1];
t = v[i] instanceof Array ? v[i] : /\,|\s/.test(v[i]) ? v[i].split(/\,|\s/) : [v[i]*1,0];
tf[i] = [t[0] * 1||0, t[1] * 1||0];
} else if (i === 'scale'){
tf[i] = v[i] * 1||1;
} else {
} else if (/skew/.test(i)) {
tf[i] = v[i] * 1||0;
}
}
// try to adjust translation when scale is used, probably we should do the same when using skews, but I think it's a waste of time
// http://www.petercollingridge.co.uk/interactive-svg-components/pan-and-zoom-control
// try to adjust translation when scale is used
if ('scale' in tf) {
tf['translate'] = !( 'translate' in tf ) ? [0,0] : tf['translate'];
tf['translate'][0] += (1-tf['scale']) * bb.width/2;
!('translate' in tf) && ( tf['translate'] = [0,0] ); // if no translate is found in current value or next value, we default to 0
tf['translate'][0] += (1-tf['scale']) * bb.width/2;
tf['translate'][1] += (1-tf['scale']) * bb.height/2;
}
// adjust rotation transform origin and translation when skews are used, to make the animation look exactly the same as if we were't using svgTransform
// http://stackoverflow.com/questions/39191054/how-to-compensate-translate-when-skewx-and-skewy-are-used-on-svg/39192565#39192565
if ('rotate' in tf) {
tf['rotate'][1] -= 'skewX' in tf ? Math.tan(tf['skewX']) * bb.height : 0;
tf['rotate'][2] -= 'skewY' in tf ? Math.tan(tf['skewY']) * bb.width : 0;
}
tf['translate'][0] += 'skewX' in tf ? Math.tan(tf['skewX']) * bb.height*2 : 0;
tf['translate'][1] += 'skewY' in tf ? Math.tan(tf['skewY']) * bb.width*2 : 0;
} // more variations here https://gist.github.com/thednp/0b93068e20adb84658b5840ead0a07f8
return tf;
}
// KUTE.prepareStart K.prS[p](el,p,to[p])
// returns an obect with current transform attribute value
K.prS['svgTransform'] = function(l,p,t) {
var tr = {}, cta = l.getAttributeNS(null,'transform'),
ct = cta && /\)/.test(cta) ? cta.split(')') : 'none', i, j, ctr ={}, pr;
if (ct instanceof Array) {
for (j=0; j<ct.length; j++){
pr = ct[j].split('(');
pr[0] !== '' && (ctr[pr[0].replace(/\s/,'')] = pr[1] );
}
}
// find a value in current attribute value or add a default value
for (i in t) { tr[i] = i in ctr ? ctr[i] : 0; }
var tr = {}, i, ctr = S.pT(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

@ -16,42 +16,44 @@
throw new Error("Text-Plugin requires KUTE.js.");
}
}( function () {
var K = window.KUTE,
var K = window.KUTE, DOM = K.dom, PP = K.pp, number = K.Interpolate.number,
_s = String("abcdefghijklmnopqrstuvwxyz").split(""), // lowercase
_S = String("abcdefghijklmnopqrstuvwxyz".toUpperCase()).split(""), // uppercase
_sb = String("~!@#$%^&*()_+{}[];'<>,./?\=-").split(""), // symbols
_n = String("0123456789").split(""), // numeric
_a = _s.concat(_S,_n), // alpha numeric
_all = _a.concat(_sb), // all caracters
_r = Math.random, _f = Math.floor, _m = Math.min;
random = Math.random, floor = Math.floor, min = Math.min;
K.prS['text'] = K.prS['number'] = function(l,p,v){
return l.innerHTML;
}
K.pp['text'] = function(p,v,l) {
if ( !( 'text' in K.dom ) ) {
K.dom['text'] = function(w,p,v) {
var tp = tp || w.textChars === 'alpha' ? _s // textChars is alpha
: w.textChars === 'upper' ? _S // textChars is numeric
: w.textChars === 'numeric' ? _n // textChars is numeric
: w.textChars === 'alphanumeric' ? _a // textChars is alphanumeric
: w.textChars === 'symbols' ? _sb // textChars is symbols
: w.textChars ? w.textChars.split('') // textChars is a custom text
: _s, l = tp.length, s = w._vE[p],
t = tp[_f((_r() * l))], tx = '', f = s.substring(0);
PP['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 === 'numeric' ? _n // textChars is numeric
: o.textChars === 'alphanumeric' ? _a // textChars is alphanumeric
: o.textChars === 'symbols' ? _sb // textChars is symbols
: o.textChars ? o.textChars.split('') // textChars is a custom text
: _s, ll = tp.length,
t = tp[floor((random() * ll))], ix = '', tx = '', fi = a.substring(0), f = b.substring(0);
tx = f.substring(0,_f(_m(v * f.length, f.length)));
w._el.innerHTML = v < 1 ? tx+t : tx;
// use string.replace(/<\/?[^>]+(>|$)/g, "") to strip HTML tags while animating ?
ix = a !== '' ? fi.substring(fi.length,floor(min(v * fi.length, fi.length))) : ''; // initial text, A value
tx = f.substring(0,floor(min(v * f.length, f.length))); // end text, B value
l.innerHTML = v < 1 ? tx + t + ix : b;
}
}
return v;
}
K.pp['number'] = function(p,v,l) {
if ( !( 'number' in K.dom ) ) {
K.dom['number'] = function(w,p,v) {
w._el.innerHTML = parseInt(w._vS[p] + (w._vE[p] - w._vS[p]) * v);
PP['number'] = function(p,v,l) {
if ( !( 'number' in DOM ) ) {
DOM['number'] = function(l,p,a,b,v) {
l.innerHTML = parseInt( number(a, b, v));
}
}
return parseInt(v) || 0;

File diff suppressed because it is too large Load diff

View file

@ -23,7 +23,7 @@
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- Ion Icons -->
<link type="text/css" href="http://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css" rel="stylesheet">
<!--<link type="text/css" href="http://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css" rel="stylesheet">-->
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
@ -282,7 +282,7 @@ var morph4 = KUTE.fromTo('#startpath2', { path: '#startpath2' }, {
<li>When morphing subpaths/multipaths instead of cloning shapes to have same number of shapes in both starting and ending shapes, you should also consider a fade and/or scale animation to improve the overal animation performance, don't forget about mobile devices.</li>
<li>Large displays would need best resolution possible so a small <code>morphPrecision</code> value (1-10) would be required, assuming performant hardware are powering the displays. For small displays you can get quite comfortable with almost any value, including the default value.</li>
<li>Polygons with only <code>lineto</code> path commands are best for performance.</li>
<li>Faster animation speed could be a great trick to hide any polygonal "artefacts".</li>
<li>Faster animation speed could be a great trick to hide any polygonal "artefacts". Strokes are also very useful for hiding the polygons' edges.</li>
<li>Always use the <code>showMorphInfo:true</code> tween option to check how the values required for the morph change with every new option value, but <strong>never forget to disable it</strong> after you have optimized the morph to your liking, this option enables a function that detects the best index for points rotation that is very expensive and delays the animation for quite some time.</li>
<li>The SVG morph performance is the same for both <code>.to()</code> and <code>.fromTo()</code> methods, but the ones that use the second method will start faster, because the values have been prepared already and for the first method the processing of the two paths happens on tween start delaying the animation, so keep that in mind when working with syncing multiple tweens, the <code>.to()</code> based morph will always start later. Of course this assumes the you cache the tween objects first and start the animation later, if not (you start the animation on object creation), both methods will be delayed.</li>
</ul>
@ -314,13 +314,21 @@ var tween3 = KUTE.fromTo('selector1',{draw:'0% 100%'}, {draw:'50% 50%'});
<p>Remember: the <code>draw</code> property also accepts absolute values, eg. <code>draw: '0 150'</code>; the <code>.to()</code> method takes <code>0% 100%</code> as start value for your tweens when <code>stroke-dasharray</code> and <code>stroke-dashoffset</code> are not set.</p>
<h3>SVG Transforms</h3>
<p>Starting with KUTE.js 1.5.2, the SVG Plugin features a new tween property for cross browser transforms for SVG, but I decided to code a separate set of methods for SVG only, to keep performance tight. A very simple roadmap was described <a href="https://github.com/thednp/kute.js/issues/31" target="_blank">here</a>; in brief we needed to find a way to enable transforms for SVG in a <a href="https://css-tricks.com/transforms-on-svg-elements/" target="_blank">reliable and cross-browser</a> supported fashion. In that sense the plugin will allow you to animate SVG shapes via the <code>transform</code> presentation attribute and the <code class="bg-indigo">svgTransform</code> tween property. To make sure we don't mess up with the current methods, we changed the syntax a little bit:</p>
<pre><code class="language-javascript">// using all possible values
var tween1 = KUTE.to('selector', {svgTransform: { translate: [150,100], rotate: [45,0,0], skewX: 15, skewY: 20, scale: [1.2,1.3] }});
// using shorthand notations
var tween2 = KUTE.to('selector', {svgTransform: { translate: 120, rotate: 45, scale: 1.2 }});
<p>Starting with KUTE.js 1.5.2, the SVG Plugin features a new tween property for cross browser SVG transforms, but was coded as a separate set of methods for SVG only, to keep performance tight. A very simple roadmap was described <a href="https://github.com/thednp/kute.js/issues/31" target="_blank">here</a>; in brief we needed to find a way to enable transforms for SVG in a <a href="https://css-tricks.com/transforms-on-svg-elements/" target="_blank">reliable and cross-browser</a> supported fashion.</p>
<p>While you can still use regular <a href="examples.html">CSS3 transforms</a> for SVGs on browsers like Google Chrome and Firefox, to animate SVG shapes on all browsers, we use the <code>transform</code> presentation attribute and the <code class="bg-indigo">svgTransform</code> tween property with a special notation:</p>
<pre><code class="language-javascript">// regular CSS3 transforms apply to SVG elements, but not working in IE and some older Opera versions
var tween1 = KUTE.to('shape', { translate: [150,100], rotate: 45, skewX: 15, skewY: 20, scale: 1.5 }, {transformOrigin: "50% 50%"});
// using the svgTransform property, working in all browsers
// the Y translation as well as rotate transform-origin are provided
var tween2 = KUTE.to('shape', {svgTransform: { translate: [120,100], rotate: [45,0,0], skewX: 15, skewY: 20, scale: 1.2 }});
// OR using shorthand notations
// we understand the Y translation is 0 and the rotation transform-origin is 50% 50%,
// the center of the shape and not the parent SVG's center
var tween2 = KUTE.to('shape', {svgTransform: { translate: 120, rotate: 45, scale: 1.2 }});
</code></pre>
<p>As you can see we have some familiar notation as well as new notation. Let's break it down.</p>
<p>As you can see we have some familiar notation as well as new notation. One thing to know is that this feature may not support and wasn't tested for SVG specific chained/nested transformations. Perhaps the most important thing to remember is the fact that SVG tranformations always use SVG coordinates system, and the <code>transform</code> attribute requires no degree or pixel as measurement units. Let's break it down.</p>
<h4>SVG Rotation</h4>
<p>In our first example we'll have a look at rotations. For instance setting <code>rotate: [45,0,0]</code>, the first value is the angle to which the shape will rotate to and the other two values are coordinates for the <code>transform-origin</code>. When <code>rotate: 45</code> notation is used, the script will calculate the coordinates of the shape's central point, as if your <code>transform-origin</code> default value is <i>50% 50%</i>, something you would expect from regular HTML elements. However keep in mind that the <code>transform-origin</code> coordinates are relative to the parent <code>&lt;svg></code> element. Let's have a look at a quick demo:</p>
@ -334,19 +342,39 @@ var tween2 = KUTE.to('selector', {svgTransform: { translate: 120, rotate: 45, sc
<a id="rotateBtn" class="btn btn-red" href="javascript:void(0)">Start</a>
</div>
</div>
<p>The first tween uses the <code>rotate: [-360,0,0]</code> notation and the animation clearly shows the shape rotating around it's top left coordinate. The second tween uses the <code>rotate: 360</code> notation and the animation shows the shape rotating around it's own central point.</p>
<p>When for CSS3 <code>transforms</code> we could have used values such as <i>50% 50%</i> or <i>center bottom</i> as <code>transform-origin</code> and the entire processing was basically none, when it comes to SVG we need to make use of the SVG API functions to determine the proper value. But stay cool, here comes <code>.getBBox()</code> to the rescue! And here's how to:</p>
<pre><code class="language-javascript">// get the bounding box
var bb = element.getBBox(); // returns an object like {x:0, y:20, width:200, height: 200} for any type of shape
<p>The first tween uses the CSS3 transform notation and the animation clearly shows the shape rotating around it's center coordinate, as we've set <code>transformOrigin</code> option to <i>50% 50%</i>, but this animation doesn't work in all browsers. The second tween uses the <code>rotate: 360</code> notation and the animation shows the shape rotating around it's own central point, an animation that DO WORK in all SVG enabled browsers.</p>
<p>When for CSS3 transforms we could have used values such as <i>center bottom</i> as <code>transform-origin</code> (also not supported in all modern browsers), the entire processing was basically in/by the browser, however when it comes to SVG we need to make use of the SVG API functions to determine the proper value. But stay cool, here comes <code>.getBBox()</code> to the rescue! Here's how to rotate an element around it's <i>25% 75%</i> coordinate:</p>
<pre><code class="language-javascript">// rotate around element's "25% 75%"" coordinate as transform-origin
// get the bounding box
// returns an object like {x:0, y:20, width:200, height: 200} for any type of SVG shape
// x is the distance from top, y is the distance from left, width and height are just that
var bb = element.getBBox();
// determine the X point of transform-origin for 25%
var transformOriginX = bb.x + (25 * bb.width / 100);
var shapeOriginX = bb.x + (25 * bb.width / 100);
// determine the Y point of transform-origin for 75%
var transformOriginY = bb.y + (75 * bb.height / 100);
var shapeOriginY = bb.y + (75 * bb.height / 100);
// set your rotation tween with "25% 75%" transform-origin
var rotationTween = KUTE.to(element, {svgTransform: {rotate: [45, transformOriginX, transformOriginY]}});
// set your rotation tween with "25% 75%" transform-origin
var rotationTween = KUTE.to(element, {svgTransform: {rotate: [45, shapeOriginX, shapeOriginY]}});
</code></pre>
<p>Or you can rotate an element around the parent's <code>&lt;svg></code> <i>50% 50%</i> coordinate:</p>
<pre><code class="language-javascript">// rotate around parent svg's "50% 50%" coordinate as transform-origin
// get the bounding box
var svgBB = element.ownerSVGElement.getBBox(); // returns same object but it's for the parent &lt;svg> element
// determine the X point of transform-origin for 50%
var svgOriginX = svgBB.x + (50 * svgBB.width / 100);
// determine the Y point of transform-origin for 50%
var svgOriginY = svgBB.y + (50 * svgBB.height / 100);
// set your rotation tween with "50% 50%" transform-origin of the parent &lt;svg> element
var rotationTween = KUTE.to(element, {svgTransform: {rotate: [150, svgOriginX, svgOriginY]}});
</code></pre>
<h4>SVG Translation</h4>
@ -361,7 +389,7 @@ var rotationTween = KUTE.to(element, {svgTransform: {rotate: [45, transformOrigi
<a id="translateBtn" class="btn btn-blue" href="javascript:void(0)">Start</a>
</div>
</div>
<p>The first tween uses the <code>translate: [580,0]</code> notation and the second tween uses the <code>translate: 0</code> notation. Keep in mind that the values are unitless and are relative to the <code>viewBox</code> attribute.</p>
<p>The first tween uses the CSS3 <code>translate: 580</code> notation and the second tween uses the <code>translate: [0,0]</code> as <code class="bg-indigo">svgTransform</code> value. For the second example the values are unitless and are relative to the <code>viewBox</code> attribute.</p>
<h4>SVG Skew</h4>
<p>For skews for SVGs we have a very simple notation: <code>skewX: 25</code> or <code>skewY: -25</code> as SVGs don't support the <code>skew: [X,Y]</code> function. Here's a quick demo:</p>
@ -375,10 +403,11 @@ var rotationTween = KUTE.to(element, {svgTransform: {rotate: [45, transformOrigi
<a id="skewBtn" class="btn btn-red" href="javascript:void(0)">Start</a>
</div>
</div>
<p>The first tween skews the shape on X (horizontal) axis and the second tween skews the shape on Y (vertical) axis.</p>
<p>The first tween skews the shape on both X and Y axis in a chain via regular CSS3 transforms and the second tween skews the shape on X and Y axis via the <code class="bg-indigo">svgTransform</code> tween property. The example also showcases the fact that chain transformations for SVGs via <code>transform</code> attribute works just as for the CSS3 transformations and you really have to check the example code here to learn how to master this technique.</p>
<p>For this particular example we've set <code>transformOrigin</code> option to "0px 0px" for the first shape (the default value for SVGs' <i>transform-origin</i> on most browsers) because we cannot set anything similar for the skews of the <code>transform</code> attribute for the second shape. Generally skews are hard to handle for SVGs because they are independent of any <i>transform-origin</i>. We can only compensate with translation, <a href="http://stackoverflow.com/questions/39191054/how-to-compensate-translate-when-skewx-and-skewy-are-used-on-svg">a very complicated story</a>.</p>
<h4>SVG Scaling</h4>
<p>Our last transform example for SVGs is the scale. Unlike translations, for scale animation the plugin only accepts single value like <code>scale: 1.5</code>, for both X (horizontal) axis and Y (vertical) axis, to keep it simple and even if SVGs do support <code>scale(X,Y)</code>. But because the scaling on SVGs depends very much on the shape's position, the script will always try to adjust the translation to make the animation look as we would expect. A quick demo:</p>
<p>Another transform example for SVGs is the scale. Unlike translations, for scale animation the plugin only accepts single value like <code>scale: 1.5</code>, for both X (horizontal) axis and Y (vertical) axis, to keep it simple and even if SVGs do support <code>scale(X,Y)</code>. But because the scaling on SVGs depends very much on the shape's position, the script will always try to adjust the translation to make the animation look as we would expect. A quick demo:</p>
<div class="featurettes">
<svg id="svgScale" class="example-box-model example-box" style="width:320px; overflow: visible;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1085 513">
<path class="bg-lime" d="M426.671 0h-341.328c-46.937 0-85.343 38.405-85.343 85.345v341.311c0 46.969 38.406 85.344 85.343 85.344h341.328c46.938 0 85.329-38.375 85.329-85.345v-341.31c0-46.94-38.391-85.345-85.329-85.345z"></path>
@ -389,15 +418,29 @@ var rotationTween = KUTE.to(element, {svgTransform: {rotate: [45, transformOrigi
<a id="scaleBtn" class="btn btn-pink" href="javascript:void(0)">Start</a>
</div>
</div>
<p>The first tween scales the shape at <code>scale: 1.5</code> and the second tween scales down the shape at <code>scale: 0.5</code> value. If you inspect the elements, you will notice for both shapes translation is involved, and this is to keep <code>transform-origin</code> at an expected <i>50% 50%</i> value, well, approximately.</p>
<p>The first tween scales the shape at <code>scale: 1.5</code> via regular CSS3 transforms, and the second tween scales down the shape at <code>scale: 0.5</code> value via <code class="bg-indigo">svgTransform</code>. If you inspect the elements, you will notice for the second shape translation is involved, and this is to keep <code>transform-origin</code> at an expected <i>50% 50%</i> value. A similar case as with the skews.</p>
<h4>SVG Mixed Transforms</h4>
<p>Our last transform example for SVGs is the mixed transformation. Similar with scale animation the plugin will try to adjust the rotation <code>transform-origin</code> to make it look as you would expect it from regular HTML elements. Let's combine 3 functions at the same time and see what happens:</p>
<div class="featurettes">
<svg id="svgMixed" class="example-box-model example-box" style="width: 320px; overflow: visible;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1085 513" xmlns:xml="http://www.w3.org/XML/1998/namespace" xml:space="preserve" version="1.1">
<path class="bg-green" d="M426.671 0h-341.328c-46.937 0-85.343 38.405-85.343 85.345v341.311c0 46.969 38.406 85.344 85.343 85.344h341.328c46.938 0 85.329-38.375 85.329-85.345v-341.31c0-46.94-38.391-85.345-85.329-85.345z"></path>
<path class="bg-indigo" transform="translate(580)" d="M426.671 0h-341.328c-46.937 0-85.343 38.405-85.343 85.345v341.311c0 46.969 38.406 85.344 85.343 85.344h341.328c46.938 0 85.329-38.375 85.329-85.345v-341.31c0-46.94-38.391-85.345-85.329-85.345z"></path>
</svg>
<div class="example-buttons">
<a id="mixedBtn" class="btn btn-teal" href="javascript:void(0)">Start</a>
</div>
</div>
<p>Both shapes are scaled at <code>scale: 1.5</code>, translated to <code>translate: 250</code> and skewed at <code>skewX: -15</code>. If you inspect the elements, you will notice the second shape's translation is different from what we've set in the tween object, and this is to keep <code>transform-origin</code> at an expected <i>50% 50%</i> value. This means that the plugin will also compensate rotation transform origin when skews are used, so that both CSS3 transform property and SVG transform attribute have an identical animation.</p>
<h4>Recommendations for SVG Transforms</h4>
<ul>
<li>To make sure animations don't go out of control, <b>always use same order of transform properties</b>: <code>translate</code>, <code>rotate</code>, <code>skewX</code>, <code>skewY</code>, <code>scale</code>.</li>
<li>The SVG Plugin coming with KUTE.js version 1.5.3 is trying to make sure animations don't go out of control, but you need to <b>always use same order of transform functions</b>: <code>translate</code>, <code>scale</code>, <code>rotate</code>, <code>skewX</code> and <code>skewY</code>. All this to make sure the animation looks like we would expect from regular HTML elements transformations. Maybe future versions will feature <code>.matrix()</code> transformations to handle all possible transform function combinations, but I'm going to need help with implementation and testing.</li>
<li>Keep in mind the adjustments required for rotations, remember the <code>.getBBox()</code> method, it's really useful to set custom <code>transform-origin</code>.</li>
<li>By default browsers use <code>overflow: hidden</code> for <code>&lt;svg></code> so child elements are partially/completelly hidden while animating. You might want to set <code>overflow: visible</code> if that is the case or some browser specific tricks.</li>
<li>By default browsers use <code>overflow: hidden</code> for <code>&lt;svg></code> so child elements are partialy/completely hidden while animating. You might want to set <code>overflow: visible</code> or some browser specific tricks if that is the case.</li>
<li>When using <code>viewBox="0 0 500 500"</code> attribute for <code>&lt;svg></code> and no <code>width</code> and/or <code>height</code> attribute(s), means that you expect the SVG to be scalable and most Internet Explorer versions simply don't work. You might want to <a href="https://css-tricks.com/scale-svg/" target="_blank">check this tutorial</a>.</li>
<li>Unlike the CSS3 <code class="bg-indigo">transform</code> animation featured in the core engine, the <code class="bg-indigo">svgTransform</code> feature does not stack properties for chains of tween objects created with the <code>.to()</code> method, you will have to provide all properties that you need in all chained tweens.</li>
<li>Similar to the CSS3 transform animation featured in the core engine, the <code class="bg-indigo">svgTransform</code> property DOES stack transform functions for chained tween objects created with the <code>.to()</code> method, you will have to provide only values for the functions that will change and the plugin will try to keep the unchanged values. However, there's a catch: you need to follow the properties that change and I highly recommend checking the example code for skews in the <a href="./assets/js/svg.js">svg.js</a> file.</li>
<li>In other cases when you need maximum control and precision or when shapes are already affected by translation, you might want to use the <code>.fromTo()</code> method with all proper values.</li>
<li>Also the <code class="bg-indigo">svgTransform</code> feature does not support 3D transforms, because they are not supported in all browsers.</li>
<li>Rotations will always use the <i>valuesEnd</i> value of the transform origin and cannot be animated, so that translations don't get messed up.</li>
@ -417,8 +460,8 @@ var tween3 = KUTE.to('selector',{stroke: 'rgba(00,66,99,0.8)'});
// strokeOpacity Number 0-1
var tween4 = KUTE.to('selector',{strokeOpacity: 0.6});
// strokeWidth Number
var tween5 = KUTE.to('selector',{strokeWidth: 10});
// strokeWidth Number / String
var tween5 = KUTE.to('selector',{strokeWidth: '10px'});
</code></pre>
<p>A quick demo with the above:</p>
<div class="featurettes">
@ -431,7 +474,7 @@ var tween5 = KUTE.to('selector',{strokeWidth: 10});
<a id="cssBtn" class="btn btn-orange" href="javascript:void(0)">Start</a>
</div>
</div>
<p>Please note that <code>strokeWidth</code> is a very unique property that acts very different: when number is provided the rendered stroke will scale depending on <code>viewBox</code> and/or <code>width</code> and <code>height</code>, but if String is provided you can actually force the browser to <a href="http://stackoverflow.com/questions/1301685/fixed-stroke-width-in-svg" target="_blank">scale the stroke</a> as you like.</p>
<p>Now let's have a look at gradients, here we can animate the <code>stopColor</code> defined within the SVG's <code>&lt;linearGradient&gt;</code> element.</p>
<pre><code class="language-markup">&lt;linearGradient id="gradient1" x1="0%" y1="0%" x2="0%" y2="100%">
&lt;stop offset="0%" style="stop-color: #ffd626; stop-opacity:1">&lt;/stop>

View file

@ -1,2 +1,2 @@
// Attributes Plugin for KUTE.js | dnp_theme | MIT License
!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=window.KUTE;e.gCA=function(t,e){return t.getAttribute(e)},e.prS.attr=function(t,r,n){var i={};for(var o in n)i[o.replace(/_+[a-z]+/,"")]=e.gCA(t,o.replace(/_+[a-z]+/,""));return i},"attr"in e.dom||(e.dom.attr=function(t,r,n){for(var i in t._vE[r])e.dom.attr.prototype[i](t,i,n)});var r=e.dom.attr.prototype;e.pp.attr=function(t,n){var i,o={};for(i in n)if(/%|px/.test(n[i])){var u=e.truD(n[i]).u,a=/%/.test(u)?"_percent":"_"+u;i+a in r||(r[i+a]=function(t,e,r){t._el.setAttribute(e.replace(a,""),t._vS.attr[e].v+(t._vE.attr[e].v-t._vS.attr[e].v)*r+t._vE.attr[e].u)}),o[i+a]=e.truD(n[i])}else i in r||(r[i]=function(t,e,r){t._el.setAttribute(e,t._vS.attr[e]+(t._vE.attr[e]-t._vS.attr[e])*r)}),o[i]=1*n[i];return o}});
(function(c){if("function"===typeof define&&define.amd)define(["./kute.js"],function(a){c(a);return a});else if("object"==typeof module&&"function"==typeof require){var a=require("./kute.js");module.exports=c(a)}else if("undefined"!==typeof window.KUTE)c(a);else throw Error("Attributes Plugin require KUTE.js.");})(function(c){var a=window.KUTE,e=a.dom;c=a.pp;var k=a.Interpolate.unit,l=a.Interpolate.number;a.gCA=function(a,d){return a.getAttribute(d)};a.prS.attr=function(c,d,h){d={};for(var b in h)d[b.replace(/_+[a-z]+/,"")]=a.gCA(c,b.replace(/_+[a-z]+/,""));return d};"attr"in e||(e.attr=function(a,d,c,b,g){for(var f in b)e.attr.prototype[f](a,f,c[f],b[f],g)});var g=e.attr.prototype;c.attr=function(c,d){var h={},b;for(b in d)if(/%|px/.test(d[b])){var e=a.truD(d[b]).u,f=/%/.test(e)?"_percent":"_"+e;b+f in g||(g[b+f]=function(a,b,d,c,e){b=b.replace(f,"");a.setAttribute(b,k(d.v,c.v,c.u,e))});h[b+f]=a.truD(d[b])}else b in g||(g[b]=function(a,b,c,d,e){a.setAttribute(b,l(c,d,e))}),h[b]=1*d[b];return h}});

View file

@ -1,2 +1,2 @@
// Bezier Easing Functions for KUTE.js | dnp_theme | MIT License
!function(n){if("function"==typeof define&&define.amd)define(["./kute.js"],function(e){return n(e),e});else if("object"==typeof module&&"function"==typeof require){var e=require("./kute.js");module.exports=n(e)}else{if("undefined"==typeof window.KUTE)throw new Error("Bezier Easing functions depend on KUTE.js. Read the docs for more info.");window.KUTE.Ease=window.KUTE.Ease||n(e)}}(function(n){"use strict";var e=e||{};e.Bezier=function(n,e,r,u){return t.pB(n,e,r,u)};var t=e.Bezier.prototype;return t.ni=4,t.nms=.001,t.sp=1e-7,t.smi=10,t.ksts=11,t.ksss=1/(t.ksts-1),t.f32as="Float32Array"in window,t.msv=t.f32as?new Float32Array(t.ksts):new Array(t.ksts),t.A=function(n,e){return 1-3*e+3*n},t.B=function(n,e){return 3*e-6*n},t.C=function(n){return 3*n},t.r={},t.pB=function(n,e,r,u){this._p=!1;var i=this;return t.r=function(s){return i._p||t.pc(n,r,e,u),n===e&&r===u?s:0===s?0:1===s?1:t.cB(t.gx(s,n,r),e,u)},t.r},t.cB=function(n,e,r){return((t.A(e,r)*n+t.B(e,r))*n+t.C(e))*n},t.gS=function(n,e,r){return 3*t.A(e,r)*n*n+2*t.B(e,r)*n+t.C(e)},t.bS=function(n,e,r,u,i){var s,o,c=0,f=t.sp,a=t.smi;do o=e+(r-e)/2,s=t.cB(o,u,i)-n,s>0?r=o:e=o;while(Math.abs(s)>f&&++c<a);return o},t.nri=function(n,e,r,u){var i=0,s=t.ni;for(i;s>i;++i){var o=t.gS(e,r,u);if(0===o)return e;var c=t.cB(e,r,u)-n;e-=c/o}return e},t.csv=function(n,e){var r=0,u=t.ksts;for(r;u>r;++r)t.msv[r]=t.cB(r*t.ksss,n,e)},t.gx=function(n,e,r){for(var u=0,i=1,s=t.ksts-1;i!=s&&t.msv[i]<=n;++i)u+=t.ksss;--i;var o=(n-t.msv[i])/(t.msv[i+1]-t.msv[i]),c=u+o*t.ksss,f=t.gS(c,e,r),a=u+t.ksss;return f>=t.nms?t.nri(n,c,e,r):0===f?c:t.bS(n,u,a,e,r)},t.pc=function(n,e,r,u){this._p=!0,(n!=r||e!=u)&&t.csv(n,e)},e.easeIn=function(){return t.pB(.42,0,1,1)},e.easeOut=function(){return t.pB(0,0,.58,1)},e.easeInOut=function(){return t.pB(.5,.16,.49,.86)},e.easeInSine=function(){return t.pB(.47,0,.745,.715)},e.easeOutSine=function(){return t.pB(.39,.575,.565,1)},e.easeInOutSine=function(){return t.pB(.445,.05,.55,.95)},e.easeInQuad=function(){return t.pB(.55,.085,.68,.53)},e.easeOutQuad=function(){return t.pB(.25,.46,.45,.94)},e.easeInOutQuad=function(){return t.pB(.455,.03,.515,.955)},e.easeInCubic=function(){return t.pB(.55,.055,.675,.19)},e.easeOutCubic=function(){return t.pB(.215,.61,.355,1)},e.easeInOutCubic=function(){return t.pB(.645,.045,.355,1)},e.easeInQuart=function(){return t.pB(.895,.03,.685,.22)},e.easeOutQuart=function(){return t.pB(.165,.84,.44,1)},e.easeInOutQuart=function(){return t.pB(.77,0,.175,1)},e.easeInQuint=function(){return t.pB(.755,.05,.855,.06)},e.easeOutQuint=function(){return t.pB(.23,1,.32,1)},e.easeInOutQuint=function(){return t.pB(.86,0,.07,1)},e.easeInExpo=function(){return t.pB(.95,.05,.795,.035)},e.easeOutExpo=function(){return t.pB(.19,1,.22,1)},e.easeInOutExpo=function(){return t.pB(1,0,0,1)},e.easeInCirc=function(){return t.pB(.6,.04,.98,.335)},e.easeOutCirc=function(){return t.pB(.075,.82,.165,1)},e.easeInOutCirc=function(){return t.pB(.785,.135,.15,.86)},e.easeInBack=function(){return t.pB(.6,-.28,.735,.045)},e.easeOutBack=function(){return t.pB(.175,.885,.32,1.275)},e.easeInOutBack=function(){return t.pB(.68,-.55,.265,1.55)},e.slowMo=function(){return t.pB(0,.5,1,.5)},e.slowMo1=function(){return t.pB(0,.7,1,.3)},e.slowMo2=function(){return t.pB(0,.9,1,.1)},e});
(function(k){if("function"===typeof define&&define.amd)define(["./kute.js"],function(a){k(a);return a});else if("object"==typeof module&&"function"==typeof require){var b=require("./kute.js");module.exports=k(b)}else if("undefined"!==typeof window.KUTE)window.KUTE.Ease=window.KUTE.Ease||k(b);else throw Error("Bezier Easing functions depend on KUTE.js. Read the docs for more info.");})(function(k){var b=b||{};b.Bezier=function(b,c,d,e){return a.pB(b,c,d,e)};var a=b.Bezier.prototype;a.ni=4;a.nms=.001;a.sp=1E-7;a.smi=10;a.ksts=11;a.ksss=1/(a.ksts-1);a.f32as="Float32Array"in window;a.msv=a.f32as?new Float32Array(a.ksts):Array(a.ksts);a.A=function(a,b){return 1-3*b+3*a};a.B=function(a,b){return 3*b-6*a};a.C=function(a){return 3*a};a.r={};a.pB=function(b,c,d,e){this._p=!1;var f=this;a.r=function(g){f._p||a.pc(b,d,c,e);return b===c&&d===e?g:0===g?0:1===g?1:a.cB(a.gx(g,b,d),c,e)};return a.r};a.cB=function(b,c,d){return((a.A(c,d)*b+a.B(c,d))*b+a.C(c))*b};a.gS=function(b,c,d){return 3*a.A(c,d)*b*b+2*a.B(c,d)*b+a.C(c)};a.bS=function(b,c,d,e,f){var g,h,k=0,l=a.sp,m=a.smi;do h=c+(d-c)/2,g=a.cB(h,e,f)-b,0<g?d=h:c=h;while(Math.abs(g)>l&&++k<m);return h};a.nri=function(b,c,d,e){var f=0,g=a.ni;for(f;f<g;++f){var h=a.gS(c,d,e);if(0===h)break;var k=a.cB(c,d,e)-b;c-=k/h}return c};a.csv=function(b,c){var d=0,e=a.ksts;for(d;d<e;++d)a.msv[d]=a.cB(d*a.ksss,b,c)};a.gx=function(b,c,d){for(var e=0,f=1,g=a.ksts-1;f!=g&&a.msv[f]<=b;++f)e+=a.ksss;--f;var f=e+(b-a.msv[f])/(a.msv[f+1]-a.msv[f])*a.ksss,g=a.gS(f,c,d),h=e+a.ksss;return g>=a.nms?a.nri(b,f,c,d):0===g?f:a.bS(b,e,h,c,d)};a.pc=function(b,c,d,e){this._p=!0;b==d&&c==e||a.csv(b,c)};b.easeIn=function(){return a.pB(.42,0,1,1)};b.easeOut=function(){return a.pB(0,0,.58,1)};b.easeInOut=function(){return a.pB(.5,.16,.49,.86)};b.easeInSine=function(){return a.pB(.47,0,.745,.715)};b.easeOutSine=function(){return a.pB(.39,.575,.565,1)};b.easeInOutSine=function(){return a.pB(.445,.05,.55,.95)};b.easeInQuad=function(){return a.pB(.55,.085,.68,.53)};b.easeOutQuad=function(){return a.pB(.25,.46,.45,.94)};b.easeInOutQuad=function(){return a.pB(.455,.03,.515,.955)};b.easeInCubic=function(){return a.pB(.55,.055,.675,.19)};b.easeOutCubic=function(){return a.pB(.215,.61,.355,1)};b.easeInOutCubic=function(){return a.pB(.645,.045,.355,1)};b.easeInQuart=function(){return a.pB(.895,.03,.685,.22)};b.easeOutQuart=function(){return a.pB(.165,.84,.44,1)};b.easeInOutQuart=function(){return a.pB(.77,0,.175,1)};b.easeInQuint=function(){return a.pB(.755,.05,.855,.06)};b.easeOutQuint=function(){return a.pB(.23,1,.32,1)};b.easeInOutQuint=function(){return a.pB(.86,0,.07,1)};b.easeInExpo=function(){return a.pB(.95,.05,.795,.035)};b.easeOutExpo=function(){return a.pB(.19,1,.22,1)};b.easeInOutExpo=function(){return a.pB(1,0,0,1)};b.easeInCirc=function(){return a.pB(.6,.04,.98,.335)};b.easeOutCirc=function(){return a.pB(.075,.82,.165,1)};b.easeInOutCirc=function(){return a.pB(.785,.135,.15,.86)};b.easeInBack=function(){return a.pB(.6,-.28,.735,.045)};b.easeOutBack=function(){return a.pB(.175,.885,.32,1.275)};b.easeInOutBack=function(){return a.pB(.68,-.55,.265,1.55)};b.slowMo=function(){return a.pB(0,.5,1,.5)};b.slowMo1=function(){return a.pB(0,.7,1,.3)};b.slowMo2=function(){return a.pB(0,.9,1,.1)};return b});

View file

@ -1,2 +1,2 @@
// CSS Plugin for KUTE.js | dnp_theme | MIT License
!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.property("borderRadius"),i=e.property("borderTopLeftRadius"),n=e.property("borderTopRightRadius"),u=e.property("borderBottomLeftRadius"),d=e.property("borderBottomRightRadius"),a=["borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","outlineColor"],v=["borderRadius","borderTopLeftRadius","borderTopRightRadius","borderBottomLeftRadius","borderBottomRightRadius"],l=["right","bottom","minWidth","minHeight","maxWidth","maxHeight","padding","margin","paddingTop","paddingBottom","paddingLeft","paddingRight","marginTop","marginBottom","marginLeft","marginRight","borderWidth","borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth","outlineWidth"],p=["fontSize","lineHeight","letterSpacing","wordSpacing"],f=["clip"],g=["backgroundPosition"],_=v.concat(l,p),s=a.concat(f,v,l,p,g),c=s.length,b=b||{},m=0;c>m;m++)r=s[m],-1!==a.indexOf(r)?b[r]="rgba(0,0,0,0)":-1!==_.indexOf(r)?b[r]=0:-1!==g.indexOf(r)?b[r]=[50,50]:"clip"===r&&(b[r]=[0,0,0,0]);for(var m=0,S=a.length;S>m;m++)r=a[m],e.pp[r]=function(t,r){return t in e.dom||(e.dom[t]=function(t,r,o){var i={};for(var n in t._vE[r].value)"a"!==n?i[n]=parseInt(t._vS[r].value[n]+(t._vE[r].value[n]-t._vS[r].value[n])*o)||0:i[n]=t._vS[r].value[n]&&t._vE[r].value[n]?parseFloat(t._vS[r].value[n]+(t._vE[r].value[n]-t._vS[r].value[n])*o):null;t._hex?t._el.style[r]=e.rth(i.r,i.g,i.b):t._el.style[r]=!i.a||_isIE8?"rgb("+i.r+","+i.g+","+i.b+")":"rgba("+i.r+","+i.g+","+i.b+","+i.a+")"}),e.pp.cls(t,r)},e.prS[r]=function(t,r,o){return e.gCS(t,r)||b[r]};for(var m=0,S=_.length;S>m;m++)r=_[m],e.pp[r]=function(t,r){return t in e.dom||(e.dom[t]=function(t,r,e){t._el.style[r]=t._vS[r].value+(t._vE[r].value-t._vS[r].value)*e+t._vE[r].unit}),e.pp.box(t,r)},e.prS[r]=function(t,r,o){return e.gCS(t,r)||b[r]};for(var m=0,S=v.length;S>m;m++)r=v[m],e.pp[r]=function(t,r){return t in e.dom||("borderRadius"===t?e.dom[t]=function(t,r,e){t._el.style[o]=t._vS[r].value+(t._vE[r].value-t._vS[r].value)*e+t._vE[r].unit}:"borderTopLeftRadius"===t?e.dom[t]=function(t,r,e){t._el.style[i]=t._vS[r].value+(t._vE[r].value-t._vS[r].value)*e+t._vE[r].unit}:"borderTopRightRadius"===t?e.dom[t]=function(t,r,e){t._el.style[n]=t._vS[r].value+(t._vE[r].value-t._vS[r].value)*e+t._vE[r].unit}:"borderBottomLeftRadius"===t?e.dom[t]=function(t,r,e){t._el.style[u]=t._vS[r].value+(t._vE[r].value-t._vS[r].value)*e+t._vE[r].unit}:"borderBottomRightRadius"===t&&(e.dom[t]=function(t,r,e){t._el.style[d]=t._vS[r].value+(t._vE[r].value-t._vS[r].value)*e+t._vE[r].unit})),e.pp.box(t,r)},e.prS[r]=function(t,r,o){return e.gCS(t,r)||b[r]};return e.pp.clip=function(t,r){if(t in e.dom||(e.dom[t]=function(t,r,e){var o=0,i=[];for(o;4>o;o++){var n=t._vS[r][o].v,u=t._vE[r][o].v,d=t._vE[r][o].u||"px";i[o]=n+(u-n)*e+d}t._el.style[r]="rect("+i+")"}),r instanceof Array)return[e.truD(r[0]),e.truD(r[1]),e.truD(r[2]),e.truD(r[3])];var o=r.replace(/rect|\(|\)/g,"");return o=/\,/g.test(o)?o.split(/\,/g):o.split(/\s/g),[e.truD(o[0]),e.truD(o[1]),e.truD(o[2]),e.truD(o[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]},e.pp.backgroundPosition=function(t,r){if(t in e.dom||(e.dom[t]=function(t,r,e){var o=t._vS[r].x.v,i=t._vE[r].x.v,n=t._vS[r].y.v,u=t._vE[r].y.v,d=o+(i-o)*e,a="%",v=n+(u-n)*e,l="%";t._el.style[r]=d+a+" "+v+l}),r instanceof Array)return{x:e.truD(r[0])||{v:50,u:"%"},y:e.truD(r[1])||{v:50,u:"%"}};var o,i,n=r.replace(/top|left/g,0).replace(/right|bottom/g,100).replace(/center|middle/g,50);return n=/\,/g.test(n)?n.split(/\,/g):n.split(/\s/g),n=2===n.length?n:[n[0],50],o=e.truD(n[0]),i=e.truD(n[1]),{x:o,y:i}},e.prS.backgroundPosition=function(t,r,o){return e.gCS(t,r)||b[r]},this});
(function(h){if("function"===typeof define&&define.amd)define(["./kute.js"],function(a){h(a);return a});else if("object"==typeof module&&"function"==typeof require){var a=require("./kute.js");module.exports=h(a)}else if("undefined"!=typeof window.KUTE)h(a);else throw Error("CSS Plugin require KUTE.js.");})(function(h){var a=window.KUTE,c,g=a.dom,m=a.pp,t=a.property("borderRadius"),u=a.property("borderTopLeftRadius"),v=a.property("borderTopRightRadius"),w=a.property("borderBottomLeftRadius"),x=a.property("borderBottomRightRadius");h="borderColor borderTopColor borderRightColor borderBottomColor borderLeftColor outlineColor".split(" ");var p=["borderRadius","borderTopLeftRadius","borderTopRightRadius","borderBottomLeftRadius","borderBottomRightRadius"];c="right bottom minWidth minHeight maxWidth maxHeight padding margin paddingTop paddingBottom paddingLeft paddingRight marginTop marginBottom marginLeft marginRight borderWidth borderTopWidth borderRightWidth borderBottomWidth borderLeftWidth outlineWidth".split(" ");for(var b=["fontSize","lineHeight","letterSpacing","wordSpacing"],n=["backgroundPosition"],q=p.concat(c,b),r=h.concat(["clip"],p,c,b,n),y=r.length,k=a.Interpolate.unit,z=a.Interpolate.color,l=l||{},b=0;b<y;b++)c=r[b],-1!==h.indexOf(c)?l[c]="rgba(0,0,0,0)":-1!==q.indexOf(c)?l[c]=0:-1!==n.indexOf(c)?l[c]=[50,50]:"clip"===c&&(l[c]=[0,0,0,0]);b=0;for(n=h.length;b<n;b++)c=h[b],m[c]=function(f,a){f in g||(g[f]=function(e,a,f,d,c,b){e.style[a]=z(f,d,c,b.keepHex)});return m.cls(f,a)},a.prS[c]=function(f,d,e){return a.gCS(f,d)||l[d]};b=0;for(n=q.length;b<n;b++)c=q[b],m[c]=function(a,d){a in g||(g[a]=function(a,f,d,c,b){a.style[f]=k(d.value,c.value,c.unit,b)});return m.box(a,d)},a.prS[c]=function(f,d,e){return a.gCS(f,d)||l[d]};b=0;for(n=p.length;b<n;b++)c=p[b],m[c]=function(a,d){a in g||("borderRadius"===a?g[a]=function(a,d,f,c,b){a.style[t]=k(f.value,c.value,c.unit,b)}:"borderTopLeftRadius"===a?g[a]=function(a,d,c,f,b){a.style[u]=k(c.value,f.value,f.unit,b)}:"borderTopRightRadius"===a?g[a]=function(a,d,f,c,b){a.style[v]=k(f.value,c.value,c.unit,b)}:"borderBottomLeftRadius"===a?g[a]=function(a,d,c,f,b){a.style[w]=k(c.value,f.value,f.unit,b)}:"borderBottomRightRadius"===a&&(g[a]=function(a,d,f,c,b){a.style[x]=k(f.value,c.value,c.unit,b)}));return m.box(a,d)},a.prS[c]=function(c,d,b){return a.gCS(c,d)||l[d]};m.clip=function(c,d){c in g||(g[c]=function(a,c,b,d,f){var e=0,g=[];for(e;4>e;e++)g[e]=k(b[e].v,d[e].v,d[e].u||"px",f);a.style[c]="rect("+g+")"});if(d instanceof Array)return[a.truD(d[0]),a.truD(d[1]),a.truD(d[2]),a.truD(d[3])];var b=d.replace(/rect|\(|\)/g,""),b=/\,/g.test(b)?b.split(/\,/g):b.split(/\s/g);return[a.truD(b[0]),a.truD(b[1]),a.truD(b[2]),a.truD(b[3])]};a.prS.clip=function(c,b,e){b=a.gCS(c,b);e=a.gCS(c,"width");c=a.gCS(c,"height");return/rect/.test(b)?b:[0,e,c,0]};m.backgroundPosition=function(c,b){c in g||(g[c]=function(a,c,b,d,e){a.style[c]=k(b.x.v,d.x.v,"%",e)+" "+k(b.y.v,d.y.v,"%",e)});if(b instanceof Array)return{x:a.truD(b[0])||{v:50,u:"%"},y:a.truD(b[1])||{v:50,u:"%"}};var e=b.replace(/top|left/g,0).replace(/right|bottom/g,100).replace(/center|middle/g,50),h,e=/\,/g.test(e)?e.split(/\,/g):e.split(/\s/g),e=2===e.length?e:[e[0],50];h=a.truD(e[0]);e=a.truD(e[1]);return{x:h,y:e}};a.prS.backgroundPosition=function(c,b,e){return a.gCS(c,b)||l[b]};return this});

File diff suppressed because one or more lines are too long

View file

@ -1,2 +1,2 @@
// Text Plugin for KUTE.js | dnp_theme & @dalisoft | MIT License
!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("Text-Plugin requires KUTE.js.");t()}}(function(){var t=window.KUTE,e=String("abcdefghijklmnopqrstuvwxyz").split(""),n=String("abcdefghijklmnopqrstuvwxyz".toUpperCase()).split(""),r=String("~!@#$%^&*()_+{}[];'<>,./?=-").split(""),i=String("0123456789").split(""),o=e.concat(n,i),u=o.concat(r),s=Math.random,a=Math.floor,p=Math.min;return t.prS.text=t.prS.number=function(t,e,n){return t.innerHTML},t.pp.text=function(f,l,h){return"text"in t.dom||(t.dom.text=function(t,f,l){var h=h||"alpha"===t.textChars?e:"upper"===t.textChars?n:"numeric"===t.textChars?i:"alphanumeric"===t.textChars?o:"symbols"===t.textChars?r:"all"===t.textChars?u:t.textChars?t.textChars.split(""):e,c=h.length,m=t._vE[f],d=h[a(s()*c)],x="",g=m.substring(0);x=g.substring(0,a(p(l*g.length,g.length))),t._el.innerHTML=1>l?x+d:x}),l},t.pp.number=function(e,n,r){return"number"in t.dom||(t.dom.number=function(t,e,n){t._el.innerHTML=parseInt(t._vS[e]+(t._vE[e]-t._vS[e])*n)}),parseInt(n)||0},this});
(function(b){if("function"===typeof define&&define.amd)define(["./kute.js"],function(a){b(a);return a});else if("object"==typeof module&&"function"==typeof require){var a=require("./kute.js");module.exports=b(a)}else if("undefined"!==typeof window.KUTE)b();else throw Error("Text-Plugin requires KUTE.js.");})(function(){var b=window.KUTE,a=b.dom,e=b.pp,t=b.Interpolate.number,d="abcdefghijklmnopqrstuvwxyz".split(""),l="ABCDEFGHIJKLMNOPQRSTUVWXYZ".split(""),m="~!@#$%^&*()_+{}[];'<>,./?=-".split(""),n="0123456789".split(""),p=d.concat(l,n);p.concat(m);var u=Math.random,k=Math.floor,q=Math.min;b.prS.text=b.prS.number=function(b,a,d){return b.innerHTML};e.text=function(b,v,e){"text"in a||(a.text=function(b,a,h,r,f,c){var g=g||"alpha"===c.textChars?d:"upper"===c.textChars?l:"numeric"===c.textChars?n:"alphanumeric"===c.textChars?p:"symbols"===c.textChars?m:c.textChars?c.textChars.split(""):d;a=g.length;g=g[k(u()*a)];c=h.substring(0);a=r.substring(0);h=""!==h?c.substring(c.length,k(q(f*c.length,c.length))):"";a=a.substring(0,k(q(f*a.length,a.length)));b.innerHTML=1>f?a+g+h:r});return v};e.number=function(b,d,e){"number"in a||(a.number=function(a,b,d,e,f){a.innerHTML=parseInt(t(d,e,f))});return parseInt(d)||0};return this});

33
dist/kute.min.js vendored

File diff suppressed because one or more lines are too long

View file

@ -21,7 +21,8 @@
}
}( function (KUTE) {
'use strict';
var K = window.KUTE;
var K = window.KUTE, DOM = K.dom, PP = K.pp, unit = K.Interpolate.unit, number = K.Interpolate.number;
// get current attribute value
K.gCA = function(e,a){
@ -35,35 +36,35 @@
}
return f;
};
// register the render attributes object
if (!('attr' in K.dom)) {
K.dom.attr = function(w,p,v){
for ( var o in w._vE[p] ){
K.dom.attr.prototype[o](w,o,v);
if (!('attr' in DOM)) {
DOM.attr = function(l,p,a,b,v) {
for ( var o in b ){
DOM.attr.prototype[o](l,o,a[o],b[o],v);
}
};
}
var ra = K.dom.attr.prototype;
var ra = DOM.attr.prototype;
// process attributes object K.pp.attr(t[x])
// and also register their render functions
K.pp['attr'] = function(a,o){
PP['attr'] = function(a,o){
var ats = {}, p;
for ( p in o ) {
if ( /%|px/.test(o[p]) ) {
var u = K.truD(o[p]).u, s = /%/.test(u) ? '_percent' : '_'+u;
if (!(p+s in ra)) {
ra[p+s] = function(w,p,v){
w._el.setAttribute(p.replace(s,''), (w._vS.attr[p].v + (w._vE.attr[p].v - w._vS.attr[p].v) * v) + w._vE.attr[p].u);
ra[p+s] = function(l,p,a,b,v) {
var _p = p.replace(s,'');
l.setAttribute(_p, unit(a.v,b.v,b.u,v) );
}
}
ats[p+s] = K.truD(o[p]);
} else {
if (!(p in ra)) {
ra[p] = function(w,p,v){
w._el.setAttribute(p, w._vS.attr[p] + (w._vE.attr[p]- w._vS.attr[p]) * v);
ra[p] = function(l,o,a,b,v) {
l.setAttribute(o, number(a,b,v));
}
}
ats[p] = o[p] * 1;

View file

@ -5,26 +5,6 @@
* optimized by dnp_theme 2015 MIT License
* Licensed under MIT-License
*/
// /* THIS IS THE OLD CODE */
// (function(kute_ea){
// // Obtain a reference to the base KUTE.
// // Since KUTE supports a variety of module systems,
// // we need to pick up which one to use.
// if(define == "function") {
// define(["./kute.js"], function(KUTE){ kute_ea(KUTE); return KUTE; });
// } else if(typeof module == "object" && typeof require == "function") {
// // We assume, that require() is sync.
// var KUTE = require("./kute.js");
// kute_ea(KUTE);
// // Export the modified one. Not really required, but convenient.
// module.exports = KUTE;
// } else if(typeof window.KUTE != "undefined") {
// kute_ea(window.KUTE);
// } else {
// throw new Error("KUTE.js Bezier/Easing depends on KUTE.js. Read the docs for more info.")
// }
// })(function(KUTE){
(function (factory) {
if (typeof define === 'function' && define.amd) {

View file

@ -16,7 +16,7 @@
throw new Error("CSS Plugin require KUTE.js.")
}
})(function(KUTE){
var K = window.KUTE, p,
var K = window.KUTE, p, DOM = K.dom, PP = K.pp,
_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)
@ -28,7 +28,8 @@
_clp = ['clip'], _bg = ['backgroundPosition'], // clip | background position
_mg = _rd.concat(_bm,_tp), // a merge of all properties with px|%|em|rem|etc unit
_all = _cls.concat(_clp, _rd, _bm, _tp, _bg), al = _all.length,
_all = _cls.concat(_clp, _rd, _bm, _tp, _bg), al = _all.length,
number = K.Interpolate.number, unit = K.Interpolate.unit, color = K.Interpolate.color,
_d = _d || {}; //all properties default values
//populate default values object
@ -48,26 +49,13 @@
// create prepare/process/render functions for additional colors properties
for (var i = 0, l = _cls.length; i<l; i++) {
p = _cls[i];
K.pp[p] = function(p,v) {
if ( (!(p in K.dom)) ) {
K.dom[p] = function(w,p,v) {
var _c = {};
for (var c in w._vE[p].value) {
if ( c !== 'a' ){
_c[c] = parseInt(w._vS[p].value[c] + (w._vE[p].value[c] - w._vS[p].value[c]) * v )||0;
} else {
_c[c] = (w._vS[p].value[c] && w._vE[p].value[c]) ? parseFloat(w._vS[p].value[c] + (w._vE[p].value[c] - w._vS[p].value[c]) * v) : null;
}
}
if ( w._hex ) {
w._el.style[p] = K.rth( _c.r, _c.g, _c.b );
} else {
w._el.style[p] = !_c.a || _isIE8 ? 'rgb(' + _c.r + ',' + _c.g + ',' + _c.b + ')' : 'rgba(' + _c.r + ',' + _c.g + ',' + _c.b + ',' + _c.a + ')';
}
PP[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 K.pp.cls(p,v);
return PP.cls(p,v);
};
K.prS[p] = function(el,p,v){
return K.gCS(el,p) || _d[p];
@ -77,13 +65,13 @@
// create prepare/process/render functions for additional box model properties
for (var i = 0, l = _mg.length; i<l; i++) {
p = _mg[i];
K.pp[p] = function(p,v){
if ( (!(p in K.dom)) ) {
K.dom[p] = function(w,p,v) {
w._el.style[p] = (w._vS[p].value + (w._vE[p].value - w._vS[p].value) * v ) + w._vE[p].unit;
};
}
return K.pp.box(p,v);
PP[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);
};
K.prS[p] = function(el,p,v){
return K.gCS(el,p) || _d[p];
@ -93,31 +81,31 @@
//create prepare/process/render functions for radius properties
for (var i = 0, l = _rd.length; i<l; i++) {
p = _rd[i];
K.pp[p] = function(p,v){
if ( (!(p in K.dom)) ) {
PP[p] = function(p,v){
if ( (!(p in DOM)) ) {
if (p === 'borderRadius') {
K.dom[p] = function(w,p,v) {
w._el.style[_br] = (w._vS[p].value + (w._vE[p].value - w._vS[p].value) * v ) + w._vE[p].unit;
};
DOM[p] = function(l,p,a,b,v){
l.style[_br] = unit(a.value,b.value,b.unit,v);
}
} else if (p === 'borderTopLeftRadius') {
K.dom[p] = function(w,p,v) {
w._el.style[_brtl] = (w._vS[p].value + (w._vE[p].value - w._vS[p].value) * v ) + w._vE[p].unit;
};
DOM[p] = function(l,p,a,b,v){
l.style[_brtl] = unit(a.value,b.value,b.unit,v);
}
} else if (p === 'borderTopRightRadius') {
K.dom[p] = function(w,p,v) {
w._el.style[_brtr] = (w._vS[p].value + (w._vE[p].value - w._vS[p].value) * v ) + w._vE[p].unit;
};
DOM[p] = function(l,p,a,b,v){
l.style[_brtr] = unit(a.value,b.value,b.unit,v);
}
} else if (p === 'borderBottomLeftRadius') {
K.dom[p] = function(w,p,v) {
w._el.style[_brbl] = (w._vS[p].value + (w._vE[p].value - w._vS[p].value) * v ) + w._vE[p].unit;
};
DOM[p] = function(l,p,a,b,v){
l.style[_brbl] = unit(a.value,b.value,b.unit,v);
}
} else if (p === 'borderBottomRightRadius') {
K.dom[p] = function(w,p,v) {
w._el.style[_brbr] = (w._vS[p].value + (w._vE[p].value - w._vS[p].value) * v ) + w._vE[p].unit;
};
DOM[p] = function(l,p,a,b,v){
l.style[_brbr] = unit(a.value,b.value,b.unit,v);
}
}
}
return K.pp.box(p,v);
return PP.box(p,v);
};
K.prS[p] = function(el,p,v){
return K.gCS(el,p) || _d[p];
@ -125,15 +113,15 @@
}
// clip
K.pp['clip'] = function(p,v){
if ( !(p in K.dom) ) {
K.dom[p] = function(w,p,v) {
PP['clip'] = function(p,v){
if ( !(p in DOM) ) {
DOM[p] = function(l,p,a,b,v) {
var h = 0, cl = [];
for (h;h<4;h++){
var c1 = w._vS[p][h].v, c2 = w._vE[p][h].v, cu = w._vE[p][h].u || 'px';
cl[h] = ((c1 + ( c2 - c1 ) * v)) + cu;
var c1 = a[h].v, c2 = b[h].v, cu = b[h].u || 'px';
cl[h] = unit(c1,c2,cu,v);
}
w._el.style[p] = 'rect('+cl+')';
l.style[p] = 'rect('+cl+')';
};
}
if ( v instanceof Array ){
@ -151,12 +139,10 @@
};
// background position
K.pp['backgroundPosition'] = function(p,v) {
if ( !(p in K.dom) ) {
K.dom[p] = function(w,p,v) {
var px1 = w._vS[p].x.v, px2 = w._vE[p].x.v, py1 = w._vS[p].y.v, py2 = w._vE[p].y.v,
px = (px1 + ( px2 - px1 ) * v), pxu = '%', py = (py1 + ( py2 - py1 ) * v), pyu = '%';
w._el.style[p] = px + pxu + ' ' + py + pyu;
PP['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);
};
}
if ( v instanceof Array ){

View file

@ -21,13 +21,24 @@
}
}( function (KUTE) {
'use strict';
var K = window.KUTE, S = S || {}, p,
var K = window.KUTE, S = S || {}, 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',
_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,
// interpolate functions
number = K.Interpolate.number, color = K.Interpolate.color,
array = function array(a,b,l,v) { // array1, array2, array2.length, progress
var na = [], i;
for(i=0;i<l;i++) { na.push( a[i] === b[i] ? b[i] : number(a[i],b[i],v) ); } // don't do math if not needed
return na;
},
coords = function coords(a,b,l,ll,o,v) { // array1, array2, array2.length, coordinates.length, joiner, progress for SVG stuff
var s = [], i;
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
@ -39,8 +50,7 @@
p.o = el.getAttribute('d');
} else if (!el && /[a-z][^a-z]*/ig.test(e)) { // maybe it's a string path already
var np = S.cP(e.trim());
p.e = np;
p.e = S.cP(e.trim());
p.o = e;
}
return p;
@ -48,11 +58,11 @@
S.pCr = function(w){ // pathCross
// path tween options
this._mpr = w.morphPrecision || 25;
this._midx = w.morphIndex;
this._smi = w.showMorphInfo;
this._rv1 = w.reverseFirstPath;
this._rv2 = w.reverseSecondPath;
this._mpr = w._ops.morphPrecision || 25;
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
@ -179,10 +189,7 @@
}
S.gOp = function(p){ // getOnePath, first path only
var a = p.split(/z/i);
if (a.length > 2) {
return a[0].trim() + 'z';
} else { return p.trim(); }
return p.split(/z/i).shift() + 'z';
}
S.cP = function (p){ // createPath
@ -216,7 +223,7 @@
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]; }
if (i === 0) { x+=np[i][0]; y +=np[i][1]; }
else {
x = np[i-1][0];
y = np[i-1][1];
@ -234,23 +241,16 @@
}
return np;
}
// a shortHand pathCross
K.svq = function(w){ if ( w._vE.path ) S.pCr(w); }
// a shortHand pathCross && SVG transform stack
K.svq = function(w){ if ( w._vE.path ) S.pCr(w); if ( w._vE.svgTransform ) S.sT(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);
if (!('path' in K.dom)) {
K.dom['path'] = function(w,p,v){
var points =[], i, l;
for(i=0,l=w._vE.path.d.length;i<l;i++) { // for each point
points[i] = [];
for(var j=0;j<2;j++) { // each point coordinate
points[i].push(w._vS.path.d[i][j]+(w._vE.path.d[i][j]-w._vS.path.d[i][j])*v);
}
}
w._el.setAttribute("d", v === 1 ? w._vE.path.o : 'M' + points.join('L') + 'Z' );
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);
@ -270,8 +270,8 @@
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,'strokeDashoffset'));
d = K.gCS(e,'strokeDasharray').split(/\,/);
o = parseFloat(K.gCS(e,'stroke-dashoffset'));
d = K.gCS(e,'stroke-dasharray').split(/\,/);
start = 0-o;
end = parseFloat(d[0]) + start || l;
@ -280,31 +280,27 @@
return { s: start, e: end, l: l }
};
S.pc = function(v,l){
S.pc = function(v,l){ // percent
return parseFloat(v) / 100 * l;
};
K.pp['draw'] = function(a,o,l){ // register the draw property
if (!('draw' in K.dom)) {
K.dom['draw'] = function(w,p,v){
var l, s, e, o;
l = w._vS.draw.l;
s = w._vS.draw.s+(w._vE.draw.s-w._vS.draw.s)*v;
e = w._vS.draw.e+(w._vE.draw.e-w._vS.draw.e)*v;
o = 0 - s;
w._el.style.strokeDashoffset = o +'px';
w._el.style.strokeDasharray = e+o<1 ? '0px, ' + l + 'px' : (e+o) + 'px, ' + l + 'px';
PP['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;
l.style.strokeDashoffset = o +'px';
l.style.strokeDasharray = e+o<1 ? '0px, ' + ll + 'px' : (e+o) + 'px, ' + ll + 'px';
}
}
return S.gDr(l,o);
return S.gDr(f,o);
}
K.prS['draw'] = function(el,p,v){
return S.gDr(el)
return S.gDr(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);
@ -325,7 +321,7 @@
return (w*2)+(h*2);
}
S.gPL = function(el){ // getPolygonLength - return the length of the Polygon / Polyline
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) {
@ -373,30 +369,16 @@
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];
K.pp[p] = function(p,v){
if (!(p in K.dom)) {
K.dom[p] = function(w,p,v){
var _c = {};
for (var c in w._vE[p]) {
if ( c !== 'a' ){
_c[c] = parseInt(w._vS[p][c] + (w._vE[p][c] - w._vS[p][c]) * v )||0;
} else {
_c[c] = (w._vS[p][c] && w._vE[p][c]) ? parseFloat(w._vS[p][c] + (w._vE[p][c] - w._vS[p][c]) * v) : null;
}
}
if ( w._hex ) {
w._el.style[p] = K.rth( _c.r, _c.g, _c.b );
} else {
w._el.style[p] = !_c.a ? 'rgb(' + _c.r + ',' + _c.g + ',' + _c.b + ')' : 'rgba(' + _c.r + ',' + _c.g + ',' + _c.b + ',' + _c.a + ')';
}
}
PP[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 K.truC(v);
}
@ -404,23 +386,25 @@
return K.gCS(el,p) || 'rgba(0,0,0,0)';
}
}
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'){
K.pp[p] = function(p,v){
if (!(p in K.dom)) {
K.dom[p] = function(w,p,v) {
w._el.style[p] = (w._vS[p].value + (w._vE[p].value - w._vS[p].value) * v) + w._vS[p].unit;
if (p === 'strokeWidth'){ // stroke can be unitless or unit | http://stackoverflow.com/questions/1301685/fixed-stroke-width-in-svg
PP[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 K.pp.box(p,v);
return /px|%|em|vh|vw/.test(v) ? PP.box(p,v) : parseFloat(v);
}
} else {
K.pp[p] = function(p,v){
if (!(p in K.dom)) {
K.dom[p] = function(w,p,v) {
w._el.style[p] = w._vS[p] + (w._vE[p] - w._vS[p]) * v;
PP[p] = function(p,v){
if (!(p in DOM)) {
DOM[p] = function(l,p,a,b,v) {
l.style[p] = number(a,b,v);
}
}
return parseFloat(v);
@ -432,72 +416,115 @@
}
// SVG Transform
K.pp['svgTransform'] = function(p,v,l){
PP['svgTransform'] = function(p,v,l){
// register the render function
if (!('svgTransform' in K.dom)) {
K.dom['svgTransform'] = function(w,p,v) {
if (!('svgTransform' in DOM)) {
DOM['svgTransform'] = function(l,p,a,b,v){
var tr = '', i;
for (i in w._vE[p]){
for (i in b){
tr += i + '('; // start string
if ( i === 'translate'){ // translate
tr += (w._vS[p][i][1] === w._vE[p][i][1] && w._vE[p][i][1] === 0 )
? (w._vS[p][i][0] + (w._vE[p][i][0] - w._vS[p][i][0]) * v )
: (w._vS[p][i][0] + (w._vE[p][i][0] - w._vS[p][i][0]) * v ) + ' ' + (w._vS[p][i][1] + (w._vE[p][i][1] - w._vS[p][i][1]) * v );
tr += (a[i][1] === b[i][1] && b[i][1] === 0 )
? number(a[i][0],b[i][0],v)
: number(a[i][0],b[i][0],v) + ' ' + number(a[i][1],b[i][1],v);
} else if ( i === 'rotate'){ // rotate
tr += w._vS[p][i][0] + (w._vE[p][i][0] - w._vS[p][i][0]) * v + ' ';
tr += !w.reversed ? w._vE[p][i][1] + ',' + w._vE[p][i][2] : w._vS[p][i][1] + ',' + w._vS[p][i][2]; // make sure to always use the right transform-origin
tr += number(a[i][0],b[i][0],v) + ' ';
tr += b[i][1] + ',' + b[i][2];
} else { // scale, skewX or skewY
tr += w._vS[p][i] + (w._vE[p][i] - w._vS[p][i]) * v;
tr += number(a[i],b[i],v);
}
tr += ') '; // end string
}
w._el.setAttributeNS(null,'transform', tr.replace(/\)\s$/,')') );
l.setAttribute('transform', tr.trim() );
}
}
// return transform object
var tf = {}, bb = l.getBBox(), cx = bb.x + bb.width/2, cy = bb.y + bb.height/2, i, r, t;
for ( i in v ) {
// now prepare transform
var tf = {}, bb = l.getBBox(), cx = bb.x + bb.width/2, cy = bb.y + bb.height/2, r, cr, t, ct;
for ( i in v ) { // populate the valuesStart and / or valuesEnd
if (i === 'rotate'){
r = v[i] instanceof Array ? v[i]
r = v[i] instanceof Array ? v[i]
: /\s/.test(v[i]) ? [v[i].split(' ')[0]*1, v[i].split(' ')[1].split(',')[0]*1, v[i].split(' ')[1].split(',')[1]*1]
: [v[i],cx,cy];
: [v[i]*1,cx,cy];
tf[i] = r;
} else if (i === 'translate'){
t = v[i] instanceof Array ? v[i] : /\s/.test(v[i]) ? v[i].split(' ') : [v[i],0];
tf[i] = [t[0] * 1||0, t[1] * 1];
t = v[i] instanceof Array ? v[i] : /\,|\s/.test(v[i]) ? v[i].split(/\,|\s/) : [v[i]*1,0];
tf[i] = [t[0] * 1||0, t[1] * 1||0];
} else if (i === 'scale'){
tf[i] = v[i] * 1||1;
} else {
} else if (/skew/.test(i)) {
tf[i] = v[i] * 1||0;
}
}
// try to adjust translation when scale is used, probably we should do the same when using skews, but I think it's a waste of time
// http://www.petercollingridge.co.uk/interactive-svg-components/pan-and-zoom-control
// try to adjust translation when scale is used
if ('scale' in tf) {
tf['translate'] = !( 'translate' in tf ) ? [0,0] : tf['translate'];
tf['translate'][0] += (1-tf['scale']) * bb.width/2;
!('translate' in tf) && ( tf['translate'] = [0,0] ); // if no translate is found in current value or next value, we default to 0
tf['translate'][0] += (1-tf['scale']) * bb.width/2;
tf['translate'][1] += (1-tf['scale']) * bb.height/2;
}
// adjust rotation transform origin and translation when skews are used, to make the animation look exactly the same as if we were't using svgTransform
// http://stackoverflow.com/questions/39191054/how-to-compensate-translate-when-skewx-and-skewy-are-used-on-svg/39192565#39192565
if ('rotate' in tf) {
tf['rotate'][1] -= 'skewX' in tf ? Math.tan(tf['skewX']) * bb.height : 0;
tf['rotate'][2] -= 'skewY' in tf ? Math.tan(tf['skewY']) * bb.width : 0;
}
tf['translate'][0] += 'skewX' in tf ? Math.tan(tf['skewX']) * bb.height*2 : 0;
tf['translate'][1] += 'skewY' in tf ? Math.tan(tf['skewY']) * bb.width*2 : 0;
} // more variations here https://gist.github.com/thednp/0b93068e20adb84658b5840ead0a07f8
return tf;
}
// KUTE.prepareStart K.prS[p](el,p,to[p])
// returns an obect with current transform attribute value
K.prS['svgTransform'] = function(l,p,t) {
var tr = {}, cta = l.getAttributeNS(null,'transform'),
ct = cta && /\)/.test(cta) ? cta.split(')') : 'none', i, j, ctr ={}, pr;
if (ct instanceof Array) {
for (j=0; j<ct.length; j++){
pr = ct[j].split('(');
pr[0] !== '' && (ctr[pr[0].replace(/\s/,'')] = pr[1] );
}
}
// find a value in current attribute value or add a default value
for (i in t) { tr[i] = i in ctr ? ctr[i] : 0; }
var tr = {}, i, ctr = S.pT(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

@ -16,42 +16,44 @@
throw new Error("Text-Plugin requires KUTE.js.");
}
}( function () {
var K = window.KUTE,
var K = window.KUTE, DOM = K.dom, PP = K.pp, number = K.Interpolate.number,
_s = String("abcdefghijklmnopqrstuvwxyz").split(""), // lowercase
_S = String("abcdefghijklmnopqrstuvwxyz".toUpperCase()).split(""), // uppercase
_sb = String("~!@#$%^&*()_+{}[];'<>,./?\=-").split(""), // symbols
_n = String("0123456789").split(""), // numeric
_a = _s.concat(_S,_n), // alpha numeric
_all = _a.concat(_sb), // all caracters
_r = Math.random, _f = Math.floor, _m = Math.min;
random = Math.random, floor = Math.floor, min = Math.min;
K.prS['text'] = K.prS['number'] = function(l,p,v){
return l.innerHTML;
}
K.pp['text'] = function(p,v,l) {
if ( !( 'text' in K.dom ) ) {
K.dom['text'] = function(w,p,v) {
var tp = tp || w.textChars === 'alpha' ? _s // textChars is alpha
: w.textChars === 'upper' ? _S // textChars is numeric
: w.textChars === 'numeric' ? _n // textChars is numeric
: w.textChars === 'alphanumeric' ? _a // textChars is alphanumeric
: w.textChars === 'symbols' ? _sb // textChars is symbols
: w.textChars ? w.textChars.split('') // textChars is a custom text
: _s, l = tp.length, s = w._vE[p],
t = tp[_f((_r() * l))], tx = '', f = s.substring(0);
PP['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 === 'numeric' ? _n // textChars is numeric
: o.textChars === 'alphanumeric' ? _a // textChars is alphanumeric
: o.textChars === 'symbols' ? _sb // textChars is symbols
: o.textChars ? o.textChars.split('') // textChars is a custom text
: _s, ll = tp.length,
t = tp[floor((random() * ll))], ix = '', tx = '', fi = a.substring(0), f = b.substring(0);
tx = f.substring(0,_f(_m(v * f.length, f.length)));
w._el.innerHTML = v < 1 ? tx+t : tx;
// use string.replace(/<\/?[^>]+(>|$)/g, "") to strip HTML tags while animating ?
ix = a !== '' ? fi.substring(fi.length,floor(min(v * fi.length, fi.length))) : ''; // initial text, A value
tx = f.substring(0,floor(min(v * f.length, f.length))); // end text, B value
l.innerHTML = v < 1 ? tx + t + ix : b;
}
}
return v;
}
K.pp['number'] = function(p,v,l) {
if ( !( 'number' in K.dom ) ) {
K.dom['number'] = function(w,p,v) {
w._el.innerHTML = parseInt(w._vS[p] + (w._vE[p] - w._vS[p]) * v);
PP['number'] = function(p,v,l) {
if ( !( 'number' in DOM ) ) {
DOM['number'] = function(l,p,a,b,v) {
l.innerHTML = parseInt( number(a, b, v));
}
}
return parseInt(v) || 0;

1100
kute.js

File diff suppressed because it is too large Load diff