Compare commits

...

40 commits

Author SHA1 Message Date
thednp ae0b200694 Some cleanup 2021-12-29 18:42:20 +02:00
thednp 91fb7aad8f Update svgMorph.html 2021-12-27 17:34:42 +02:00
thednp 3835b6e95c Updated to latest SVGPathCommander 2021-12-27 17:33:05 +02:00
thednp 5c8b75f15b V 2.2.0 2021-12-10 09:22:21 +02:00
thednp 8f5c58195e Update package.json 2021-12-10 09:16:06 +02:00
thednp 0dac43bc88 1 2021-12-10 09:01:35 +02:00
thednp a17bacbd58 Update svgMorph.html 2021-12-09 00:18:36 +02:00
thednp 2a5bac2bb3 Changes V2.2.0:
* major JSDoc write up
* removed ESLint `no-bitwise` exception, it only applies to specific functions and not the entire code
* the `SVGCubicMorph` component will remove un-necessary `Z` path commands when is the case for better out of the box animation
* fixed a minor disambiguation with `filterEffects` and `drop-shadow` property and its `dropshadow` interpolation function
* TypeScript strong: all files are modules, easy to implement in any third party app
* updated `CubicBezier` and SVGPathCommander
* code cleanup
2021-12-08 23:43:31 +02:00
thednp e5456b86e9 Changes:
* added a more consistent Typescript generate tsconfig.json
* in regards to Typescript, all internals/externals well defined
2021-11-13 18:51:59 +02:00
thednp d96d08a36b Update 2021-11-13 12:24:30 +02:00
thednp 0290fa67cb Update package.json 2021-11-13 08:58:10 +02:00
thednp 5dfbf91ce3 Update now.js 2021-11-12 18:14:07 +02:00
thednp c786e062c0 Test 2021-11-12 18:05:53 +02:00
thednp cd0898b67f Test 2021-11-12 17:58:48 +02:00
thednp b70d46d387 Changes:
* added Typescript support
* added Typescript generate `index.d.ts` script
* fixed minor `textWrite` component type error
* reworked the index source files
2021-11-12 15:30:52 +02:00
thednp f56e19369a Update now.js
Co-Authored-By: Thamjith Thaha <jithuthaha8@gmail.com>
Co-Authored-By: Frederic R. <frederic.rousseau@storyful.com>
2021-11-10 17:09:00 +02:00
thednp b36f26195c Attempt to address #109
Please test latest master

Co-Authored-By: Thamjith Thaha <jithuthaha8@gmail.com>
Co-Authored-By: Frederic R. <frederic.rousseau@storyful.com>
2021-11-10 17:05:07 +02:00
thednp ebd86bf9e3 2021-05-31 08:37:02 +00:00
thednp b0f6220413 Changes:
* updated dependencies
* ESM is now ES6+
2021-05-31 07:47:30 +00:00
thednp 0efd9a10e4 Easing 'easingCircularOut' typo. 2021-03-31 08:29:41 +00:00
thednp 2a309434c1 Fixed some IE issues with new code base. 2021-03-31 08:08:58 +00:00
thednp a1f59fe181 2021-03-30 11:26:50 +00:00
thednp c011a9368b 2021-03-30 11:19:27 +00:00
thednp 933d61de19 Changes:
* added ESLint and updated all code base 
* updated SVGPathCommander, CubicBezier, shorter-js, minifill
* updated polyfills
* minor CSS fixes
2021-03-30 09:23:29 +00:00
thednp bfc3fabc92 Changes:
* updated SVGPathCommander
* fixed small typo issue with SVGDraw
* version bump
2021-01-09 13:31:00 +00:00
thednp 14585d7a51 2020-09-24 05:07:47 +00:00
thednp 2ad17fdd00 2020-09-24 04:57:49 +00:00
thednp 0b7fd91bab Changes, lots of them:
* Updated SVGPathCommander to make use of the new features, the SVG morph components can now process paths in Node.js
* svgCubicMorph component now can morph lines properly, as shown in the updated demo
* svgMorph component also updated
* documentation updates for more clarity with the morph components
2020-09-23 18:59:39 +00:00
thednp 85d9c09ede Changes:
* Solved some minor issue with `pathToCurve` utility
* Updated SVGPathCommander
2020-09-02 13:26:47 +00:00
thednp 7a782229dd Changes (big update):
* updated SVGPathCommander to support a wider range of shapes, including closed/unclosed shapes
* added d3-polygon dependency for ***svgMorph*** component
* updated both ***svgMorph*** and ***svgCubicMorph*** components
* updated polyfill
* code cleanup
* documentation updates
2020-08-31 15:39:43 +00:00
thednp 730583caff 2020-08-18 12:32:22 +00:00
thednp 0528e3a0af Changes:
* updated `svg-path-commander`, solving an important path processing script `a2c` for `arcTo` path commands with `largeArcFlag` values
* solved some build tools issues (unzipped was working, zipped wasn't)
2020-08-18 12:23:26 +00:00
thednp b0a6495748 Changes:
* replaced some path processing with SVGPathCommander
* minor improvements
2020-08-16 20:20:36 +00:00
thednp b152aa8fa6 Solves #103 2020-08-14 11:51:10 +00:00
thednp 65a56cd338 Changes:
* KUTE.js now works when added to `<head>` but tween object initialization scripting must be added after `<body>` or when new `Element` target is appended into document
* updated `shorter-js`
2020-07-27 09:42:21 +00:00
thednp 64ac54a4d0 Changes:
* typo in svgMorph components/svgMorph.js
2020-07-03 09:25:03 +00:00
thednp da4a2108f8 2020-07-02 10:57:32 +00:00
thednp 6bfa00da75 Changes:
* Added a Spicr demo to the index.page.
* Some demo updates
2020-07-02 10:50:04 +00:00
thednp ce0a5192b3 2020-06-24 05:45:15 +00:00
thednp 072a61533c 2020-06-24 05:39:57 +00:00
184 changed files with 28207 additions and 13955 deletions

41
.eslintrc Normal file
View file

@ -0,0 +1,41 @@
{
"extends": [
// Extend the airbnb eslint config
"airbnb-base"
// Vue
// "plugin:vue/vue3-recommended"
],
// "parser": "vue-eslint-parser",
// "parser": "eslint-plugin-vue",
"parserOptions": {
"sourceType": "module"
},
// ESLint will not look in parent folders for eslint configs
"root": false,
// An environment defines global variables that are predefined.
"env": {
"browser": true,
"es6": true,
"node": true
},
// Rule overrides
"rules": {
// Disable no-restricted-globals for global objects
"no-restricted-globals": 0,
// Disable no-params-reassign for properties
// "no-param-reassign": ["error", { "props": false }],
// Allow strict mode (we are not dealing with modules)
// "strict": [0],
// Allow use of "private methods" - impossible to satisfy
"no-underscore-dangle": 0
// Disable alert rule till we have a CE in place
// "no-alert": 0
// Allow extensions on imports
// "import/extensions": 0,
// Allow exporting mutable 'let' binding
// "import/no-mutable-exports": 0,
// Allow no named as default / member
// "import/no-named-as-default": 0,
// "import/no-named-as-default-member": 0
}
}

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
node_modules/
experiments/
.npmignore
package-lock.json

View file

@ -1,3 +1,5 @@
node_modules/
demo/
experiments/
package-lock.json
.gitignore

View file

@ -1,5 +1,6 @@
# KUTE.js
A modern JavaScript animation engine built on ES6/ES7 standards with most essential features for web developers, designers and animators, delivering easy to use methods to set up high performance, cross-browser animations. The focus is code quality, flexibility, performance and size.
A modern JavaScript animation engine built on ES6+ standards with strong TypeScript definitions and most essential features for the web with easy to use methods to set up high performance, cross-browser animations. The focus is code quality, flexibility, performance and size.
[![NPM Version](https://img.shields.io/npm/v/kute.js.svg?style=flat-square)](https://www.npmjs.com/package/kute.js)
[![NPM Downloads](https://img.shields.io/npm/dm/kute.js.svg?style=flat-square)](http://npm-stat.com/charts.html?package=kute.js)
@ -40,9 +41,11 @@ All above mentioned components have a BASE version which doesn't include value p
# Wiki
For a complete developer guide, usage and stuff like npm, visit [the wiki](https://github.com/thednp/kute.js/wiki).
# Browser Support
KUTE.js is redeveloped for maximum performance on modern browsers. Some legacy browsers might some help, so give them a small polyfill set with most essential features required by KUTE.js to work, powered by [minifill](https://github.com/thednp/minifill), try it. For broader projects you might want to consider <a href="https://cdn.polyfill.io/v2/docs/">polyfills</a>.
# Special Thanks
* [Mike Bostock](https://bost.ocks.org/mike/) for his awesome [D3.js](https://github.com/d3/d3), one of the sources for our reworked [SVGMorph](http://thednp.github.io/kute.js/svgMorph.html) component.
* [Noah Veltman](https://github.com/veltman) for his awesome [flubber](https://github.com/veltman/flubber), another one of the sources for the SVGMorph component.
@ -50,8 +53,10 @@ KUTE.js is redeveloped for maximum performance on modern browsers. Some legacy b
* [Dmitry Baranovskiy](https://dmitry.baranovskiy.com/) for his awesome [Raphael.js](https://dmitrybaranovskiy.github.io/raphael/), another source for our SVGCubicMorph component.
* [@dalisoft](https://github.com/dalisoft) contributed a great deal to the performance and functionality of previous versions of KUTE.js.
# Contributions
* [Contributors &amp; Collaborators](https://github.com/thednp/kute.js/graphs/contributors)
# License
[MIT License](https://github.com/thednp/kute.js/blob/master/LICENSE)

View file

@ -6,16 +6,15 @@
/* GLOBAL STYLES
-------------------------------------------------- */
body {
font-family: "Roboto", "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
line-height: 24px; /* ~25px */
letter-spacing: 0.02em;
color: #ccc;
background-color: #08263d;
position: relative
}
.condensed { font-family: "Roboto Condensed", "Helvetica Neue", Helvetica, Arial, sans-serif; font-weight: normal !important;}
.condensed {
font-family: "Roboto Condensed", "Helvetica Neue", Helvetica, Arial, sans-serif;
font-weight: normal !important
}
/* smooth scroll */
html {
@ -259,10 +258,9 @@ h1.example-item span {
.media {float: left; margin: 5px 20px 0 0; height: auto; font-size: 64px; line-height: 64px; width: 64px; text-align: center}
/* COLUMN STYLES
-------------------------------------------------- */
.columns { position: relative; width: auto; margin: 0 -20px; display:flex; flex-direction: column; }
.columns { position: relative; width: 100%; margin: 0 -20px; display:flex; flex-wrap: wrap; }
.columns > [class*="col"] { padding: 0 20px; position: relative }
.columns.welcome {min-height:330px}
@ -290,30 +288,6 @@ h1.example-item span {
}
}
/* welcome */
.col3.bg { /*min-height: 120px;*/ width: 32%; margin: 1.3% 1.3% 0 0; float: left; padding: 0; opacity:0 }
.col3.bg:nth-child(3),
.col3.bg:nth-child(6),
.col3.bg:nth-child(9) { margin: 1.3% 0 0 }
.welcome > .table > .cell {perspective: 600px; -webkit-perspective: 600px; }
#blocks {
transform: rotateY(-10deg); -webkit-transform: rotateY(-10deg); width: 90%;
}
/*.replay { display: none; }*/
.frontpage { margin-top: 30%; }
.columns.welcome .col2:nth-child(2) { position: absolute; top: 0; z-index: -1; left: 20%; opacity: 0.5 }
.kute-logo {
margin-top: 12%;
}
@media (min-width: 768px){
.columns.welcome .col2:nth-child(2) { position: relative; top: auto; left: auto; z-index: auto; opacity: 1 }
}
/* STYLING CONTENT
-------------------------------------------------- */
@ -336,24 +310,18 @@ a:focus {
}
hr {
border: 1px solid #444;
margin: 10px 0;
border: 1px solid #444;
margin: 10px 0;
}
.d-block {display: block;}
.d-flex {display: flex;}
.d-none {display: none;}
.align-self-center {align-self: center;}
.align-items-center {align-items: center;}
.justify-content-space {justify-content: space-between;}
.justify-content-even {justify-content: space-evenly;}
/* buttons */
.btns .btn { float: left; line-height: 1; margin: 0 3px 3px 0}
.btns {
display: inline-flex;
flex: 1 1 auto;
justify-content: center;
text-align: center;
}
.btns .btn { display:inline; line-height: 1; margin: 0 3px 3px 0;}
.btn { padding: 12px 15px; color:#fff; border:0; background-color: #999; line-height: 44px; }
.bg-gray { color:#fff; background-color: #555; fill: #555 }
.btn.active { background-color: #2196F3 }
@ -472,7 +440,7 @@ pre.language-markup:after {
font-size: 12px; color: #999;
}
pre.language-javascript:after {content: 'Javascript';}
pre.language-javascript:after {content: 'JavaScript';}
pre.language-clike:after {content: 'node';}
pre.language-markup:after {content: 'HTML';}
pre code {background: none;padding: 0; font-weight: normal; font-size: 100%;}
@ -495,5 +463,761 @@ kbd {
font-weight: bold
}
.kute-logo,
#rectangle {transform-origin: 50% 50%;}
#rectangle {transform-origin: 50% 50%;}
.w-20{
width:20% !important
}
.w-25{
width:25% !important
}
.w-33{
width:33.33% !important
}
.w-50{
width:50% !important
}
.w-66{
width:66.67% !important
}
.w-75{
width:75% !important
}
.w-80{
width:80% !important
}
.w-100{
width:100% !important
}
.w-auto{
width:auto !important
}
.h-20vh{
height:20vh !important
}
.h-25vh{
height:25vh !important
}
.h-33vh{
height:33.33vh !important
}
.h-50vh{
height:50vh !important
}
.h-66vh{
height:66.67vh !important
}
.h-75vh{
height:75vh !important
}
.h-80vh{
height:80vh !important
}
.h-100{
height:100% !important
}
.h-auto{
height:auto !important
}
@media(min-width: 768px){
.w-md-20{
width:20% !important
}
.w-md-25{
width:25% !important
}
.w-md-33{
width:33.33% !important
}
.w-md-50{
width:50% !important
}
.w-md-66{
width:66.67% !important
}
.w-md-75{
width:75% !important
}
.w-md-80{
width:80% !important
}
.w-md-100{
width:100% !important
}
.w-md-auto{
width:auto !important
}
.h-md-20vh{
height:20vh !important
}
.h-md-25vh{
height:25vh !important
}
.h-md-33vh{
height:33.33vh !important
}
.h-md-50vh{
height:50vh !important
}
.h-md-66vh{
height:66.67vh !important
}
.h-md-75vh{
height:75vh !important
}
.h-md-80vh{
height:80vh !important
}
.h-md-100{
height:100% !important
}
.h-md-auto{
height:auto !important
}
}
.d-none{
display:none
}
.d-inline{
display:inline
}
.d-flex{
display:flex
}
.d-block{
display:block
}
@media(min-width: 768px){
.d-md-none{
display:none
}
.d-md-inline{
display:inline
}
.d-md-flex{
display:flex
}
.d-md-block{
display:block
}
}
.flex-row{
flex-direction:row
}
.flex-row-reverse{
flex-direction:row-reverse
}
.flex-column{
flex-direction:column
}
.flex-column-reverse{
flex-direction:column-reverse
}
.align-items-start{
align-items:flex-start
}
.align-items-end{
align-items:flex-end
}
.align-items-center{
align-items:center
}
.align-items-baseline{
align-items:baseline
}
.align-items-stretch{
align-items:stretch
}
.align-self-start{
align-self:flex-start
}
.align-self-end{
align-self:flex-end
}
.align-self-center{
align-self:center
}
.align-self-baseline{
align-self:baseline
}
.align-self-stretch{
align-self:stretch
}
.justify-content-start{
justify-content:flex-start
}
.justify-content-end{
justify-content:flex-end
}
.justify-content-center{
justify-content:center
}
.justify-content-between{
justify-content:space-between
}
.justify-content-around{
justify-content:space-around
}
.align-content-start{
align-content:flex-start
}
.align-content-end{
align-content:flex-end
}
.align-content-center{
align-content:center
}
.align-content-around{
align-content:space-around
}
.align-content-stretch{
align-content:stretch
}
.flex-fill{
flex:1 1 auto !important
}
.flex-grow-1{
flex-grow:1
}
.flex-grow-0{
flex-grow:0
}
.flex-shrink-1{
flex-shrink:1
}
.flex-shrink-0{
flex-shrink:0
}
.flex-nowrap{
flex-wrap:nowrap
}
.flex-wrap{
flex-wrap:wrap
}
.flex-wrap-reverse{
flex-wrap:wrap-reverse
}
@media(min-width: 768px){
.flex-md-row{
flex-direction:row
}
.flex-md-row-reverse{
flex-direction:row-reverse
}
.flex-md-column{
flex-direction:column
}
.flex-md-column-reverse{
flex-direction:column-reverse
}
.align-items-md-start{
align-items:flex-start
}
.align-items-md-end{
align-items:flex-end
}
.align-items-md-center{
align-items:center
}
.align-items-md-baseline{
align-items:baseline
}
.align-items-md-stretch{
align-items:stretch
}
.align-self-md-start{
align-self:flex-start
}
.align-self-md-end{
align-self:flex-end
}
.align-self-md-center{
align-self:center
}
.align-self-md-baseline{
align-self:baseline
}
.align-self-md-stretch{
align-self:stretch
}
.justify-content-md-start{
justify-content:flex-start
}
.justify-content-md-end{
justify-content:flex-end
}
.justify-content-md-center{
justify-content:center
}
.justify-content-md-between{
justify-content:space-between
}
.justify-content-md-around{
justify-content:space-around
}
.flex-md-fill{
flex:1 1 auto !important
}
.flex-md-grow-1{
flex-grow:1
}
.flex-md-grow-0{
flex-grow:0
}
.flex-md-shrink-1{
flex-shrink:1
}
.flex-md-shrink-0{
flex-shrink:0
}
.flex-md-nowrap{
flex-wrap:nowrap
}
.flex-md-wrap{
flex-wrap:wrap
}
.flex-md-wrap-reverse{
flex-wrap:wrap-reverse
}
}
.overflow-visible{
overflow:visible
}
.overflow-hidden{
overflow:hidden
}
.perspective{
perspective:500px;
backface-visibility:hidden
}
.perspective-1000{
perspective:1000px;
backface-visibility:hidden
}
.perspective-1500{
perspective:1500px;
backface-visibility:hidden
}
.m-0{
margin:0 !important
}
.m-1{
margin:.25rem !important
}
.m-2{
margin:.5rem !important
}
.m-3{
margin:1rem !important
}
.m-4{
margin:1.5rem !important
}
.m-5{
margin:3rem !important
}
.m-auto{
margin:auto !important
}
.mx-0{
margin-right:0 !important;
margin-left:0 !important
}
.mx-1{
margin-right:.25rem !important;
margin-left:.25rem !important
}
.mx-2{
margin-right:.5rem !important;
margin-left:.5rem !important
}
.mx-3{
margin-right:1rem !important;
margin-left:1rem !important
}
.mx-4{
margin-right:1.5rem !important;
margin-left:1.5rem !important
}
.mx-5{
margin-right:3rem !important;
margin-left:3rem !important
}
.mx-auto{
margin-right:auto !important;
margin-left:auto !important
}
.my-0{
margin-top:0 !important;
margin-bottom:0 !important
}
.my-1{
margin-top:.25rem !important;
margin-bottom:.25rem !important
}
.my-2{
margin-top:.5rem !important;
margin-bottom:.5rem !important
}
.my-3{
margin-top:1rem !important;
margin-bottom:1rem !important
}
.my-4{
margin-top:1.5rem !important;
margin-bottom:1.5rem !important
}
.my-5{
margin-top:3rem !important;
margin-bottom:3rem !important
}
.my-auto{
margin-top:auto !important;
margin-bottom:auto !important
}
.mt-0{
margin-top:0 !important
}
.mt-1{
margin-top:.25rem !important
}
.mt-2{
margin-top:.5rem !important
}
.mt-3{
margin-top:1rem !important
}
.mt-4{
margin-top:1.5rem !important
}
.mt-5{
margin-top:3rem !important
}
.mt-auto{
margin-top:auto !important
}
.mr-0{
margin-right:0 !important
}
.mr-1{
margin-right:.25rem !important
}
.mr-2{
margin-right:.5rem !important
}
.mr-3{
margin-right:1rem !important
}
.mr-4{
margin-right:1.5rem !important
}
.mr-5{
margin-right:3rem !important
}
.mr-auto{
margin-right:auto !important
}
.mb-0{
margin-bottom:0 !important
}
.mb-1{
margin-bottom:.25rem !important
}
.mb-2{
margin-bottom:.5rem !important
}
.mb-3{
margin-bottom:1rem !important
}
.mb-4{
margin-bottom:1.5rem !important
}
.mb-5{
margin-bottom:3rem !important
}
.mb-auto{
margin-bottom:auto !important
}
.ml-0{
margin-left:0 !important
}
.ml-1{
margin-left:.25rem !important
}
.ml-2{
margin-left:.5rem !important
}
.ml-3{
margin-left:1rem !important
}
.ml-4{
margin-left:1.5rem !important
}
.ml-5{
margin-left:3rem !important
}
.ml-auto{
margin-left:auto !important
}
.p-0{
padding:0 !important
}
.p-1{
padding:.25rem !important
}
.p-2{
padding:.5rem !important
}
.p-3{
padding:1rem !important
}
.p-4{
padding:1.5rem !important
}
.p-5{
padding:3rem !important
}
.px-0{
padding-right:0 !important;
padding-left:0 !important
}
.px-1{
padding-right:.25rem !important;
padding-left:.25rem !important
}
.px-2{
padding-right:.5rem !important;
padding-left:.5rem !important
}
.px-3{
padding-right:1rem !important;
padding-left:1rem !important
}
.px-4{
padding-right:1.5rem !important;
padding-left:1.5rem !important
}
.px-5{
padding-right:3rem !important;
padding-left:3rem !important
}
.py-0{
padding-top:0 !important;
padding-bottom:0 !important
}
.py-1{
padding-top:.25rem !important;
padding-bottom:.25rem !important
}
.py-2{
padding-top:.5rem !important;
padding-bottom:.5rem !important
}
.py-3{
padding-top:1rem !important;
padding-bottom:1rem !important
}
.py-4{
padding-top:1.5rem !important;
padding-bottom:1.5rem !important
}
.py-5{
padding-top:3rem !important;
padding-bottom:3rem !important
}
.pt-0{
padding-top:0 !important
}
.pt-1{
padding-top:.25rem !important
}
.pt-2{
padding-top:.5rem !important
}
.pt-3{
padding-top:1rem !important
}
.pt-4{
padding-top:1.5rem !important
}
.pt-5{
padding-top:3rem !important
}
.pr-0{
padding-right:0 !important
}
.pr-1{
padding-right:.25rem !important
}
.pr-2{
padding-right:.5rem !important
}
.pr-3{
padding-right:1rem !important
}
.pr-4{
padding-right:1.5rem !important
}
.pr-5{
padding-right:3rem !important
}
.pb-0{
padding-bottom:0 !important
}
.pb-1{
padding-bottom:.25rem !important
}
.pb-2{
padding-bottom:.5rem !important
}
.pb-3{
padding-bottom:1rem !important
}
.pb-4{
padding-bottom:1.5rem !important
}
.pb-5{
padding-bottom:3rem !important
}
.pl-0{
padding-left:0 !important
}
.pl-1{
padding-left:.25rem !important
}
.pl-2{
padding-left:.5rem !important
}
.pl-3{
padding-left:1rem !important
}
.pl-4{
padding-left:1.5rem !important
}
.pl-5{
padding-left:3rem !important
}
.vertical-align-top{
vertical-align:top
}
.vertical-align-middle{
vertical-align:middle
}
.vertical-align-bottom{
vertical-align:bottom
}
.vertical-align-baseline{
vertical-align:baseline
}
.vertical-align-text-top{
vertical-align:text-top
}
.vertical-align-text-bottom{
vertical-align:text-bottom
}
@media(min-width: 768px){
.vertical-align-md-top{
vertical-align:top
}
.vertical-align-md-middle{
vertical-align:middle
}
.vertical-align-md-bottom{
vertical-align:bottom
}
.vertical-align-md-baseline{
vertical-align:baseline
}
.vertical-align-md-text-top{
vertical-align:text-top
}
.vertical-align-md-text-bottom{
vertical-align:text-bottom
}
}
.b-position-center-top{
background-position:center top !important
}
.b-position-center{
background-position:center center !important
}
.b-position-center-bottom{
background-position:center bottom !important
}
.b-position-left-top{
background-position:left top !important
}
.b-position-left-center{
background-position:left center !important
}
.b-position-left-bottom{
background-position:left bottom !important
}
.b-position-right-top{
background-position:right top !important
}
.b-position-right-center{
background-position:right center !important
}
.b-position-right-bottom{
background-position:right bottom !important
}
@media screen and (-ms-high-contrast: active),(-ms-high-contrast: none){
.h-20vh{
height:216px !important
}
.h-25vh{
height:270px !important
}
.h-33vh{
height:359.964px !important
}
.h-50vh{
height:540px !important
}
.h-66vh{
height:720.036px !important
}
.h-75vh{
height:810px !important
}
.h-80vh{
height:864px !important
}
.h-100{
height:100% !important
}
.h-auto{
height:auto !important
}
}
@media screen and (-ms-high-contrast: active)and (min-width: 768px),(-ms-high-contrast: none)and (min-width: 768px){
.h-md-20vh{
height:216px !important
}
.h-md-25vh{
height:270px !important
}
.h-md-33vh{
height:359.964px !important
}
.h-md-50vh{
height:540px !important
}
.h-md-66vh{
height:720.036px !important
}
.h-md-75vh{
height:810px !important
}
.h-md-80vh{
height:864px !important
}
.h-md-100{
height:100% !important
}
.h-md-auto{
height:auto !important
}
}

View file

@ -1,210 +1,305 @@
/*! normalize.css v3.0.1 | MIT License | git.io/normalize */
html {
font-family: sans-serif;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
*,*::before,*::after{
box-sizing:border-box
}
body {
margin: 0;
body{
margin:0;
font-family:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
font-size:1rem;
font-weight:400;
line-height:1.5;
color:#212529;
background-color:#fff;
-webkit-text-size-adjust:100%;
-webkit-tap-highlight-color:rgba(0,0,0,0)
}
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
main,
nav,
section,
summary {
display: block;
[tabindex="-1"]:focus:not(:focus-visible){
outline:0 !important
}
audio,
canvas,
progress,
video {
display: inline-block;
vertical-align: baseline;
hr{
margin:1rem 0;
color:inherit;
background-color:currentColor;
border:0;
opacity:.25
}
audio:not([controls]) {
display: none;
height: 0;
hr:not([size]){
height:1px
}
[hidden],
template {
display: none;
h1,h2,h3,h4,h5,h6{
margin-top:0;
font-weight:500;
line-height:1.2
}
a {
background: transparent;
h1{
font-size:calc(1.375rem + 1.5vw)
}
a:active,
a:hover {
outline: 0;
@media(min-width: 1200px){
h1{
font-size:2.5rem
}
}
abbr[title] {
border-bottom: 1px dotted;
h2{
font-size:calc(1.325rem + 0.9vw)
}
b,
strong {
font-weight: bold;
@media(min-width: 1200px){
h2{
font-size:2rem
}
}
dfn {
font-style: italic;
h3{
font-size:calc(1.3rem + 0.6vw)
}
h1 {
font-size: 2em;
margin: 0.67em 0;
@media(min-width: 1200px){
h3{
font-size:1.75rem
}
}
mark {
background: #ff0;
color: #000;
h4{
font-size:calc(1.275rem + 0.3vw)
}
small {
font-size: 80%;
@media(min-width: 1200px){
h4{
font-size:1.5rem
}
}
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
h5{
font-size:1.25rem
}
sup {
top: -0.5em;
h6{
font-size:1rem
}
sub {
bottom: -0.25em;
p{
margin-top:0;
margin-bottom:1rem
}
img {
border: 0;
abbr[title],abbr[data-original-title]{
text-decoration:underline;
-webkit-text-decoration:underline dotted;
text-decoration:underline dotted;
cursor:help;
-webkit-text-decoration-skip-ink:none;
text-decoration-skip-ink:none
}
svg:not(:root) {
/*overflow: hidden;*/
overflow: visible;
address{
margin-bottom:1rem;
font-style:normal;
line-height:inherit
}
figure {
margin: 1em 40px;
ol,ul{
padding-left:2rem
}
hr {
-moz-box-sizing: content-box;
box-sizing: content-box;
height: 0;
ol,ul,dl{
margin-top:0;
margin-bottom:1rem
}
pre {
overflow: auto;
ol ol,ul ul,ol ul,ul ol{
margin-bottom:0
}
code,
kbd,
pre,
samp {
font-family: monospace, monospace;
font-size: 1em;
dt{
font-weight:700
}
button,
input,
optgroup,
select,
textarea {
color: inherit;
font: inherit;
margin: 0;
dd{
margin-bottom:.5rem;
margin-left:0
}
button {
overflow: visible;
blockquote{
margin:0 0 1rem
}
button,
select {
text-transform: none;
b,strong{
font-weight:bolder
}
button,
html input[type="button"],
input[type="reset"],
input[type="submit"] {
-webkit-appearance: button;
cursor: pointer;
small{
font-size:.875em
}
button[disabled],
html input[disabled] {
cursor: default;
mark{
padding:.2em;
background-color:#fcf8e3
}
button::-moz-focus-inner,
input::-moz-focus-inner {
border: 0;
padding: 0;
sub,sup{
position:relative;
font-size:.75em;
line-height:0;
vertical-align:baseline
}
input {
line-height: normal;
sub{
bottom:-0.25em
}
input[type="checkbox"],
input[type="radio"] {
box-sizing: border-box;
padding: 0;
sup{
top:-0.5em
}
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
height: auto;
a{
color:#0d6efd;
text-decoration:underline
}
input[type="search"] {
-webkit-appearance: textfield;
-moz-box-sizing: content-box;
-webkit-box-sizing: content-box;
box-sizing: content-box;
a:hover{
color:#024dbc
}
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
a:not([href]):not([class]),a:not([href]):not([class]):hover{
color:inherit;
text-decoration:none
}
fieldset {
border: 1px solid #c0c0c0;
margin: 0 2px;
padding: 0.35em 0.625em 0.75em;
pre,code,kbd,samp{
font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
font-size:1em
}
legend {
border: 0;
padding: 0;
pre{
display:block;
margin-top:0;
margin-bottom:1rem;
overflow:auto;
font-size:.875em;
-ms-overflow-style:scrollbar
}
textarea {
overflow: auto;
pre code{
font-size:inherit;
color:inherit;
word-break:normal
}
optgroup {
font-weight: bold;
code{
font-size:.875em;
color:#d63384;
word-wrap:break-word
}
table {
border-collapse: collapse;
border-spacing: 0;
a>code{
color:inherit
}
td,
th {
padding: 0;
kbd{
padding:.2rem .4rem;
font-size:.875em;
color:#fff;
background-color:#212529;
border-radius:.2rem
}
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
kbd kbd{
padding:0;
font-size:1em;
font-weight:700
}
*:before,
*:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
figure{
margin:0 0 1rem
}
html {
font-size: 10px;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
img,svg{
vertical-align:middle
}
input,
button,
select,
textarea {
font-family: inherit;
font-size: inherit;
line-height: inherit;
table{
caption-side:bottom;
border-collapse:collapse
}
figure {
margin: 0;
caption{
padding-top:.5rem;
padding-bottom:.5rem;
color:#6c757d;
text-align:left
}
img {
/*vertical-align: middle;*/
th{
text-align:inherit;
text-align:-webkit-match-parent
}
thead,tbody,tfoot,tr,td,th{
border-color:inherit;
border-style:solid;
border-width:0
}
label{
display:inline-block
}
button{
border-radius:0
}
button:focus{
outline:1px dotted;
outline:5px auto -webkit-focus-ring-color
}
input,button,select,optgroup,textarea{
margin:0;
font-family:inherit;
font-size:inherit;
line-height:inherit
}
button,input{
overflow:visible
}
button,select{
text-transform:none
}
[role=button]{
cursor:pointer
}
select{
word-wrap:normal
}
[list]::-webkit-calendar-picker-indicator{
display:none
}
button,[type=button],[type=reset],[type=submit]{
-webkit-appearance:button
}
button:not(:disabled),[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled){
cursor:pointer
}
::-moz-focus-inner{
padding:0;
border-style:none
}
textarea{
resize:vertical
}
fieldset{
min-width:0;
padding:0;
margin:0;
border:0
}
legend{
float:left;
width:100%;
padding:0;
margin-bottom:.5rem;
font-size:calc(1.275rem + 0.3vw);
line-height:inherit;
white-space:normal
}
@media(min-width: 1200px){
legend{
font-size:1.5rem
}
}
legend+*{
clear:left
}
::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-text,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-year-field{
padding:0
}
::-webkit-inner-spin-button{
height:auto
}
[type=search]{
outline-offset:-2px;
-webkit-appearance:textfield
}
::-webkit-search-decoration{
-webkit-appearance:none
}
::-webkit-color-swatch-wrapper{
padding:0
}
::-webkit-file-upload-button{
font:inherit;
-webkit-appearance:button
}
output{
display:inline-block
}
iframe{
border:0
}
summary{
display:list-item;
cursor:pointer
}
progress{
vertical-align:baseline
}
[hidden]{
display:none !important
}

View file

@ -0,0 +1,172 @@
/* Spicr theme | thednp © 2020 | MIT-License */
.text-left{
text-align:left
}
.text-center{
text-align:center
}
.text-right{
text-align:right
}
@media(min-width: 768px){
.text-md-left{
text-align:left
}
.text-md-center{
text-align:center
}
.text-md-right{
text-align:right
}
}
.center-block{
display:block;
margin-left:auto;
margin-right:auto
}
.float-right{
float:right !important
}
.float-left{
float:left !important
}
.float-none{
float:none !important
}
.font-weight-normal{
font-weight:normal
}
.font-weight-bold{
font-weight:bold
}
#SpicrDemo{
height:600px
}
.spicr .lead{
margin:0;
font-weight:bold;
text-transform:uppercase;
color:#fff
}
.overlay{
background:rgba(0,0,0,.45);
position:absolute;
top:0;
right:0;
width:100%;
height:100%
}
.spicr-carousel-navigation>*{
vertical-align:text-bottom
}
@media(min-width: 479px){
.spicr-control.long-shadows{
transition:opacity .3s ease-in
}
.spicr-control.long-shadows .arrow-prev{
margin-left:-280px;
padding:0px 5px 0px 250px;
transform:translate(-100%)
}
.spicr-control.long-shadows .arrow-next{
margin-right:-280px;
padding:0px 250px 0px 5px;
transform:translate(100%)
}
.spicr-control.long-shadows .arrow-prev,.spicr-control.long-shadows .arrow-next{
transition:all 1s ease-in
}
.spicr:hover .spicr-control.long-shadows .arrow-prev,.spicr:hover .spicr-control.long-shadows .arrow-next{
transition-duration:.3s;
transition-timing-function:ease-out
}
.spicr-control.long-shadows:focus .arrow-prev,.spicr-control.long-shadows:focus .arrow-next{
transform:translate(0%)
}
.spicr:hover .spicr-control.long-shadows .arrow-prev{
transform:translate(0%)
}
.spicr:hover .spicr-control.long-shadows .arrow-next{
transform:translate(0%)
}
.spicr-control.long-shadows .spicr-icon{
width:40px;
height:40px
}
.spicr-control.long-shadows .arrow-next,.spicr-control.long-shadows .arrow-prev{
border-radius:40px;
margin-top:-20px
}
.spicr-control.long-shadows:focus .arrow-prev{
transform:translate(0%)
}
.spicr-control.long-shadows:focus .arrow-next{
transform:translate(0%)
}
.spicr-control.long-shadows .arrow-prev,.spicr-control.long-shadows .arrow-next{
display:block;
width:auto;
height:auto;
background-color:#000;
background-color:rgba(0,0,0,.3)
}
}
.spicr-carousel h4{
margin-top:0
}
.spicr-slider{
font-size:calc(0.5rem + 1.5vw);
line-height:calc(0.6rem + 1.5vw)
}
.spicr-slider h1{
font-size:calc(1.375rem + 1.5vw);
letter-spacing:-1px;
margin:0
}
.spicr-slider h2{
font-size:calc(1.375rem + 0.9vw);
letter-spacing:0;
margin:0
}
.features-carousel .spicr-pages{
top:.5rem
}
.features-carousel .spicr-pages li{
line-height:1.5rem;
padding:.5rem 1rem
}
@media(min-width: 768px){
.featurette-heading span{
font-size:24px;
line-height:1;
letter-spacing:-1px
}
.spicr-slider{
font-size:1rem;
line-height:1.8rem
}
.spicr-slider h1{
font-size:42px;
line-height:1;
letter-spacing:-2px;
margin:0 0 1.5rem
}
.spicr-slider h2{
font-size:36px;
line-height:1;
letter-spacing:-1px;
margin:0 0 1.5rem
}
}
.background-top-left { background-position: top left !important}
.background-top-center { background-position: top center !important}
.background-top-right { background-position: top center !important}
.background-center-left { background-position: center left !important}
.background-center-center { background-position: center center !important}
.background-center-right { background-position: center right !important}
.background-bottom-left { background-position: bottom left !important}
.background-bottom-center { background-position: bottom center !important}
.background-bottom-right { background-position: bottom right !important}

View file

@ -1,9 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
<path id="rectangle" class="st0" d="M559,597.4H302.1H43.6c-21,0-38-17-38-38V408.8V223.6V44c0-21,17-38,38-38h105.6H300h160.3H559
c21,0,38,17,38,38v184v331.4C597,580.4,580,597.4,559,597.4z"/>
<path id="star" d="M302.1,17.9c16,29,81.4,147.7,98.2,178.2c31.1,6,62.3,11.9,93.4,17.9c35.5,6.8,71,13.6,106.5,20.4
c-46.4,49.5-92.7,99-139.1,148.5c1.1,8.5,6.7,53.4,12.4,99.1c5.7,45.3,11.4,91.4,12.9,102.9c-36-16.9-158.8-74.5-184.2-86.4
c-28.5,13.4-151.3,71-184.2,86.4c0.4-3.2,13.3-106.6,13.3-106.6s10.1-81,11.9-95.3C96.8,333.5,50.4,284,4,234.5
c34.4-6.6,68.8-13.2,103.3-19.8c32.2-6.2,64.4-12.3,96.5-18.5C221,165.1,286.5,46.2,302.1,17.9z"/>
<!-- Generator: Adobe Illustrator 23.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 600 600" style="enable-background:new 0 0 600 600;" xml:space="preserve">
<style type="text/css">
.st0{display:none;}
</style>
<path id="rectangle" class="st0" d="M559,597.4H302.1H43.6c-21,0-38-17-38-38V300V44c0-21,17-38,38-38H300h259c21,0,38,17,38,38
v257.7v257.7C597,580.4,580,597.4,559,597.4z"/>
<path id="star" d="M302.1,17.9c16,29,81.4,147.7,98.2,178.2c13.7,2.6,47.3,9.1,83.5,16c46.1,8.8,96.5,18.5,116.4,22.3
c-25.1,26.7-117.8,125.7-139.1,148.5c1.1,8.5,23.8,190.5,25.3,202c-36-16.9-158.8-74.5-184.2-86.4c-28.5,13.4-151.3,71-184.2,86.4
c0.4-3.2,23.4-187.6,25.2-201.9C122.8,361.3,30,262.3,4,234.5c17.3-3.3,59.5-11.4,101.3-19.4c41.4-7.9,82.5-15.8,98.5-18.9
C221,165.1,286.5,46.2,302.1,17.9z"/>
</svg>

Before

Width:  |  Height:  |  Size: 770 B

After

Width:  |  Height:  |  Size: 997 B

View file

@ -1,29 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" id="complex-morph-example" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 513">
<path id="symbol-left" d="M155.9,333.4h-55.6c-3.4,0-5.9-1.5-7.3-3.8c-1.5-2.4-1.5-5.5,0-8.5l59.1-104.3c0.1-0.1,0.1-0.2,0-0.3
l-37.6-65.1c-1.6-3.1-1.8-6.2-0.3-8.5c1.4-2.3,4.2-3.5,7.6-3.5h55.6c8.5,0,12.7,5.5,15.5,10.4c0,0,38,66.3,38.2,66.7
c-2.3,4-60.1,106.2-60.1,106.2C168.2,327.8,164.2,333.4,155.9,333.4z"/>
<path id="symbol-left-clone" class="st0" d="M155.9,333.4h-55.6c-3.4,0-5.9-1.5-7.3-3.8c-1.5-2.4-1.5-5.5,0-8.5l59.1-104.3
c0.1-0.1,0.1-0.2,0-0.3l-37.6-65.1c-1.6-3.1-1.8-6.2-0.3-8.5c1.4-2.3,4.2-3.5,7.6-3.5h55.6c8.5,0,12.7,5.5,15.5,10.4
c0,0,38,66.3,38.2,66.7c-2.3,4-60.1,106.2-60.1,106.2C168.2,327.8,164.2,333.4,155.9,333.4z"/>
<path id="symbol-right" class="st0" d="M419,75.3L295.8,293.1c-0.1,0.1-0.1,0.3,0,0.4l78.4,143.3c1.6,3.1,1.6,6.2,0.1,8.6
c-1.4,2.3-4,3.6-7.4,3.6h-55.6c-8.5,0-12.8-5.7-15.5-10.6c0,0-78.8-144.6-79.1-145c3.9-7,123.8-219.5,123.8-219.5
c3-5.4,6.6-10.6,14.9-10.6h56.2c3.4,0,6,1.3,7.4,3.6C420.5,69.1,420.5,72.2,419,75.3L419,75.3z"/>
<path id="eye-right" class="st0" d="M352,128c2.6,0,5,0.5,7.4,1.3c2.3,0.8,4.5,2,6.6,3.6c10.6,7.8,18,24.2,18,43.1
c0,16.2-5.3,30.5-13.5,39.2c-3.1,3.3-6.6,5.8-10.5,7.3c-2.6,1-5.3,1.5-8,1.5c-4,0-7.8-1.1-11.3-3.1c-2.7-1.6-5.3-3.7-7.6-6.2
c-7.9-8.7-13-22.8-13-38.7c0-19.2,7.5-35.7,18.4-43.4c1.9-1.4,4-2.5,6.1-3.2C346.9,128.5,349.4,128,352,128z"/>
<path id="eye-left" class="st0" d="M176,156c10.4,0,19.7,1.4,27.5,3.9c14.5,4.7,23.5,13.4,23.5,24.8c0,3.7,1.9,21.5-0.1,24.8
c-3.3-5.5-9.2-10.3-16.7-13.9c-5.6-2.7-12.2-4.8-19.4-6c-4.7-0.8-9.6-1.2-14.7-1.2c-8.9,0-17.3,1.3-24.7,3.5
c-12.2,3.7-21.6,10-26.3,17.6c-2-3.3-0.1-21.1-0.1-24.8c0-11.3,8.8-19.9,23-24.6c3.7-1.2,7.8-2.2,12.2-2.9
C165.1,156.4,170.4,156,176,156z"/>
<path id="mouth" d="M250.2,416c-42.9,0-82-16.6-111.5-43.9c-7-6.5-13.5-13.6-19.4-21.2c-3.8-4.9-7.3-10-10.6-15.4
c5.6,4.4,11.9,8.2,18.7,11.5c7.1,3.4,14.8,6.2,23,8.4c33.9,9.2,76.7,8.9,120.9,0.1c47.2-9.3,87.3-26.8,114.5-50.3
c6-5.1,11.3-10.6,16-16.3c5.6-6.9,10.3-14.2,13.8-21.8c-1.2,9.2-3.1,18.2-5.7,26.9c-2.6,8.8-5.9,17.3-9.7,25.5
C373.1,376.7,316.1,416,250.2,416L250.2,416z"/>
<path id="rectangle-container" class="st2" d="M426.7,0H85.3C38.4,0,0,38.4,0,85.3v341.3c0,47,38.4,85.3,85.3,85.3h341.3
c46.9,0,85.3-38.4,85.3-85.3V85.3C512,38.4,473.6,0,426.7,0z"/>
<path id="circle-container" class="st0" d="M0,256c0,100.9,59.8,165.3,72,177.9c11.2,11.6,77.7,78.1,184,78.1
c14.5,0,115.8-1.7,190.7-85.3C510.1,356,512,274.1,512,256c0-18.9-2.1-96.7-61-165.9C375.7,1.8,269.4,0,256,0
C241,0,141.3,1.7,66.6,83.7C1.9,154.8,0,237.9,0,256z"/>
<!-- Generator: Adobe Illustrator 23.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="complex-morph-example" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px" y="0px" viewBox="0 0 513 513" style="enable-background:new 0 0 513 513;" xml:space="preserve">
<style type="text/css">
.st0{display:none;}
</style>
<path id="symbol-left" class="st0" d="M155.9,333.4h-55.6c-3.4,0-5.9-1.5-7.3-3.8c-1.5-2.4-1.5-5.5,0-8.5l59.1-104.3
c0.1-0.1,0.1-0.2,0-0.3l-37.6-65.1c-1.6-3.1-1.8-6.2-0.3-8.5c1.4-2.3,4.2-3.5,7.6-3.5h55.6c8.5,0,12.7,5.5,15.5,10.4
c0,0,38,66.3,38.2,66.7c-2.3,4-60.1,106.2-60.1,106.2C168.2,327.8,164.2,333.4,155.9,333.4z"/>
<path id="symbol-left-clone" class="st0" d="M155.9,333.4h-55.6c-3.4,0-5.9-1.5-7.3-3.8c-1.5-2.4-1.5-5.5,0-8.5l59.1-104.3
c0.1-0.1,0.1-0.2,0-0.3l-37.6-65.1c-1.6-3.1-1.8-6.2-0.3-8.5c1.4-2.3,4.2-3.5,7.6-3.5h55.6c8.5,0,12.7,5.5,15.5,10.4
c0,0,38,66.3,38.2,66.7c-2.3,4-60.1,106.2-60.1,106.2C168.2,327.8,164.2,333.4,155.9,333.4z"/>
<path id="symbol-right" class="st0" d="M419,75.3L295.8,293.1c-0.1,0.1-0.1,0.3,0,0.4l78.4,143.3c1.6,3.1,1.6,6.2,0.1,8.6
c-1.4,2.3-4,3.6-7.4,3.6h-55.6c-8.5,0-12.8-5.7-15.5-10.6c0,0-78.8-144.6-79.1-145c3.9-7,123.8-219.5,123.8-219.5
c3-5.4,6.6-10.6,14.9-10.6h56.2c3.4,0,6,1.3,7.4,3.6C420.5,69.1,420.5,72.2,419,75.3L419,75.3z"/>
<path id="eye-right" class="st0" d="M352,128c2.6,0,5,0.5,7.4,1.3c2.3,0.8,4.5,2,6.6,3.6c10.6,7.8,18,24.2,18,43.1
c0,16.2-5.3,30.5-13.5,39.2c-3.1,3.3-6.6,5.8-10.5,7.3c-2.6,1-5.3,1.5-8,1.5c-4,0-7.8-1.1-11.3-3.1c-2.7-1.6-5.3-3.7-7.6-6.2
c-7.9-8.7-13-22.8-13-38.7c0-19.2,7.5-35.7,18.4-43.4c1.9-1.4,4-2.5,6.1-3.2C346.9,128.5,349.4,128,352,128z"/>
<path id="eye-left" class="st0" d="M176,156c10.4,0,19.7,1.4,27.5,3.9c14.5,4.7,23.5,13.4,23.5,24.8c0,3.7,1.9,21.5-0.1,24.8
c-3.3-5.5-9.2-10.3-16.7-13.9c-5.6-2.7-12.2-4.8-19.4-6c-4.7-0.8-9.6-1.2-14.7-1.2c-8.9,0-17.3,1.3-24.7,3.5
c-12.2,3.7-21.6,10-26.3,17.6c-2-3.3-0.1-21.1-0.1-24.8c0-11.3,8.8-19.9,23-24.6c3.7-1.2,7.8-2.2,12.2-2.9
C165.1,156.4,170.4,156,176,156z"/>
<path id="mouth" class="st0" d="M250.2,416c-42.9,0-82-16.6-111.5-43.9c-7-6.5-13.5-13.6-19.4-21.2c-3.8-4.9-7.3-10-10.6-15.4
c5.6,4.4,11.9,8.2,18.7,11.5c7.1,3.4,14.8,6.2,23,8.4c33.9,9.2,76.7,8.9,120.9,0.1c47.2-9.3,87.3-26.8,114.5-50.3
c6-5.1,11.3-10.6,16-16.3c5.6-6.9,10.3-14.2,13.8-21.8c-1.2,9.2-3.1,18.2-5.7,26.9c-2.6,8.8-5.9,17.3-9.7,25.5
C373.1,376.7,316.1,416,250.2,416L250.2,416z"/>
<path id="rectangle-container" class="st0" d="M426.7,0H85.3C38.4,0,0,38.4,0,85.3v341.3c0,47,38.4,85.3,85.3,85.3h341.3
c46.9,0,85.3-38.4,85.3-85.3V85.3C512,38.4,473.6,0,426.7,0z"/>
<path id="circle-container" d="M0,256c0,100.9,59.8,165.3,72,177.9c9.1,9.4,34.7,34.4,75.6,53.5c50.6,23.7,95,24.6,108.4,24.6
c10.9,0,61.3-0.9,117.6-30c42.1-21.8,67.4-49,73.1-55.3c64-70.6,65.3-157,65.3-170.7c0-18.9-2.1-96.7-61-165.9
c-8.6-10.2-37.3-42-86-65C313.6,0.9,268.6,0,256,0c-11,0-61.8,0.8-118.2,30.1C97.1,51.3,72.4,77.3,66.6,83.7C1.3,154.7,0,243,0,256z
"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 3 KiB

View file

@ -1,68 +1,14 @@
var frontpage = document.getElementsByClassName('frontpage'),
rectangle = document.getElementById('rectangle'),
star = document.getElementById('star'),
hexagon = document.getElementById('hexagon'),
cat = document.getElementById('cat'),
circle = document.getElementById('circle'),
head = document.getElementById('head'),
winkyFace = document.getElementById('winky-face'),
dropInitial = document.getElementById('drop-initial'),
drop = document.getElementById('drop'),
mouth = document.getElementById('mouth'),
eyeLeft = document.getElementById('eye-left'),
eyeRight = document.getElementById('eye-right'),
heading = document.querySelector('h2.nomargin'),
plead = document.querySelector('p.lead')
var SpicrMainDemo = document.getElementById('SpicrDemo');
var t0 = KUTE.to(rectangle,{translateX:0, opacity:1 }, { easing:'easingCubicOut'}),
t1 = KUTE.fromTo(rectangle,{path:rectangle, attr: {fill: rectangle.getAttribute('fill') }}, {path:star, attr: {fill: star.getAttribute('fill') }}, {morphPrecision: 5, easing:'easingCubicOut'}),
t2 = KUTE.fromTo(rectangle,{path:star, rotateZ: 0, attr: {fill: rectangle.getAttribute('fill') }}, {path:hexagon, rotateZ: 360, attr: {fill: hexagon.getAttribute('fill') }}, {morphPrecision: 5, easing:'easingCubicOut'}),
t3 = KUTE.fromTo(rectangle,{path:hexagon, attr: {fill: rectangle.getAttribute('fill') }}, {path:cat, attr: {fill: cat.getAttribute('fill') }}, {morphPrecision: 5, easing:'easingCubicOut'}),
t4 = KUTE.fromTo(rectangle,{path:cat, attr: {fill: rectangle.getAttribute('fill') }}, {path:circle, attr: {fill: circle.getAttribute('fill') }}, {morphPrecision: 5, easing:'easingCubicOut'}),
t5 = KUTE.fromTo(rectangle,{path:circle, attr: {fill: rectangle.getAttribute('fill') }}, {path:head, attr: {fill: head.getAttribute('fill') }}, {morphPrecision: 5, easing:'easingCubicOut'}),
t6 = KUTE.fromTo(dropInitial,{path: dropInitial,opacity:1},{path: drop,opacity:1}, {morphPrecision: 5, easing:'easingCubicOut', onComplete: mergeLogo}),
t7 = KUTE.to(mouth,{opacity:1}),
t8 = KUTE.to(eyeLeft,{opacity:1}),
t9 = KUTE.to(eyeRight,{opacity:1}),
t10 = KUTE.fromTo(winkyFace,{opacity:0,translateY:50},{opacity:1,translateY:0},{easing:'easingCubicOut'}),
t11 = KUTE.to(eyeLeft,{path:'#eye-left-closed'}, {morphPrecision: 5}, {easing:'easingCubicOut'}),
t12 = KUTE.to(eyeRight,{path:'#eye-right-closed'}, {morphPrecision: 5}, {easing:'easingCubicOut'}),
t13 = KUTE.to(mouth,{path:'#mouth-happy'}, {morphPrecision: 5, easing:'easingCubicOut', duration:3500}),
loop1 = KUTE.to(rectangle,{ attr: {fill: '#52aef7' }}, {duration: 1500}),
loop2 = KUTE.to(rectangle,{ attr: {fill: '#f98f6d' }}, {duration: 1500}),
loop3 = KUTE.to(rectangle,{ attr: {fill: '#f95054' }}, {duration: 1500}),
loop4 = KUTE.to(rectangle,{ attr: {fill: '#ffd626' }}, {duration: 1500}),
loop5 = KUTE.to(rectangle,{ attr: {fill: '#d661ea' }}, {duration: 1500}),
showText = KUTE.to(heading,{opacity: 1},{duration: 3000}),
showText1 = KUTE.fromTo(heading,{ text: ''},{ text:heading.getAttribute('data-text')},{duration: 1500}),
showText2 = KUTE.fromTo(plead,{ text:''}, { text:plead.getAttribute('data-text')},{duration: 3500, onComplete: textComplete}),
showBTNS = KUTE.allFromTo('.btns .btn',{opacity: 0, translate3d: [150,50,0]}, {opacity: 1, translate3d: [0,0,0]},{duration: 500, offset: 250, delay: 500, easing: 'easingBackOut'})
function mergeLogo(){
rectangle.setAttribute('d', rectangle.getAttribute('d')+ drop.getAttribute('d') )
dropInitial.style.opacity = 0
}
function textComplete(){
heading.removeAttribute('data-text')
plead.removeAttribute('data-text')
showBTNS.start()
function initMainSpicr(){
new Spicr(SpicrMainDemo);
}
t0.chain(t1)
t1.chain(t2)
t2.chain(t3)
t3.chain(t4)
t4.chain([t5,t6])
t6.chain([t7,t8,t9])
t9.chain([t10,t11,t12,t13])
function loadCarouselMedia(){
new dll(SpicrMainDemo,initMainSpicr)
}
t8.chain([loop1,showText,showText1])
showText1.chain(showText2)
loop1.chain(loop2)
loop2.chain(loop3)
loop3.chain(loop4)
loop4.chain(loop5)
loop5.chain(loop1)
t0.start()
document.addEventListener('DOMContentLoaded', function loadWrapper(){
loadCarouselMedia();
document.removeEventListener('DOMContentLoaded', loadWrapper, false)
}, false);

View file

@ -78,18 +78,18 @@ function complete(){
container.style.display = 'none';
}
var engine = document.getElementById('kute'),
fromCSS = { rotate3d: [ 0, 0,0 ], perspective:600 },
fromMX = { transform: { rotate3d: [ 0, 0,0 ], perspective:600 }},
toCSS = { rotate3d: [ 360,0,0 ], perspective:600 },
toMX = { transform: { rotate3d: [ 0,360,0 ], perspective:600 }},
ops = { duration: 2000, repeat: 5 }
var engine = document.getElementById('kute'),
fromCSS = { rotate3d: [ 0, 0,0 ], perspective:600 },
fromMX = { transform: { rotate3d: [ 0, 0,0 ], perspective:600 }},
toCSS = { rotate3d: [ 360,0,0 ], perspective:600 },
toMX = { transform: { rotate3d: [ 0,360,0 ], perspective:600 }},
ops = { duration: 2000, repeat: 5 }
// since our engines don't do sync, we make it our own here
if (engine.src.indexOf('kute.min.js')>-1) {
if (!engine.src.includes('extra')) {
[].slice.call(collection).map((el,i) => { i===lastIdx && (ops.onComplete = complete); tws.push ( KUTE.fromTo(el,fromCSS,toCSS,ops) ) })
}
if (engine.src.indexOf('kute-extra.min.js')>-1) {
if (engine.src.includes('extra')) {
[].slice.call(collection).map((el,i) => { i===lastIdx && (ops.onComplete = complete); tws.push ( KUTE.fromTo(el,fromMX,toMX,ops) ) })
}
@ -98,15 +98,13 @@ function startTest(){
infoContainer.style.display = 'none';
container.style.display = 'block'
!tws[0].playing && startKUTE();
tws.length && !tws[0].playing && startKUTE();
}
function startKUTE() {
var now = window.performance.now(), count = tws.length;
for (var t=0; t<count; t++){
tws[t].start(now)
}
tws.forEach((t) => t.start(now));
}
// the start button handle

View file

@ -1,32 +1,47 @@
// general tween options
var morphOps = {
duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'
}
// basic morph
var morphTween = KUTE.to('#rectangle', { path: '#star' }, {
duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'
});
var morphTween1 = KUTE.to('#rectangle1', { path: '#star1' }, {
duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'
});
var morphTween = KUTE.to('#rectangle', { path: '#star' }, morphOps);
var morphTween2 = KUTE.to('#rectangle2', { path: '#star2' }, morphOps);
var morphBtn = document.getElementById('morphBtn');
morphBtn.addEventListener('click', function(){
!morphTween.playing && morphTween.start() && morphTween1.start()
!morphTween.playing && morphTween.start();
!morphTween2.playing && morphTween2.start();
}, false);
// line to circle
var lineMorph = KUTE.to('#line' ,{path:'#circle' }, morphOps);
var lineMorph1 = KUTE.to('#line1',{path:'#circle1'}, morphOps);
var morphBtnClosed = document.getElementById('morphBtnClosed')
morphBtnClosed.addEventListener('click', function(){
!lineMorph.playing && lineMorph.start();
!lineMorph1.playing && lineMorph1.start();
}, false);
var morphOps1 = {
duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'
}
// multishape morph
var multiMorphBtn = document.getElementById('multiMorphBtn');
var multiMorph1 = KUTE.fromTo('#w11', { path: '#w11', attr:{ fill: "rgb(233,27,31)" } }, { path: '#w21', attr:{ fill: "#56C5FF" } }, { reverseSecondPath: true, duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'});
var multiMorph2 = KUTE.fromTo('#w12', { path: '#w12', attr:{ fill: "rgb(255,87,34)" } }, { path: '#w22', attr:{ fill: "#56C5FF" } }, { reverseSecondPath: true, duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'});
var multiMorph3 = KUTE.fromTo('#w13', { path: '#w13', attr:{ fill: "rgb(76,175,80)" } }, { path: '#w23', attr:{ fill: "#56C5FF" } }, { reverseSecondPath: true, duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'});
var multiMorph4 = KUTE.fromTo('#w14', { path: '#w14', attr:{ fill: "rgb(33,150,243)" } }, { path: '#w24', attr:{ fill: "#56C5FF" } }, { reverseSecondPath: true, duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'});
var multiMorph1 = KUTE.fromTo('#w11', { path: '#w11', attr:{ fill: "rgb(233,27,31)" } }, { path: '#w21', attr:{ fill: "#56C5FF" } }, morphOps1);
var multiMorph2 = KUTE.fromTo('#w12', { path: '#w12', attr:{ fill: "rgb(255,87,34)" } }, { path: '#w22', attr:{ fill: "#56C5FF" } }, morphOps1);
var multiMorph3 = KUTE.fromTo('#w13', { path: '#w13', attr:{ fill: "rgb(76,175,80)" } }, { path: '#w23', attr:{ fill: "#56C5FF" } }, morphOps1);
var multiMorph4 = KUTE.fromTo('#w14', { path: '#w14', attr:{ fill: "rgb(33,150,243)" } }, { path: '#w24', attr:{ fill: "#56C5FF" } }, morphOps1);
var multiMorph11 = KUTE.fromTo('#w111', { path: '#w111', attr:{ fill: "rgb(233,27,31)" } }, { path: '#w211', attr:{ fill: "#56C5FF" } }, { reverseSecondPath: true, duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'});
var multiMorph21 = KUTE.fromTo('#w121', { path: '#w121', attr:{ fill: "rgb(255,87,34)" } }, { path: '#w221', attr:{ fill: "#56C5FF" } }, { reverseSecondPath: true, duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'});
var multiMorph31 = KUTE.fromTo('#w131', { path: '#w131', attr:{ fill: "rgb(76,175,80)" } }, { path: '#w231', attr:{ fill: "#56C5FF" } }, { reverseSecondPath: true, duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'});
var multiMorph41 = KUTE.fromTo('#w141', { path: '#w141', attr:{ fill: "rgb(33,150,243)" } }, { path: '#w241', attr:{ fill: "#56C5FF" } }, { reverseSecondPath: true, duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'});
var multiMorph11 = KUTE.fromTo('#w111', { path: '#w111', attr:{ fill: "rgb(233,27,31)" } }, { path: '#w211', attr:{ fill: "#56C5FF" } }, morphOps1);
var multiMorph21 = KUTE.fromTo('#w121', { path: '#w121', attr:{ fill: "rgb(255,87,34)" } }, { path: '#w221', attr:{ fill: "#56C5FF" } }, morphOps1);
var multiMorph31 = KUTE.fromTo('#w131', { path: '#w131', attr:{ fill: "rgb(76,175,80)" } }, { path: '#w231', attr:{ fill: "#56C5FF" } }, morphOps1);
var multiMorph41 = KUTE.fromTo('#w141', { path: '#w141', attr:{ fill: "rgb(33,150,243)" } }, { path: '#w241', attr:{ fill: "#56C5FF" } }, morphOps1);
var multiMorph1s = KUTE.fromTo('#s11', { path: '#s11', attr:{ fill: "rgb(233,27,31)" } }, { path: '#s23', attr:{ fill: "#56C5FF" } }, { reverseSecondPath: true, duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'});
var multiMorph2s = KUTE.fromTo('#s12', { path: '#s12', attr:{ fill: "rgb(255,87,34)" } }, { path: '#s21', attr:{ fill: "#56C5FF" } }, { reverseSecondPath: true, duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'});
var multiMorph3s = KUTE.fromTo('#s13', { path: '#s13', attr:{ fill: "rgb(76,175,80)" } }, { path: '#s24', attr:{ fill: "#56C5FF" } }, { reverseSecondPath: true, duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'});
var multiMorph4s = KUTE.fromTo('#s14', { path: '#s14', attr:{ fill: "rgb(33,150,243)" } }, { path: '#s22', attr:{ fill: "#56C5FF" } }, { reverseSecondPath: true, duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'});
var multiMorph1s = KUTE.fromTo('#s11', { path: '#s11', attr:{ fill: "rgb(233,27,31)" } }, { path: '#s23', attr:{ fill: "#56C5FF" } }, morphOps1);
var multiMorph2s = KUTE.fromTo('#s12', { path: '#s12', attr:{ fill: "rgb(255,87,34)" } }, { path: '#s21', attr:{ fill: "#56C5FF" } }, morphOps1);
var multiMorph3s = KUTE.fromTo('#s13', { path: '#s13', attr:{ fill: "rgb(76,175,80)" } }, { path: '#s24', attr:{ fill: "#56C5FF" } }, morphOps1);
var multiMorph4s = KUTE.fromTo('#s14', { path: '#s14', attr:{ fill: "rgb(33,150,243)" } }, { path: '#s22', attr:{ fill: "#56C5FF" } }, morphOps1);
multiMorphBtn.addEventListener('click', function(){
!multiMorph1.playing && multiMorph1.start() && multiMorph11.start() && multiMorph1s.start();
@ -37,24 +52,19 @@ multiMorphBtn.addEventListener('click', function(){
// complex multi morph
var compliMorphBtn = document.getElementById('compliMorphBtn');
var compliMorph1 = KUTE.fromTo('#rectangle-container', {path: '#rectangle-container', attr:{ fill: "#2196F3"} }, { path: '#circle-container', attr:{ fill: "#FF5722"} }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'});
var compliMorph2 = KUTE.fromTo('#symbol-left', {path: '#symbol-left'}, { path: '#eye-left' }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'});
var compliMorph3 = KUTE.fromTo('#symbol-left-clone', {path: '#symbol-left-clone'}, { path: '#mouth' }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'});
var compliMorph4 = KUTE.fromTo('#symbol-right', {path: '#symbol-right'}, { path: '#eye-right' }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'});
var compliMorph1 = KUTE.fromTo('#rectangle-container', {path: '#rectangle-container', attr:{ fill: "#2196F3"} }, { path: '#circle-container', attr:{ fill: "#FF5722"} }, morphOps1);
var compliMorph2 = KUTE.fromTo('#symbol-left', {path: '#symbol-left'}, { path: '#eye-left' }, morphOps1);
var compliMorph3 = KUTE.fromTo('#symbol-left-clone', {path: '#symbol-left-clone'}, { path: '#mouth' }, morphOps1);
var compliMorph4 = KUTE.fromTo('#symbol-right', {path: '#symbol-right'}, { path: '#eye-right' }, morphOps1);
var compliMorph11 = KUTE.fromTo('#rectangle-container1', {path: '#rectangle-container1', attr:{ fill: "#9C27B0"} }, { path: '#circle-container1', attr:{ fill: "#FF5722"} }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'});
var compliMorph21 = KUTE.fromTo('#symbol-left1', {path: '#symbol-left1'}, { path: '#eye-left1' }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'});
var compliMorph31 = KUTE.fromTo('#symbol-left-clone1', {path: '#symbol-left-clone1'}, { path: '#mouth1' }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'});
var compliMorph41 = KUTE.fromTo('#symbol-right1', {path: '#symbol-right1'}, { path: '#eye-right1' }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'});
var compliMorph12 = KUTE.fromTo('#rectangle-container2', {path: '#rectangle-container2', attr:{ fill: "#e91b1f"} }, { path: '#circle-container2', attr:{ fill: "#FF5722"} }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'});
var compliMorph22 = KUTE.fromTo('#symbol-left2', {path: '#symbol-left2'}, { path: '#eye-left2' }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'});
var compliMorph32 = KUTE.fromTo('#sample-shape2', {path: '#sample-shape2'}, { path: '#mouth2' }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'});
var compliMorph42 = KUTE.fromTo('#symbol-right2', {path: '#symbol-right2'}, { path: '#eye-right2' }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'});
var compliMorph12 = KUTE.fromTo('#rectangle-container2', {path: '#rectangle-container2', attr:{ fill: "#e91b1f"} }, { path: '#circle-container2', attr:{ fill: "#FF5722"} }, morphOps1);
var compliMorph22 = KUTE.fromTo('#symbol-left2', {path: '#symbol-left2'}, { path: '#eye-left2' }, morphOps1);
var compliMorph32 = KUTE.fromTo('#sample-shape2', {path: '#sample-shape2'}, { path: '#mouth2' }, morphOps1);
var compliMorph42 = KUTE.fromTo('#symbol-right2', {path: '#symbol-right2'}, { path: '#eye-right2' }, morphOps1);
compliMorphBtn.addEventListener('click', function(){
!compliMorph1.playing && compliMorph1.start() && compliMorph11.start() && compliMorph12.start();
!compliMorph2.playing && compliMorph2.start() && compliMorph21.start() && compliMorph22.start();
!compliMorph3.playing && compliMorph3.start() && compliMorph31.start() && compliMorph32.start();
!compliMorph4.playing && compliMorph4.start() && compliMorph41.start() && compliMorph42.start();
!compliMorph1.playing && compliMorph1.start() && compliMorph12.start();
!compliMorph2.playing && compliMorph2.start() && compliMorph22.start();
!compliMorph3.playing && compliMorph3.start() && compliMorph32.start();
!compliMorph4.playing && compliMorph4.start() && compliMorph42.start();
}, false);

View file

@ -8,6 +8,15 @@ morphBtn.addEventListener('click', function(){
!morphTween.playing && morphTween.start();
}, false);
// line to circle
var lineMorph = KUTE.to('#line',{path:'#circle'},{ yoyo:true, repeat:1, duration:2000, easing: 'easingCubicOut'}),
lineMorph1 = KUTE.to('#line1',{path:'#circle1'},{ yoyo:true, repeat:1, duration:2000, easing: 'easingCubicOut'}),
morphBtnClosed = document.getElementById('morphBtnClosed');
morphBtnClosed.addEventListener('click', function(){
!lineMorph.playing && lineMorph.start()
!lineMorph1.playing && lineMorph1.start()
}, false);
// polygon morph
var morphTween21 = KUTE.fromTo('#triangle', {attr: { fill: '#673AB7'}, path: '#triangle' }, { attr: { fill: '#2196F3' }, path: '#square' }, {

View file

@ -6,10 +6,11 @@ var translateExamples = document.getElementById('translate-examples'),
trx = translateExamples.getElementsByTagName('div')[1],
trry = translateExamples.getElementsByTagName('div')[2],
trz = translateExamples.getElementsByTagName('div')[3],
tr2dTween = KUTE.to(tr2d, {translate:[170,0]}, {easing:'easingCubicOut', yoyo:true, repeat: 1, duration:1500}),
trxTween = KUTE.to(trx, {translateX:-170}, {easing:'easingCubicOut', yoyo:true, repeat: 1, duration:1500})
tr2dTween = KUTE.to(tr2d, {translate:[170,170]}, {easing:'easingCubicOut', yoyo:true, repeat: 1, duration:1500}),
trxTween = KUTE.to(trx, {translateX:-170}, {easing:'easingCubicOut', yoyo:true, repeat: 1, duration:1500}),
trryTween = KUTE.to(trry, {translate3d:[0,170,0]}, {easing:'easingCubicOut', yoyo:true, repeat: 1, duration:1500}),
trzTween = KUTE.to(trz, {perspective:200, translate3d:[0,0,-100]}, {easing:'easingCubicOut', yoyo:true, repeat: 1, duration:1500});
translateBtn.addEventListener('click', function(){
!tr2dTween.playing && tr2dTween.start();
!trxTween.playing && trxTween.start();
@ -27,6 +28,7 @@ var rotExamples = document.getElementById('rotExamples'),
rxTween = KUTE.to(rx, {rotateX:180}, {easing:'linear', yoyo:true, repeat: 1, duration:1500}),
ryTween = KUTE.to(ry, {perspective:200, rotate3d:[0,-180,0],scale:1.2}, {easing:'easingCubicInOut', yoyo:true, repeat: 1, duration:1500}),
rzTween = KUTE.to(rz, {rotateZ:360}, {easing:'easingBackOut', yoyo:true, repeat: 1, duration:1500});
rotBtn.addEventListener('click', function(){
!r2dTween.playing && r2dTween.start();
!rxTween.playing && rxTween.start();

View file

@ -35,10 +35,10 @@ var tween13 = KUTE.fromTo(el1, { transform: {perspective:400,translate3d:[150,20
// chain tweens
try {
tween11.chain(tween12);
tween12.chain(tween13);
tween11.chain(tween12);
tween12.chain(tween13);
} catch(e) {
console.warn(e+". TweenBase doesn\'t support chain method")
console.warn(e+". TweenBase doesn\'t support chain method")
}
// built the tween objects for element2
@ -48,10 +48,10 @@ var tween23 = KUTE.fromTo(el2, { transform: {perspective:400,translate3d:[150,20
// chain tweens
try{
tween21.chain(tween22);
tween22.chain(tween23);
tween21.chain(tween22);
tween22.chain(tween23);
}catch(e){
console.warn(e+". TweenBase doesn\'t support chain method")
console.warn(e+". TweenBase doesn\'t support chain method")
}
// built the tween objects for element3

View file

@ -1,108 +1,107 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="The Background Position component for KUTE.js allows you to animate the background-position property on most browsers.">
<meta name="keywords" content="backgroundPosition,background-position,background,kute,kute.js,animation,javascript animation,tweening engine,animation engine,JavaScript,Native JavaScript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<!-- TO DO -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="The Background Position component for KUTE.js allows you to animate the background-position property on most browsers.">
<meta name="keywords" content="backgroundPosition,background-position,background,kute,kute.js,animation,javascript animation,tweening engine,animation engine,JavaScript,Native JavaScript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<title>KUTE.js Background Position</title>
<title>KUTE.js Background Position</title>
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
<style></style>
<style></style>
</head>
<body>
<div class="site-wrapper">
<div class="site-wrapper">
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-space">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li class="active"><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-between">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li class="active"><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</div>
</nav>
</div>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div class="content-wrap">
<h2 class="head-title">Background Position</h2>
<p class="condensed lead">The component that animates the CSS property controling the <i>background-position</i> property of a target element.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<h2 class="head-title">Background Position</h2>
<p class="condensed lead">The component that animates the CSS property controling the <i>background-position</i> property of a target element.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<div class="columns">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">Animate the position of the background image, simple and effective.</p>
</div>
<div class="col9 border">
<p class="lead condensed">The KUTE.js <b>Background Position</b> component enables animation for the CSS <b>backgroundPosition</b> property on most browsers.</p>
<p>It can handle an entire set of input values <b>[x,y]</b>, <b>'0% 50%'</b> and even <b>'left center'</b>. The component always updates the values of the position
property via <b>%</b> suffix for simplicity reasons and even if <b>px</b> or any other unit is supported.</p>
<p>While we might not have much use for this kind of animation, some older browsers will love to show you something if that is the case.</p>
</div>
<div class="columns">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">Animate the position of the background image, simple and effective.</p>
</div>
<div class="col9 border">
<p class="lead condensed">The KUTE.js <b>Background Position</b> component enables animation for the CSS <b>backgroundPosition</b> property on most browsers.</p>
<p>It can handle an entire set of input values <b>[x,y]</b>, <b>'0% 50%'</b> and even <b>'left center'</b>. The component always updates the values of the position
property via <b>%</b> suffix for simplicity reasons and even if <b>px</b> or any other unit is supported.</p>
<p>While we might not have much use for this kind of animation, some older browsers will love to show you something if that is the case.</p>
</div>
</div>
</div>
</div>
<div class="content-wrap">
<div class="content-wrap">
<h3>Example</h3>
<h3>Example</h3>
<p>Here a couple of possible tween objects:</p>
<p>Here a couple of possible tween objects:</p>
<pre><code class="language-javascript">// provide the exact values for interpolation
let bgPosTween = KUTE.to('selector1',{backgroundPosition:[0,50]}).start();
@ -114,45 +113,45 @@ let bgPosTween = KUTE.to('selector1',{backgroundPosition:"0% 50%"}).start();
let bgPosTween = KUTE.to('selector1',{backgroundPosition:"left center"}).start();
</code></pre>
<div id="bgPos" class="featurettes">
<div class="example-item example-box" style="background: url('https://picsum.photos/400/300') center center no-repeat;"></div>
<div id="bgPos" class="featurettes">
<div class="example-item example-box" style="background: url('https://picsum.photos/400/300') center center no-repeat;"></div>
<div class="example-buttons">
<a class="btn btn-orange" href="#">Start</a>
</div>
</div>
<div class="example-buttons">
<a class="btn btn-orange" href="#">Start</a>
</div>
</div>
<h3>Notes</h3>
<ul>
<li>Unfortunatelly this property also has no access at the sub-pixel level, animations are as good as it gets, despite the fact that the <code>%</code> suffix is used.</li>
<li>There are thankfully replacements for this forgotten property that strangelly supports CSS3 transitions, you can simply use all kinds of SVG masks and filters
and the <a href="htmlAttributes.html">HTML Attributes</a> component for much more animation potential and supreme animation quality.</li>
<li>This component is bundled with the <i>demo/src/kute-extra.js</i> file.</li>
</ul>
</div>
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2020 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
<h3>Notes</h3>
<ul>
<li>Unfortunatelly this property also has no access at the sub-pixel level, animations are as good as it gets, despite the fact that the <code>%</code> suffix is used.</li>
<li>There are thankfully replacements for this forgotten property that strangelly supports CSS3 transitions, you can simply use all kinds of SVG masks and filters
and the <a href="htmlAttributes.html">HTML Attributes</a> component for much more animation potential and supreme animation quality.</li>
<li>This component is bundled with the <i>demo/src/kute-extra.js</i> file.</li>
</ul>
</div>
<!-- /.site-wrapper -->
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2021 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
</div>
<!-- /.site-wrapper -->
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute-extra.min.js"></script>
<script src="./assets/js/prism.js"></script>
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute-extra.min.js"></script>
<script src="./assets/js/prism.js"></script>
<script src="./assets/js/backgroundPosition.js"></script>
<script src="./assets/js/scripts.js"></script>
<script src="./assets/js/backgroundPosition.js"></script>
<script src="./assets/js/scripts.js"></script>
</body>
</html>

View file

@ -2,117 +2,117 @@
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="The SVG Border Radius component for KUTE.js enables animation for all the radius based CSS3 properties.">
<meta name="keywords" content="border-radius,border radius,kute,kute.js,animation,javascript animation,tweening engine,animation engine,Javascript,Native Javascript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="The SVG Border Radius component for KUTE.js enables animation for all the radius based CSS3 properties.">
<meta name="keywords" content="border-radius,border radius,kute,kute.js,animation,javascript animation,tweening engine,animation engine,Javascript,Native Javascript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<title>KUTE.js Border Radius</title>
<title>KUTE.js Border Radius</title>
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
</head>
<body>
<div class="site-wrapper">
<div class="site-wrapper">
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-space">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li class="active"><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-between">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li class="active"><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</div>
</nav>
</div>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div class="content-wrap">
<h2 class="head-title">Border Radius</h2>
<p class="condensed lead">The component that animates the CSS properties that control the radius of the corners of a target element.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<h2 class="head-title">Border Radius</h2>
<p class="condensed lead">The component that animates the CSS properties that control the radius of the corners of a target element.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<div class="columns">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">Animate the radius for all corners or a specific one for a target element.</p>
</div>
<div class="col9 border">
<p class="lead condensed">The KUTE.js <b>Border Radius</b> component provides support for the CSS3 <b>border-radius</b> property and all corner variations.</p>
<p>The component accepts any measurement unit but the best results in terms of visual presentation are when you use <b>%</b>, <b>em</b> or any other
subpixel units.</p>
<p>Even if you don't provide any unit at all, the component will work it out with <b>px</b>.</p>
<p>For a quick reference, here are the properties supported:</p>
</div>
<div class="columns">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">Animate the radius for all corners or a specific one for a target element.</p>
</div>
<div class="col9 border">
<p class="lead condensed">The KUTE.js <b>Border Radius</b> component provides support for the CSS3 <b>border-radius</b> property and all corner variations.</p>
<p>The component accepts any measurement unit but the best results in terms of visual presentation are when you use <b>%</b>, <b>em</b> or any other
subpixel units.</p>
<p>Even if you don't provide any unit at all, the component will work it out with <b>px</b>.</p>
<p>For a quick reference, here are the properties supported:</p>
</div>
</div>
</div>
</div>
<div class="content-wrap">
<div class="content-wrap">
<h3>Border Radius Properties</h3>
<ul>
<li><kbd class="bg-olive">borderRadius</kbd> allows you to animate the <code>border-radius</code> on all corners for a given element.</li>
<li><kbd class="bg-olive">borderTopLeftRadius</kbd> allows you to animate the <code>border-top-left-radius</code> for a given element.</li>
<li><kbd class="bg-olive">borderTopRightRadius</kbd> allows you to animate the <code>border-top-right-radius</code> for a given element.</li>
<li><kbd class="bg-olive">borderBottomLeftRadius</kbd> allows you to animate the <code>border-bottom-left-radius</code>for a given element.</li>
<li><kbd class="bg-olive">borderBottomRightRadius</kbd> allows you to animate the <code>border-bottom-right-radius</code>for a given element.</li>
</ul>
<h3>Border Radius Properties</h3>
<ul>
<li><kbd class="bg-olive">borderRadius</kbd> allows you to animate the <code>border-radius</code> on all corners for a given element.</li>
<li><kbd class="bg-olive">borderTopLeftRadius</kbd> allows you to animate the <code>border-top-left-radius</code> for a given element.</li>
<li><kbd class="bg-olive">borderTopRightRadius</kbd> allows you to animate the <code>border-top-right-radius</code> for a given element.</li>
<li><kbd class="bg-olive">borderBottomLeftRadius</kbd> allows you to animate the <code>border-bottom-left-radius</code>for a given element.</li>
<li><kbd class="bg-olive">borderBottomRightRadius</kbd> allows you to animate the <code>border-bottom-right-radius</code>for a given element.</li>
</ul>
<h3>Examples</h3>
<p>OK let's have a look at some sample tween objects and a quick demo:</p>
<h3>Examples</h3>
<p>OK let's have a look at some sample tween objects and a quick demo:</p>
<pre><code class="language-javascript">KUTE.to('selector1',{borderRadius:'100%'}).start();
KUTE.to('selector2',{borderTopLeftRadius:'100%'}).start();
KUTE.to('selector3',{borderTopRightRadius:'5em'}).start();
@ -120,52 +120,52 @@ KUTE.to('selector4',{borderBottomLeftRadius:50}).start();
KUTE.to('selector5',{borderBottomRightRadius:'20px'}).start();
</code></pre>
<div class="featurettes">
<div id="allRadius" class="example-item example-box bg-red">ALL</div>
<div id="tlRadius" class="example-item example-box bg-pink">TL</div>
<div id="trRadius" class="example-item example-box bg-olive">TR</div>
<div id="blRadius" class="example-item example-box bg-indigo">BL</div>
<div id="brRadius" class="example-item example-box bg-blue">BR</div>
<div class="featurettes">
<div id="allRadius" class="example-item example-box bg-red">ALL</div>
<div id="tlRadius" class="example-item example-box bg-pink">TL</div>
<div id="trRadius" class="example-item example-box bg-olive">TR</div>
<div id="blRadius" class="example-item example-box bg-indigo">BL</div>
<div id="brRadius" class="example-item example-box bg-blue">BR</div>
<div class="example-buttons">
<a id="radiusBtn" class="btn btn-green" href="javascript:void(0)">Start</a>
</div>
</div>
<h3>Notes</h3>
<ul>
<li>A quick reminder here is that the component does not support radius shorthand values, EG <code>border-radius: 50px 20px</code>.</li>
<li>The component does not use vendor property preffixes anymore, the major browsers don't need for quite some time now. If you want to support
legacy browsers, you still have the utilities available.</li>
<li>Early implementations from any browser that have been deprecated are also not supported.</li>
<li>This component is bundled with <i>demo/src/kute-extra.js</i> file.</li>
</ul>
</div>
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2020 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
<div class="example-buttons">
<a id="radiusBtn" class="btn btn-green" href="javascript:void(0)">Start</a>
</div>
</div>
<h3>Notes</h3>
<ul>
<li>A quick reminder here is that the component does not support radius shorthand values, EG <code>border-radius: 50px 20px</code>.</li>
<li>The component does not use vendor property preffixes anymore, the major browsers don't need for quite some time now. If you want to support
legacy browsers, you still have the utilities available.</li>
<li>Early implementations from any browser that have been deprecated are also not supported.</li>
<li>This component is bundled with <i>demo/src/kute-extra.js</i> file.</li>
</ul>
</div>
<!-- /.site-wrapper -->
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2021 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
</div>
<!-- /.site-wrapper -->
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute-extra.min.js"></script>
<script src="./assets/js/prism.js"></script>
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute-extra.min.js"></script>
<script src="./assets/js/prism.js"></script>
<script src="./assets/js/scripts.js"></script>
<script src="./assets/js/borderRadius.js"></script>
<script src="./assets/js/scripts.js"></script>
<script src="./assets/js/borderRadius.js"></script>
</body>

View file

@ -2,125 +2,125 @@
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="The Box Model component for KUTE.js enables animation for all box model properties.">
<meta name="keywords" content="top,left,width,height,kute,kute.js,animation,javascript animation,tweening engine,animation engine,Javascript,Native Javascript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="The Box Model component for KUTE.js enables animation for all box model properties.">
<meta name="keywords" content="top,left,width,height,kute,kute.js,animation,javascript animation,tweening engine,animation engine,Javascript,Native Javascript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<title>KUTE.js Box Model</title>
<title>KUTE.js Box Model</title>
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
</head>
<body>
<div class="site-wrapper">
<div class="site-wrapper">
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-space">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li class="active"><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-between">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li class="active"><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</div>
</nav>
</div>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div class="content-wrap">
<h2 class="head-title">Box Model</h2>
<p class="condensed lead">The component that animates most of the CSS box model properties of a target element on all browsers.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<h2 class="head-title">Box Model</h2>
<p class="condensed lead">The component that animates most of the CSS box model properties of a target element on all browsers.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<div class="columns">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">Animate the <b>width</b>, <b>height</b>, <b>borderWidth</b> or spacing for a target element on all browsers.</p>
</div>
<div class="col9 border">
<p class="lead condensed">The KUTE.js <b>Box Model</b> component provides support for all box-model properties and all their variations.</p>
<p>Unlike other components, this one only works with <b>px</b> measurement unit, simply because these properties have no control at subpixel level. This means that even if you use <b>%</b>
as suffix, the computed values are still pixel based in all browsers.</p>
<p>Because modern browsers shine with <b>transform</b> animations and box model properties generally come with performance penalties and other animation
jank, they can be used as fallback for legacy browsers, for your very special clients of course.</p>
</div>
<div class="columns">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">Animate the <b>width</b>, <b>height</b>, <b>borderWidth</b> or spacing for a target element on all browsers.</p>
</div>
<div class="col9 border">
<p class="lead condensed">The KUTE.js <b>Box Model</b> component provides support for all box-model properties and all their variations.</p>
<p>Unlike other components, this one only works with <b>px</b> measurement unit, simply because these properties have no control at subpixel level. This means that even if you use <b>%</b>
as suffix, the computed values are still pixel based in all browsers.</p>
<p>Because modern browsers shine with <b>transform</b> animations and box model properties generally come with performance penalties and other animation
jank, they can be used as fallback for legacy browsers, for your very special clients of course.</p>
</div>
</div>
</div>
</div>
<div class="content-wrap">
<div class="content-wrap">
<h3>Box Model Properties</h3>
<ul>
<li><kbd class="bg-blue">left</kbd>, <kbd class="bg-blue">top</kbd>, <kbd class="bg-olive">right</kbd> and <kbd class="bg-olive">bottom</kbd> are <code>position</code> based properties for movement on
vertical and / or horizontal axis. These properties require that the element to animate uses <code>position: absolute/relative</code> styling as well as it's parent element requires
<code>position:relative</code>. These properties can be used as fallback for browsers with no support for <code>translate</code> properties such as IE8.</li>
<li><kbd class="bg-blue">width</kbd>, <kbd class="bg-blue">height</kbd>, <kbd class="bg-olive">minWidth</kbd>, <kbd class="bg-olive">minHeight</kbd>, <kbd class="bg-olive">maxWidth</kbd>,
<kbd class="bg-olive">maxHeight</kbd> are properties that allow you to animate the size of an element on horizontal and / or vertical axis. These properties can be used on images as fallback for
<code>scale</code> on IE8 again, as well as for other purposes.</li>
<li><kbd class="bg-olive">padding</kbd>, <kbd class="bg-olive">margin</kbd>, <kbd class="bg-olive">paddingTop</kbd>, <kbd class="bg-olive">paddingBottom</kbd>, <kbd class="bg-olive">paddingLeft</kbd>,
<kbd class="bg-olive">paddingRight</kbd>, <kbd class="bg-olive">marginTop</kbd>, <kbd class="bg-olive">marginBottom</kbd>, <kbd class="bg-olive">marginLeft</kbd> and
<kbd class="bg-olive">marginRight</kbd> are properties that allow you to animate the spacing of an element inside (via padding) and outside (via margin).</li>
<li><kbd class="bg-olive">borderWidth</kbd>, <kbd class="bg-olive">borderTopWidth</kbd>, <kbd class="bg-olive">borderRightWidth</kbd>, <kbd class="bg-olive">borderBottomWidth</kbd> are
<kbd class="bg-olive">borderLeftWidth</kbd> are properties that allow you to animate the border of an element either on all sides at once or each side separatelly.</li>
<li><kbd class="bg-olive">outlineWidth</kbd> property allows you to animate the <code>outline-width</code> of an element.</li>
</ul>
<p>The properties marked with different color, namely <kbd class="bg-blue">left</kbd>, <kbd class="bg-blue">top</kbd>, <kbd class="bg-blue">width</kbd> and <kbd class="bg-blue">height</kbd> are part of a lighter
version of the component called <i>baseBoxModel.js</i>, since they're the most used and probably most needed in just about every KUTE.js distribution.</p>
<h3>Box Model Properties</h3>
<ul>
<li><kbd class="bg-blue">left</kbd>, <kbd class="bg-blue">top</kbd>, <kbd class="bg-olive">right</kbd> and <kbd class="bg-olive">bottom</kbd> are <code>position</code> based properties for movement on
vertical and / or horizontal axis. These properties require that the element to animate uses <code>position: absolute/relative</code> styling as well as it's parent element requires
<code>position:relative</code>. These properties can be used as fallback for browsers with no support for <code>translate</code> properties such as IE8.</li>
<li><kbd class="bg-blue">width</kbd>, <kbd class="bg-blue">height</kbd>, <kbd class="bg-olive">minWidth</kbd>, <kbd class="bg-olive">minHeight</kbd>, <kbd class="bg-olive">maxWidth</kbd>,
<kbd class="bg-olive">maxHeight</kbd> are properties that allow you to animate the size of an element on horizontal and / or vertical axis. These properties can be used on images as fallback for
<code>scale</code> on IE8 again, as well as for other purposes.</li>
<li><kbd class="bg-olive">padding</kbd>, <kbd class="bg-olive">margin</kbd>, <kbd class="bg-olive">paddingTop</kbd>, <kbd class="bg-olive">paddingBottom</kbd>, <kbd class="bg-olive">paddingLeft</kbd>,
<kbd class="bg-olive">paddingRight</kbd>, <kbd class="bg-olive">marginTop</kbd>, <kbd class="bg-olive">marginBottom</kbd>, <kbd class="bg-olive">marginLeft</kbd> and
<kbd class="bg-olive">marginRight</kbd> are properties that allow you to animate the spacing of an element inside (via padding) and outside (via margin).</li>
<li><kbd class="bg-olive">borderWidth</kbd>, <kbd class="bg-olive">borderTopWidth</kbd>, <kbd class="bg-olive">borderRightWidth</kbd>, <kbd class="bg-olive">borderBottomWidth</kbd> are
<kbd class="bg-olive">borderLeftWidth</kbd> are properties that allow you to animate the border of an element either on all sides at once or each side separatelly.</li>
<li><kbd class="bg-olive">outlineWidth</kbd> property allows you to animate the <code>outline-width</code> of an element.</li>
</ul>
<p>The properties marked with different color, namely <kbd class="bg-blue">left</kbd>, <kbd class="bg-blue">top</kbd>, <kbd class="bg-blue">width</kbd> and <kbd class="bg-blue">height</kbd> are part of a lighter
version of the component called <i>baseBoxModel.js</i>, since they're the most used and probably most needed in just about every KUTE.js distribution.</p>
<h3>Examples</h3>
<p>OK let's have a look at some sample tween objects and a quick demo:</p>
<h3>Examples</h3>
<p>OK let's have a look at some sample tween objects and a quick demo:</p>
<pre><code class="language-javascript">let tween1 = KUTE.to('selector1',{width:200})
let tween2 = KUTE.to('selector1',{height:300})
@ -132,47 +132,47 @@ let tween7 = KUTE.to('selector1',{padding:30})
let tween8 = KUTE.to('selector1',{margin:'5px'})
</code></pre>
<p>We're gonna chain these tweens and start the animation.</p>
<div id="boxModel" class="featurettes">
<div class="example-box example-box-model bg-lime" style="padding: 0; font-size:26px; line-height: 70px;">BOX<br>&nbsp;MODEL&nbsp;</div>
<p>We're gonna chain these tweens and start the animation.</p>
<div id="boxModel" class="featurettes">
<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>
</div>
</div>
<div class="example-buttons">
<a class="btn btn-orange" href="#">Start</a>
</div>
</div>
<h3>Notes</h3>
<ul>
<li>Shorthand notations such as <code>margin: "20px 50px"</code> or any other property are not supported.</li>
<li>Most box-model properties (except <code>top</code>, <code>left</code>, <code>bottom</code> and <code>right</code>) are layout modifiers and will not
produce the best visual experience mainly because they force re-paint on all page layout and they don't support animation under the pixel level.</li>
<li>The <i>baseBoxModel</i> component is featured in all distributions, while the full component is bundled with <i>demo/src/kute-extra.js</i> file.</li>
</ul>
</div>
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2020 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
<h3>Notes</h3>
<ul>
<li>Shorthand notations such as <code>margin: "20px 50px"</code> or any other property are not supported.</li>
<li>Most box-model properties (except <code>top</code>, <code>left</code>, <code>bottom</code> and <code>right</code>) are layout modifiers and will not
produce the best visual experience mainly because they force re-paint on all page layout and they don't support animation under the pixel level.</li>
<li>The <i>baseBoxModel</i> component is featured in all distributions, while the full component is bundled with <i>demo/src/kute-extra.js</i> file.</li>
</ul>
</div>
<!-- /.site-wrapper -->
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2021 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
</div>
<!-- /.site-wrapper -->
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute-extra.min.js"></script>
<script src="./assets/js/prism.js"></script>
<script src="./assets/js/scripts.js"></script>
<script src="./assets/js/boxModel.js"></script>
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute-extra.min.js"></script>
<script src="./assets/js/prism.js"></script>
<script src="./assets/js/scripts.js"></script>
<script src="./assets/js/boxModel.js"></script>
</body>

View file

@ -1,153 +1,153 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="The Clip Property component for KUTE.js allows you to animate the CSS clip property on most browsers.">
<meta name="keywords" content="clip,css clip,kute,kute.js,animation,javascript animation,tweening engine,animation engine,JavaScript,Native JavaScript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="The Clip Property component for KUTE.js allows you to animate the CSS clip property on most browsers.">
<meta name="keywords" content="clip,css clip,kute,kute.js,animation,javascript animation,tweening engine,animation engine,JavaScript,Native JavaScript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<title>KUTE.js Clip Property</title>
<title>KUTE.js Clip Property</title>
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
</head>
<body>
<div class="site-wrapper">
<div class="site-wrapper">
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-space">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li class="active"><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-between">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li class="active"><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</div>
</nav>
</div>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div class="content-wrap">
<h2 class="head-title">Clip Property</h2>
<p class="condensed lead">The component that animates the CSS <i>clip</i> property of a target element on most browsers.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<h2 class="head-title">Clip Property</h2>
<p class="condensed lead">The component that animates the CSS <i>clip</i> property of a target element on most browsers.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<div class="columns">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">Animate the <b>clip</b> property of a target element when certain conditions are met.</p>
</div>
<div class="col9 border">
<p class="lead condensed">The KUTE.js <b>Clip Property</b> component enables animation for the CSS <b>clip</b> property on most browsers.</p>
<p>What exactly does it do? Well you can animate the <b>visible</b> rectangular shape of an element that is set to <b>position:absolute</b>.
If conditions are not met (more conditions apply, see notes below), the component will update the target element, but the effect is not visible.</p>
<p>Generally you can set the CSS rule for this property like this <b>clip: rect(top,right,bottom,left)</b> which forms a rectangular masking shape above
a target element making parts of it invisible.</p>
<p>While the CSS <b>clip</b> property has been deprecated, it can still be used to emulate a type of scale/reveal animation for legacy browsers in certain cases.</p>
<p>This component is bundled with the <i>demo/src/kute-extra.js</i> file.</p>
</div>
<div class="columns">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">Animate the <b>clip</b> property of a target element when certain conditions are met.</p>
</div>
<div class="col9 border">
<p class="lead condensed">The KUTE.js <b>Clip Property</b> component enables animation for the CSS <b>clip</b> property on most browsers.</p>
<p>What exactly does it do? Well you can animate the <b>visible</b> rectangular shape of an element that is set to <b>position:absolute</b>.
If conditions are not met (more conditions apply, see notes below), the component will update the target element, but the effect is not visible.</p>
<p>Generally you can set the CSS rule for this property like this <b>clip: rect(top,right,bottom,left)</b> which forms a rectangular masking shape above
a target element making parts of it invisible.</p>
<p>While the CSS <b>clip</b> property has been deprecated, it can still be used to emulate a type of scale/reveal animation for legacy browsers in certain cases.</p>
<p>This component is bundled with the <i>demo/src/kute-extra.js</i> file.</p>
</div>
</div>
</div>
</div>
<div class="content-wrap">
<div class="content-wrap">
<h3>Example</h3>
<p>A possible tween object using the property:</p>
<h3>Example</h3>
<p>A possible tween object using the property:</p>
<pre><code class="language-javascript">KUTE.to('selector',{clip:[0,150,100,0]}).start();</code></pre>
<p>And a quick example here could look like this:</p>
<p>And a quick example here could look like this:</p>
<div id="clip" class="featurettes" style="min-height: 190px">
<div class="example-item example-box bg-red" style="position: absolute; background: url('https://picsum.photos/250/250') center center no-repeat;"></div>
<div class="example-buttons">
<a class="btn btn-olive" href="#">Start</a>
</div>
</div>
<h3>Notes</h3>
<ul>
<li>The component will produce no effect for target elements that have <code>overflow:visible</code> style rule.</li>
<li>Also target elements without <code>position:absolute</code> CSS rule will produce no effect.</li>
<li>This property will only work with <code>px</code> unit for the rectangular mask, which is unfortunate.</li>
<li>Don't stop here, there are thankfully replacements for this property, you can simply use all kinds of SVG masks and filters in combination
with the <a href="htmlAttributes.html">HTML Attributes</a> component for much more animation potential and for no compromise on animation quality.</li>
<li>This component is bundled with the <i>demo/src/kute-extra.js</i> file.</li>
</ul>
<div id="clip" class="featurettes" style="min-height: 190px">
<div class="example-item example-box bg-red" style="position: absolute; background: url('https://picsum.photos/250/250') center center no-repeat;"></div>
<div class="example-buttons">
<a class="btn btn-olive" href="#">Start</a>
</div>
</div>
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2020 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
<h3>Notes</h3>
<ul>
<li>The component will produce no effect for target elements that have <code>overflow:visible</code> style rule.</li>
<li>Also target elements without <code>position:absolute</code> CSS rule will produce no effect.</li>
<li>This property will only work with <code>px</code> unit for the rectangular mask, which is unfortunate.</li>
<li>Don't stop here, there are thankfully replacements for this property, you can simply use all kinds of SVG masks and filters in combination
with the <a href="htmlAttributes.html">HTML Attributes</a> component for much more animation potential and for no compromise on animation quality.</li>
<li>This component is bundled with the <i>demo/src/kute-extra.js</i> file.</li>
</ul>
</div>
<!-- /.site-wrapper -->
</div>
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute-extra.min.js"></script>
<script src="./assets/js/prism.js"></script>
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2021 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
<script src="./assets/js/clipProperty.js"></script>
<script src="./assets/js/scripts.js"></script>
</div>
<!-- /.site-wrapper -->
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute-extra.min.js"></script>
<script src="./assets/js/prism.js"></script>
<script src="./assets/js/clipProperty.js"></script>
<script src="./assets/js/scripts.js"></script>
</body>
</html>

View file

@ -2,168 +2,168 @@
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="The Color Properties component for KUTE.js enables animation for color based properties and their variations.">
<meta name="keywords" content="color,background-color,outline-color,kute,kute.js,animation,javascript animation,tweening engine,animation engine,Javascript,Native Javascript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="The Color Properties component for KUTE.js enables animation for color based properties and their variations.">
<meta name="keywords" content="color,background-color,outline-color,kute,kute.js,animation,javascript animation,tweening engine,animation engine,Javascript,Native Javascript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<title>KUTE.js Color Properties</title>
<title>KUTE.js Color Properties</title>
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
</head>
<body>
<div class="site-wrapper">
<div class="site-wrapper">
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-space">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li class="active"><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-between">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li class="active"><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</div>
</nav>
</div>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div class="content-wrap">
<h2 class="head-title">Color Properties</h2>
<p class="condensed lead">The component that animates CSS color properties for <b>Element</b> targets on most browsers.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<h2 class="head-title">Color Properties</h2>
<p class="condensed lead">The component that animates CSS color properties for <b>Element</b> targets on most browsers.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<div class="columns">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">Animate <i>color</i> properties for a target element and updates its CSS style via <b>RGB</b>.</p>
</div>
<div class="col9 border">
<p class="lead condensed">The KUTE.js <b>Color Properties</b> component provides support for all color properties and all their variations on most browsers.</p>
<p>While with previous versions we used to have a <b>keepHex</b> option to always use the <b>HEX</b> format of the output color, modern browsers outright ignore the option and always
deliver colors in <b>RGB</b> format, probably for performance reasons.</p>
<p>The component supports input values such as <b>HEX</b>, <b>RGB</b> and <b>RGBA</b> for all color properties and most browsers should also work with
<a href="http://www.w3schools.com/colors/colors_names.asp" target="_blank">web safe colors</a>, eg. <b>color: 'red'</b>.</p>
<p>For a quick reference, here are all the supported properties:</p>
</div>
</div>
<div class="columns">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">Animate <i>color</i> properties for a target element and updates its CSS style via <b>RGB</b>.</p>
</div>
<div class="col9 border">
<p class="lead condensed">The KUTE.js <b>Color Properties</b> component provides support for all color properties and all their variations on most browsers.</p>
<p>While with previous versions we used to have a <b>keepHex</b> option to always use the <b>HEX</b> format of the output color, modern browsers outright ignore the option and always
deliver colors in <b>RGB</b> format, probably for performance reasons.</p>
<p>The component supports input values such as <b>HEX</b>, <b>RGB</b> and <b>RGBA</b> for all color properties and most browsers should also work with
<a href="http://www.w3schools.com/colors/colors_names.asp" target="_blank">web safe colors</a>, eg. <b>color: 'red'</b>.</p>
<p>For a quick reference, here are all the supported properties:</p>
</div>
</div>
</div>
</div>
<div class="content-wrap">
<h3>Supported Properties</h3>
<ul>
<li><kbd class="bg-olive">color</kbd> allows you to animate the color for a target text element. Eg. <code>color: '#ff0000'</code>.</li>
<li><kbd class="bg-olive">backgroundColor</kbd> allows you to animate the <code>background-color</code> for a target element. Eg. <code>backgroundColor: 'rgb(202,150,20)'</code>.</li>
<li><kbd class="bg-olive">outlineColor</kbd> allows you to animate the <code>outline-color</code> for a target element. Eg. <code>outline-color: 'cyan'</code>.</li>
<li><kbd class="bg-olive">borderColor</kbd> allows you to animate the <code>border-color</code> on all sides for a target element. Eg. <code>borderColor: 'rgba(250,100,20,0.5)'</code>.</li>
<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 target element. Eg. <code>borderTopColor: 'rgb(0,66,99)'</code>.</li>
</ul>
<div class="content-wrap">
<h3>Supported Properties</h3>
<ul>
<li><kbd class="bg-olive">color</kbd> allows you to animate the color for a target text element. Eg. <code>color: '#ff0000'</code>.</li>
<li><kbd class="bg-olive">backgroundColor</kbd> allows you to animate the <code>background-color</code> for a target element. Eg. <code>backgroundColor: 'rgb(202,150,20)'</code>.</li>
<li><kbd class="bg-olive">outlineColor</kbd> allows you to animate the <code>outline-color</code> for a target element. Eg. <code>outline-color: 'cyan'</code>.</li>
<li><kbd class="bg-olive">borderColor</kbd> allows you to animate the <code>border-color</code> on all sides for a target element. Eg. <code>borderColor: 'rgba(250,100,20,0.5)'</code>.</li>
<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 target element. Eg. <code>borderTopColor: 'rgb(0,66,99)'</code>.</li>
</ul>
<h3>Examples</h3>
<p>OK let's have a look at some sample tween objects and a quick demo:</p>
<h3>Examples</h3>
<p>OK let's have a look at some sample tween objects and a quick demo:</p>
<pre><code class="language-javascript">KUTE.to('selector1',{color:'rgb(0,66,99)'}).start();
KUTE.to('selector1',{backgroundColor:'#069'}).start();
KUTE.to('selector1',{borderColor:'turquoise'}).start(); // IE9+
</code></pre>
<div id="colBox" class="featurettes">
<div class="example-item example-box bg-olive" style="outline: #fff solid 5px; width: 155px; height: 155px; border:15px solid #9C27B0; line-height: 125px;">Colors</div>
<div id="colBox" class="featurettes">
<div class="example-item example-box bg-olive" style="outline: #fff solid 5px; width: 155px; height: 155px; border:15px solid #9C27B0; line-height: 125px;">Colors</div>
<div class="example-buttons">
<a class="btn btn-blue" href="#">Start</a>
</div>
<div class="example-buttons">
<a class="btn btn-blue" href="#">Start</a>
</div>
<h3>Notes</h3>
<ul>
<li>The component will NOT work with <b>SVGElement</b> targets and their specific color attributes like <code>fill</code> or <code>stroke</code>, for that you can use the
<a href="htmlAttributes.html">HTML Attributes</a> component.</li>
<li>To simplify your workflow, the value processing can also work with web safe colors like <code>steelblue</code> or <code>darkorange</code>.</li>
<li>You can also use <code>RGB</code> or <code>RGBA</code>, but the last one is not supported on legacy browsers and it should fallback to <code>RGB</code>.</li>
<li>Some properties like <code>borderColor</code> and its variations or <code>outlineColor</code> won't have any visible effect if no border or outline style is applied to
your target element.</li>
<li>This component is bundled with the standard <i>kute.js</i> distribution file and the <i>demo/src/kute-extra.js</i> file.</li>
</ul>
</div>
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2020 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
<h3>Notes</h3>
<ul>
<li>The component will NOT work with <b>SVGElement</b> targets and their specific color attributes like <code>fill</code> or <code>stroke</code>, for that you can use the
<a href="htmlAttributes.html">HTML Attributes</a> component.</li>
<li>To simplify your workflow, the value processing can also work with web safe colors like <code>steelblue</code> or <code>darkorange</code>.</li>
<li>You can also use <code>RGB</code> or <code>RGBA</code>, but the last one is not supported on legacy browsers and it should fallback to <code>RGB</code>.</li>
<li>Some properties like <code>borderColor</code> and its variations or <code>outlineColor</code> won't have any visible effect if no border or outline style is applied to
your target element.</li>
<li>This component is bundled with the standard <i>kute.js</i> distribution file and the <i>demo/src/kute-extra.js</i> file.</li>
</ul>
</div>
<!-- /.site-wrapper -->
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2021 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
</div>
<!-- /.site-wrapper -->
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute-extra.min.js"></script>
<script src="./assets/js/prism.js"></script>
<script src="./assets/js/scripts.js"></script>
<script src="./assets/js/colorProperties.js"></script>
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute-extra.min.js"></script>
<script src="./assets/js/prism.js"></script>
<script src="./assets/js/scripts.js"></script>
<script src="./assets/js/colorProperties.js"></script>
</body>

View file

@ -1,125 +1,125 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="The Filter Effects component for KUTE.js allows you to create CSS3 filter based animations on supporting browsers.">
<meta name="keywords" content="css3 filter,filter,kute,kute.js,animation,javascript animation,tweening engine,animation engine,JavaScript,Native JavaScript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="The Filter Effects component for KUTE.js allows you to create CSS3 filter based animations on supporting browsers.">
<meta name="keywords" content="css3 filter,filter,kute,kute.js,animation,javascript animation,tweening engine,animation engine,JavaScript,Native JavaScript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<title>KUTE.js Filter Effects</title>
<title>KUTE.js Filter Effects</title>
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
<style></style>
<style></style>
</head>
<body>
<div class="site-wrapper">
<div class="site-wrapper">
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-space">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li class="active"><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-between">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li class="active"><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</div>
</nav>
</div>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div class="content-wrap">
<h2 class="head-title">Filter Effects</h2>
<p class="condensed lead">The component that animates the CSS3 <i>filter</i> property for specific <b>Element</b> targets on modern browsers.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<h2 class="head-title">Filter Effects</h2>
<p class="condensed lead">The component that animates the CSS3 <i>filter</i> property for specific <b>Element</b> targets on modern browsers.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<div class="columns">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">Animate <b>filter</b> functions for a target <b>Element</b> and deliver the best possible animation.</p>
</div>
<div class="col9 border">
<p class="lead condensed">The KUTE.js <b>Filter Effects</b> component provides support for the CSS3 <b>filter</b> property on modern browsers.</p>
<p>The component covers all <b>filter</b> functions, except that the <b>url()</b> function cannot be animated, however the component will
try and keep it's value into the target element styling at all times.</p>
<p>Similar to the <a href="transformFunctions.html">Transform Functions</a> and the <a href="transformMatrix.html">Transform Matrix</a> components,
this component will try and keep same order of the filter functions, regardless of the input order, and the reason is that chained animations can
have some unwanted janky artifact effects.</p>
<p>Most values are in [0-Infinity] range and the presentation is delivered with <b>%</b> suffixed values, except <b>blur()</b> which uses <b>px</b>
as unit/suffix.</p>
</div>
<div class="columns">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">Animate <b>filter</b> functions for a target <b>Element</b> and deliver the best possible animation.</p>
</div>
<div class="col9 border">
<p class="lead condensed">The KUTE.js <b>Filter Effects</b> component provides support for the CSS3 <b>filter</b> property on modern browsers.</p>
<p>The component covers all <b>filter</b> functions, except that the <b>url()</b> function cannot be animated, however the component will
try and keep it's value into the target element styling at all times.</p>
<p>Similar to the <a href="transformFunctions.html">Transform Functions</a> and the <a href="transformMatrix.html">Transform Matrix</a> components,
this component will try and keep same order of the filter functions, regardless of the input order, and the reason is that chained animations can
have some unwanted janky artifact effects.</p>
<p>Most values are in [0-Infinity] range and the presentation is delivered with <b>%</b> suffixed values, except <b>blur()</b> which uses <b>px</b>
as unit/suffix.</p>
</div>
</div>
</div>
</div>
<div class="content-wrap">
<h3>Filter Functions</h3>
<ul>
<li><kbd class="bg-olive">url()</kbd> function links an element to an SVG filter, the function is supported to keep it's value into the target element's style in case it's set
initially or you want to set it yourself.</li>
<li><kbd class="bg-olive">opacity()</kbd> can animate the opacity for a target element in the 0-100% range. Default is 100%.</li>
<li><kbd class="bg-olive">blur()</kbd> can animate the blur for a target element in the 0-Infinity range. Default is <b>0px</b> and the unit is always <code>px</code>.</li>
<li><kbd class="bg-olive">saturate()</kbd> can animate the color saturation for a target element in the 0-Infinity range. Default is 100%.</li>
<li><kbd class="bg-olive">grayscale()</kbd> can animate the color desaturation for a target element in the 0-100% range. Default is 0%.</li>
<li><kbd class="bg-olive">brightness()</kbd> can animate the brightness for a target element in the 0-Infinity range. Default is 100%.</li>
<li><kbd class="bg-olive">contrast()</kbd> can animate the contrast for a target element in the 0-Infinity range. Default is 100%.</li>
<li><kbd class="bg-olive">sepia()</kbd> can animate the sepia filter for a target element in the 0-100% range. Default is 0%.</li>
<li><kbd class="bg-olive">invert()</kbd> can animate the color inversion for a target element in the 0-100% range. Default is 0%.</li>
<li><kbd class="bg-olive">hueRotate()</kbd> can animate the color hue rotation for a target element in the 0-Infinity range. Default is 0deg.</li>
<li><kbd class="bg-olive">dropShadow()</kbd> can animate the shadow and all related parameters for a target element. Default is <code>[0,0,0,'black']</code></li>
</ul>
<h3>Examples</h3>
<p>Let's have a look at some sample tween objects and a quick example:</p>
<div class="content-wrap">
<h3>Filter Functions</h3>
<ul>
<li><kbd class="bg-olive">url()</kbd> function links an element to an SVG filter, the function is supported to keep it's value into the target element's style in case it's set
initially or you want to set it yourself.</li>
<li><kbd class="bg-olive">opacity()</kbd> can animate the opacity for a target element in the 0-100% range. Default is 100%.</li>
<li><kbd class="bg-olive">blur()</kbd> can animate the blur for a target element in the 0-Infinity range. Default is <b>0px</b> and the unit is always <code>px</code>.</li>
<li><kbd class="bg-olive">saturate()</kbd> can animate the color saturation for a target element in the 0-Infinity range. Default is 100%.</li>
<li><kbd class="bg-olive">grayscale()</kbd> can animate the color desaturation for a target element in the 0-100% range. Default is 0%.</li>
<li><kbd class="bg-olive">brightness()</kbd> can animate the brightness for a target element in the 0-Infinity range. Default is 100%.</li>
<li><kbd class="bg-olive">contrast()</kbd> can animate the contrast for a target element in the 0-Infinity range. Default is 100%.</li>
<li><kbd class="bg-olive">sepia()</kbd> can animate the sepia filter for a target element in the 0-100% range. Default is 0%.</li>
<li><kbd class="bg-olive">invert()</kbd> can animate the color inversion for a target element in the 0-100% range. Default is 0%.</li>
<li><kbd class="bg-olive">hueRotate()</kbd> can animate the color hue rotation for a target element in the 0-Infinity range. Default is 0deg.</li>
<li><kbd class="bg-olive">dropShadow()</kbd> can animate the shadow and all related parameters for a target element. Default is <code>[0,0,0,'black']</code></li>
</ul>
<h3>Examples</h3>
<p>Let's have a look at some sample tween objects and a quick example:</p>
<pre><code class="language-javascript">let fe1 = KUTE.to('selector1', {filter :{ blur: 5 }})
let fe2 = KUTE.to('selector2', {filter :{ sepia: 50, invert: 80 }})
@ -127,64 +127,64 @@ let fe3 = KUTE.to('selector3', {filter :{ saturate: 150, brightness: 90 }})
let fe4 = KUTE.to('selector4', {filter :{ url: '#mySVGFilter', opacity: 40, dropShadow:[5,5,5,'olive'] }})
</code></pre>
<div id="filter-examples" class="featurettes">
<svg style="display: none;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<filter id="mySVGFilter">
<feGaussianBlur in="SourceAlpha" stdDeviation="5"/>
<feOffset dx="5" dy="5" result="offsetblur"/>
<feFlood flood-color="#000000"/>
<feComposite in2="offsetblur" operator="in"/>
<feMerge>
<feMergeNode/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
</svg>
<div class="example-item example-box" style="background: url('https://picsum.photos/400/300') center center no-repeat; filter: url(#mySVGFilter)">FE1</div>
<div class="example-item example-box" style="background: url('https://picsum.photos/400/300') center center no-repeat; filter: url(#mySVGFilter)">FE2</div>
<div class="example-item example-box" style="background: url('https://picsum.photos/400/300') center center no-repeat; filter: url(#mySVGFilter)">FE3</div>
<div class="example-item example-box" style="background: url('https://picsum.photos/400/300') center center no-repeat; filter: url(#mySVGFilter)">FE4</div>
<div class="example-buttons">
<a class="btn btn-blue" href="javascript:void(0)">Start</a>
</div>
</div>
<h3>Notes</h3>
<ul>
<li>The CSS filter property is supported on all major browsers nowadays, but it's better to <a href="https://caniuse.com/#feat=css-filter-function">check</a> and
<a href="https://css-tricks.com/almanac/properties/f/filter/#browser-support">double check</a>.</li>
<li>This component can be a great addition to all SVG related components, especially because the <code>dropShadow</code> provides a better experience than
<code>boxShadow</code>, as <a href="https://codepen.io/Kseso/pen/Ajamv">shown here</a>.</li>
<li>Since this component can work with the <code>url()</code> function the way it does, the <a href="htmlAttributes.html">HTML Attributes</a> component will
complement greatly for even more animation potential.</li>
<li>Similar to the <a href="htmlAttributes.html">HTML Attributes</a> component, this one can also deal with specific function namespace, for instance <code>hue-rotate</code> and
<code>hueRotate</code>.</li>
<li>This component is bundled with the <i>demo/src/kute-extra.js</i> file.</li>
</ul>
</div>
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2020 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
<div id="filter-examples" class="featurettes">
<svg style="display: none;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<filter id="mySVGFilter">
<feGaussianBlur in="SourceAlpha" stdDeviation="5"/>
<feOffset dx="5" dy="5" result="offsetblur"/>
<feFlood flood-color="#000000"/>
<feComposite in2="offsetblur" operator="in"/>
<feMerge>
<feMergeNode/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
</svg>
<div class="example-item example-box" style="background: url('https://picsum.photos/400/300') center center no-repeat; filter: url(#mySVGFilter)">FE1</div>
<div class="example-item example-box" style="background: url('https://picsum.photos/400/300') center center no-repeat; filter: url(#mySVGFilter)">FE2</div>
<div class="example-item example-box" style="background: url('https://picsum.photos/400/300') center center no-repeat; filter: url(#mySVGFilter)">FE3</div>
<div class="example-item example-box" style="background: url('https://picsum.photos/400/300') center center no-repeat">FE4</div>
<div class="example-buttons">
<a class="btn btn-blue" href="javascript:void(0)">Start</a>
</div>
</div>
<h3>Notes</h3>
<ul>
<li>The CSS filter property is supported on all major browsers nowadays, but it's better to <a href="https://caniuse.com/#feat=css-filter-function">check</a> and
<a href="https://css-tricks.com/almanac/properties/f/filter/#browser-support">double check</a>.</li>
<li>This component can be a great addition to all SVG related components, especially because the <code>dropShadow</code> provides a better experience than
<code>boxShadow</code>, as <a href="https://codepen.io/Kseso/pen/Ajamv">shown here</a>.</li>
<li>Since this component can work with the <code>url()</code> function the way it does, the <a href="htmlAttributes.html">HTML Attributes</a> component will
complement greatly for even more animation potential.</li>
<li>Similar to the <a href="htmlAttributes.html">HTML Attributes</a> component, this one can also deal with specific function namespace, for instance <code>hue-rotate</code> and
<code>hueRotate</code>.</li>
<li>This component is bundled with the <i>demo/src/kute-extra.js</i> file.</li>
</ul>
</div>
<!-- /.site-wrapper -->
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2021 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
</div>
<!-- /.site-wrapper -->
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute-extra.min.js"></script>
<script src="./assets/js/prism.js"></script>
<script src="./assets/js/filterEffects.js"></script>
<script src="./assets/js/scripts.js"></script>
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute-extra.min.js"></script>
<script src="./assets/js/prism.js"></script>
<script src="./assets/js/filterEffects.js"></script>
<script src="./assets/js/scripts.js"></script>
</body>
</html>

View file

@ -1,106 +1,106 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="The HTML Attributes component for KUTE.js enables animation for any numeric presentation attribute as well as specific color attributes.">
<meta name="keywords" content="presentation attributes,attributes,html attributes,kute,kute.js,animation,javascript animations,tweening engine,animation engine,Javascript,Native Javascript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="The HTML Attributes component for KUTE.js enables animation for any numeric presentation attribute as well as specific color attributes.">
<meta name="keywords" content="presentation attributes,attributes,html attributes,kute,kute.js,animation,javascript animations,tweening engine,animation engine,Javascript,Native Javascript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<title>KUTE.js HTML Attributes</title>
<title>KUTE.js HTML Attributes</title>
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
</head>
<body>
<div class="site-wrapper">
<div class="site-wrapper">
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-space">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li class="active"><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-between">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li class="active"><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</div>
</nav>
</div>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div class="content-wrap">
<h2 class="head-title">HTML Attributes</h2>
<p class="condensed lead">The component that animates color attributes or any single value presentation attribute of a target element on most browsers.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<h2 class="head-title">HTML Attributes</h2>
<p class="condensed lead">The component that animates color attributes or any single value presentation attribute of a target element on most browsers.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<div class="columns">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">Animate a wide variety of presetantion attributes of a target element.</p>
</div>
<div class="col9 border">
<p class="lead condensed">The KUTE.js <b>HTML Attributes</b> component enables animation for any numeric presentation attribute, with or without a measurement unit / suffix as well as specific color attributes.</p>
<p>The component can be a great asset for creating complex animations in combination with the SVG components as we'll see in the following examples.</p>
<p>The component doesn't support attributes with multiple values like <b>stroke-dasharray</b>, <b>viewBox</b> or <b>transform</b> for specific reasons. To animate the <b>stroke</b> related attributes, the
<a href="svgDraw.html">SVG Draw</a> component is the tool for you, while for transform you have the <a href="svgTransform.html">SVG Transform</a> component and the
<a href="transformMatrix.html">Transform Matrix</a> component.</p>
<p>Despite the "limitations" of this component, you have access to just about any <b>SVGElement</b> or <b>Element</b>
<a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute" target="_blank">presentation attribute</a> available.</p>
</div>
<div class="columns">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">Animate a wide variety of presetantion attributes of a target element.</p>
</div>
<div class="col9 border">
<p class="lead condensed">The KUTE.js <b>HTML Attributes</b> component enables animation for any numeric presentation attribute, with or without a measurement unit / suffix as well as specific color attributes.</p>
<p>The component can be a great asset for creating complex animations in combination with the SVG components as we'll see in the following examples.</p>
<p>The component doesn't support attributes with multiple values like <b>stroke-dasharray</b>, <b>viewBox</b> or <b>transform</b> for specific reasons. To animate the <b>stroke</b> related attributes, the
<a href="svgDraw.html">SVG Draw</a> component is the tool for you, while for transform you have the <a href="svgTransform.html">SVG Transform</a> component and the
<a href="transformMatrix.html">Transform Matrix</a> component.</p>
<p>Despite the "limitations" of this component, you have access to just about any <b>SVGElement</b> or <b>Element</b>
<a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute" target="_blank">presentation attribute</a> available.</p>
</div>
</div>
</div>
</div>
<div class="content-wrap">
<h3>General Usage</h3>
<div class="content-wrap">
<h3>General Usage</h3>
<pre><code class="language-javascript">// basic notation for unitless attributes
var myAttrTween = KUTE.to('selector', {attr: {attributeName: 75}});
@ -109,9 +109,9 @@ var myAttrTween = KUTE.to('selector', {attr: {attributeName: 75}});
var mySuffAttrTween = KUTE.to('selector', {attr:{attributeName: '15%'}});
</code></pre>
<h3>Attributes Namespace</h3>
<p>The <b>HTML Attributes</b> component can handle all possible single value presentation attributes with both dashed string and camel-case notation. Let's have a look at a sample notation so you can
get the idea:</p>
<h3>Attributes Namespace</h3>
<p>The <b>HTML Attributes</b> component can handle all possible single value presentation attributes with both dashed string and camel-case notation. Let's have a look at a sample notation so you can
get the idea:</p>
<pre><code class="language-javascript">// dashed attribute notation
var myDashedAttrStringTween = KUTE.to('selector', {attr: {'stroke-width': 75}});
@ -120,13 +120,13 @@ var myDashedAttrStringTween = KUTE.to('selector', {attr: {'stroke-width': 75}});
var myNonDashedAttrStringTween = KUTE.to('selector', {attr:{strokeWidth: '15px'}});
</code></pre>
<p>The <code>strokeWidth</code> attribute is very interesting because it can work with <code>px</code>, <code>%</code> or with no unit/suffix. In this case, and in any context, the component will always work with the
attribute's current value suffix to eliminate any possible janky animation.</p>
<p>The <code>strokeWidth</code> attribute is very interesting because it can work with <code>px</code>, <code>%</code> or with no unit/suffix. In this case, and in any context, the component will always work with the
attribute's current value suffix to eliminate any possible janky animation.</p>
<h3>Examples</h3>
<h4>Color Attributes</h4>
<p>The <b>HTML Attributes</b> component can also animate color attributes: <code>fill</code>, <code>stroke</code> and <code>stopColor</code>. If the elements are affected by their CSS counterparts, the effect
is not visible, you need to make sure that doesn't happen.</p>
<h3>Examples</h3>
<h4>Color Attributes</h4>
<p>The <b>HTML Attributes</b> component can also animate color attributes: <code>fill</code>, <code>stroke</code> and <code>stopColor</code>. If the elements are affected by their CSS counterparts, the effect
is not visible, you need to make sure that doesn't happen.</p>
<pre><code class="language-javascript">// some fill rgb, rgba, hex
var fillTween = KUTE.to('#element-to-fill', {attr: { fill: 'red' }});
@ -135,23 +135,23 @@ var fillTween = KUTE.to('#element-to-fill', {attr: { fill: 'red' }});
var stopColorTween = KUTE.to('#element-to-do-stop-color', {attr: {stopColor: 'rgb(0,66,99)'}});
</code></pre>
<div class="featurettes">
<svg class="example-box-model example-box" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 615 615">
<div class="featurettes">
<svg class="example-box-model example-box" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 615 615">
<path id="fill" fill="#673AB7" d="M38.01,5.653h526.531c17.905,0,32.422,14.516,32.422,32.422v526.531
c0,17.905-14.517,32.422-32.422,32.422H38.01c-17.906,0-32.422-14.517-32.422-32.422V38.075C5.588,20.169,20.104,5.653,38.01,5.653z"/>
</svg>
<path id="fill" fill="#673AB7" d="M38.01,5.653h526.531c17.905,0,32.422,14.516,32.422,32.422v526.531
c0,17.905-14.517,32.422-32.422,32.422H38.01c-17.906,0-32.422-14.517-32.422-32.422V38.075C5.588,20.169,20.104,5.653,38.01,5.653z"/>
</svg>
<div class="example-buttons">
<a id="fillBtn" class="btn btn-blue" href="javascript:void(0)">Start</a>
</div>
</div>
<p>If in this example the <code>fill</code> attribute value would reference a gradient, then <i>rgba(0,0,0,0)</i> is used. Keep in mind that the component will not work with combined
fill values like <code>url(#pattern) rgba()</code>, you are better of only using the <code>url(#pattern)</code> and use other attributes to control directly the animation of that
linked pattern, just like in the last example below.</p>
<div class="example-buttons">
<a id="fillBtn" class="btn btn-blue" href="javascript:void(0)">Start</a>
</div>
</div>
<p>If in this example the <code>fill</code> attribute value would reference a gradient, then <i>rgba(0,0,0,0)</i> is used. Keep in mind that the component will not work with combined
fill values like <code>url(#pattern) rgba()</code>, you are better of only using the <code>url(#pattern)</code> and use other attributes to control directly the animation of that
linked pattern, just like in the last example below.</p>
<h4>Unitless Attributes</h4>
<p>In the next example, let's play with the attributes of a <code>&lt;circle&gt;</code> element: radius and center coordinates.</p>
<h4>Unitless Attributes</h4>
<p>In the next example, let's play with the attributes of a <code>&lt;circle&gt;</code> element: radius and center coordinates.</p>
<pre><code class="language-javascript">// radius attribute
var radiusTween = KUTE.to('#circle', {attr: {r: 75}});
@ -160,21 +160,21 @@ var radiusTween = KUTE.to('#circle', {attr: {r: 75}});
var coordinatesTween = KUTE.to('#circle', {attr:{cx:0,cy:0}});
</code></pre>
<p>A quick demo with the above:</p>
<p>A quick demo with the above:</p>
<div class="featurettes">
<svg class="example-box-model example-box" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 150 150">
<circle class="bg-orange" id="circle" cx="75" cy="75" r="40" />
</svg>
<div class="featurettes">
<svg class="example-box-model example-box" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 150 150">
<circle class="bg-orange" id="circle" cx="75" cy="75" r="40" />
</svg>
<div class="example-buttons">
<a id="circleBtn" class="btn btn-orange" href="javascript:void(0)">Start</a>
</div>
</div>
<div class="example-buttons">
<a id="circleBtn" class="btn btn-orange" href="javascript:void(0)">Start</a>
</div>
</div>
<h4>Suffixed Attributes</h4 >
<p>Similar to the example on circle attributes, we can also animate the gradient positions but this time with a specific to gradients suffix, and the component will make sure
to always include the suffix for you, as in this example the <code>%</code> unit is found in the current value and used as unit for the DOM update:</p>
<h4>Suffixed Attributes</h4 >
<p>Similar to the example on circle attributes, we can also animate the gradient positions but this time with a specific to gradients suffix, and the component will make sure
to always include the suffix for you, as in this example the <code>%</code> unit is found in the current value and used as unit for the DOM update:</p>
<pre><code class="language-javascript">// gradient positions to middle
var closingGradient = KUTE.to('#gradient', {attr: {x1:'49%', x2:'49%', y1:'49%', y2:'49%'}});
@ -183,50 +183,50 @@ var closingGradient = KUTE.to('#gradient', {attr: {x1:'49%', x2:'49%', y1:'49%',
var rotatingGradient = KUTE.to('#gradient', {attr: {x1:'49%', x2:'51%', y1:'51%', y2:'51%'}});
</code></pre>
<div class="featurettes">
<svg class="example-box-model example-box" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 615 615">
<defs>
<linearGradient id="gradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color: #e91b1f; stop-opacity:1"></stop>
<stop offset="100%" style="stop-color: #2196F3; stop-opacity:1"></stop>
</linearGradient>
</defs>
<path fill="url(#gradient)" d="M38.01,5.653h526.531c17.905,0,32.422,14.516,32.422,32.422v526.531
c0,17.905-14.517,32.422-32.422,32.422H38.01c-17.906,0-32.422-14.517-32.422-32.422V38.075C5.588,20.169,20.104,5.653,38.01,5.653z"/>
</svg>
<div class="featurettes">
<svg class="example-box-model example-box" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 615 615">
<defs>
<linearGradient id="gradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color: #e91b1f; stop-opacity:1"></stop>
<stop offset="100%" style="stop-color: #2196F3; stop-opacity:1"></stop>
</linearGradient>
</defs>
<path fill="url(#gradient)" d="M38.01,5.653h526.531c17.905,0,32.422,14.516,32.422,32.422v526.531
c0,17.905-14.517,32.422-32.422,32.422H38.01c-17.906,0-32.422-14.517-32.422-32.422V38.075C5.588,20.169,20.104,5.653,38.01,5.653z"/>
</svg>
<div class="example-buttons">
<a id="gradBtn" class="btn btn-pink" href="javascript:void(0)">Start</a>
</div>
<div class="example-buttons">
<a id="gradBtn" class="btn btn-pink" href="javascript:void(0)">Start</a>
</div>
<h3>Notes</h3>
<ul>
<li>The power of this little gem comes from the fact that it can work with internally undefined/unknown attributes, as well as with attributes that are not yet present in the W3 draft. As long as you provide valid values specific
to the attribute, the component will assign an update function and will always double check for the current value to determine if it needs a suffix or if the attribute name needs adjustments
(EG: <code>fillOpacity</code> becomes <code>fill-opacity</code>).</li>
<li>This component is a great addition to complement any SVG related component as well as a great complement to <a href="filterEffects.html">Filter Effects</a> component.</li>
<li>Remember to check your elements markup for changes, your animation might not be visible because equivalent CSS is used.</li>
<li>This component is bundled with the standard <i>kute.js</i> distribution file and the <i>demo/src/kute-extra.js</i> file.</li>
</ul>
</div>
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2020 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
</div><!-- /.site-wrapper -->
<h3>Notes</h3>
<ul>
<li>The power of this little gem comes from the fact that it can work with internally undefined/unknown attributes, as well as with attributes that are not yet present in the W3 draft. As long as you provide valid values specific
to the attribute, the component will assign an update function and will always double check for the current value to determine if it needs a suffix or if the attribute name needs adjustments
(EG: <code>fillOpacity</code> becomes <code>fill-opacity</code>).</li>
<li>This component is a great addition to complement any SVG related component as well as a great complement to <a href="filterEffects.html">Filter Effects</a> component.</li>
<li>Remember to check your elements markup for changes, your animation might not be visible because equivalent CSS is used.</li>
<li>This component is bundled with the standard <i>kute.js</i> distribution file and the <i>demo/src/kute-extra.js</i> file.</li>
</ul>
</div>
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute-extra.min.js"></script>
<script src="./assets/js/prism.js"></script>
<script src="./assets/js/scripts.js"></script>
<script src="./assets/js/htmlAttributes.js"></script>
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2021 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
</div><!-- /.site-wrapper -->
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute-extra.min.js"></script>
<script src="./assets/js/prism.js"></script>
<script src="./assets/js/scripts.js"></script>
<script src="./assets/js/htmlAttributes.js"></script>
</body>

View file

@ -16,8 +16,12 @@
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- Spicr CSS -->
<link type="text/css" href="https://cdn.jsdelivr.net/npm/spicr/dist/css/spicr.min.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<link type="text/css" href="./assets/css/spicr-theme.css" rel="stylesheet">
</head>
@ -28,7 +32,7 @@
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1 class="active">KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-space">
<div class="nav-wrapper d-flex align-items-center justify-content-between">
<ul class="nav">
<li class="btn-group"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
@ -55,15 +59,15 @@
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEjs animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</a>
</li>
</ul>
</div>
@ -71,78 +75,136 @@
</div>
</div>
<div class="content-wrap">
<div class="columns welcome">
<div class="col2">
<div class="frontpage">
<h2 class="nomargin" data-text="Welcome to KUTE.js" style="opacity: 0;">Welcome to KUTE.js!</h2>
<p class="lead" data-text="The modern, completely reworked and fully featured animation engine for the modern web."></p>
<p class="btns">
<a class="btn btn-orange" style="opacity: 0;" href="https://github.com/thednp/kute.js/archive/master.zip">Download</a>
<a class="btn btn-red" style="opacity: 0;" href="https://github.com/thednp/kute.js">Github</a>
<a class="btn btn-pink" style="opacity: 0;" href="http://www.jsdelivr.com/#!kute.js">CDN 1</a>
<a class="btn btn-olive" style="opacity: 0;" href="https://cdnjs.com/libraries/kute.js">CDN 2</a>
<a class="btn btn-indigo" style="opacity: 0;" href="https://npmjs.com/kute.js">NPM</a>
</p>
<div id="SpicrDemo" class="spicr spicr-slider" data-interval="false" >
<div class="spicr-inner">
<div class="item">
<div class="item-bg spicr-layer bg-blue background-bottom-center" data-translate="x:-100%" data-duration="700" data-easing="easingCubicInOut" data-src="https://picsum.photos/id/992/1680/720.jpg">
<div class="overlay"></div>
</div>
<div class="content-wrap h-100"> <!-- IE9 fix -->
<div class="d-flex align-items-end h-100">
<div class="flex-column w-md-50 text-center mb-5" style="margin: 0 auto">
<div class="spicr-layer" data-translate="x:-250" data-duration="600" data-easing="easingCubicInOut">
<h1>Welcome to KUTE.js!</h1>
</div>
<div class="spicr-layer" data-translate="x:-250" data-delay="350" data-duration="700" data-easing="easingCubicInOut">
<p class="lead condensed">The JavaScript animation engine of the future</p>
</div>
<div class="spicr-layer" data-translate="x:-250" data-delay="450" data-duration="800" data-easing="easingCubicInOut">
<p>The magic behind <a class="text-light font-weight-bold" href="https://thednp.github.io/spicr/">Spicr</a>, the result of hard work,
the bridge between old and new, the dream and inspiration.</p>
</div>
<div>
<p class="btns">
<a class="btn btn-red spicr-layer" href="https://github.com/thednp/kute.js/archive/master.zip" data-translate="x:-250" data-delay="750" data-duration="900" data-easing="easingCircularInOut">Download</a>
<a class="btn btn-olive spicr-layer" href="https://thednp.github.io/kute.js" data-translate="x:-250" data-delay="650" data-duration="800" data-easing="easingCircularInOut">Github</a>
<a class="btn btn-indigo spicr-layer" href="https://www.npmjs.com/package/kute.js" data-translate="x:-250" data-delay="550" data-duration="700" data-easing="easingCircularInOut">NPM</a>
<a class="btn btn-blue spicr-layer" href="https://www.jsdelivr.com/package/npm/kute.js" data-translate="x:-250" data-delay="450" data-duration="600" data-easing="easingCircularInOut">CDN</a>
</p>
</div>
</div>
</div>
</div>
</div>
<div class="col2">
<svg class="kute-logo" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600" width="100%">
<path id="rectangle" style="transform: translateX(-250px); opacity: 0;" fill="#e91b1f" d="M559,597.4H302.1H43.6c-21,0-38-17-38-38V408.8V223.6V44c0-21,17-38,38-38h105.6H300h160.3H559
c21,0,38,17,38,38v184v331.4C597,580.4,580,597.4,559,597.4z"/>
<path id="star" visibility="hidden" fill="#FF5722" d="M302.1,17.9c16,29,81.4,147.7,98.2,178.2c31.1,6,62.3,11.9,93.4,17.9c35.5,6.8,71,13.6,106.5,20.4
c-46.4,49.5-92.7,99-139.1,148.5c1.1,8.5,6.7,53.4,12.4,99.1c5.7,45.3,11.4,91.4,12.9,102.9c-36-16.9-158.8-74.5-184.2-86.4
c-28.5,13.4-151.3,71-184.2,86.4c0.4-3.2,13.3-106.6,13.3-106.6s10.1-81,11.9-95.3C96.8,333.5,50.4,284,4,234.5
c34.4-6.6,68.8-13.2,103.3-19.8c32.2-6.2,64.4-12.3,96.5-18.5C221,165.1,286.5,46.2,302.1,17.9z"/>
<path id="circle" visibility="hidden" fill="#9C27B0" d="M157,367a210,210 0 1,0 420,0a210,210 0 1,0 -420,0z"/>
<path id="cat" visibility="hidden" fill="#ffd626" d="M519.8,118.6C518.4,90.8,483.3,78,460,82.5c-51.1,9.7-59.4,67.2-48.3,109.4c5.4,20.5,15.1,42.7,13.6,64.3
c-1.3,19.5-7.8,39.2-20.7,54.1c1-0.1,2.2-0.3,3.2-0.4c-1,0.1-2.2,0.3-3.2,0.4c-12.9,2-25.3,7.4-29.6,9.6
c-0.9-13.3-1.8-24.5-2.3-31.9c-0.4-10.3-0.8-18.6-1.1-23.9c-1-12.6-15.9-25.3-28.2-33.7c-8.8-6-16.5-9.8-16.5-9.8
c13.8-10.2,19.8-17.6,21.6-23.9c2.3-8,4.3-35.1,4.3-35.1s1.1-6,1.1-15.2c0-11.6-2-22.6-5.7-32.9h0.1c0,0,25.4-45.8,14.7-60.1
c-8.9-11.7-46.3,16.7-46.3,16.7c-16.3-12.6-36.9-20.2-59.1-20.2c-6,0-11.9,0.5-17.7,1.7c0,0-7.4-41.3-27.3-39.7
c-19.8,1.7-29.3,72.8-29.3,72.8l0.1,0.1c-8.3,9.9-14.7,21.6-18.4,34.3c0,0-11.2,26.4-10.3,42.7c0.9,16.2,15.9,31.2,25.6,42.3
l18.9,19.1c0,0,2.8,3.1,6.9,6.9c-0.4,0.3-3.1,1.5-7,3.8c-11.1,6.4-31.5,20.5-36,41.5c-0.4,1.9-0.8,4-1,6.1
c-1.7,12.8-1.4,30.1-0.4,46.6c-5.9-4.1-25.5-15.8-40.3-4.3c-0.6,0.5-1.1,0.9-1.8,1.4c-16.5,13.9-25.4,34.4-25.4,53.8
c0,9.7,3.7,29.1,12,50.4c1,2.8,2.3,5.6,3.6,8.4c4.6,10.3,10.2,20.8,17.2,30.6c6.8,9.7,14.8,18.6,24.1,26c0,0-24.2,13.8-33,32.7
s-6.6,28.1,3.3,29.7c10.1,1.7,57.1-21.8,57.1-21.8c-0.6,2.9-1.5,6.1-2.6,9.6c-5.7,9.7-12.8,22.2-7.3,31.4c1.8,2.9,4.8,5.6,9.8,7.7
c20.8,8.8,41.2,2.3,50.8-8.4c2.9-3.2,4.8-6.6,5.6-10.3c1.1-6.1,1-19.3,0.5-34.3c0,0,39.5,9.9,74.9-4c2.9,21.4,5.5,38.8,6.1,43.2
c0.1,0.9,0.4,1.7,0.6,2.4c2,4.5,9.9,17.5,34.8,14.5c12.6-1.5,19.4-7.8,22.8-12.8c1.1-1.7,1.9-3.4,2.2-5.4c0.1-1.1,0.1-2.4-0.1-3.6
c-0.8-1.8-1.5-4.1-2.3-6.8c-3.1-8.5-7.7-21.6-10.7-33h0.1c0,0,1.3,0.3,3.4,0.8c11.7,2.8,50.3,11.5,53.1,9.3
c3.3-2.4,5.7-10.6,2.6-24.2c-3.8-16.5-38.5-24.7-38.5-24.7s3.7-4.8,9.2-12.5c14.2-19.8,40.4-58.3,46.4-80.4
c7.7-27.9,9.3-58.7-4.2-74.9c20.3-37.8,27.5-78.3,15.1-120c-5.4-18-21.7-63.1,0.9-75.9c8.9-5,25.9-8.4,30.1,4.7
c0,0-7.8,8.7-9.2,14.4c-1.3,5.9-1.9,16.2,14,18.1C502.4,162.3,521.4,150.6,519.8,118.6z"/>
<path id="hexagon" visibility="hidden" fill="#4CAF50" d="M447,45.4H153L6.1,300L153,554.6h294L593.9,300L447,45.4z"/>
<path id="head" visibility="hidden" fill="#2196F3" d="M505.1,520.1c-15.5-13-26-49.1-50.6-67.2c-61.6-45-107.4-15-77.4,20.1
c14.3,16.8,27.2,13.2,40.5,25.2c20.1,18.6,3.1,40.7-15.5,39.2c-10.4-0.8-16.5-10.4-38.2-17.6c-34.9-11.7-84.2-11.2-164.7-24.4
c-109.4-17.8-230.6-111-182-241C62.5,133.5,115.5,62.5,244.8,62.5c170.5,0,213.5,140.7,248.4,210c16.3,32.3,22.7,26.2,36.1,44.8
c12.2,17.1,1.5,46.1-22.9,37.9c-53.7-17.8-77.1,27.2-23.2,62.9c14.5,9.7,59.3,15,73.8,24.7C610.8,478.6,553,560.1,505.1,520.1
L505.1,520.1z"/>
<path id="winky-face" fill="rgba(0,0,0,0.5)" style="opacity:0" d="M347.1,289.3l-13-16.5c-20.1,25.7-15.8,25.2-35.6,0l-13,16.5c-5.1,6.6-14.8-1.3-9.7-7.6
c25.2-32.3,19.9-32.8,40.5-6.4c20.4-26,14.8-26.7,40.5,6.4c2,2.8,1.3,6.6-1.5,8.7C352.7,292.1,349.1,291.6,347.1,289.3L347.1,289.3z
M118,289.3l-13-16.5c-20.1,25.7-15.8,25.2-35.6,0l-13,16.5c-5.1,6.6-14.8-1.3-9.7-7.6c25.2-32.3,19.9-32.8,40.5-6.4
c20.4-26,14.8-26.7,40.5,6.4c2,2.8,1.3,6.6-1.5,8.7C123.6,292.1,120.1,291.6,118,289.3L118,289.3z"/>
<path id="drop" visibility="hidden" d="M558.6,365.4c-13,20.4,23.4,44,36.7,23.7C608.2,368.9,571.8,345.3,558.6,365.4z"/>
<path id="drop-initial" style="opacity:0" fill="#2196F3" d="M505.2,327.1"/>
<path id="mouth-happy" visibility="hidden" d="M251.9,259c-2,26.5-24.2,46.8-50.4,46.8c-26.5,0-48.4-20.4-50.4-46.6c0-2,1.3-3.8,3.3-3.8
h93.9C250.4,255.2,251.9,256.9,251.9,259L251.9,259z"/>
<path id="mouth" style="opacity:0" fill="#000" d="M173.6,270.5c18,0.4,37.1,0.2,55.9,0c17.3-0.2,17.2,27.3-0.6,27.4c-24.5,0.2-29.4,0.4-54.6,0
C158.9,297.8,156.9,270.2,173.6,270.5z"/>
<path id="eye-left-closed" visibility="hidden" d="M123.1,221.8c-11.5-9.7-35.1-9.7-46.6,0c-10.9,9.4-25.5-7.1-14.5-16.8c19.9-16.8,55.7-16.8,75.6,0
C148.6,214.4,133.8,231.5,123.1,221.8z"/>
<path id="eye-right-closed" visibility="hidden" d="M339.7,221.8c-11.5-9.7-35.1-9.7-46.6,0c-10.9,9.4-25.7-7.1-14.5-16.8c19.9-16.8,55.7-16.8,75.6,0
C365.4,214.4,350.7,231.2,339.7,221.8z"/>
<path id="eye-right" style="opacity:0" fill="#000" d="M316.2,236.1c-31.6,0-48.7-21.4-37.5-31.1c19.9-16.8,55.7-16.8,75.6,0
C365.4,214.4,350.9,236.1,316.2,236.1z"/>
<path id="eye-left" style="opacity:0" fill="#000" d="M99.4,236.1c-31.6,0-48.7-21.4-37.5-31.1c19.9-16.8,55.7-16.8,75.6,0
C148.7,214.4,134.1,236.1,99.4,236.1z"/>
</svg>
<div class="item perspective-1500">
<div class="item-bg spicr-layer bg-olive" data-rotate="x:90" data-transform-origin="z:50%v" data-duration="700" data-easing="easingCubicInOut" data-src="https://picsum.photos/id/931/1680/720.jpg">
<div class="overlay"></div>
</div>
<div class="content-wrap h-100"><!-- IE9 fix -->
<div class="columns h-100 align-content-center">
<div class="col2 h-md-100"><!-- IE9 fix -->
<div class="d-flex perspective align-items-end align-items-md-center h-md-100">
<div class="spicr-layer" data-translate="y:10%" data-rotate="x:90" data-transform-origin="z:50%" data-duration="800" data-easing="easingCubicInOut">
<h1>Forward Looking</h1>
<p>The modern JavaScript powering the core functionality, the modular architecture, the solid and complete components are all geared towards the future of web development.</p>
</div>
</div>
</div>
<div class="col2 h-md-100">
<div class="d-flex perspective align-items-start align-items-md-center h-md-100">
<div class="spicr-layer" data-translate="y:10%" data-rotate="x:90" data-transform-origin="z:50%" data-duration="900" data-delay="350" data-easing="easingCubicInOut">
<h1>Knowing the Past</h1>
<p>While KUTE.js was re-developed to support mainly modern browsers, it also leaves the door open to old browsers with its legacy components, tools and polyfills.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="item">
<div class="item-bg spicr-layer bg-pink" data-translate="y:-100%" data-duration="700" data-easing="easingCubicInOut" data-src="https://picsum.photos/id/668/1680/720.jpg">
<div class="overlay"></div>
</div>
<div class="content-wrap h-100">
<div class="columns align-content-center h-100">
<div class="col2 h-md-100">
<div class="d-flex align-items-start align-items-md-center h-md-100">
<div class="w-100 flex-column"> <!-- IE9 fix -->
<div class="spicr-layer" data-translate="y:-150" data-duration="800" data-delay="550" data-easing="easingCircularOut">
<h1>ES6+ JavaScript</h1>
</div>
<div class="spicr-layer" data-translate="y:-150" data-duration="900" data-delay="650" data-easing="easingCircularOut">
<p>Inside the sources you will find fast &amp; modern JavaScript code with solid build tools. Everything and anything can be done with <b>SVGElement</b>,
HTML attributes, CSS transform, etc.</p>
</div>
</div>
</div>
</div>
<div class="col2 h-md-100"> <!-- IE9 fix -->
<div class="d-flex align-items-end align-items-md-center h-md-100">
<div class="w-100 flex-column"> <!-- IE9 fix -->
<div class="spicr-layer" data-translate="y:-150" data-duration="700" data-delay="350" data-easing="easingCircularOut">
<h1>Cubic Bezier Easing</h1>
</div>
<div class="spicr-layer" data-translate="y:-150" data-duration="800" data-delay="450" data-easing="easingCircularOut">
<p>While the library includes Robert Penner's <a href="http://robertpenner.com/easing/">easing functions</a>, KUTE.js also includes its own
<a href="https://github.com/thednp/CubicBezier">CubicBezier Easing</a> class to provide fast and accurate easing for your animation.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="item perspective-1500">
<div class="item-bg spicr-layer bg-indigo" data-rotate="y:90" data-transform-origin="z:-50%" data-duration="1000" data-easing="easingCubicInOut" data-src="https://picsum.photos/id/581/1680/720.jpg">
<div class="overlay"></div>
</div>
<div class="content-wrap h-100">
<div class="d-flex w-md-75 align-items-center text-md-center justify-content-md-center h-100" style="margin: 0 auto">
<div class="spicr-layer" data-rotate="y:90" data-transform-origin="z:-50%" data-duration="1200" data-easing="easingCubicInOut">
<h1><span>What's not to love about it?</span></h1>
<p>Yeah, the open source, modular and fully featured animation engine for the modern web, fully documented and MIT Licensed.</p>
<p>Any question? Find answers <a href="https://stackoverflow.com/search?q=kute.js">here</a>, or post them <a href="https://github.com/thednp/kute.js/issues">here</a>!</p>
</div>
</div>
</div>
</div>
</div>
<!-- pages -->
<ol class="spicr-pages d-flex flex-row justify-content-center">
<li data-slide-to="0" class=""></li>
<li data-slide-to="1"></li>
<li data-slide-to="2"></li>
<li data-slide-to="3"></li>
</ol>
<a class="left spicr-control long-shadows" data-slide="prev">
<span class="arrow-prev">
<svg class="spicr-icon" viewBox="0 0 1024 1024">
<path d="M658 686l-60 60-256-256 256-256 60 60-196 196z"></path>
</svg>
</span>
</a>
<a class="right spicr-control long-shadows" data-slide="next">
<span class="arrow-next">
<svg class="spicr-icon" viewBox="0 0 1024 1024">
<path d="M366 698l196-196-196-196 60-60 256 256-256 256z"></path>
</svg>
</span>
</a>
</div>
<div class="featurettes dark">
<div class="featurettes dark mt-0">
<div class="content-wrap">
<div class="columns">
<div class="col3">
@ -153,11 +215,10 @@
<p class="lead condensed">The JavaScript animation engine reimagined for the evolving modern web, the library that keeps track on the changing standards, the modular tool
to enable creativity.</p>
<p>Built on modern ES6/ES7 JavaScript Standard, packed with utilities, build tools and a wide range of supported properties, <b>KUTE</b>.js is now a fully featured animation engine
<p>Built on modern ES6+ JavaScript Standard, packed with utilities, build tools and a wide range of supported properties, <b>KUTE</b>.js is now a fully featured animation engine
you can use to create complex animations, with properties or elements that cannot be animated with CSS3 transitions or other animation engines, or attributes that aren't
even drafted in the specification yet.</p>
<p class="lead condensed">The JavaScript animation engine that never stops evolving just like we never stop learning. Instead of becoming more bloated, we make it more modular,
instead of compromising we chose innovating. </p>
<p>While <b>KUTE</b>.js doesn't activelly support legacy browsers, it provides a wide range of tools and utilities you can use to create a fallback animation for every browser
@ -175,8 +236,8 @@
<div class="columns">
<div class="col2">
<h3 class="border">ES6/ES7 JavaScript</h2>
<p class="condensed">The entire codebase reworked on the latest standards with flexible rollup based build tools. Most classes are extensible via the ES6 <code>extend</code>
<h3 class="border">ES6+ JavaScript</h2>
<p class="condensed">The entire codebase reworked on the latest standards with flexible <code>rollup</code> based build tools. Most classes are extensible via the ES6 <code>extend</code>
or your usual <code>prototype</code>, depending on the class.</p>
</div>
<div class="col2">
@ -209,7 +270,7 @@
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2020 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
<p>&copy; 2015 - 2021 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
@ -221,6 +282,8 @@
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/spicr/dist/js/spicr.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/dll.js@1.5.5/dist/dll.min.js"></script>
<script src="./assets/js/scripts.js"></script>
<script src="./assets/js/home.js"></script>

View file

@ -1,108 +1,108 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="The Opacity Property component for KUTE.js allows you to animate the opacity CSS property on most browsers.">
<meta name="keywords" content="opacity,kute.js,animation,javascript animation,tweening engine,animation engine,JavaScript,Native JavaScript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="The Opacity Property component for KUTE.js allows you to animate the opacity CSS property on most browsers.">
<meta name="keywords" content="opacity,kute.js,animation,javascript animation,tweening engine,animation engine,JavaScript,Native JavaScript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<title>KUTE.js Opacity Property</title>
<title>KUTE.js Opacity Property</title>
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
<style></style>
<style></style>
</head>
<body>
<div class="site-wrapper">
<div class="site-wrapper">
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-space">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li class="active"><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-between">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li class="active"><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</div>
</nav>
</div>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div class="content-wrap">
<h2 class="head-title">Opacity Property</h2>
<p class="condensed lead">The component that animates the CSS <i>opacity</i> property of a target <b>Element</b> on most browsers.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<h2 class="head-title">Opacity Property</h2>
<p class="condensed lead">The component that animates the CSS <i>opacity</i> property of a target <b>Element</b> on most browsers.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<div class="columns">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">Animate the <b>opacity</b> property of a target element.</p>
</div>
<div class="col9 border">
<p>The KUTE.js <b>Opacity Property</b> component enables animation for the <b>opacity</b> CSS property of an <b>Element</b> target on most browsers.</p>
<p>In most cases, the best presentatation can be offered with a nice and smooth fade animation, with opacity going from 0% all the way up to to 100%.</p>
<p>While some components like <a href="htmlAttributes.html">HTML Attributes</a> and <a href="filterEffects.html">Filter Effects</a> do provide some
similar functionality for specific <b>Element</b> types, this component covers all types of elements and is supported on a wide range of modern
and legacy browsers alike.</p>
</div>
<div class="columns">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">Animate the <b>opacity</b> property of a target element.</p>
</div>
<div class="col9 border">
<p>The KUTE.js <b>Opacity Property</b> component enables animation for the <b>opacity</b> CSS property of an <b>Element</b> target on most browsers.</p>
<p>In most cases, the best presentatation can be offered with a nice and smooth fade animation, with opacity going from 0% all the way up to to 100%.</p>
<p>While some components like <a href="htmlAttributes.html">HTML Attributes</a> and <a href="filterEffects.html">Filter Effects</a> do provide some
similar functionality for specific <b>Element</b> types, this component covers all types of elements and is supported on a wide range of modern
and legacy browsers alike.</p>
</div>
</div>
</div>
</div>
</div>
<div class="content-wrap">
<div class="content-wrap">
<h3>Example</h3>
<h3>Example</h3>
<pre><code class="language-javascript">// fade out
let fadeOutTween = KUTE.to('selector1',{opacity:0}).start()
@ -110,44 +110,44 @@ let fadeOutTween = KUTE.to('selector1',{opacity:0}).start()
let fadeInTween = KUTE.to('selector1',{opacity:1}).start()
</code></pre>
<div id="opacityProperty" class="featurettes">
<div class="example-item example-box" style="opacity:0">
<svg class="" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
<path fill="red" d="M880.128 199.936c-85.606-78.541-224.41-78.541-310.016 0l-58.112 53.35-58.163-53.35c-85.606-78.541-224.358-78.541-309.965 0-96.307 88.422-96.307 231.424 0 319.795l368.128 337.869 368.128-337.869c96.256-88.371 96.256-231.424 0-319.795z"></path>
</svg>
</div>
<div class="example-buttons"><a class="btn btn-red" href="javascript:void(0)">Start</a></div>
<div id="opacityProperty" class="featurettes">
<div class="example-item example-box" style="opacity:0">
<svg class="" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
<path fill="red" d="M880.128 199.936c-85.606-78.541-224.41-78.541-310.016 0l-58.112 53.35-58.163-53.35c-85.606-78.541-224.358-78.541-309.965 0-96.307 88.422-96.307 231.424 0 319.795l368.128 337.869 368.128-337.869c96.256-88.371 96.256-231.424 0-319.795z"></path>
</svg>
</div>
<h3>Notes</h3>
<ul>
<li>This demo should work with IE9+ browsers.</li>
<li>Support for the specific IE8 <code>filter:alpha(opacity=50)</code> have been dropped.</li>
<li>Early implementations with vendor preffixes such as <code>-o-opacity</code>, <code>-moz-opacity</code> or <code>-ms-opacity</code> are not supported.</li>
<li>The component is an essential part in ALL KUTE.js distributions.</li>
</ul>
</div>
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2020 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
<div class="example-buttons"><a class="btn btn-red" href="javascript:void(0)">Start</a></div>
</div>
<h3>Notes</h3>
<ul>
<li>This demo should work with IE9+ browsers.</li>
<li>Support for the specific IE8 <code>filter:alpha(opacity=50)</code> have been dropped.</li>
<li>Early implementations with vendor preffixes such as <code>-o-opacity</code>, <code>-moz-opacity</code> or <code>-ms-opacity</code> are not supported.</li>
<li>The component is an essential part in ALL KUTE.js distributions.</li>
</ul>
</div>
<!-- /.site-wrapper -->
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<!-- <script src="./src/polyfill-legacy.min.js"></script> -->
<script src="./src/polyfill-legacy.min.js"></script>
<script src="./src/kute.min.js"></script>
<script src="./assets/js/prism.js"></script>
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2021 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
<script src="./assets/js/opacityProperty.js"></script>
<script src="./assets/js/scripts.js"></script>
</div>
<!-- /.site-wrapper -->
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<!-- <script src="./src/polyfill-legacy.min.js"></script> -->
<script src="./src/polyfill-legacy.min.js"></script>
<script src="./src/kute.min.js"></script>
<script src="./assets/js/prism.js"></script>
<script src="./assets/js/opacityProperty.js"></script>
<script src="./assets/js/scripts.js"></script>
</body>
</html>

View file

@ -203,7 +203,9 @@
<!-- Placed at the end of the document so the pages load faster -->
<script type="text/javascript" src="https://cdn.jsdelivr.net/bootstrap.native/1.0.1/bootstrap-native.min.js"></script>
<!-- <script src="../experiments/CSSMatrix.js"></script> -->
<script id="kute" src="./src/kute-extra.min.js"></script>
<!-- <script id="kute" src="./src/kute-extra.js"></script> -->
<script src="./assets/js/perf-matrix.js"></script>
</body>

View file

@ -2,212 +2,212 @@
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="KUTE.js performance testing page, comparing basic transform to matrix transform.">
<meta name="keywords" content="kute,kute.js,Javascript,Native Javascript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="KUTE.js performance testing page, comparing basic transform to matrix transform.">
<meta name="keywords" content="kute,kute.js,Javascript,Native Javascript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<title>KUTE.js | Regular Transform Performance Testing Page</title>
<style>
body {
background-color: #08263d;
color: #999;
font-size: 12px;
font-family: Helvetica, Arial, Helvetica, sans-serif;
}
<title>KUTE.js | Regular Transform Performance Testing Page</title>
<style>
body {
background-color: #08263d;
color: #999;
font-size: 12px;
font-family: Helvetica, Arial, Helvetica, sans-serif;
}
a {
color: #ffd626;
text-decoration: none
}
a {
color: #ffd626;
text-decoration: none
}
.hr { border-color: rgba(255, 255, 255, 0.2); margin: 15px 0 }
.hr { border-color: rgba(255, 255, 255, 0.2); margin: 15px 0 }
a:hover,
a:focus {
color: #fff;
}
a:hover,
a:focus {
color: #fff;
}
#container {
width: 70%;
/*height: 200px;*/
margin: 5% auto 0 auto;
position: relative;
display: none;
/* perspective: 1200px; */
/* transform-style: preserve-3d; don't overDO the preserve3d */
}
#container {
width: 70%;
/*height: 200px;*/
margin: 5% auto 0 auto;
position: relative;
display: none;
/* perspective: 1200px; */
/* transform-style: preserve-3d; don't overDO the preserve3d */
}
iframe {
width: 100%;
height: 100%;
border: 0
}
iframe {
width: 100%;
height: 100%;
border: 0
}
.line {
width: 200px;
height: 2px;
position: absolute;
}
.line {
width: 200px;
height: 2px;
position: absolute;
}
.box {
height: 200px
}
.box {
height: 200px
}
#info {
position: absolute;
top: 20%;
left: 0;
width: 350px;
}
#info {
position: absolute;
top: 20%;
left: 0;
width: 350px;
}
.padding {
padding: 20px
}
.padding {
padding: 20px
}
.btn-group {
margin-bottom: 15px;
}
.btn-group {
margin-bottom: 15px;
}
.btn {
display: inline-block;
padding: 6px 12px;
margin-bottom: 0;
font-size: 14px;
font-weight: 400;
line-height: 1.42857143;
text-align: center;
white-space: nowrap;
vertical-align: middle;
-ms-touch-action: manipulation;
touch-action: manipulation;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background-image: none;
border: 1px solid transparent;
}
.btn-primary {
color: #fff;
background-color: #337ab7;
}
.btn-success {
color: #fff;
background-color: #5cb85c;
}
.btn {
display: inline-block;
padding: 6px 12px;
margin-bottom: 0;
font-size: 14px;
font-weight: 400;
line-height: 1.42857143;
text-align: center;
white-space: nowrap;
vertical-align: middle;
-ms-touch-action: manipulation;
touch-action: manipulation;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background-image: none;
border: 1px solid transparent;
}
.btn-primary {
color: #fff;
background-color: #337ab7;
}
.btn-success {
color: #fff;
background-color: #5cb85c;
}
.text-note {
color: #069
}
.text-note {
color: #069
}
.text-danger {
font-weight: bold
}
.text-danger {
font-weight: bold
}
.list-inline {
padding-left: 0;
list-style: none;
margin-left: -5px;
}
.list-inline {
padding-left: 0;
list-style: none;
margin-left: -5px;
}
.list-inline>li {
display: inline-block;
padding-right: 5px;
padding-left: 5px;
}
.list-inline>li {
display: inline-block;
padding-right: 5px;
padding-left: 5px;
}
.cube {
flex: 0 1 auto;
width: 100px;
height: 100px;
transform-style: preserve-3d;
display: inline-flex;
margin: 3%
.cube {
flex: 0 1 auto;
width: 100px;
height: 100px;
transform-style: preserve-3d;
display: inline-flex;
margin: 3%
}
}
.cube .cube__side {
position: absolute;
height: 100%;
width: 100%;
background-color: rgba(80, 176, 255, 0.1);
box-shadow: inset 0 0 0 2px rgb(13, 165, 64);
}
.cube .cube__side:nth-child(1) {transform: translateZ(50px); }
.cube .cube__side:nth-child(2) {transform: translateZ(-50px); }
.cube .cube__side:nth-child(3) {transform: translateX(-50px) rotateY(90deg); }
.cube .cube__side:nth-child(4) {transform: translateX(50px) rotateY(-90deg); }
.cube .cube__side:nth-child(5) {transform: translateY(50px) rotateX(90deg); }
.cube .cube__side:nth-child(6) {transform: translateY(-50px) rotateX(-90deg); }
.cube .cube__side:nth-child(7),
.cube .cube__side:nth-child(8),
.cube .cube__side:nth-child(9),
.cube .cube__side:nth-child(10),
.cube .cube__side:nth-child(11),
.cube .cube__side:nth-child(12),
.cube .cube__side:nth-child(13),
.cube .cube__side:nth-child(14),
.cube .cube__side:nth-child(15) {
background-color: rgba(129, 11, 109, 0.1) !important;
box-shadow: 0 0 1rem #d7ff6a, inset 0 0 0 2px #6aff8f;
opacity: 0.2;
}
.cube.alive .cube__side:nth-child(7),
.cube.alive .cube__side:nth-child(8),
.cube.alive .cube__side:nth-child(9),
.cube.alive .cube__side:nth-child(10),
.cube.alive .cube__side:nth-child(11),
.cube.alive .cube__side:nth-child(12),
.cube.alive .cube__side:nth-child(13),
.cube.alive .cube__side:nth-child(14),
.cube.alive .cube__side:nth-child(15) {opacity: 0.5; }
.cube .cube__side:nth-child(7) {transform: translateY(-25px) rotateX(-90deg); }
.cube .cube__side:nth-child(8) {transform: rotateX(-90deg); }
.cube .cube__side:nth-child(9) {transform: translateY(25px) rotateX(-90deg); }
.cube .cube__side:nth-child(10) {transform: translateZ(25px); }
.cube .cube__side:nth-child(11) {transform: none; }
.cube .cube__side:nth-child(12) {transform: translateZ(-25px); }
.cube .cube__side:nth-child(13) {transform: translateX(-25px) rotateY(90deg); }
.cube .cube__side:nth-child(14) {transform: rotateY(90deg); }
.cube .cube__side:nth-child(15) {transform: translateX(25px) rotateY(90deg); }
</style>
.cube .cube__side {
position: absolute;
height: 100%;
width: 100%;
background-color: rgba(80, 176, 255, 0.1);
box-shadow: inset 0 0 0 2px rgb(13, 165, 64);
}
.cube .cube__side:nth-child(1) {transform: translateZ(50px); }
.cube .cube__side:nth-child(2) {transform: translateZ(-50px); }
.cube .cube__side:nth-child(3) {transform: translateX(-50px) rotateY(90deg); }
.cube .cube__side:nth-child(4) {transform: translateX(50px) rotateY(-90deg); }
.cube .cube__side:nth-child(5) {transform: translateY(50px) rotateX(90deg); }
.cube .cube__side:nth-child(6) {transform: translateY(-50px) rotateX(-90deg); }
.cube .cube__side:nth-child(7),
.cube .cube__side:nth-child(8),
.cube .cube__side:nth-child(9),
.cube .cube__side:nth-child(10),
.cube .cube__side:nth-child(11),
.cube .cube__side:nth-child(12),
.cube .cube__side:nth-child(13),
.cube .cube__side:nth-child(14),
.cube .cube__side:nth-child(15) {
background-color: rgba(129, 11, 109, 0.1) !important;
box-shadow: 0 0 1rem #d7ff6a, inset 0 0 0 2px #6aff8f;
opacity: 0.2;
}
.cube.alive .cube__side:nth-child(7),
.cube.alive .cube__side:nth-child(8),
.cube.alive .cube__side:nth-child(9),
.cube.alive .cube__side:nth-child(10),
.cube.alive .cube__side:nth-child(11),
.cube.alive .cube__side:nth-child(12),
.cube.alive .cube__side:nth-child(13),
.cube.alive .cube__side:nth-child(14),
.cube.alive .cube__side:nth-child(15) {opacity: 0.5; }
.cube .cube__side:nth-child(7) {transform: translateY(-25px) rotateX(-90deg); }
.cube .cube__side:nth-child(8) {transform: rotateX(-90deg); }
.cube .cube__side:nth-child(9) {transform: translateY(25px) rotateX(-90deg); }
.cube .cube__side:nth-child(10) {transform: translateZ(25px); }
.cube .cube__side:nth-child(11) {transform: none; }
.cube .cube__side:nth-child(12) {transform: translateZ(-25px); }
.cube .cube__side:nth-child(13) {transform: translateX(-25px) rotateY(90deg); }
.cube .cube__side:nth-child(14) {transform: rotateY(90deg); }
.cube .cube__side:nth-child(15) {transform: translateX(25px) rotateY(90deg); }
</style>
</head>
<body>
<div id="info" class="padding">
<div id="info" class="padding">
<ul class="list-inline">
<li><a title="Go to KUTE.js homepage" href="index.html">Homepage</a></li>
<li><a title="Go to animation engine performance comparison page" href="performance.html">Engine Comparison</a></li>
<li><a title="Go to Transform Matrix component testing page" href="performance-matrix.html">Transform Matrix</a></li>
</ul>
<hr class="hr">
<ul class="list-inline">
<li><a title="Go to KUTE.js homepage" href="index.html">Homepage</a></li>
<li><a title="Go to animation engine performance comparison page" href="performance.html">Engine Comparison</a></li>
<li><a title="Go to Transform Matrix component testing page" href="performance-matrix.html">Transform Matrix</a></li>
</ul>
<hr class="hr">
<div style="width:100%;clear: both">
<button class="btn btn-success" id="start" type="button" style="margin-bottom: 15px">Start</button>
</div>
<div style="width:100%;clear: both">
<button class="btn btn-success" id="start" type="button" style="margin-bottom: 15px">Start</button>
</div>
<p>These tests are only for modern browsers. In Webkit browsers like Google Chrome and Opera you can enable the FPS metter in developer tools, <a href="https://developer.chrome.com/devtools/docs/rendering-settings" target="_blank">here's how</a>.</p>
<p class="text-note">Please know that a local copy of this page will outperform the live site demo on Google Chrome, the reason is unknown.</p>
<p>These tests are only for modern browsers. In Webkit browsers like Google Chrome and Opera you can enable the FPS metter in developer tools, <a href="https://developer.chrome.com/devtools/docs/rendering-settings" target="_blank">here's how</a>.</p>
<p class="text-note">Please know that a local copy of this page will outperform the live site demo on Google Chrome, the reason is unknown.</p>
</div>
</div>
<div id="container"></div>
<div id="container"></div>
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script type="text/javascript" src="https://cdn.jsdelivr.net/bootstrap.native/1.0.1/bootstrap-native.min.js"></script>
<script id="kute" src="./src/kute.min.js"></script>
<script src="./assets/js/perf-matrix.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/bootstrap.native/1.0.1/bootstrap-native.min.js"></script>
<script id="kute" src="./src/kute.min.js"></script>
<script src="./assets/js/perf-matrix.js"></script>
</body>
</html>

View file

@ -2,243 +2,243 @@
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="KUTE.js performance testing page, in comparison with GSAP and Tween.js">
<meta name="keywords" content="kute,kute.js,Javascript,Native Javascript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="KUTE.js performance testing page, in comparison with GSAP and Tween.js">
<meta name="keywords" content="kute,kute.js,Javascript,Native Javascript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<title>KUTE.js | Performance Testing Page</title>
<!-- <link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"> -->
<style>
body {
background-color: #08263d;
color: #999;
font-size: 12px;
font-family: Helvetica, Arial, Helvetica, sans-serif;
}
<title>KUTE.js | Performance Testing Page</title>
<!-- <link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"> -->
<style>
body {
background-color: #08263d;
color: #999;
font-size: 12px;
font-family: Helvetica, Arial, Helvetica, sans-serif;
}
.hr { border-color: rgba(255, 255, 255, 0.2); margin: 15px 0; clear:both }
.hr { border-color: rgba(255, 255, 255, 0.2); margin: 15px 0; clear:both }
a {
color: #ffd626;
text-decoration: none
}
a {
color: #ffd626;
text-decoration: none
}
.btn-group { display: inline-block}
.btn-group { display: inline-block}
a:hover,
a:focus {
color: #fff;
}
a:hover,
a:focus {
color: #fff;
}
#container {
width: 200px;
/*height: 200px;*/
margin: 0 auto;
position: relative;
display: block;
}
#container {
width: 200px;
/*height: 200px;*/
margin: 0 auto;
position: relative;
display: block;
}
iframe {
width: 100%;
height: 100%;
border: 0
}
iframe {
width: 100%;
height: 100%;
border: 0
}
.line {
width: 200px;
height: 2px;
position: absolute;
}
.line {
width: 200px;
height: 2px;
position: absolute;
}
.box {
height: 200px
}
.box {
height: 200px
}
#info {
position: absolute;
top: 20%;
left: 0;
width: 350px;
}
#info {
position: absolute;
top: 20%;
left: 0;
width: 350px;
}
.padding {
padding: 20px
}
.padding {
padding: 20px
}
.btn {
display: inline-block;
padding: 6px 12px;
margin-bottom: 0;
font-size: 14px;
font-weight: 400;
line-height: 1.42857143;
text-align: center;
white-space: nowrap;
vertical-align: middle;
-ms-touch-action: manipulation;
touch-action: manipulation;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background-image: none;
border: 1px solid transparent;
}
.btn:focus { outline: none }
.btn {
display: inline-block;
padding: 6px 12px;
margin-bottom: 0;
font-size: 14px;
font-weight: 400;
line-height: 1.42857143;
text-align: center;
white-space: nowrap;
vertical-align: middle;
-ms-touch-action: manipulation;
touch-action: manipulation;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background-image: none;
border: 1px solid transparent;
}
.btn:focus { outline: none }
.btn-primary {
color: #fff;
background-color: #337ab7;
}
.btn-success {
color: #fff;
background-color: #5cb85c;
}
.dropdown-menu {
position: absolute;
top: 100%;
left: 0;
z-index: 1000;
display: none;
float: left;
min-width: 160px;
padding: 5px 0;
margin: 2px 0 0;
font-size: 14px;
text-align: left;
list-style: none;
background-color: #fff;
background-clip: padding-box;
border: 1px solid #ccc;
border: 1px solid rgba(0,0,0,.15);
}
.dropdown-menu>li:hover { background-color: rgba(0,0,0,0.2); }
.dropdown-menu>li>a {
display: block;
padding: 3px 20px;
clear: both;
font-weight: 400;
line-height: 1.42857143;
color: #333;
white-space: nowrap;
}
.dropdown {
position:relative
}
.dropdown.open .dropdown-menu {
display: block
}
.text-note {
color: #069
}
.btn-primary {
color: #fff;
background-color: #337ab7;
}
.btn-success {
color: #fff;
background-color: #5cb85c;
}
.dropdown-menu {
position: absolute;
top: 100%;
left: 0;
z-index: 1000;
display: none;
float: left;
min-width: 160px;
padding: 5px 0;
margin: 2px 0 0;
font-size: 14px;
text-align: left;
list-style: none;
background-color: #fff;
background-clip: padding-box;
border: 1px solid #ccc;
border: 1px solid rgba(0,0,0,.15);
}
.dropdown-menu>li:hover { background-color: rgba(0,0,0,0.2); }
.dropdown-menu>li>a {
display: block;
padding: 3px 20px;
clear: both;
font-weight: 400;
line-height: 1.42857143;
color: #333;
white-space: nowrap;
}
.dropdown {
position:relative
}
.dropdown.open .dropdown-menu {
display: block
}
.text-note {
color: #069
}
.text-danger {
font-weight: bold
}
.list-inline {
padding-left: 0;
list-style: none;
margin-left: -5px;
}
.text-danger {
font-weight: bold
}
.list-inline {
padding-left: 0;
list-style: none;
margin-left: -5px;
}
.list-inline>li {
display: inline-block;
padding-right: 5px;
padding-left: 5px;
}
</style>
.list-inline>li {
display: inline-block;
padding-right: 5px;
padding-left: 5px;
}
</style>
</head>
<body>
<div id="info" class="padding">
<ul class="list-inline">
<li><a title="Go to KUTE.js homepage" href="index.html">Homepage</a></li>
<li><a title="Go to Transform Functions component testing page" href="performance-transform.html">Transform Functions</a></li>
<li><a title="Go to Transform Matrix component testing page" href="performance-matrix.html">Transform Matrix</a></li>
</ul>
<hr class="hr">
<div id="info" class="padding">
<ul class="list-inline">
<li><a title="Go to KUTE.js homepage" href="index.html">Homepage</a></li>
<li><a title="Go to Transform Functions component testing page" href="performance-transform.html">Transform Functions</a></li>
<li><a title="Go to Transform Matrix component testing page" href="performance-matrix.html">Transform Matrix</a></li>
</ul>
<hr class="hr">
<span id="engine" class="btn-group dropdown">
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-expanded="false" tabindex="0">Engine <span class="caret"></span></button>
<ul class="dropdown-menu" role="menu">
<li><a id="kute" href="#">KUTE</a></li>
<li><a id="gsap" href="#">GSAP</a></li>
<li><a id="tween" href="#">Tween.js</a></li>
</ul>
</span>
<span id="engine" class="btn-group dropdown">
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-expanded="false" tabindex="0">Engine <span class="caret"></span></button>
<ul class="dropdown-menu" role="menu">
<li><a id="kute" href="#">KUTE</a></li>
<li><a id="gsap" href="#">GSAP</a></li>
<li><a id="tween" href="#">Tween.js</a></li>
</ul>
</span>
<span id="property" class="btn-group dropdown">
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-expanded="false" tabindex="0">Property <span class="caret"></span></button>
<ul class="dropdown-menu" role="menu">
<li><a id="left" href="#">left</a></li>
<li><a id="translateX" href="#">translateX</a></li>
</ul>
</span>
<span id="property" class="btn-group dropdown">
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-expanded="false" tabindex="0">Property <span class="caret"></span></button>
<ul class="dropdown-menu" role="menu">
<li><a id="left" href="#">left</a></li>
<li><a id="translateX" href="#">translateX</a></li>
</ul>
</span>
<span id="repeat" class="btn-group dropdown">
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-expanded="false" tabindex="0">Repeat <span class="caret"></span></button>
<ul class="dropdown-menu" role="menu">
<li><a id="5" href="#">5</a></li>
<li><a id="10" href="#">10</a></li>
<li><a id="15" href="#">15</a></li>
<li><a id="20" href="#">20</a></li>
</ul>
</span>
<span id="repeat" class="btn-group dropdown">
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-expanded="false" tabindex="0">Repeat <span class="caret"></span></button>
<ul class="dropdown-menu" role="menu">
<li><a id="5" href="#">5</a></li>
<li><a id="10" href="#">10</a></li>
<li><a id="15" href="#">15</a></li>
<li><a id="20" href="#">20</a></li>
</ul>
</span>
<span id="count" class="btn-group dropdown">
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-expanded="false" tabindex="0">Count <span class="caret"></span></button>
<ul class="dropdown-menu" role="menu">
<li><a id="100" href="#">100</a></li>
<li><a id="200" href="#">200</a></li>
<li><a id="300" href="#">300</a></li>
<li><a id="400" href="#">400</a></li>
<li><a id="500" href="#">500</a></li>
<li><a id="600" href="#">600</a></li>
<li><a id="700" href="#">700</a></li>
<li><a id="800" href="#">800</a></li>
<li><a id="900" href="#">900</a></li>
<li><a id="1000" href="#"><span style="color: red">1000</span></a></li>
<li><a id="1500" href="#"><span style="color: red">1500</span></a></li>
<li><a id="2000" href="#"><span style="color: red">2000</span></a></li>
</ul>
</span>
<hr class="hr">
<div style="width:100%;clear: both">
<button class="btn btn-success" id="start" type="button" style="margin-bottom: 15px">Start</button>
</div>
<p>These tests are only for modern browsers. In Webkit browsers like Google Chrome and Opera you can enable the FPS metter in developer tools, <a href="https://developer.chrome.com/devtools/docs/rendering-settings" target="_blank">here's how</a>.</p>
<p class="text-note">Please know that a local copy of this page will outperform the live site demo on Google Chrome, the reason is unknown.</p>
<span id="count" class="btn-group dropdown">
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-expanded="false" tabindex="0">Count <span class="caret"></span></button>
<ul class="dropdown-menu" role="menu">
<li><a id="100" href="#">100</a></li>
<li><a id="200" href="#">200</a></li>
<li><a id="300" href="#">300</a></li>
<li><a id="400" href="#">400</a></li>
<li><a id="500" href="#">500</a></li>
<li><a id="600" href="#">600</a></li>
<li><a id="700" href="#">700</a></li>
<li><a id="800" href="#">800</a></li>
<li><a id="900" href="#">900</a></li>
<li><a id="1000" href="#"><span style="color: red">1000</span></a></li>
<li><a id="1500" href="#"><span style="color: red">1500</span></a></li>
<li><a id="2000" href="#"><span style="color: red">2000</span></a></li>
</ul>
</span>
<hr class="hr">
<div style="width:100%;clear: both">
<button class="btn btn-success" id="start" type="button" style="margin-bottom: 15px">Start</button>
</div>
<p>These tests are only for modern browsers. In Webkit browsers like Google Chrome and Opera you can enable the FPS metter in developer tools, <a href="https://developer.chrome.com/devtools/docs/rendering-settings" target="_blank">here's how</a>.</p>
<p class="text-note">Please know that a local copy of this page will outperform the live site demo on Google Chrome, the reason is unknown.</p>
<div id="container"></div>
</div>
<div id="container"></div>
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<!--[if !IE ]><!-->
<script src="https://cdn.jsdelivr.net/bootstrap.native/1.0.1/bootstrap-native.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.0.5/gsap.min.js"></script>
<script src="./assets/js/tween.min.js"></script>
<script src="./src/kute-extra.min.js"></script>
<!--[if !IE ]><!-->
<script src="https://cdn.jsdelivr.net/bootstrap.native/1.0.1/bootstrap-native.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.0.5/gsap.min.js"></script>
<script src="./assets/js/tween.min.js"></script>
<script src="./src/kute-extra.min.js"></script>
<script src="./assets/js/perf.js"></script>
<!--<![endif]-->
<script src="./assets/js/perf.js"></script>
<!--<![endif]-->
</body>
</html>

View file

@ -3,160 +3,160 @@
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="A simple tool to showcase control KUTE.js tween objects progress.">
<meta name="keywords" content="kute,kute.js,animation,javascript animation,tweening engine,animation engine,progress,Javascript,Native Javascript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="A simple tool to showcase control KUTE.js tween objects progress.">
<meta name="keywords" content="kute,kute.js,animation,javascript animation,tweening engine,animation engine,progress,Javascript,Native Javascript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<title>KUTE.js Using Update Functions | Javascript Animation Engine</title>
<title>KUTE.js Using Update Functions | Javascript Animation Engine</title>
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
<style>
.text-example {
margin: 0 0 20px;
font-size: 28px
}
<style>
.text-example {
margin: 0 0 20px;
font-size: 28px
}
.red {
color: red
}
.slider {
margin-right: 20px;
}
input[type="range"] {
-webkit-appearance: none !important;
width: 100%;
height: 12px;
background-color: #b0cde4;
border: 0;
border-radius: 5px;
margin: auto;
transition: all 0.3s ease;
}
input[type="range"]:hover {
background-color: #a3bdd2;
}
input[type="range"]:focus {
outline: none;
}
.red {
color: red
}
.slider {
margin-right: 20px;
}
input[type="range"] {
-webkit-appearance: none !important;
width: 100%;
height: 12px;
background-color: #b0cde4;
border: 0;
border-radius: 5px;
margin: auto;
transition: all 0.3s ease;
}
input[type="range"]:hover {
background-color: #a3bdd2;
}
input[type="range"]:focus {
outline: none;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none !important;
width: 20px;
height: 20px;
background-color: #2196F3;
border-radius: 30px;
transition: all 0.5s ease;
}
input[type="range"]::-webkit-slider-thumb:hover {
background-color: #1b7bc7;
}
input[type="range"]::-webkit-slider-thumb:active {
box-shadow: 0px 0px 1px #1b7bc7;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none !important;
width: 20px;
height: 20px;
background-color: #2196F3;
border-radius: 30px;
transition: all 0.5s ease;
}
input[type="range"]::-webkit-slider-thumb:hover {
background-color: #1b7bc7;
}
input[type="range"]::-webkit-slider-thumb:active {
box-shadow: 0px 0px 1px #1b7bc7;
}
#rangevalue {
position: absolute; bottom: 20px; right: 20px;
}
#rangevalue {
position: absolute; bottom: 20px; right: 20px;
}
</style>
</style>
</head>
<body>
<div class="site-wrapper">
<div class="site-wrapper">
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1 class="active">KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-space">
<ul class="nav">
<li class="btn-group"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1 class="active">KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-between">
<ul class="nav">
<li class="btn-group"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div class="content-wrap">
<h2 class="head-title">Tween Progress Control</h2>
<p class="condensed lead">The handy tool to manually update a tween via an <b>Input</b> slider.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<div class="columns">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">Create a tween object and link it to a range slider <b>Input</b>. Some stuff happening.</p>
</div>
<div class="col9 border">
<p class="lead condensed">The <b>Progress Bar</b> can be a handy tool that enables you to manually update your tween animation, just in case there is a little
detail you want to make it right.</p>
<p>KUTE.js object exposes all required methods in order for it to work, so why not try to do something fun? How about control tween progress? So let's make a quick tool:</p>
<ul>
<li>We need an <code>&lt;input type="range" min="0" max="1" step="0.00001" /&gt;</code> with these exact <code>min</code>, <code>max</code> and <code>step</code> attributes</li>
<li>Now we need a tween object, let's just do a svg morph for instance, but make sure you use <code>KUTE.fromTo()</code> method, the others don't prepare start values for the tween object</li>
<li>We also need to make sure nothing controls the progress except the range input, so don't use <code>start()</code> or <code>pause()</code> methods at all, as well as <code>repeat</code> and / or <code>yoyo</code> options</li>
<li>Next we attach an <code>input</code> event handler to update the tween progress by using the <code>KUTE.update</code> function, which is the step function triggered on every <code>requestAnimationFrame</code> tick</li>
</ul>
</div>
</li>
</ul>
</div>
</div>
</nav>
</div>
</div>
<div class="content-wrap">
<h2 class="head-title">Tween Progress Control</h2>
<p class="condensed lead">The handy tool to manually update a tween via an <b>Input</b> slider.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<div class="columns">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">Create a tween object and link it to a range slider <b>Input</b>. Some stuff happening.</p>
</div>
<div class="col9 border">
<p class="lead condensed">The <b>Progress Bar</b> can be a handy tool that enables you to manually update your tween animation, just in case there is a little
detail you want to make it right.</p>
<p>KUTE.js object exposes all required methods in order for it to work, so why not try to do something fun? How about control tween progress? So let's make a quick tool:</p>
<ul>
<li>We need an <code>&lt;input type="range" min="0" max="1" step="0.00001" /&gt;</code> with these exact <code>min</code>, <code>max</code> and <code>step</code> attributes</li>
<li>Now we need a tween object, let's just do a svg morph for instance, but make sure you use <code>KUTE.fromTo()</code> method, the others don't prepare start values for the tween object</li>
<li>We also need to make sure nothing controls the progress except the range input, so don't use <code>start()</code> or <code>pause()</code> methods at all, as well as <code>repeat</code> and / or <code>yoyo</code> options</li>
<li>Next we attach an <code>input</code> event handler to update the tween progress by using the <code>KUTE.update</code> function, which is the step function triggered on every <code>requestAnimationFrame</code> tick</li>
</ul>
</div>
</div>
</div>
</div>
<div class="content-wrap">
<p>A very basic code sample will look like this:</p>
<p>A very basic code sample will look like this:</p>
<pre><code class="language-javascript">// the range slider
@ -170,50 +170,50 @@ var progressBar = new KUTE.ProgressBar(rangeSlider,morphTween)
// also start animation when Element is clicked
document.getElementById('rectangle').addEventListener('click',function(){
!morphTween.playing && morphTween.start()
!morphTween.playing && morphTween.start()
})
</code></pre>
<p>And now let's see the code in action:</p>
<div class="featurettes">
<div class="slider">
<input type="range" min="0" max="1" value="0" step="0.0001" />
<output id="rangevalue">0%</output>
</div>
<svg class="example-box-model example-box" id="morph-example1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
<path id="rectangle" class="bg-blue" d="M559,597.4H302.1H43.6c-21,0-38-17-38-38V408.8V223.6V44c0-21,17-38,38-38h105.6H300h160.3H559
c21,0,38,17,38,38v184v331.4C597,580.4,580,597.4,559,597.4z"/>
<path id="star" style="visibility:hidden" d="M302.1,17.9c16,29,81.4,147.7,98.2,178.2c31.1,6,62.3,11.9,93.4,17.9c35.5,6.8,71,13.6,106.5,20.4
c-46.4,49.5-92.7,99-139.1,148.5c1.1,8.5,6.7,53.4,12.4,99.1c5.7,45.3,11.4,91.4,12.9,102.9c-36-16.9-158.8-74.5-184.2-86.4
c-28.5,13.4-151.3,71-184.2,86.4c0.4-3.2,13.3-106.6,13.3-106.6s10.1-81,11.9-95.3C96.8,333.5,50.4,284,4,234.5
c34.4-6.6,68.8-13.2,103.3-19.8c32.2-6.2,64.4-12.3,96.5-18.5C221,165.1,286.5,46.2,302.1,17.9z"/>
</svg>
<p>And now let's see the code in action:</p>
<div class="featurettes">
<div class="slider">
<input type="range" min="0" max="1" value="0" step="0.0001" />
<output id="rangevalue">0%</output>
</div>
<p>We might argue that we want to use other methods in combination with this method, or use this method while animations are running, but there are other libraries out there that can do that already. This example here is just to showcase KUTE.js can do this too.</p>
<p>Note that this tool is not included in the official distribution file.</p>
</div>
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2020 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
<svg class="example-box-model example-box" id="morph-example1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
<path id="rectangle" class="bg-blue" d="M559,597.4H302.1H43.6c-21,0-38-17-38-38V408.8V223.6V44c0-21,17-38,38-38h105.6H300h160.3H559
c21,0,38,17,38,38v184v331.4C597,580.4,580,597.4,559,597.4z"/>
<path id="star" style="visibility:hidden" d="M302.1,17.9c16,29,81.4,147.7,98.2,178.2c31.1,6,62.3,11.9,93.4,17.9c35.5,6.8,71,13.6,106.5,20.4
c-46.4,49.5-92.7,99-139.1,148.5c1.1,8.5,6.7,53.4,12.4,99.1c5.7,45.3,11.4,91.4,12.9,102.9c-36-16.9-158.8-74.5-184.2-86.4
c-28.5,13.4-151.3,71-184.2,86.4c0.4-3.2,13.3-106.6,13.3-106.6s10.1-81,11.9-95.3C96.8,333.5,50.4,284,4,234.5
c34.4-6.6,68.8-13.2,103.3-19.8c32.2-6.2,64.4-12.3,96.5-18.5C221,165.1,286.5,46.2,302.1,17.9z"/>
</svg>
</div>
</footer>
<p>We might argue that we want to use other methods in combination with this method, or use this method while animations are running, but there are other libraries out there that can do that already. This example here is just to showcase KUTE.js can do this too.</p>
<p>Note that this tool is not included in the official distribution file.</p>
</div>
<!-- /.site-wrapper -->
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute-extra.min.js"></script>
<script src="./assets/js/prism.js"></script>
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2021 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
<script src="./assets/js/scripts.js"></script>
<script src="./assets/js/progress.js"></script>
</div>
<!-- /.site-wrapper -->
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute-extra.min.js"></script>
<script src="./assets/js/prism.js"></script>
<script src="./assets/js/scripts.js"></script>
<script src="./assets/js/progress.js"></script>
</body>
</html>

View file

@ -35,7 +35,7 @@
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-space">
<div class="nav-wrapper d-flex align-items-center justify-content-between">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
@ -198,7 +198,7 @@ KUTE.to('#myElement',{scroll: 0 }).start()
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2020 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
<p>&copy; 2015 - 2021 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>

View file

@ -1,182 +1,182 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="The Shadow Properties component for KUTE.js allows you to create animations for shadow properties on supporting browsers.">
<meta name="keywords" content="textShadow,text-shadow,boxShadow,box-shadow,kute,kute.js,animation,javascript animation,tweening engine,animation engine,JavaScript,Native JavaScript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="The Shadow Properties component for KUTE.js allows you to create animations for shadow properties on supporting browsers.">
<meta name="keywords" content="textShadow,text-shadow,boxShadow,box-shadow,kute,kute.js,animation,javascript animation,tweening engine,animation engine,JavaScript,Native JavaScript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<title>KUTE.js Shadow Properties</title>
<title>KUTE.js Shadow Properties</title>
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
<style>
.text-example {
margin: 0 0 20px;
font-size: 28px;
line-height: 1.5;
white-space: nowrap;
color: #222
}
</style>
<style>
.text-example {
margin: 0 0 20px;
font-size: 28px;
line-height: 1.5;
white-space: nowrap;
color: #222
}
</style>
</head>
<body>
<div class="site-wrapper">
<div class="site-wrapper">
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-space">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li class="active"><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-between">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li class="active"><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</div>
</nav>
</div>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div class="content-wrap">
<h2 class="head-title">Shadow Properties</h2>
<p class="condensed lead">The component that animates shadow properties of a specific target element on most browsers.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<h2 class="head-title">Shadow Properties</h2>
<p class="condensed lead">The component that animates shadow properties of a specific target element on most browsers.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<div class="columns">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">Animate the shadow properties of a target element.</p>
</div>
<div class="col9 border">
<p class='condensed lead'>The KUTE.js <b>Shadow Properties</b> component enables animation for the <b>text-shadow</b> CSS property of text elements
as well as the <b>box-shadow</b> property of any element on most browsers.</p>
<p>The functionality was developed while writing a guide on how to extend KUTE.js a couple of years ago and is now a fully featured component.</p>
<p>The component uses <b>px</b> as unit for the shadow parameters, can animate the color of the shadow and can also handle the <b>inset</b> shadow parameter
of the <b>boxShadow</b> property.</p>
<p>OK let's have a look at a couple of quick examples:</p>
</div>
<div class="columns">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">Animate the shadow properties of a target element.</p>
</div>
<div class="col9 border">
<p class='condensed lead'>The KUTE.js <b>Shadow Properties</b> component enables animation for the <b>text-shadow</b> CSS property of text elements
as well as the <b>box-shadow</b> property of any element on most browsers.</p>
<p>The functionality was developed while writing a guide on how to extend KUTE.js a couple of years ago and is now a fully featured component.</p>
<p>The component uses <b>px</b> as unit for the shadow parameters, can animate the color of the shadow and can also handle the <b>inset</b> shadow parameter
of the <b>boxShadow</b> property.</p>
<p>OK let's have a look at a couple of quick examples:</p>
</div>
</div>
</div>
</div>
<div class="content-wrap">
<div class="content-wrap">
<h3>Box Shadow</h3>
<h3>Box Shadow</h3>
<pre><code class="language-javascript">// tween to a string value
var myBSTween1 = KUTE.to('selector', {boxShadow: '10px 10px #069'}).start();
// or a fromTo with string and array, hex and rgb
var myBSTween2 = KUTE.fromTo(
'selector', // target
{boxShadow: [0, 0, 0, '#069']}, // from
{boxShadow: '5px 5px rgb(0,0,0)'}) // to
.start();
'selector', // target
{boxShadow: [0, 0, 0, '#069']}, // from
{boxShadow: '5px 5px rgb(0,0,0)'}) // to
.start();
// maybe you want to animate an inset boxShadow?
var myBSTween3 = KUTE.fromTo(
'selector', // target
{boxShadow: [5, 5, 0, '#069', 'inset']}, // from
{boxShadow: '0px 0px rgb(0,0,0)'}) // to
.start();
'selector', // target
{boxShadow: [5, 5, 0, '#069', 'inset']}, // from
{boxShadow: '0px 0px rgb(0,0,0)'}) // to
.start();
</code></pre>
<div id="boxShadow" class="featurettes">
<div class="example-item example-box bg-lime"></div>
<div class="example-buttons">
<a class="btn btn-pink" href="javascript:void(0)">Start</a>
</div>
</div>
<div id="boxShadow" class="featurettes">
<div class="example-item example-box bg-lime"></div>
<div class="example-buttons">
<a class="btn btn-pink" href="javascript:void(0)">Start</a>
</div>
</div>
<h3>Text Shadow</h3>
<h3>Text Shadow</h3>
<pre><code class="language-javascript">// tween to a string value
var myTSTween1 = KUTE.to('selector', {textShadow: '10px 10px #069'}).start();
// or a fromTo with string and array, hex and rgb
var myTSTween2 = KUTE.fromTo(
'selector', // target
{textShadow: [0, 0, 0, '#069']}, // from
{textShadow: '5px 5px rgb(0,0,0)'}) // to
.start();
'selector', // target
{textShadow: [0, 0, 0, '#069']}, // from
{textShadow: '5px 5px rgb(0,0,0)'}) // to
.start();
</code></pre>
<div id="textShadow" class="featurettes">
<div class="text-example">Sample Text</div>
<div class="example-buttons">
<a class="btn btn-orange" href="javascript:void(0)">Start</a>
</div>
<div id="textShadow" class="featurettes">
<div class="text-example">Sample Text</div>
<div class="example-buttons">
<a class="btn btn-orange" href="javascript:void(0)">Start</a>
</div>
</div>
<h3>Notes</h3>
<ul>
<li>The component will NOT handle multiple shadows per target at the same time.</li>
<li>The component features a solid value processing script, it can handle a great deal of combinations of input values.</li>
<li>I highly recommend that you check the <a href="./assets/js/boxShadow.js">boxShadow.js</a> for more insight.</li>
<li>This component is bundled with the <i>demo/src/kute-extra.js</i> file.</li>
</ul>
<h3>Notes</h3>
<ul>
<li>The component will NOT handle multiple shadows per target at the same time.</li>
<li>The component features a solid value processing script, it can handle a great deal of combinations of input values.</li>
<li>I highly recommend that you check the <a href="./assets/js/boxShadow.js">boxShadow.js</a> for more insight.</li>
<li>This component is bundled with the <i>demo/src/kute-extra.js</i> file.</li>
</ul>
</div>
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2020 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
<p>&copy; 2015 - 2021 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
</div>
<!-- /.site-wrapper -->
<!-- /.site-wrapper -->
<!-- JavaScript =============================================== -->

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,3 +1,3 @@
// KUTE.js Polyfill v2.0.9 | 2020 © thednp | MIT-License
// KUTE.js Polyfill v2.1.1-alpha1 | 2021 © thednp | MIT-License
"use strict";
var r,t,n,e;if(Function.prototype.bind||(Function.prototype.bind=function(){var r=Array.prototype.slice,t=this,n=arguments[0],e=r.call(arguments,1);if("function"!=typeof t)throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");return function(){var o=e.concat(r.call(arguments));return t.apply(n,o)}}),Array.from||(Array.from=(r=Object.prototype.toString,t=function(t){return"function"==typeof t||"[object Function]"===r.call(t)},n=Math.pow(2,53)-1,e=function(r){var t=function(r){var t=Number(r);return isNaN(t)?0:0!==t&&isFinite(t)?(t>0?1:-1)*Math.floor(Math.abs(t)):t}(r);return Math.min(Math.max(t,0),n)},function(r){var n=this,o=Object(r);if(null==r)throw new TypeError("Array.from requires an array-like object - not null or undefined");var i,a=arguments.length>1?arguments[1]:void 0;if(void 0!==a){if(!t(a))throw new TypeError("Array.from: when provided, the second argument must be a function");arguments.length>2&&(i=arguments[2])}for(var f,u=e(o.length),c=t(n)?Object(new n(u)):new Array(u),p=0;p<u;)f=o[p],c[p]=a?void 0===i?a(f,p):a.call(i,f,p):f,p+=1;return c.length=u,c})),Array.prototype.map||(Array.prototype.map=function(r){var t,n,e;if(null==this)throw new TypeError("this is null or not defined");var o=Object(this),i=o.length>>>0;if("function"!=typeof r)throw new TypeError(r+" is not a function");for(arguments.length>1&&(t=arguments[1]),n=new Array(i),e=0;e<i;){var a,f;e in o&&(a=o[e],f=r.call(t,a,e,o),n[e]=f),e++}return n}),Array.prototype.some||(Array.prototype.some=function(r,t){if(null==this)throw new TypeError("Array.prototype.some called on null or undefined");if("function"!=typeof r)throw new TypeError;for(var n=Object(this),e=n.length>>>0,o=0;o<e;o++)if(o in n&&r.call(t,n[o],o,n))return!0;return!1}),Array.prototype.every||(Array.prototype.every=function(r,t){var n,e;if(null==this)throw new TypeError("this is null or not defined");var o=Object(this),i=o.length>>>0;if("function"!=typeof r&&"[object Function]"!==Object.prototype.toString.call(r))throw new TypeError;for(arguments.length>1&&(n=t),e=0;e<i;){var a;if(e in o)if(a=o[e],!(n?r.call(n,a,e,o):r(a,e,o)))return!1;e++}return!0}),Array.prototype.includes||(Array.prototype.includes=function(r){var t=Object(this),n=parseInt(t.length)||0;if(0===n)return!1;var e,o,i=parseInt(arguments[1])||0;for(i>=0?e=i:(e=n+i)<0&&(e=0);e<n;){if(r===(o=t[e])||r!=r&&o!=o)return!0;e++}return!1}),String.prototype.includes||(String.prototype.includes=function(r,t){if(r instanceof RegExp)throw TypeError("first argument must not be a RegExp");return void 0===t&&(t=0),-1!==this.indexOf(r,t)}),Date.now||(Date.now=function(){return(new Date).getTime()}),self.performance||(self.performance={}),!self.performance.now){var o=Date.now();self.performance.now=function(){return Date.now()-o}}if(!window.requestAnimationFrame){var i=Date.now();window.requestAnimationFrame=function(r){if("function"!=typeof r)throw new TypeError(r+"is not a function");var t=Date.now(),n=16+i-t;return n<0&&(n=0),i=t,setTimeout((function(){i=Date.now(),r(performance.now())}),n)},window.cancelAnimationFrame=function(r){clearTimeout(r)}}
var r,t,n,e;if(Function.prototype.bind||(Function.prototype.bind=function(){var r=Array.prototype.slice,t=this,n=arguments[0],e=r.call(arguments,1);if("function"!=typeof t)throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");return function(){var o=e.concat(r.call(arguments));return t.apply(n,o)}}),Array.from||(Array.from=(r=Object.prototype.toString,t=function(t){return"function"==typeof t||"[object Function]"===r.call(t)},n=Math.pow(2,53)-1,e=function(r){var t=function(r){var t=Number(r);return isNaN(t)?0:0!==t&&isFinite(t)?(t>0?1:-1)*Math.floor(Math.abs(t)):t}(r);return Math.min(Math.max(t,0),n)},function(r){var n=this,o=Object(r);if(null==r)throw new TypeError("Array.from requires an array-like object - not null or undefined");var i,a=arguments.length>1?arguments[1]:void 0;if(void 0!==a){if(!t(a))throw new TypeError("Array.from: when provided, the second argument must be a function");arguments.length>2&&(i=arguments[2])}for(var u,f=e(o.length),p=t(n)?Object(new n(f)):new Array(f),c=0;c<f;)u=o[c],p[c]=a?void 0===i?a(u,c):a.call(i,u,c):u,c+=1;return p.length=f,p})),Array.prototype.map||(Array.prototype.map=function(r){var t,n,e;if(null==this)throw new TypeError("this is null or not defined");var o=Object(this),i=o.length>>>0;if("function"!=typeof r)throw new TypeError(r+" is not a function");for(arguments.length>1&&(t=arguments[1]),n=new Array(i),e=0;e<i;){var a,u;e in o&&(a=o[e],u=r.call(t,a,e,o),n[e]=u),e++}return n}),Array.prototype.some||(Array.prototype.some=function(r,t){if(null==this)throw new TypeError("Array.prototype.some called on null or undefined");if("function"!=typeof r)throw new TypeError;for(var n=Object(this),e=n.length>>>0,o=0;o<e;o++)if(o in n&&r.call(t,n[o],o,n))return!0;return!1}),Array.prototype.every||(Array.prototype.every=function(r,t){var n,e;if(null==this)throw new TypeError("this is null or not defined");var o=Object(this),i=o.length>>>0;if("function"!=typeof r&&"[object Function]"!==Object.prototype.toString.call(r))throw new TypeError;for(arguments.length>1&&(n=t),e=0;e<i;){var a;if(e in o)if(a=o[e],!(n?r.call(n,a,e,o):r(a,e,o)))return!1;e++}return!0}),Array.prototype.includes||(Array.prototype.includes=function(r){var t=Object(this),n=parseInt(t.length)||0;if(0===n)return!1;var e,o,i=parseInt(arguments[1])||0;for(i>=0?e=i:(e=n+i)<0&&(e=0);e<n;){if(r===(o=t[e])||r!=r&&o!=o)return!0;e++}return!1}),Array.prototype.flat||Object.defineProperty(Array.prototype,"flat",{configurable:!0,value:function r(){var t=isNaN(arguments[0])?1:Number(arguments[0]);return t?Array.prototype.reduce.call(this,(function(n,e){return Array.isArray(e)?n.push.apply(n,r.call(e,t-1)):n.push(e),n}),[]):Array.prototype.slice.call(this)},writable:!0}),String.prototype.includes||(String.prototype.includes=function(r,t){if(r instanceof RegExp)throw TypeError("first argument must not be a RegExp");return void 0===t&&(t=0),-1!==this.indexOf(r,t)}),Date.now||(Date.now=function(){return(new Date).getTime()}),self.performance||(self.performance={}),!self.performance.now){var o=Date.now();self.performance.now=function(){return Date.now()-o}}if(!window.requestAnimationFrame){var i=Date.now();window.requestAnimationFrame=function(r){if("function"!=typeof r)throw new TypeError(r+"is not a function");var t=Date.now(),n=16+i-t;return n<0&&(n=0),i=t,setTimeout((function(){i=Date.now(),r(performance.now())}),n)},window.cancelAnimationFrame=function(r){clearTimeout(r)}}

View file

@ -1,3 +1,3 @@
// KUTE.js Polyfill v2.0.9 | 2020 © thednp | MIT-License
// KUTE.js Polyfill v2.1.1-alpha1 | 2021 © thednp | MIT-License
"use strict";
var r,t,n,e;Array.from||(Array.from=(r=Object.prototype.toString,t=function(t){return"function"==typeof t||"[object Function]"===r.call(t)},n=Math.pow(2,53)-1,e=function(r){var t=function(r){var t=Number(r);return isNaN(t)?0:0!==t&&isFinite(t)?(t>0?1:-1)*Math.floor(Math.abs(t)):t}(r);return Math.min(Math.max(t,0),n)},function(r){var n=this,o=Object(r);if(null==r)throw new TypeError("Array.from requires an array-like object - not null or undefined");var i,a=arguments.length>1?arguments[1]:void 0;if(void 0!==a){if(!t(a))throw new TypeError("Array.from: when provided, the second argument must be a function");arguments.length>2&&(i=arguments[2])}for(var u,f=e(o.length),c=t(n)?Object(new n(f)):new Array(f),p=0;p<f;)u=o[p],c[p]=a?void 0===i?a(u,p):a.call(i,u,p):u,p+=1;return c.length=f,c})),Array.prototype.includes||(Array.prototype.includes=function(r){var t=Object(this),n=parseInt(t.length)||0;if(0===n)return!1;var e,o,i=parseInt(arguments[1])||0;for(i>=0?e=i:(e=n+i)<0&&(e=0);e<n;){if(r===(o=t[e])||r!=r&&o!=o)return!0;e++}return!1}),String.prototype.includes||(String.prototype.includes=function(r,t){if(r instanceof RegExp)throw TypeError("first argument must not be a RegExp");return void 0===t&&(t=0),-1!==this.indexOf(r,t)});
var r,t,e,n;Array.from||(Array.from=(r=Object.prototype.toString,t=function(t){return"function"==typeof t||"[object Function]"===r.call(t)},e=Math.pow(2,53)-1,n=function(r){var t=function(r){var t=Number(r);return isNaN(t)?0:0!==t&&isFinite(t)?(t>0?1:-1)*Math.floor(Math.abs(t)):t}(r);return Math.min(Math.max(t,0),e)},function(r){var e=this,i=Object(r);if(null==r)throw new TypeError("Array.from requires an array-like object - not null or undefined");var o,a=arguments.length>1?arguments[1]:void 0;if(void 0!==a){if(!t(a))throw new TypeError("Array.from: when provided, the second argument must be a function");arguments.length>2&&(o=arguments[2])}for(var u,f=n(i.length),p=t(e)?Object(new e(f)):new Array(f),c=0;c<f;)u=i[c],p[c]=a?void 0===o?a(u,c):a.call(o,u,c):u,c+=1;return p.length=f,p})),Array.prototype.flat||Object.defineProperty(Array.prototype,"flat",{configurable:!0,value:function r(){var t=isNaN(arguments[0])?1:Number(arguments[0]);return t?Array.prototype.reduce.call(this,(function(e,n){return Array.isArray(n)?e.push.apply(e,r.call(n,t-1)):e.push(n),e}),[]):Array.prototype.slice.call(this)},writable:!0}),Array.prototype.includes||(Array.prototype.includes=function(r){var t=Object(this),e=parseInt(t.length)||0;if(0===e)return!1;var n,i,o=parseInt(arguments[1])||0;for(o>=0?n=o:(n=e+o)<0&&(n=0);n<e;){if(r===(i=t[n])||r!=r&&i!=i)return!0;n++}return!1}),String.prototype.includes||(String.prototype.includes=function(r,t){if(r instanceof RegExp)throw TypeError("first argument must not be a RegExp");return void 0===t&&(t=0),-1!==this.indexOf(r,t)}),Number.isFinite||(Number.isFinite=function(r){return"number"==typeof r&&isFinite(r)}),Number.isInteger||(Number.isInteger=function(r){return"number"==typeof r&&isFinite(r)&&Math.floor(r)===r}),Number.isNaN||(Number.isNaN=function(r){return"number"==typeof r&&r!=r});

View file

@ -26,108 +26,96 @@
</head>
<body>
<div class="site-wrapper">
<div class="site-wrapper">
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-space">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li class="active"><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-between">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li class="active"><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
</nav>
</div>
</div>
<div class="content-wrap">
<h2 class="head-title">SVG Cubic Morph</h2>
<p class="condensed lead">The component that also covers <i>SVG morphing</i>, with similar functionality as for the <a href="svgMorph.html">SVG Morph</a> component, but with a different
implementation for value processing and animation setup.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<h2 class="head-title">SVG Cubic Morph</h2>
<p class="condensed lead">The component that also covers <i>SVG morphing</i>, with similar functionality as for the <a href="svgMorph.html">SVG Morph</a> component, but with a different
implementation for value processing and animation setup.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<div class="columns margin-bottom">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">Animate SVG paths with <b>cubic-bezier</b> path commands and improved performance.</p>
</div>
<div class="col9 border">
<p class="lead condensed">The KUTE.js <b>SVG Cubic Morph</b> component enables animation for the <b>d</b> (description) presentation attribute and is the latest in all the SVG
components.</p>
<p>The main difference with the other <a href="svgMorph.html">SVG Morph</a> component is the fact that this time we're using some path processing scripts borrowed from
<a href="http://www.raphaeljs.com/">Raphael.js</a> and other libraries to convert all path commands into <i>cubic-bezier</i> path commands.</p>
<p>This component will process paths and out of the box will provide the closest possible interpolation by default. It comes with two tween options to help you manage the morphing
animation in certain conditions:</p>
</div>
</div>
<div class="columns">
<div class="col3">
<h3 class="border text-right">Options</h3>
<p class="condensed text-right">A series of familiar options to optimize the animation for every situation.</p>
</div>
<div class="col9 border">
<p class="condensed lead">To enhance processing and improve the morphing animation, in certain cases you will need to control the outcome via two options
to reverse paths.</p>
<ul>
<li><kbd>reverseFirstPath: <b class='text-olive'>FALSE</b></kbd> when is <b>TRUE</b> you will reverse the FIRST shape. By default this option is <b>false</b>.</li>
<li><kbd>reverseSecondPath: <b class='text-olive'>FALSE</b></kbd> when is <b>TRUE</b> you will reverse the SECOND shape. By default this option is also <b>false</b>.</li>
</ul>
</div>
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">Animate SVG paths with <b>cubic-bezier</b> path commands and improved performance.</p>
</div>
<div class="col9 border">
<p class="lead condensed">The KUTE.js <b>SVG Cubic Morph</b> component enables animation for the <b>d</b> (description) presentation attribute and is the latest in all the SVG
components.</p>
<p>The component will process paths and out of the box will provide the closest possible interpolation by default. It also implements a series of solutions from
<a href="https://github.com/paperjs/paper.js/">Paper.js</a> to determine paths draw direction and automatically reverse one of them for most accurate presentation and as a result
the previously featured options <kbd>reverseFirstPath</kbd> and <kbd>reverseSecondPath</kbd> have been deprecated.</p>
<p>The main difference with the <a href="svgMorph.html">SVG Morph</a> component is the fact that this components is converting all path commands to <i>cubicBezierTo</i>, giving it
the upper hand over the original morph component in many regards. While the other component will spend time to process the path data and create polygons, this component should
deliver the animation faster and using considerably less power.</p>
<p>All path processing is powered by our <a href="https://github.com/thednp/svg-path-commander">SVGPathCommander</a> starting KUTE.js version 2.0.14, which aims to modernize and
improve the path processing and enable transition from closed to and from un-closed shapes.</p>
</div>
</div>
</div>
</div>
<div class="content-wrap">
<h3>Basic Example</h3>
<p>The first morphing animation example is a transition from a rectangle into a star, just like for the other component.</p>
<div class="content-wrap">
<h3>Basic Example</h3>
<p>The first morphing animation example is a transition from a rectangle into a star, just like for the other component.</p>
<pre><code class="language-markup">&lt;svg id="morph-example" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
&lt;path id="rectangle" class="bg-lime" d="M38.01,5.653h526.531c17.905,0,32.422,14.516,32.422,32.422v526.531 c0,17.905-14.517,32.422-32.422,32.422H38.01c-17.906,0-32.422-14.517-32.422-32.422V38.075C5.588,20.169,20.104,5.653,38.01,5.653z"/>
&lt;path id="star" style="visibility:hidden" d="M301.113,12.011l99.25,179.996l201.864,38.778L461.706,380.808 l25.508,203.958l-186.101-87.287L115.01,584.766l25.507-203.958L0,230.785l201.86-38.778L301.113,12.011"/>
&lt;path id="rectangle" class="bg-lime" d="M38.01,5.653h526.531c17.905,0,32.422,14.516,32.422,32.422v526.531 c0,17.905-14.517,32.422-32.422,32.422H38.01c-17.906,0-32.422-14.517-32.422-32.422V38.075C5.588,20.169,20.104,5.653,38.01,5.653z"/>
&lt;path id="star" style="visibility:hidden" d="M301.113,12.011l99.25,179.996l201.864,38.778L461.706,380.808 l25.508,203.958l-186.101-87.287L115.01,584.766l25.507-203.958L0,230.785l201.86-38.778L301.113,12.011"/>
&lt;/svg>
</code></pre>
<p>Now we can apply both <code>.to()</code> and <code>fromTo()</code> methods:</p>
<p>Now we can apply both <code>.to()</code> and <code>fromTo()</code> methods:</p>
<pre><code class="language-javascript">// the fromTo() method
var tween = KUTE.fromTo('#rectangle', {path: '#rectangle' }, { path: '#star' }).start();
@ -139,217 +127,242 @@ var tween = KUTE.to('#rectangle', { path: '#star' }).start();
var tween = KUTE.to('#rectangle', { path: 'M301.113,12.011l99.25,179.996l201.864,38.778L461.706,380.808l25.508,203.958l-186.101-87.287L115.01,584.766l25.507-203.958L0,230.785l201.86-38.778L301.113,12.011' }).start();
</code></pre>
<p>By default, the component will process the paths as authored and deliver its best without any option required, like for the first red rectangle below which applies to any of the above invocations:</p>
<p>By default, the component will process the paths as authored and deliver its best without any option required, like for the first red rectangle below which applies to any of the above invocations:</p>
<div class="featurettes">
<svg class="example-box-model example-box" id="morph-example" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
<path id="rectangle" class="bg-red" d="M559,597.4H43.6c-21,0-38-17-38-38V44c0-21,17-38,38-38H559c21,0,38,17,38,38v515.4 C597,580.4,580,597.4,559,597.4z"/>
<path id="star" style="visibility:hidden" d="M301.113,12.011l99.25,179.996l201.864,38.778L461.706,380.808 l25.508,203.958l-186.101-87.287L115.01,584.766l25.507-203.958L0,230.785l201.86-38.778L301.113,12.011z"/>
</svg>
<svg class="example-box-model example-box" id="morph-example1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
<path id="rectangle1" class="bg-blue" d="M559,597.4H302.1H43.6c-21,0-38-17-38-38V408.8V223.6V44c0-21,17-38,38-38h105.6H300h160.3H559
c21,0,38,17,38,38v184v331.4C597,580.4,580,597.4,559,597.4z"/>
<path id="star1" style="visibility:hidden" d="M302.1,17.9c16,29,81.4,147.7,98.2,178.2c31.1,6,62.3,11.9,93.4,17.9c35.5,6.8,71,13.6,106.5,20.4
c-46.4,49.5-92.7,99-139.1,148.5c1.1,8.5,6.7,53.4,12.4,99.1c5.7,45.3,11.4,91.4,12.9,102.9c-36-16.9-158.8-74.5-184.2-86.4
c-28.5,13.4-151.3,71-184.2,86.4c0.4-3.2,13.3-106.6,13.3-106.6s10.1-81,11.9-95.3C96.8,333.5,50.4,284,4,234.5
c34.4-6.6,68.8-13.2,103.3-19.8c32.2-6.2,64.4-12.3,96.5-18.5C221,165.1,286.5,46.2,302.1,17.9z"/>
</svg>
<div class="example-buttons">
<a id="morphBtn" class="btn btn-green" href="javascript:void(0)">Start</a>
</div>
<div class="featurettes">
<svg class="example-box-model example-box" id="morph-example" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
<path id="rectangle" class="bg-olive" d="M559,597.4H43.6c-21,0-38-17-38-38V44c0-21,17-38,38-38H559c21,0,38,17,38,38v515.4 C597,580.4,580,597.4,559,597.4z"/>
<path id="star" style="visibility:hidden" d="M301.113,12.011l99.25,179.996l201.864,38.778L461.706,380.808 l25.508,203.958l-186.101-87.287L115.01,584.766l25.507-203.958L0,230.785l201.86-38.778L301.113,12.011z"/>
</svg>
<svg class="example-box-model example-box" id="morph-example2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
<path id="rectangle2" class="bg-blue" d="M559,597.4H302.1H43.6c-21,0-38-17-38-38V300V44c0-21,17-38,38-38H300h259c21,0,38,17,38,38
v257.7v257.7C597,580.4,580,597.4,559,597.4"/>
<path id="star2" style="visibility:hidden" d="M302.1,17.9c16,29,81.4,147.7,98.2,178.2c13.7,2.6,47.3,9.1,83.5,16c46.1,8.8,96.5,18.5,116.4,22.3
c-25.1,26.7-117.8,125.7-139.1,148.5c1.1,8.5,23.8,190.5,25.3,202c-36-16.9-158.8-74.5-184.2-86.4c-28.5,13.4-151.3,71-184.2,86.4
c0.4-3.2,23.4-187.6,25.2-201.9C122.8,361.3,30,262.3,4,234.5c17.3-3.3,59.5-11.4,101.3-19.4c41.4-7.9,82.5-15.8,98.5-18.9
C221,165.1,286.5,46.2,302.1,17.9"/>
</svg>
<div class="example-buttons">
<a id="morphBtn" class="btn btn-green" href="javascript:void(0)">Start</a>
</div>
</div>
<p>The second blue shape and its corresponding end shape have been edited by adding additional curve points using a vector graphics editor to match the amount of points in both shapes as well as to optimize their travel
distance during the animation. You can use the same technique on your shapes to control the animation to your style.</p>
<p>Chris Coyier wrote an <a href="https://css-tricks.com/svg-shape-morphing-works/">excelent article</a> to explain how SVG morphing animation works, it should give you a pretty good idea on the concept, terminology.</p>
<p><b>Some takeaways:</b></p>
<ul>
<li>The <b class="text-olive">olive shape</b> and its corresponding end shape are both the originals, un-edited shapes.</li>
<li>The <b class="text-blue">blue shape</b> and its corresponding end shape have been edited by removing their <code>Z</code> path commands and by adding additional curve points using a vector graphics editor to match
the amount of points in both shapes.</li>
</ul>
<p>In this example we focus on experimentation to discover ways to optimize the morph animation so that the points travel optimal distance. Keep in mind that the <code>Z</code> path command is actually a shorthand
for <code>L</code> (line path command), sometimes it's required to close the shape, however the path processing tools will remove it or replace it when converting path segments to <code>C</code> cubic-bezier.</p>
<p>Each morph animation as well as each pair of shapes can have its own quirks. You can use the technique on your shapes to optimize the animation to your style. Chris Coyier wrote
<a href="https://css-tricks.com/svg-shape-morphing-works/">an excelent article</a> in which he explains the terminology and workflow on how SVG morphing animation works with simple examples.</p>
<h3>Morphing Unclosed Shapes To Closed Shapes</h3>
<p>The next set of morphing animations is a transition from a line into a circle and showcases the component's behavior when both shapes are closed (they have the <code>Z</code> path command) or one or another is not,
but first let's create the necessary markup and scripting:</p>
<pre><code class="language-markup">&lt;svg id="morph-example" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
&lt;path id="line" fill="transparent" stroke="orange" stroke-linejoin="round" stroke-width="10" d="M10 300 L580 300"/>
&lt;path id="star" style="visibility:hidden" d="M10,300a290,290 0 1,0 580,0a290,290 0 1,0 -580,0z"/>
&lt;/svg>
</code></pre>
<pre><code class="language-javascript">// the fromTo() method
var tween = KUTE.fromTo('#line', {path: '#line' }, { path: '#circle' }).start();
// OR
// the to() method will take the path's d attribute value and use it as start value
var tween = KUTE.to('#line', { path: '#circle' }).start();
</code></pre>
<div class="featurettes">
<svg class="example-box-model example-box" id="morph-example-closed" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
<path id="line" fill="transparent" stroke="#FF5722" stroke-linejoin="round" stroke-width="15" d="M10 300 L580 300z"/>
<path id="circle" style="visibility:hidden" d="M10,300a290,290 0 1,1 580,0a290,290 0 1,1 -580,0z"/>
</svg>
<svg class="example-box-model example-box" id="morph-example-closed1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
<path id="line1" fill="transparent" stroke="#4CAF50" stroke-linejoin="round" stroke-width="15" d="M10 300 L580 300"/>
<path id="circle1" style="visibility:hidden" d="M10,300a290,290 0 1,1 580,0a290,290 0 1,1 -580,0z"/>
</svg>
<div class="example-buttons">
<a id="morphBtnClosed" class="btn btn-green" href="javascript:void(0)">Start</a>
</div>
</div>
<p>As you can see, the functionality of this component is very different from the <a href="svgMorph.html">svgMorph</a> component in the sense that it will
morph shapes as authored. If you replay the above animations, here are a few takeaways:</p>
<ul>
<li>the <b class="text-orange">orange</b> line is <b>closed</b>, this makes the last <code>Z</code> path command behave like a regular line;</li>
<li>the <b class="text-green">green</b> line is <b>not closed</b>, and the presentation looks quite different compared to the other example as well as
the other <a href="./cubicMorph.html">cubicMorph</a> component.</li>
</ul>
<p>This is the visual presentation you can expect with this component. Keep in mind that stroke attributes like <code>stroke-linejoin</code> such can have
a small impact on your animation, particularly on start and end points.</p>
<h3>Subpath Example</h3>
<p>In other cases, you may want to morph paths that have subpaths. Let's have a look at the following SVG:</p>
<pre><code class="language-markup">&lt;svg id="multi-morph-example" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
&lt;path id="w1" d="M412.23 511.914c-47.708-24.518-94.086-36.958-137.88-36.958-5.956 0-11.952 0.18-17.948 0.708-55.88 4.624-106.922 19.368-139.75 30.828-8.708 3.198-17.634 6.576-26.83 10.306l-89.822 311.394c61.702-22.832 116.292-33.938 166.27-33.938 80.846 0 139.528 30.208 187.992 61.304 22.962-77.918 78.044-266.09 94.482-322.324-11.95-7.284-24.076-14.57-36.514-21.32z
m116.118 79.156l-90.446 314.148c26.832 15.372 117.098 64.05 186.212 64.05 55.792 0 118.252-14.296 190.834-43.792l86.356-301.976c-58.632 18.922-114.876 28.52-167.464 28.52-95.95 0-163.114-31.098-205.492-60.95z
m-235.526-222.28c77.118 0.798 134.152 30.208 181.416 60.502l92.752-317.344c-19.546-11.196-70.806-39.094-107.858-48.6-24.386-5.684-50.02-8.616-77.204-8.616-51.796 0.976-108.388 13.946-172.888 39.8l-88.44 310.596c64.808-24.436 120.644-36.34 172.086-36.34 0.046 0.002 0.136 0.002 0.136 0.002z
m731.178-170.666c-58.814 22.832-116.208 34.466-171.028 34.466-91.686 0-159.292-31.802-203.094-62.366l-91.95 318.236c61.746 39.708 128.29 59.878 198.122 59.878 56.948 0 115.94-13.68 175.462-40.688l-0.182-2.222 3.734-0.886 88.936-306.418z"/>
&lt;path id="w2" d="M0 187.396l367.2-50.6v354.798h-367.2v-304.2z
m0 649.2v-299.798h367.2v350.398z
m407.6 56v-355.798h488.4v423.2z
m0-761.2l488.4-67.4v427.6h-488.4v-360.2z"/>
&lt;path id="w1" d="M412.23 511.914c-47.708-24.518-94.086-36.958-137.88-36.958-5.956 0-11.952 0.18-17.948 0.708-55.88 4.624-106.922 19.368-139.75 30.828-8.708 3.198-17.634 6.576-26.83 10.306l-89.822 311.394c61.702-22.832 116.292-33.938 166.27-33.938 80.846 0 139.528 30.208 187.992 61.304 22.962-77.918 78.044-266.09 94.482-322.324-11.95-7.284-24.076-14.57-36.514-21.32z
m116.118 79.156l-90.446 314.148c26.832 15.372 117.098 64.05 186.212 64.05 55.792 0 118.252-14.296 190.834-43.792l86.356-301.976c-58.632 18.922-114.876 28.52-167.464 28.52-95.95 0-163.114-31.098-205.492-60.95z
m-235.526-222.28c77.118 0.798 134.152 30.208 181.416 60.502l92.752-317.344c-19.546-11.196-70.806-39.094-107.858-48.6-24.386-5.684-50.02-8.616-77.204-8.616-51.796 0.976-108.388 13.946-172.888 39.8l-88.44 310.596c64.808-24.436 120.644-36.34 172.086-36.34 0.046 0.002 0.136 0.002 0.136 0.002z
m731.178-170.666c-58.814 22.832-116.208 34.466-171.028 34.466-91.686 0-159.292-31.802-203.094-62.366l-91.95 318.236c61.746 39.708 128.29 59.878 198.122 59.878 56.948 0 115.94-13.68 175.462-40.688l-0.182-2.222 3.734-0.886 88.936-306.418z"/>
&lt;path id="w2" d="M0 187.396l367.2-50.6v354.798h-367.2v-304.2z
m0 649.2v-299.798h367.2v350.398z
m407.6 56v-355.798h488.4v423.2z
m0-761.2l488.4-67.4v427.6h-488.4v-360.2z"/>
&lt;/svg>
</code></pre>
<p>Similar to the <a href="svgMorph.html">svgMorph</a> component, this component doesn't provide multipath processing so we should split the sub-paths into multiple <b>&lt;path&gt;</b> shapes, analyze and associate them
in a way that corresponding shapes are close and their points travel the least possible distance.</p>
<p>Similar to the <a href="svgMorph.html">svgMorph</a> component, this component doesn't provide multipath processing so we should split the sub-paths into multiple <b>&lt;path&gt;</b> shapes, analyze and associate them
in a way that corresponding shapes are close and their points travel the least possible distance.</p>
<p>Now since we've worked with these paths before, the first example below showcases how the <b>svgCubicMorph</b> component handles it by default, using the <code>reverseSecondPath:true</code> option for all tweens because
each shape have a slightly different position from its corresponding shape. The following example was made possible by editing the shapes with a vector graphics editor. The last example showcases a creative use of
association between starting and end shapes. Let's have a look:</p>
<p>Now since we've worked with these paths before, the first example below showcases how the <b>svgCubicMorph</b> component handles it by default. The following example was made possible by editing the shapes with a vector
graphics editor. The last example showcases a creative use of association between starting and end shapes. Let's have a look:</p>
<div class="featurettes">
<svg class="example-box-model example-box" id="multi-morph-example" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 550 550">
<path id="w11" fill="#e91b1f" d="M206.115,255.957c-23.854-12.259-47.043-18.479-68.94-18.479c-2.978,0-5.976,0.09-8.974,0.354 c-27.94,2.312-53.461,9.684-69.875,15.414c-4.354,1.599-8.817,3.288-13.415,5.152L0,414.096 c30.851-11.416,58.146-16.969,83.135-16.969c40.423,0,69.764,15.104,93.996,30.652c11.481-38.959,39.022-133.045,47.241-161.162 C218.397,262.975,212.334,259.332,206.115,255.957z"/>
<path id="w12" fill="#FF5722" d="M264.174,295.535l-45.223,157.074c13.416,7.686,58.549,32.024,93.105,32.024 c27.896,0,59.127-7.147,95.417-21.896l43.179-150.988c-29.316,9.461-57.438,14.26-83.732,14.26 C318.945,326.01,285.363,310.461,264.174,295.535z"/>
<path id="w13" fill="#4CAF50" d="M146.411,184.395c38.559,0.399,67.076,15.104,90.708,30.251l46.376-158.672c-9.772-5.598-35.403-19.547-53.929-24.3c-12.193-2.842-25.01-4.308-38.602-4.308c-25.898,0.488-54.194,6.973-86.444,19.9 L60.3,202.564c32.404-12.218,60.322-18.17,86.043-18.17C146.366,184.395,146.411,184.395,146.411,184.395L146.411,184.395z"/>
<path id="w14" fill="#2196F3" d="M512,99.062c-29.407,11.416-58.104,17.233-85.514,17.233c-45.844,0-79.646-15.901-101.547-31.183L278.964,244.23 c30.873,19.854,64.146,29.939,99.062,29.939c28.474,0,57.97-6.84,87.73-20.344l-0.091-1.111l1.867-0.443L512,99.062z"/>
<path id="w21" style="visibility:hidden" d="M192 471.918l-191.844-26.297-0.010-157.621h191.854z"/>
<path id="w22" style="visibility:hidden" d="M479.999 288l-0.063 224-255.936-36.008v-187.992z"/>
<path id="w23" style="visibility:hidden" d="M0.175 256l-0.175-156.037 192-26.072v182.109z"/>
<path id="w24" style="visibility:hidden" d="M224 69.241l255.936-37.241v224h-255.936z"/>
</svg>
<svg class="example-box-model example-box" id="multi-morph-example1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 550 550">
<path id="w111" fill="#e91b1f" d="M128.2,237.8c-44.1,0-78.7,18.7-83.3,20.6L0,414.1c30.9-11.4,58.1-17,83.1-17
c40.4,0,69.8,15.1,94,30.7c11.5-39,39-133,47.2-161.2C205.7,254.8,176.7,237.8,128.2,237.8z"/>
<path id="w121" fill="#FF5722" d="M264.2,295.5L219,452.6c13.4,7.7,58.5,32,93.1,32c27.9,0,59.1-7.1,95.4-21.9l43.2-151
c-29.3,9.5-57.4,14.3-83.7,14.3C318.9,326,285.4,310.5,264.2,295.5z"/>
<path id="w131" fill="#4CAF50" d="M146.4,184.4c38.6,0.4,67.1,15.1,90.7,30.3L283.5,56c-9.8-5.6-41.4-27.7-92.5-28.6
c-25.9,0.5-54.2,7-86.4,19.9L60.3,202.6C92.7,190.3,120.6,184.4,146.4,184.4C146.4,184.4,146.4,184.4,146.4,184.4L146.4,184.4z"/>
<path id="w141" fill="#2196F3" d="M512,99.1c-29.4,11.4-58.1,17.2-85.5,17.2c-45.8,0-79.6-15.9-101.5-31.2l-46,159.1
c30.9,19.9,64.1,29.9,99.1,29.9c43.1,0,89.5-21.9,89.5-21.9L512,99.1z"/>
<path id="w211" style="visibility:hidden" d="M192,470.9L0.2,444.6l0-98.7l0-58.9h107.8H192L192,470.9z"/>
<path id="w221" style="visibility:hidden" d="M480,288l-0.1,224l-138.7-19.5L224,476V288h128H480z"/>
<path id="w231" style="visibility:hidden" d="M0.2,256L0,100l99.5-13.5L192,73.9V256H87H0.2z"/>
<path id="w241" style="visibility:hidden" d="M224,69.2l147.7-21.5L479.9,32v224H352H224V69.2z"/>
</svg>
<svg class="example-box-model example-box" id="multi-morph-example2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 550 550">
<path id="s11" fill="#e91b1f" d="M128.2,237.8c-44.1,0-78.7,18.7-83.3,20.6L0,414.1c30.9-11.4,58.1-17,83.1-17
c40.4,0,69.8,15.1,94,30.7c11.5-39,39-133,47.2-161.2C205.7,254.8,176.7,237.8,128.2,237.8z"/>
<path id="s12" fill="#FF5722" d="M264.2,295.5L219,452.6c13.4,7.7,58.5,32,93.1,32c27.9,0,59.1-7.1,95.4-21.9l43.2-151
c-29.3,9.5-57.4,14.4-83.7,14.3C310.6,325.9,276,303.9,264.2,295.5z"/>
<path id="s13" fill="#4CAF50" d="M146.4,184.4c38.6,0.4,67.1,15.1,90.7,30.3L283.5,56c-6.6-3.7-45.7-28.6-92.5-28.6
c-25.9,0.5-54.2,7-86.4,19.9L60.3,202.6C92.7,190.3,120.6,184.4,146.4,184.4z"/>
<path id="s14" fill="#2196F3" d="M512,99.1c-29.4,11.4-58.1,17.2-85.5,17.2c-45.8,0-79.6-15.9-101.5-31.2l-46,159.1
c30.9,19.9,64.1,29.9,99.1,29.9c43.1,0,89.5-21.9,89.5-21.9L512,99.1z"/>
<path id="s21" style="visibility:hidden" d="M192,471.9L0.2,445.6V288h87.3h52.3H192V471.9z"/>
<path id="s22" style="visibility:hidden" d="M479.999 288l-0.063 224-255.936-36.008v-187.992z"/>
<path id="s23" style="visibility:hidden" d="M0.2,256L0,100l88.7-12.1l103.3-14V256H0.2z"/>
<path id="s24" style="visibility:hidden" d="M224,69.2L479.9,32v224H354.7h-69.4H224V69.2z"/>
</svg>
<div class="featurettes">
<svg class="example-box-model example-box" id="multi-morph-example" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 550 550">
<path id="w11" fill="#e91b1f" d="M206.115,255.957c-23.854-12.259-47.043-18.479-68.94-18.479c-2.978,0-5.976,0.09-8.974,0.354 c-27.94,2.312-53.461,9.684-69.875,15.414c-4.354,1.599-8.817,3.288-13.415,5.152L0,414.096 c30.851-11.416,58.146-16.969,83.135-16.969c40.423,0,69.764,15.104,93.996,30.652c11.481-38.959,39.022-133.045,47.241-161.162 C218.397,262.975,212.334,259.332,206.115,255.957z"/>
<path id="w12" fill="#FF5722" d="M264.174,295.535l-45.223,157.074c13.416,7.686,58.549,32.024,93.105,32.024 c27.896,0,59.127-7.147,95.417-21.896l43.179-150.988c-29.316,9.461-57.438,14.26-83.732,14.26 C318.945,326.01,285.363,310.461,264.174,295.535z"/>
<path id="w13" fill="#4CAF50" d="M146.411,184.395c38.559,0.399,67.076,15.104,90.708,30.251l46.376-158.672c-9.772-5.598-35.403-19.547-53.929-24.3c-12.193-2.842-25.01-4.308-38.602-4.308c-25.898,0.488-54.194,6.973-86.444,19.9 L60.3,202.564c32.404-12.218,60.322-18.17,86.043-18.17C146.366,184.395,146.411,184.395,146.411,184.395L146.411,184.395z"/>
<path id="w14" fill="#2196F3" d="M512,99.062c-29.407,11.416-58.104,17.233-85.514,17.233c-45.844,0-79.646-15.901-101.547-31.183L278.964,244.23 c30.873,19.854,64.146,29.939,99.062,29.939c28.474,0,57.97-6.84,87.73-20.344l-0.091-1.111l1.867-0.443L512,99.062z"/>
<path id="w21" style="visibility:hidden" d="M192 471.918l-191.844-26.297-0.010-157.621h191.854z"/>
<path id="w22" style="visibility:hidden" d="M479.999 288l-0.063 224-255.936-36.008v-187.992z"/>
<path id="w23" style="visibility:hidden" d="M0.175 256l-0.175-156.037 192-26.072v182.109z"/>
<path id="w24" style="visibility:hidden" d="M224 69.241l255.936-37.241v224h-255.936z"/>
</svg>
<svg class="example-box-model example-box" id="multi-morph-example1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 550 550">
<path id="w111" fill="#e91b1f" d="M128.2,237.8c-44.1,0-78.7,18.7-83.3,20.6L0,414.1c30.9-11.4,58.1-17,83.1-17
c40.4,0,69.8,15.1,94,30.7c11.5-39,39-133,47.2-161.2C205.7,254.8,176.7,237.8,128.2,237.8z"/>
<path id="w121" fill="#FF5722" d="M264.2,295.5L219,452.6c13.4,7.7,58.5,32,93.1,32c27.9,0,59.1-7.1,95.4-21.9l43.2-151
c-29.3,9.5-57.4,14.3-83.7,14.3C318.9,326,285.4,310.5,264.2,295.5z"/>
<path id="w131" fill="#4CAF50" d="M146.4,184.4c38.6,0.4,67.1,15.1,90.7,30.3L283.5,56c-9.8-5.6-41.4-27.7-92.5-28.6
c-25.9,0.5-54.2,7-86.4,19.9L60.3,202.6C92.7,190.3,120.6,184.4,146.4,184.4C146.4,184.4,146.4,184.4,146.4,184.4L146.4,184.4z"/>
<path id="w141" fill="#2196F3" d="M512,99.1c-29.4,11.4-58.1,17.2-85.5,17.2c-45.8,0-79.6-15.9-101.5-31.2l-46,159.1
c30.9,19.9,64.1,29.9,99.1,29.9c43.1,0,89.5-21.9,89.5-21.9L512,99.1z"/>
<path id="w211" style="visibility:hidden" d="M192,470.9L0.2,444.6l0-98.7l0-58.9h107.8H192L192,470.9z"/>
<path id="w221" style="visibility:hidden" d="M480,288l-0.1,224l-138.7-19.5L224,476V288h128H480z"/>
<path id="w231" style="visibility:hidden" d="M0.2,256L0,100l99.5-13.5L192,73.9V256H87H0.2z"/>
<path id="w241" style="visibility:hidden" d="M224,69.2l147.7-21.5L479.9,32v224H352H224V69.2z"/>
</svg>
<svg class="example-box-model example-box" id="multi-morph-example2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 550 550">
<path id="s11" fill="#e91b1f" d="M128.2,237.8c-44.1,0-78.7,18.7-83.3,20.6L0,414.1c30.9-11.4,58.1-17,83.1-17
c40.4,0,69.8,15.1,94,30.7c11.5-39,39-133,47.2-161.2C205.7,254.8,176.7,237.8,128.2,237.8z"/>
<path id="s12" fill="#FF5722" d="M264.2,295.5L219,452.6c13.4,7.7,58.5,32,93.1,32c27.9,0,59.1-7.1,95.4-21.9l43.2-151
c-29.3,9.5-57.4,14.4-83.7,14.3C310.6,325.9,276,303.9,264.2,295.5z"/>
<path id="s13" fill="#4CAF50" d="M146.4,184.4c38.6,0.4,67.1,15.1,90.7,30.3L283.5,56c-6.6-3.7-45.7-28.6-92.5-28.6
c-25.9,0.5-54.2,7-86.4,19.9L60.3,202.6C92.7,190.3,120.6,184.4,146.4,184.4z"/>
<path id="s14" fill="#2196F3" d="M512,99.1c-29.4,11.4-58.1,17.2-85.5,17.2c-45.8,0-79.6-15.9-101.5-31.2l-46,159.1
c30.9,19.9,64.1,29.9,99.1,29.9c43.1,0,89.5-21.9,89.5-21.9L512,99.1z"/>
<path id="s21" style="visibility:hidden" d="M192,471.9L0.2,445.6V288h87.3h52.3H192V471.9z"/>
<path id="s22" style="visibility:hidden" d="M479.999 288l-0.063 224-255.936-36.008v-187.992z"/>
<path id="s23" style="visibility:hidden" d="M0.2,256L0,100l88.7-12.1l103.3-14V256H0.2z"/>
<path id="s24" style="visibility:hidden" d="M224,69.2L479.9,32v224H354.7h-69.4H224V69.2z"/>
</svg>
<div class="example-buttons">
<a id="multiMorphBtn" class="btn btn-indigo" href="javascript:void(0)">Start</a>
</div>
</div>
<p>Make sure to check the markup here as well as the <a href="assets/js/svgCubicMorph.js" target="_blank">svgCubicMorph.js</a> for a full code review.</p>
<h3>Intersecting Paths Example</h3>
<p>The same preparation apply here, however the outcome is a bit different with cubic-bezier path commands, as shown in the first example. For the next two examples, the shapes have been edited for a better outcome.
Let's have a look:</p>
<div class="featurettes">
<svg class="example-box-model example-box" id="complex-morph-example" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 513">
<defs>
<mask id="symbol">
<rect width="100%" height="100%" fill="#fff"></rect>
<path id="symbol-left" fill="#000" d="M155.889 333.394h-55.632c-3.351 0-5.854-1.504-7.271-3.792-1.467-2.379-1.542-5.464 0-8.534l59.11-104.313c0.063-0.114 0.063-0.19 0-0.316l-37.615-65.116c-1.556-3.098-1.783-6.157-0.316-8.534 1.417-2.301 4.235-3.477 7.586-3.477h55.632c8.535 0 12.72 5.499 15.489 10.431 0 0 38.020 66.33 38.249 66.696-2.252 3.97-60.059 106.21-60.059 106.21-2.844 5.131-6.852 10.745-15.173 10.745z"></path>
<path id="symbol-left-clone" fill="#000" d="M155.889 333.394h-55.632c-3.351 0-5.854-1.504-7.271-3.792-1.467-2.379-1.542-5.464 0-8.534l59.11-104.313c0.063-0.114 0.063-0.19 0-0.316l-37.615-65.116c-1.556-3.098-1.783-6.157-0.316-8.534 1.417-2.301 4.235-3.477 7.586-3.477h55.632c8.535 0 12.72 5.499 15.489 10.431 0 0 38.020 66.33 38.249 66.696-2.252 3.97-60.059 106.21-60.059 106.21-2.844 5.131-6.852 10.745-15.173 10.745z"></path>
<path id="symbol-right" fill="#000" d="M418.956 75.269l-123.176 217.79c-0.075 0.115-0.075 0.255 0 0.367l78.431 143.295c1.556 3.084 1.593 6.221 0.113 8.597-1.415 2.288-4.033 3.552-7.383 3.552h-55.57c-8.522 0-12.783-5.663-15.54-10.596 0 0-78.848-144.646-79.050-145.023 3.944-6.98 123.797-219.523 123.797-219.523 2.984-5.362 6.587-10.596 14.894-10.596h56.203c3.351 0 5.981 1.265 7.396 3.553 1.466 2.376 1.428 5.511-0.115 8.584z"></path>
<path id="eye-right" style="visibility: hidden;" d="M352 128c17.673 0 32 21.49 32 48s-14.327 48-32 48-32-21.49-32-48 14.327-48 32-48z"></path>
<path id="eye-left" style="visibility: hidden;" d="M176 156.031c29.823 0 51 11.166 51 28.641 0 3.699 1.906 21.497-0.085 24.797-7.414-12.288-27.405-21.094-50.915-21.094s-43.501 8.806-50.915 21.094c-1.991-3.3-0.085-21.098-0.085-24.797 0-17.475 21.177-28.641 51-28.641z"></path>
<path id="mouth" style="visibility: hidden;" d="M250.172 416c-59.621 0-111.929-32.14-141.446-80.476 35.205 27.53 97.267 32.905 162.644 19.989 70.124-13.853 124.555-45.771 144.227-88.297-10.827 83.98-80.759 148.784-165.425 148.784z"></path>
</mask>
</defs>
<path id="rectangle-container" fill="#2196F3" mask="url(#symbol)" 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 id="circle-container" style="visibility: hidden;" d="M0,256a256,256 0 1,0 512,0a256,256 0 1,0 -512,0z"></path>
</svg>
<svg class="example-box-model example-box" id="complex-morph-example1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 513">
<defs>
<mask id="symbol1">
<rect width="100%" height="100%" fill="#fff"></rect>
<path id="symbol-left1" fill="#000" d="M155.889 333.394h-55.632c-3.351 0-5.854-1.504-7.271-3.792-1.467-2.379-1.542-5.464 0-8.534l59.11-104.313c0.063-0.114 0.063-0.19 0-0.316l-37.615-65.116c-1.556-3.098-1.783-6.157-0.316-8.534 1.417-2.301 4.235-3.477 7.586-3.477h55.632c8.535 0 12.72 5.499 15.489 10.431 0 0 38.020 66.33 38.249 66.696-2.252 3.97-60.059 106.21-60.059 106.21-2.844 5.131-6.852 10.745-15.173 10.745z"></path>
<path id="symbol-left-clone1" fill="#000" d="M155.889 333.394h-55.632c-3.351 0-5.854-1.504-7.271-3.792-1.467-2.379-1.542-5.464 0-8.534l59.11-104.313c0.063-0.114 0.063-0.19 0-0.316l-37.615-65.116c-1.556-3.098-1.783-6.157-0.316-8.534 1.417-2.301 4.235-3.477 7.586-3.477h55.632c8.535 0 12.72 5.499 15.489 10.431 0 0 38.020 66.33 38.249 66.696-2.252 3.97-60.059 106.21-60.059 106.21-2.844 5.131-6.852 10.745-15.173 10.745z"></path>
<path id="symbol-right1" fill="#000" d="M418.956 75.269l-123.176 217.79c-0.075 0.115-0.075 0.255 0 0.367l78.431 143.295c1.556 3.084 1.593 6.221 0.113 8.597-1.415 2.288-4.033 3.552-7.383 3.552h-55.57c-8.522 0-12.783-5.663-15.54-10.596 0 0-78.848-144.646-79.050-145.023 3.944-6.98 123.797-219.523 123.797-219.523 2.984-5.362 6.587-10.596 14.894-10.596h56.203c3.351 0 5.981 1.265 7.396 3.553 1.466 2.376 1.428 5.511-0.115 8.584z"></path>
<path id="eye-right1" style="visibility: hidden;" d="M352,128c2.6,0,5,0.5,7.4,1.3c2.3,0.8,4.5,2,6.6,3.6c10.6,7.8,18,24.2,18,43.1c0,16.2-5.3,30.5-13.5,39.2
c-3.1,3.3-6.6,5.8-10.5,7.3c-2.6,1-5.3,1.5-8,1.5c-4,0-7.8-1.1-11.3-3.1c-2.7-1.6-5.3-3.7-7.6-6.2c-7.9-8.7-13-22.8-13-38.7
c0-19.2,7.5-35.7,18.4-43.4c1.9-1.4,4-2.5,6.1-3.2C346.9,128.5,349.4,128,352,128z"></path>
<path id="eye-left1" style="visibility: hidden;" d="M176,156c10.4,0,19.7,1.4,27.5,3.9c14.5,4.7,23.5,13.4,23.5,24.8c0,3.7,1.9,21.5-0.1,24.8
c-3.3-5.5-9.2-10.3-16.7-13.9c-5.6-2.7-12.2-4.8-19.4-6c-4.7-0.8-9.6-1.2-14.7-1.2c-8.9,0-17.3,1.3-24.7,3.5
c-12.2,3.7-21.6,10-26.3,17.6c-2-3.3-0.1-21.1-0.1-24.8c0-11.3,8.8-19.9,23-24.6c3.7-1.2,7.8-2.2,12.2-2.9
C165.1,156.4,170.4,156,176,156z"></path>
<path id="mouth1" style="visibility: hidden;" d="M250.2,416c-42.9,0-82-16.6-111.5-43.9c-7-6.5-13.5-13.6-19.4-21.2c-3.8-4.9-7.3-10-10.6-15.4
c5.6,4.4,11.9,8.2,18.7,11.5c7.1,3.4,14.8,6.2,23,8.4c33.9,9.2,76.7,8.9,120.9,0.1c47.2-9.3,87.3-26.8,114.5-50.3
c6-5.1,11.3-10.6,16-16.3c5.6-6.9,10.3-14.2,13.8-21.8c-1.2,9.2-3.1,18.2-5.7,26.9c-2.6,8.8-5.9,17.3-9.7,25.5
C373.1,376.7,316.1,416,250.2,416L250.2,416z"></path>
</mask>
</defs>
<path id="rectangle-container1" fill="#9C27B0" mask="url(#symbol1)" d="M426.7,0H85.3C38.4,0,0,38.4,0,85.3v341.3c0,47,38.4,85.3,85.3,85.3h341.3
c46.9,0,85.3-38.4,85.3-85.3V85.3C512,38.4,473.6,0,426.7,0z"></path>
<path id="circle-container1" style="visibility: hidden;" d="M0,256c0,100.9,59.8,165.3,72,177.9c11.2,11.6,77.7,78.1,184,78.1c14.5,0,115.8-1.7,190.7-85.3
C510.1,356,512,274.1,512,256c0-18.9-2.1-96.7-61-165.9C375.7,1.8,269.4,0,256,0C241,0,141.3,1.7,66.6,83.7C1.9,154.8,0,237.9,0,256 z"></path>
</svg>
<svg class="example-box-model example-box" id="complex-morph-example2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 513">
<defs>
<mask id="symbol2">
<rect width="100%" height="100%" fill="#fff"></rect>
<path id="symbol-left2" fill="#000" d="M155.889 333.394h-55.632c-3.351 0-5.854-1.504-7.271-3.792-1.467-2.379-1.542-5.464 0-8.534l59.11-104.313c0.063-0.114 0.063-0.19 0-0.316l-37.615-65.116c-1.556-3.098-1.783-6.157-0.316-8.534 1.417-2.301 4.235-3.477 7.586-3.477h55.632c8.535 0 12.72 5.499 15.489 10.431 0 0 38.020 66.33 38.249 66.696-2.252 3.97-60.059 106.21-60.059 106.21-2.844 5.131-6.852 10.745-15.173 10.745z"></path>
<path id="sample-shape2" fill="#000" d="M250 450 L250 450"></path>
<path id="symbol-right2" fill="#000" d="M418.956 75.269l-123.176 217.79c-0.075 0.115-0.075 0.255 0 0.367l78.431 143.295c1.556 3.084 1.593 6.221 0.113 8.597-1.415 2.288-4.033 3.552-7.383 3.552h-55.57c-8.522 0-12.783-5.663-15.54-10.596 0 0-78.848-144.646-79.050-145.023 3.944-6.98 123.797-219.523 123.797-219.523 2.984-5.362 6.587-10.596 14.894-10.596h56.203c3.351 0 5.981 1.265 7.396 3.553 1.466 2.376 1.428 5.511-0.115 8.584z"></path>
<path id="eye-right2" style="visibility: hidden;" d="M352,128c2.6,0,5,0.5,7.4,1.3c2.3,0.8,4.5,2,6.6,3.6c10.6,7.8,18,24.2,18,43.1c0,16.2-5.3,30.5-13.5,39.2
c-3.1,3.3-6.6,5.8-10.5,7.3c-2.6,1-5.3,1.5-8,1.5c-4,0-7.8-1.1-11.3-3.1c-2.7-1.6-5.3-3.7-7.6-6.2c-7.9-8.7-13-22.8-13-38.7
c0-19.2,7.5-35.7,18.4-43.4c1.9-1.4,4-2.5,6.1-3.2C346.9,128.5,349.4,128,352,128z"></path>
<path id="eye-left2" style="visibility: hidden;" d="M176,156c10.4,0,19.7,1.4,27.5,3.9c14.5,4.7,23.5,13.4,23.5,24.8c0,3.7,1.9,21.5-0.1,24.8
c-3.3-5.5-9.2-10.3-16.7-13.9c-5.6-2.7-12.2-4.8-19.4-6c-4.7-0.8-9.6-1.2-14.7-1.2c-8.9,0-17.3,1.3-24.7,3.5
c-12.2,3.7-21.6,10-26.3,17.6c-2-3.3-0.1-21.1-0.1-24.8c0-11.3,8.8-19.9,23-24.6c3.7-1.2,7.8-2.2,12.2-2.9
C165.1,156.4,170.4,156,176,156z"></path>
<path id="mouth2" style="visibility: hidden;" d="M250.172 416c-59.621 0-111.929-32.14-141.446-80.476 35.205 27.53 97.267 32.905 162.644 19.989 70.124-13.853 124.555-45.771 144.227-88.297-10.827 83.98-80.759 148.784-165.425 148.784z"></path>
</mask>
</defs>
<path id="rectangle-container2" fill="#e91b1f" mask="url(#symbol2)" d="M426.7,0H85.3C38.4,0,0,38.4,0,85.3v341.3c0,47,38.4,85.3,85.3,85.3h341.3
c46.9,0,85.3-38.4,85.3-85.3V85.3C512,38.4,473.6,0,426.7,0z"></path>
<path id="circle-container2" style="visibility: hidden;" d="M0,256c0,100.9,59.8,165.3,72,177.9c11.2,11.6,77.7,78.1,184,78.1c14.5,0,115.8-1.7,190.7-85.3
C510.1,356,512,274.1,512,256c0-18.9-2.1-96.7-61-165.9C375.7,1.8,269.4,0,256,0C241,0,141.3,1.7,66.6,83.7C1.9,154.8,0,237.9,0,256 z"></path>
</svg>
<div class="example-buttons">
<a id="compliMorphBtn" class="btn btn-green" href="javascript:void(0)">Start</a>
</div>
</div>
<p>So the technique involves creating <code>&lt;mask></code> elements, splitting multipath shapes into multiple <code>&lt;path></code> shapes, matching the amount of starting and ending shapes by duplicating
an existing shape or by sampling another shape for the same purpose, editing shapes for more accurate point-to-point animation, as well as various options to optimize the visual presentation.</p>
<p>That's it, you now mastered the <b>SVG Cubic Morph</b> component.</p>
<h3>Notes</h3>
<ul>
<li>Since animation works only with <code>path</code> <b>SVGElement</b>s, you might need a <a href="https://github.com/Waest/SVGPathConverter" target="_blank">convertToPath</a> utility.</li>
<li>In some cases your start and end shapes don't have a very close size, you can use your vector graphics editor of choice or something like <a href="https://github.com/fontello/svgpath">SVGPath</a> tools to
apply a scale transformation to your shapes' path commands.</li>
<li>The <b>SVG Cubic Morph</b> component WILL animate paths with sub-paths, but the animation isn't very appealing unless you've prepared your paths for this specific case, in other cases hopefuly
this guide will help you break the ice.</li>
<li>Compared to <a href="svgMorph.html">svgMorph</a>, this component requires more work, but can be more memory efficient, as we're dealing with significantly less interpolation points which translates directly
into better performance and the shapes never show any sign of "polygon artifacts".</li>
<li>Some shapes can be broken even if the browser won't throw any error so make sure you double check with your SVG editor of choice.</li>
<li>In some cases the duplicated curve bezier points don't produce the best morphing animation, but you can edit the shapes and add your own additional path commands between the existing ones
so that the component will work with actual points that travel less and produce a much more "natural" morphing animation.</li>
<li>The edited shapes can be found in the <b>assets/img</b> folder of this demo, make sure to check them out.</li>
<li>Make sure to check the <a href="assets/js/svgCubicMorph.js" target="_blank">svgCubicMorph.js</a> for a full code review.</li>
<li>This component is affected by the the <code>fill-rule="evenodd"</code> specific SVG attribute, you must make sure you check your shapes in that regard as well.</li>
<li>This component is bundled with the <i>demo/src/kute-extra.js</i> file.</li>
</ul>
</div>
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2020 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
<div class="example-buttons">
<a id="multiMorphBtn" class="btn btn-indigo" href="javascript:void(0)">Start</a>
</div>
</div>
</footer>
<p>Make sure to check the markup here as well as the <a href="assets/js/svgCubicMorph.js" target="_blank">svgCubicMorph.js</a> for a full code review.</p>
<h3>Intersecting Paths Example</h3>
<p>The same preparation apply here, however the outcome is a bit different with cubic-bezier path commands, as shown in the first example. For the next two examples, the shapes have been edited for a better outcome.
Let's have a look:</p>
<div class="featurettes">
<svg class="example-box-model example-box" id="complex-morph-example" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 513">
<defs>
<mask id="symbol">
<rect width="100%" height="100%" fill="#fff"></rect>
<path id="symbol-left" fill="#000" d="M155.889 333.394h-55.632c-3.351 0-5.854-1.504-7.271-3.792-1.467-2.379-1.542-5.464 0-8.534l59.11-104.313c0.063-0.114 0.063-0.19 0-0.316l-37.615-65.116c-1.556-3.098-1.783-6.157-0.316-8.534 1.417-2.301 4.235-3.477 7.586-3.477h55.632c8.535 0 12.72 5.499 15.489 10.431 0 0 38.020 66.33 38.249 66.696-2.252 3.97-60.059 106.21-60.059 106.21-2.844 5.131-6.852 10.745-15.173 10.745z"></path>
<path id="symbol-left-clone" fill="#000" d="M155.889 333.394h-55.632c-3.351 0-5.854-1.504-7.271-3.792-1.467-2.379-1.542-5.464 0-8.534l59.11-104.313c0.063-0.114 0.063-0.19 0-0.316l-37.615-65.116c-1.556-3.098-1.783-6.157-0.316-8.534 1.417-2.301 4.235-3.477 7.586-3.477h55.632c8.535 0 12.72 5.499 15.489 10.431 0 0 38.020 66.33 38.249 66.696-2.252 3.97-60.059 106.21-60.059 106.21-2.844 5.131-6.852 10.745-15.173 10.745z"></path>
<path id="symbol-right" fill="#000" d="M418.956 75.269l-123.176 217.79c-0.075 0.115-0.075 0.255 0 0.367l78.431 143.295c1.556 3.084 1.593 6.221 0.113 8.597-1.415 2.288-4.033 3.552-7.383 3.552h-55.57c-8.522 0-12.783-5.663-15.54-10.596 0 0-78.848-144.646-79.050-145.023 3.944-6.98 123.797-219.523 123.797-219.523 2.984-5.362 6.587-10.596 14.894-10.596h56.203c3.351 0 5.981 1.265 7.396 3.553 1.466 2.376 1.428 5.511-0.115 8.584z"></path>
<path id="eye-right" style="visibility: hidden;" d="M352 128c17.673 0 32 21.49 32 48s-14.327 48-32 48-32-21.49-32-48 14.327-48 32-48z"></path>
<path id="eye-left" style="visibility: hidden;" d="M176 156.031c29.823 0 51 11.166 51 28.641 0 3.699 1.906 21.497-0.085 24.797-7.414-12.288-27.405-21.094-50.915-21.094s-43.501 8.806-50.915 21.094c-1.991-3.3-0.085-21.098-0.085-24.797 0-17.475 21.177-28.641 51-28.641z"></path>
<path id="mouth" style="visibility: hidden;" d="M250.172 416c-59.621 0-111.929-32.14-141.446-80.476 35.205 27.53 97.267 32.905 162.644 19.989 70.124-13.853 124.555-45.771 144.227-88.297-10.827 83.98-80.759 148.784-165.425 148.784z"></path>
</mask>
</defs>
<path id="rectangle-container" fill="#2196F3" mask="url(#symbol)" 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 id="circle-container" style="visibility: hidden;" d="M0,256a256,256 0 1,0 512,0a256,256 0 1,0 -512,0z"></path>
</svg>
<svg class="example-box-model example-box" id="complex-morph-example2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 513">
<defs>
<mask id="symbol2">
<rect width="100%" height="100%" fill="#fff"></rect>
<path id="symbol-left2" fill="#000" d="M155.889 333.394h-55.632c-3.351 0-5.854-1.504-7.271-3.792-1.467-2.379-1.542-5.464 0-8.534l59.11-104.313c0.063-0.114 0.063-0.19 0-0.316l-37.615-65.116c-1.556-3.098-1.783-6.157-0.316-8.534 1.417-2.301 4.235-3.477 7.586-3.477h55.632c8.535 0 12.72 5.499 15.489 10.431 0 0 38.020 66.33 38.249 66.696-2.252 3.97-60.059 106.21-60.059 106.21-2.844 5.131-6.852 10.745-15.173 10.745"></path>
<path id="sample-shape2" fill="#000" d="M250 450 L250 450"></path>
<path id="symbol-right2" fill="#000" d="M418.956 75.269l-123.176 217.79c-0.075 0.115-0.075 0.255 0 0.367l78.431 143.295c1.556 3.084 1.593 6.221 0.113 8.597-1.415 2.288-4.033 3.552-7.383 3.552h-55.57c-8.522 0-12.783-5.663-15.54-10.596 0 0-78.848-144.646-79.050-145.023 3.944-6.98 123.797-219.523 123.797-219.523 2.984-5.362 6.587-10.596 14.894-10.596h56.203c3.351 0 5.981 1.265 7.396 3.553 1.466 2.376 1.428 5.511-0.115 8.584"></path>
<path id="eye-right2" style="visibility: hidden;" d="M352,128c2.6,0,5,0.5,7.4,1.3c2.3,0.8,4.5,2,6.6,3.6c10.6,7.8,18,24.2,18,43.1c0,16.2-5.3,30.5-13.5,39.2
c-3.1,3.3-6.6,5.8-10.5,7.3c-2.6,1-5.3,1.5-8,1.5c-4,0-7.8-1.1-11.3-3.1c-2.7-1.6-5.3-3.7-7.6-6.2c-7.9-8.7-13-22.8-13-38.7
c0-19.2,7.5-35.7,18.4-43.4c1.9-1.4,4-2.5,6.1-3.2C346.9,128.5,349.4,128,352,128"></path>
<path id="eye-left2" style="visibility: hidden;" d="M176,156c10.4,0,19.7,1.4,27.5,3.9c14.5,4.7,23.5,13.4,23.5,24.8c0,3.7,1.9,21.5-0.1,24.8
c-3.3-5.5-9.2-10.3-16.7-13.9c-5.6-2.7-12.2-4.8-19.4-6c-4.7-0.8-9.6-1.2-14.7-1.2c-8.9,0-17.3,1.3-24.7,3.5
c-12.2,3.7-21.6,10-26.3,17.6c-2-3.3-0.1-21.1-0.1-24.8c0-11.3,8.8-19.9,23-24.6c3.7-1.2,7.8-2.2,12.2-2.9
C165.1,156.4,170.4,156,176,156"></path>
<path id="mouth2" style="visibility: hidden;" d="M250.172 416c-59.621 0-111.929-32.14-141.446-80.476 35.205 27.53 97.267 32.905 162.644 19.989 70.124-13.853 124.555-45.771 144.227-88.297-10.827 83.98-80.759 148.784-165.425 148.784"></path>
</mask>
</defs>
<path id="rectangle-container2" fill="#e91b1f" mask="url(#symbol2)" d="M426.7,0H85.3C38.4,0,0,38.4,0,85.3v341.3c0,47,38.4,85.3,85.3,85.3h341.3
c46.9,0,85.3-38.4,85.3-85.3V85.3C512,38.4,473.6,0,426.7,0"></path>
<path id="circle-container2" style="visibility: hidden;" d="M0,256c0,100.9,59.8,165.3,72,177.9c9.1,9.4,34.7,34.4,75.6,53.5c50.6,23.7,95,24.6,108.4,24.6
c10.9,0,61.3-0.9,117.6-30c42.1-21.8,67.4-49,73.1-55.3c64-70.6,65.3-157,65.3-170.7c0-18.9-2.1-96.7-61-165.9
c-8.6-10.2-37.3-42-86-65C313.6,0.9,268.6,0,256,0c-11,0-61.8,0.8-118.2,30.1C97.1,51.3,72.4,77.3,66.6,83.7C1.3,154.7,0,243,0,256"></path>
</svg>
<div class="example-buttons">
<a id="compliMorphBtn" class="btn btn-green" href="javascript:void(0)">Start</a>
</div>
</div>
<p>So the technique involves creating <code>&lt;mask></code> elements, splitting multipath shapes into multiple <code>&lt;path></code> shapes, matching the amount of starting and ending shapes by duplicating
an existing shape or by sampling another shape for the same purpose, editing shapes for more accurate point-to-point animation, as well as various options to optimize the visual presentation.</p>
<p>That's it, you now mastered the <b>SVG Cubic Morph</b> component.</p>
<h3>Notes</h3>
<ul>
<li>Starting with KUTE.js version 2.0.14 the component implements <a href="https://github.com/thednp/svg-path-commander">SVGPathCommander</a> for path processing, solving previous issues with over-optimized
path strings among other issues. You can try the <a href="https://thednp.github.io/svg-path-commander/">SVGPathCommander demo page</a> to prepare your path strings.</li>
<li>Since animation works only with <code>path</code> <b>SVGElement</b>s, you might need a <a href="https://thednp.github.io/svg-path-commander/convert.html" target="_blank">shapeToPath</a> utility.</li>
<li>Both SVG morph components will always animate first sub-path from both starting and ending shapes, and for any case hopefully this demo will guide you in mastering the technique.</li>
<li>In some cases your start and end shapes don't have a very close size, you can use your vector graphics editor of choice or <a href="https://github.com/Waest/SVGPathConverter">SVGPathCommander</a>
to apply a scale transformation to your shapes' path commands.</li>
<li>The <b>SVG Cubic Morph</b> component WILL NOT animate paths with sub-paths as of KUTE.js version 2.0.14, hopefuly this guide will help you break the ice.</li>
<li>Compared to <a href="svgMorph.html">svgMorph</a>, this component can be more memory efficient, as we're dealing with significantly less interpolation points which translates directly
into better performance and the shapes never show any sign of "polygon artifacts".</li>
<li>Some shapes can be broken even if the browser won't throw any error so make sure you double check with your SVG editor of choice.</li>
<li>In some cases the duplicated curve bezier points don't produce the best morphing animation, but you can edit the shapes and add your own additional path commands between the existing ones
so that the component will work with actual points that travel less and produce a much more "natural" morphing animation.</li>
<li>The edited shapes can be found in the <b>assets/img</b> folder of this demo, make sure to check them out.</li>
<li>Make sure to check the <a href="assets/js/svgCubicMorph.js" target="_blank">svgCubicMorph.js</a> for a full code review.</li>
<li>This component is affected by the the <code>fill-rule="evenodd"</code> specific SVG attribute, you must make sure you check your shapes in that regard as well.</li>
<li>This component is bundled with the <i>demo/src/kute-extra.js</i> file.</li>
</ul>
</div>
<!-- /.site-wrapper -->
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2021 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
</div>
<!-- /.site-wrapper -->
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute-extra.min.js"></script>
<script src="./assets/js/prism.js"></script>
<script src="./assets/js/scripts.js"></script>
<script src="./assets/js/svgCubicMorph.js"></script>
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute-extra.js"></script>
<script src="./assets/js/svgCubicMorph.js"></script>
<script src="./assets/js/prism.js"></script>
<script src="./assets/js/scripts.js"></script>
</body>

View file

@ -2,104 +2,104 @@
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="The SVG Draw component for KUTE.js enables animation for the stroke-dasharray and stroke-dashoffset.">
<meta name="keywords" content="svg draw,svg,stroke-dasharray,stroke-dashoffset,svg animation,kute,kute.js,animation,javascript animation,tweening engine,animation engine,Javascript,Native Javascript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="The SVG Draw component for KUTE.js enables animation for the stroke-dasharray and stroke-dashoffset.">
<meta name="keywords" content="svg draw,svg,stroke-dasharray,stroke-dashoffset,svg animation,kute,kute.js,animation,javascript animation,tweening engine,animation engine,Javascript,Native Javascript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<title>KUTE.js SVG Draw</title>
<title>KUTE.js SVG Draw</title>
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
</head>
<body>
<div class="site-wrapper">
<div class="site-wrapper">
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-space">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li class="active"><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-between">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li class="active"><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</div>
</nav>
</div>
</div>
<div class="content-wrap">
<h2 class="head-title">SVG Draw</h2>
<p class="condensed lead">The component that animates the stroke of any <b>SVGElement</b> and updates the <i>style</i> attribute of the target.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<div class="columns">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">Animate the stroke for most <b>SVGElement</b> shapes, with a very easy to use coordinates system.</p>
</div>
<div class="col9 border">
<p class="lead condensed">The KUTE.js <b>SVG Draw</b> component enables animation for the <b>stroke-dasharray</b> and <b>stroke-dashoffset</b> properties via CSS style.</p>
<p>The component uses the SVG standard <b>.getTotalLength()</b> method for <b>&lt;path></b> shapes, while for the other shapes it uses some helper methods to calculate the values
required for animation.</p>
<p>It can work with <b>&lt;path></b>, <b>&lt;glyph></b>, <b>&lt;circle></b>, <b>&lt;ellipse></b>, <b>&lt;rect></b>, <b>&lt;line></b>, <b>&lt;polyline></b> and <b>&lt;polygon></b>
shapes. It uses a very simple to use coordinates system so you can set up animations right away.</p>
<p>As you will see in the examples below, there is alot of flexibility in terms of input values.</p>
</div>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
</ul>
</div>
</div>
</div>
</nav>
</div>
</div>
<div class="content-wrap">
<h2 class="head-title">SVG Draw</h2>
<p class="condensed lead">The component that animates the stroke of any <b>SVGElement</b> and updates the <i>style</i> attribute of the target.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<h3>Examples</h3>
<div class="columns">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">Animate the stroke for most <b>SVGElement</b> shapes, with a very easy to use coordinates system.</p>
</div>
<div class="col9 border">
<p class="lead condensed">The KUTE.js <b>SVG Draw</b> component enables animation for the <b>stroke-dasharray</b> and <b>stroke-dashoffset</b> properties via CSS style.</p>
<p>The component uses the SVG standard <b>.getTotalLength()</b> method for <b>&lt;path></b> shapes, while for the other shapes it uses some helper methods to calculate the values
required for animation.</p>
<p>It can work with <b>&lt;path></b>, <b>&lt;glyph></b>, <b>&lt;circle></b>, <b>&lt;ellipse></b>, <b>&lt;rect></b>, <b>&lt;line></b>, <b>&lt;polyline></b> and <b>&lt;polygon></b>
shapes. It uses a very simple to use coordinates system so you can set up animations right away.</p>
<p>As you will see in the examples below, there is alot of flexibility in terms of input values.</p>
</div>
</div>
</div>
</div>
<div class="content-wrap">
<h3>Examples</h3>
<pre><code class="language-javascript">// draw the stroke from 0-10% to 90-100%
var tween1 = KUTE.fromTo('selector1',{draw:'0% 10%'}, {draw:'90% 100%'});
@ -112,53 +112,53 @@ var tween3 = KUTE.fromTo('selector1',{draw:'0% 100%'}, {draw:'50% 50%'});
</code></pre>
<p>Based on the above sample code, let's see some animation going on:</p>
<div class="featurettes">
<svg style="width:600px" class="example-box-model example-box" id="draw-example" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2046 513">
<path fill="none" style="stroke:#2196F3; stroke-width:20; stroke-dashoffset: -724.077px; stroke-dasharray: 0px, 1448.15px" id="drawSVG" d="M432 64l-240 240-112-112-80 80 192 192 320-320z"/>
<circle fill="none" r="220" cx="780" cy="255" style="stroke:#4CAF50; stroke-width:20; stroke-dashoffset: -690.8px; stroke-dasharray: 0px, 1381.6px" id="drawSVG1"/>
<ellipse fill="none" rx="220" ry="100" cx="780" cy="255" style="stroke:#55c55a; stroke-width:20; stroke-dashoffset: -690.8px; stroke-dasharray: 0px, 1381.6px" id="drawSVG11"/>
<rect fill="none" width="430" height="430" x="1070" y="30" style="stroke:#FF5722; stroke-width:20; stroke-dashoffset: -860px; stroke-dasharray: 0px, 1720px" id="drawSVG2"/>
<polygon fill="none" points="1579,307 1623,117 1801,33 1978,117 2022,307 1899,460 1702,460 1579,307" style="stroke:#673AB7; stroke-width:20; stroke-dashoffset: -860px; stroke-dasharray: 0px, 1720px" id="drawSVG3"/>
</svg>
<div class="example-buttons">
<a id="drawBtn" class="btn btn-blue" href="javascript:void(0)">Start</a>
</div>
</div>
<h3>Notes</h3>
<ul>
<li>Remember that the <code class="bg-indigo">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> properties are not set.</li>
<li>Sometimes the <code>stroke</code> on some shapes may not completely close, you might want to consider values outside the [0-100] percent range.</li>
<li>The <b>SVG Draw</b> component can be combined with any other SVG based component to create even more complex animations for SVG elements.</li>
<li>This component is bundled with the default distribution <i>kute.js</i> and the <i>demo/src/kute-extra.js</i> file.</li>
</ul>
</div>
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2020 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
<p>Based on the above sample code, let's see some animation going on:</p>
<div class="featurettes">
<svg style="width:600px" class="example-box-model example-box" id="draw-example" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2046 513">
<path fill="none" style="stroke:#2196F3; stroke-width:20; stroke-dashoffset: -724.077px; stroke-dasharray: 0px, 1448.15px" id="drawSVG" d="M432 64l-240 240-112-112-80 80 192 192 320-320z"/>
<circle fill="none" r="220" cx="780" cy="255" style="stroke:#4CAF50; stroke-width:20; stroke-dashoffset: -690.8px; stroke-dasharray: 0px, 1381.6px" id="drawSVG1"/>
<ellipse fill="none" rx="220" ry="100" cx="780" cy="255" style="stroke:#55c55a; stroke-width:20; stroke-dashoffset: -690.8px; stroke-dasharray: 0px, 1381.6px" id="drawSVG11"/>
<rect fill="none" width="430" height="430" x="1070" y="30" style="stroke:#FF5722; stroke-width:20; stroke-dashoffset: -860px; stroke-dasharray: 0px, 1720px" id="drawSVG2"/>
<polygon fill="none" points="1579,307 1623,117 1801,33 1978,117 2022,307 1899,460 1702,460 1579,307" style="stroke:#673AB7; stroke-width:20; stroke-dashoffset: -860px; stroke-dasharray: 0px, 1720px" id="drawSVG3"/>
</svg>
<div class="example-buttons">
<a id="drawBtn" class="btn btn-blue" href="javascript:void(0)">Start</a>
</div>
</div>
<h3>Notes</h3>
<ul>
<li>Remember that the <code class="bg-indigo">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> properties are not set.</li>
<li>Sometimes the <code>stroke</code> on some shapes may not completely close, you might want to consider values outside the [0-100] percent range.</li>
<li>The <b>SVG Draw</b> component can be combined with any other SVG based component to create even more complex animations for SVG elements.</li>
<li>This component is bundled with the default distribution <i>kute.js</i> and the <i>demo/src/kute-extra.js</i> file.</li>
</ul>
</div>
<!-- /.site-wrapper -->
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2021 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute-extra.min.js"></script>
<script src="./assets/js/prism.js"></script>
<script src="./assets/js/scripts.js"></script>
<script src="./assets/js/svgDraw.js"></script>
</div>
<!-- /.site-wrapper -->
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute-extra.min.js"></script>
<script src="./assets/js/prism.js"></script>
<script src="./assets/js/scripts.js"></script>
<script src="./assets/js/svgDraw.js"></script>
</body>

View file

@ -30,7 +30,7 @@
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-space">
<div class="nav-wrapper d-flex align-items-center justify-content-between">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
@ -89,15 +89,16 @@
<div class="col9 border">
<p class="lead condensed">The KUTE.js <b>SVG Morph</b> component enables animation for the <b>d</b> (description) presentation attribute and is one of the most important in all the
SVG components.</p>
<p>It only applies to inline <b>&lt;path></b> <b>SVGElement</b> shapes and requires that these shapes are closed (their <b>d</b> attribute ends with
<b>Z</b> path command). On initialization or animation start, depending on the chosen KUTE.js method, it will
<a href="http://phrogz.net/SVG/convert_path_to_polygon.xhtml" target="_blank">sample a number of points</a> along the two paths based on a default / given sample size and will
create two arrays of coordinates we need for interpolation.</p>
<p>It only works with inline <b>SVGPathElement</b> shapes and the presentation is always the same when shapes are closed or not (their <b>d</b> attribute ends with <b>Z</b> path command).
On initialization or animation start, depending on the chosen KUTE.js method, it will <a href="http://phrogz.net/SVG/convert_path_to_polygon.xhtml" target="_blank">sample a number of points</a>
along the two paths based on a default / given sample size and will create two arrays of coordinates we need for interpolation.</p>
<p>This component was originally inspired by a <a href="http://bl.ocks.org/mbostock/3081153" target="_blank">D3.js path morphing example</a> and now implements a set of
<a href="https://github.com/d3/d3-polygon">D3 polygon</a> geometric operations and other functionalities from <a href="https://github.com/veltman/flubber">flubber</a> to
produce the coordinates for a very consistent morphing animation.</p>
<p>While in some cases you might be able to create SVG morphing animations via CSS3 <i>transition</i>, this component was developed to provide various solutions for working
with complex shapes, bringing convenience, resources and clarity to one of the most complex types of animation.</p>
<p>All path processing is powered by our <a href="https://github.com/thednp/svg-path-commander">SVGPathCommander</a> starting KUTE.js version 2.0.14, which aims to modernize and
improve the path processing and enable you to prepare your path strings in Node.js.</p>
</div>
</div>
@ -108,7 +109,7 @@
</div>
<div class="col9 border">
<p class="lead condensed">The <b>SVG Morph</b> component comes with a simple option to optimize animation on every device. Previous versions used to have additional options required for processing,
but now the component will handle all that for you thanks to the new code.</p>
but now the component will handle all that for you.</p>
<ul>
<li><kbd>morphPrecision: <b class='text-olive'>Number</b></kbd> option allows you to set the sampling size of the shapes in pixels. The lesser value the better visual but the more power consumption
@ -159,6 +160,43 @@ var tween = KUTE.to('#rectangle', { path: 'M301.113,12.011l99.25,179.996l201.864
<p>That's it, let move on to the next example.</p>
<h3>Morphing Unclosed Shapes To Closed Shapes</h3>
<p>The next morphing animation example is a transition from a line into a circle and this example showcases the component's behavior when one of the paths is not closed (it doesn't have the <i>Z</i> path command),
while the other is closed. In all cases, the component will always consider shapes to be closed, so let's have a look at the example:</p>
<pre><code class="language-markup">&lt;svg id="morph-example" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
&lt;path id="line" fill="transparent" stroke="orange" stroke-linejoin="round" stroke-width="10" d="M10 300L590 300"/>
&lt;path id="circle" style="visibility:hidden" d="M10,300a290,290 0 1,0 580,0a290,290 0 1,0 -580,0z"/>
&lt;/svg>
</code></pre>
<p>Now we can apply both <code>.to()</code> and <code>fromTo()</code> methods:</p>
<pre><code class="language-javascript">// the fromTo() method
var tween = KUTE.fromTo('#line', {path: '#line' }, { path: '#circle' }).start();
// OR
// the to() method will take the path's d attribute value and use it as start value
var tween = KUTE.to('#line', { path: '#circle' }).start();
</code></pre>
<div class="featurettes">
<svg class="example-box-model example-box" id="morph-example-closed" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
<path id="line" fill="transparent" stroke="#FF5722" stroke-linejoin="round" stroke-width="15" d="M10 300L590 300Z"/>
<path id="circle" style="visibility:hidden" d="M10,300a290,290 0 1,0 580,0a290,290 0 1,0 -580,0z"/>
</svg>
<svg class="example-box-model example-box" id="morph-example-closed1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
<path id="line1" fill="transparent" stroke="#4CAF50" stroke-linejoin="round" stroke-width="15" d="M10 300L590 300"/>
<path id="circle1" style="visibility:hidden" d="M10,300a290,290 0 1,0 580,0a290,290 0 1,0 -580,0"/>
</svg>
<div class="example-buttons">
<a id="morphBtnClosed" class="btn btn-green" href="javascript:void(0)">Start</a>
</div>
</div>
<p>The functionality of this component is different from the <a href="svgCubicMorph.html">svgCubicMorph</a> component in the sense that it will animate the shapes as if they are both and always closed.
In the above example, the orange line is closed while the green line is not, and the animation is the same.</p>
<h3>Polygon Paths</h3>
<p>When your paths are only <code>lineto</code>, <code>vertical-lineto</code> and <code>horizontal-lineto</code> based shapes (the <code>d</code> attribute consists of only <code>L</code>, <code>V</code> and
<code>H</code> path commands), the <b>SVG Morph</b> component will work differently from previous versions, it will sample points as for any other non-polygon shapes. In this case you can set a higher
@ -224,9 +262,9 @@ var tween2 = KUTE.to('#triangle', { path: '#square' }).start();
<p>As you can see, both these paths have subpaths, and this component will only animate the first subpath from both paths. To animate them all there are a few easy steps required in preparation for
the animation, so here's a quick guide:</p>
<ol>
<li>Use the <a href="https://codepen.io/thednp/pen/EgVqLw">convertToAbsolute</a> utility to convert path commands to absolute values. It's <b>important</b> to do this
conversion first.</li>
<li>Create a new <b>&lt;path&gt;</b> shape for each subpath string from <b>M</b> to <b>Z</b> path commands. See the sample code below.</li>
<li>Use the <a href="https://thednp.github.io/svg-path-commander/">SVGPathCommander demo page</a> to split your path string into multiple sub-path strings. It's <b>important</b> to do this to avoid
inconsistencies with shapes having relative sub-path commands. You can also use the utility to reverse paths if required.</li>
<li>Create a new <b>&lt;path&gt;</b> shape for each sub-path string from <b>M</b> to <b>Z</b> path commands. See the sample code below.</li>
<li>Give the new paths an <b>id="uniqueID"</b> attribute so you can target them easily. You could use relevant namespace to help you better understand positioning. EG: <b>id="square-top-left"</b>
or <b>id="left-eye"</b></li>
<li>In the browser console inspect with your mouse all paths from both starting and ending shapes and determine which shapes should morph to which. The idea is to produce a morphing animation
@ -340,24 +378,29 @@ var tween2 = KUTE.to('#triangle', { path: '#square' }).start();
<h3>Notes</h3>
<ul>
<li>Starting with KUTE.js version 2.0.14 the component implements <a href="https://github.com/thednp/svg-path-commander">SVGPathCommander</a> for path processing, solving previous issues with over-optimized
path strings among other issues. You can try the <a href="https://thednp.github.io/svg-path-commander/">SVGPathCommander demo page</a> to prepare your path strings.</li>
<li>Since <b>SVG Morph</b> animation works only with <code>path</code> elements, you might need a <code>convertToPath</code> feature, so
<a href="https://github.com/Waest/SVGPathConverter" target="_blank">grab one here</a> and get to working.</li>
<li>In some cases your start and end shapes don't have a very close size, you can use your vector graphics editor of choice or something like <a href="https://github.com/fontello/svgpath">SVGPath</a> tools to
apply a scale transformation to your shapes' path commands.</li>
<a href="https://thednp.github.io/svg-path-commander/convert.html" target="_blank">grab one here</a>.</li>
<li>Both SVG morph components will always animate first sub-path from both starting and ending shapes, and for any case hopefully this demo will guide you in mastering the technique.</li>
<li>In some cases your start and end shapes don't have a very close size, you can use your vector graphics editor of choice or <a href="https://github.com/Waest/SVGPathConverter">SVGPathCommander</a>
to apply a scale transformation to your shapes' path commands.</li>
<li>The morphing animation is expensive so try to optimize the number of morph animations that run at the same time. When morphing sub-paths/multi-paths 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, mobile devices still don't do very much, regardless
of the advertising.</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>Because you have the tools at hand, you can also try to use a <code>morphPrecision</code> value for every resolution. Take some time to experiement, you might find a better <code>morphPrecision</code>
<li>With all the tools at hand, you can also try to use a <code>morphPrecision</code> value for every resolution. Take some time to experiement, you might find a better <code>morphPrecision</code>
value you can use for any particular device and / or resolution.</li>
<li>The animation 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, thus 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>
<li>The <b>SVG Morph</b> component uses approximatelly the same algorithm as D3.js for determining the coordinates for interpolation, it might be a better solution for your applications.</li>
already and for the first method the processing of the two paths happens on tween <code>.start()</code> call, thus 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>
<li>The <b>SVG Morph</b> component uses approximatelly the same algorithm as D3.js for determining the coordinates for interpolation, the visual presentation is more natural compared to the other component,
it might be a better solution for your applications.</li>
<li>Make sure to check the <a href="assets/js/svgMorph.js" target="_blank">svgMorph.js</a> for a full code review.</li>
<li>This component should ignore the <code>fill-rule="evenodd"</code> specific SVG attribute, but you can make sure you check your shapes in that regard as well.</li>
<li>This component is bundled with the standard <i>kute.js</i> distribution file.</li>
<li>This component is bundled with the official <i>kute.js</i> distribution file.</li>
</ul>
</div>
@ -365,15 +408,13 @@ var tween2 = KUTE.to('#triangle', { path: '#square' }).start();
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2020 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
<p>&copy; 2015 - 2021 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
</div>
<!-- /.site-wrapper -->
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
@ -382,7 +423,5 @@ var tween2 = KUTE.to('#triangle', { path: '#square' }).start();
<script src="./assets/js/prism.js"></script>
<script src="./assets/js/scripts.js"></script>
<script src="./assets/js/svgMorph.js"></script>
</body>
</html>

View file

@ -1,209 +1,209 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="The SVG Transform component for KUTE.js enables animation for the transform presentation attribute.">
<meta name="keywords" content="svg transform,cross-browser svg transform,svg animation,kute,kute.js,tweening engine,animation engine,animation,javascript animation,Javascript,Native Javascript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="The SVG Transform component for KUTE.js enables animation for the transform presentation attribute.">
<meta name="keywords" content="svg transform,cross-browser svg transform,svg animation,kute,kute.js,tweening engine,animation engine,animation,javascript animation,Javascript,Native Javascript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<title>KUTE.js SVG Transform</title>
<title>KUTE.js SVG Transform</title>
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
</head>
<body>
<div class="site-wrapper">
<div class="site-wrapper">
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-space">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li class="active"><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-between">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li class="active"><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</div>
</nav>
</div>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div class="content-wrap">
<h2 class="head-title">SVG Transform</h2>
<p class="condensed lead">The component that covers <i>transform</i> animation on <b>SVGElement</b> targets, solves browser inconsistencies and provides a similar visual presentation as
with other transform based components on non-<b>SVGElements</b> targets.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<h2 class="head-title">SVG Transform</h2>
<p class="condensed lead">The component that covers <i>transform</i> animation on <b>SVGElement</b> targets, solves browser inconsistencies and provides a similar visual presentation as
with other transform based components on non-<b>SVGElements</b> targets.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<div class="columns margin-bottom">
<div class="columns margin-bottom">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">Animate 2D transform functions on SVG elements on any SVG enabled browser.</p>
</div>
<div class="col9 border">
<p class="lead condensed">The KUTE.js <b>SVG Transform</b> component enables animation for the <b>transform</b> presentation attribute on any <b>SVGElement</b> target.</p>
<p>The <b>SVG Transform</b> is an important part of the SVG components for some reasons:</p>
<ul>
<li>It was developed to solve most browser inconsistencies of the time for transform animation. Nowadays modern browsers are Chromium browsers that work with regular 2D
transform functions.</li>
<li>The unique way to normalize translation to produce the kind of animation that is just as consistent as for CSS3 transforms on non-<b>SVGElement</b> targets.</li>
<li>The value processing is consistent with the current <a href="https://www.w3.org/TR/SVG/coords.html#EstablishingANewUserSpace">W3 draft</a>.</li>
</ul>
<p>Keep in mind that the <b>transform</b> attribute accepts no measurement units such as degrees or pixels, but it expects rotation / skew angles to be in degrees, and
translations in lengths measured around the parent <b>&lt;svg&gt;</b> element viewBox attribute.</p>
</div>
</div>
<div class="columns">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">Animate 2D transform functions on SVG elements on any SVG enabled browser.</p>
<h3 class="border text-right">Options</h3>
<p class="condensed text-right">Keep everything under control and handle any situation with a single option.</p>
</div>
<div class="col9 border">
<p class="lead condensed">The KUTE.js <b>SVG Transform</b> component enables animation for the <b>transform</b> presentation attribute on any <b>SVGElement</b> target.</p>
<p>The <b>SVG Transform</b> is an important part of the SVG components for some reasons:</p>
<p class="lead condensed">The only component that keeps the <b>transformOrigin</b> option because it's required to compute transform functions in the SVG
cooordinates system.</p>
<ul>
<li>It was developed to solve most browser inconsistencies of the time for transform animation. Nowadays modern browsers are Chromium browsers that work with regular 2D
transform functions.</li>
<li>The unique way to normalize translation to produce the kind of animation that is just as consistent as for CSS3 transforms on non-<b>SVGElement</b> targets.</li>
<li>The value processing is consistent with the current <a href="https://www.w3.org/TR/SVG/coords.html#EstablishingANewUserSpace">W3 draft</a>.</li>
<li><kbd>transformOrigin: <b class='text-olive'>['50%','50%']</b></kbd> sets the much needed origin. Eg: <b>transformOrigin:[50,50]</b>. The default
value is <b>50% 50%</b> of the target element box, which is contrary with the SVG draft.</li>
</ul>
<p>Keep in mind that the <b>transform</b> attribute accepts no measurement units such as degrees or pixels, but it expects rotation / skew angles to be in degrees, and
translations in lengths measured around the parent <b>&lt;svg&gt;</b> element viewBox attribute.</p>
<p>Keep in mind that the component will disregard the current SVG default origin of <i>0px 0px</i> of the target's parent, even if the browsers' default
<b>transformOrigin</b> have been normalized over the years.</p>
<p>The <b>transformOrigin</b> tween option can also be used to set coordinates of a parent <b>&lt;svg&gt;</b> element (in the second example below).
Values like <i>top left</i> values are also accepted, but will take the target element's box as a reference, not the parent's box.</p>
</div>
</div>
<div class="columns">
<div class="col3">
<h3 class="border text-right">Options</h3>
<p class="condensed text-right">Keep everything under control and handle any situation with a single option.</p>
</div>
<div class="col9 border">
<p class="lead condensed">The only component that keeps the <b>transformOrigin</b> option because it's required to compute transform functions in the SVG
cooordinates system.</p>
<ul>
<li><kbd>transformOrigin: <b class='text-olive'>['50%','50%']</b></kbd> sets the much needed origin. Eg: <b>transformOrigin:[50,50]</b>. The default
value is <b>50% 50%</b> of the target element box, which is contrary with the SVG draft.</li>
</ul>
<p>Keep in mind that the component will disregard the current SVG default origin of <i>0px 0px</i> of the target's parent, even if the browsers' default
<b>transformOrigin</b> have been normalized over the years.</p>
<p>The <b>transformOrigin</b> tween option can also be used to set coordinates of a parent <b>&lt;svg&gt;</b> element (in the second example below).
Values like <i>top left</i> values are also accepted, but will take the target element's box as a reference, not the parent's box.</p>
</div>
</div>
</div>
</div>
</div>
<div class="content-wrap">
<h3>2D Transform</h3>
<ul>
<li><kbd class="bg-olive">translate</kbd> function applies horizontal and / or vertical translation. EG. <code>translate:150</code> to translate a shape 150px to the right or
<code>translate:[-150,200]</code> to move the element to the left by 150px and to bottom by 200px. <kbd class="bg-lime">IE9+</kbd></li>
<li><kbd class="bg-olive">rotate</kbd> function applies rotation to a shape on the Z axis. Eg. <code>rotate:150</code> will rotate a shape clockwise by 150 degrees around it's own center or around
the <code>transformOrigin: '450 450'</code> set tween option coordinate of the parent element. <kbd class="bg-lime">IE9+</kbd></li>
<li><kbd class="bg-olive">skewX</kbd> function used to apply a skew transformation on the X axis. Eg. <code>skewX:25</code> will skew a shape by 25 degrees. <kbd class="bg-lime">IE9+</kbd></li>
<li><kbd class="bg-olive">skewY</kbd> function used to apply a skew transformation on the Y axis. Eg. <code>skewY:25</code> will skew a shape by 25 degrees. <kbd class="bg-lime">IE9+</kbd></li>
<li><kbd class="bg-olive">scale</kbd> function used to apply a single value size transformation. Eg. <code>scale:0.5</code> will scale a shape to half of it's initial size. <kbd class="bg-lime">IE9+</kbd></li>
<li><kbd class="bg-red">matrix</kbd> function is not supported, but the Transform Matrix covers you there, if you'll read below.</li>
</ul>
<div class="content-wrap">
<h3>2D Transform</h3>
<ul>
<li><kbd class="bg-olive">translate</kbd> function applies horizontal and / or vertical translation. EG. <code>translate:150</code> to translate a shape 150px to the right or
<code>translate:[-150,200]</code> to move the element to the left by 150px and to bottom by 200px. <kbd class="bg-lime">IE9+</kbd></li>
<li><kbd class="bg-olive">rotate</kbd> function applies rotation to a shape on the Z axis. Eg. <code>rotate:150</code> will rotate a shape clockwise by 150 degrees around it's own center or around
the <code>transformOrigin: '450 450'</code> set tween option coordinate of the parent element. <kbd class="bg-lime">IE9+</kbd></li>
<li><kbd class="bg-olive">skewX</kbd> function used to apply a skew transformation on the X axis. Eg. <code>skewX:25</code> will skew a shape by 25 degrees. <kbd class="bg-lime">IE9+</kbd></li>
<li><kbd class="bg-olive">skewY</kbd> function used to apply a skew transformation on the Y axis. Eg. <code>skewY:25</code> will skew a shape by 25 degrees. <kbd class="bg-lime">IE9+</kbd></li>
<li><kbd class="bg-olive">scale</kbd> function used to apply a single value size transformation. Eg. <code>scale:0.5</code> will scale a shape to half of it's initial size. <kbd class="bg-lime">IE9+</kbd></li>
<li><kbd class="bg-red">matrix</kbd> function is not supported, but the Transform Matrix covers you there, if you'll read below.</li>
</ul>
<h3>Examples</h3>
<p>As explained with the <a href="transformMatrix.html">Transform Matrix</a> component, the <b>DOMMatrix</b> API will replace <b>webkitCSSMatrix</b> and <b>SVGMatrix</b> and on this page we intend to put
the two components head to head, the elements on the left will be using <b>Transform Matrix</b> component and equivalent 2D transform functions, while the elements on the right will be using 2D functions of
the <b>SVG Transform</b> component.</p>
<p>The <b>SVG Transform</b> component comes with a reliable set of scripts that work on all browsers, making use of the <b>SVGMatrix</b> API for some origin calculation, the <code>transform</code> presentation
attribute and the <code class="bg-indigo">svgTransform</code> tween property with a familiar and very easy notation:</p>
<h3>Examples</h3>
<p>As explained with the <a href="transformMatrix.html">Transform Matrix</a> component, the <b>DOMMatrix</b> API will replace <b>webkitCSSMatrix</b> and <b>SVGMatrix</b> and on this page we intend to put
the two components head to head, the elements on the left will be using <b>Transform Matrix</b> component and equivalent 2D transform functions, while the elements on the right will be using 2D functions of
the <b>SVG Transform</b> component.</p>
<p>The <b>SVG Transform</b> component comes with a reliable set of scripts that work on all browsers, making use of the <b>SVGMatrix</b> API for some origin calculation, the <code>transform</code> presentation
attribute and the <code class="bg-indigo">svgTransform</code> tween property with a familiar and very easy notation:</p>
<pre><code class="language-javascript">// using the svgTransform property works in all SVG enabled browsers
var tween2 = KUTE.to(
'shape', // target
{ // to
svgTransform: {
translate: [150,100],
rotate: 45,
skewX: 15, skewY: 20,
scale: 1.5
}
'shape', // target
{ // to
svgTransform: {
translate: [150,100],
rotate: 45,
skewX: 15, skewY: 20,
scale: 1.5
}
}
);
// transformMatrix can animate SVGElement targets on modern browsers
// requires adding styling like `transform-origin:50% 50%` to the target element
var tween1 = KUTE.to(
'shape', // target
{ // to
transform: {
translate3d: [150,100,0],
rotate3d: [0,0,45],
skew: [15,20],
scale3d: [1.5,1.5,1]
}
}
'shape', // target
{ // to
transform: {
translate3d: [150,100,0],
rotate3d: [0,0,45],
skew: [15,20],
scale3d: [1.5,1.5,1]
}
}
);
</code></pre>
<p>Let's see some examples and explain each case.</p>
<p>Let's see some examples and explain each case.</p>
<h4>SVG Rotation</h4>
<p>Our first chapter of the SVG transform is all about rotations, perhaps the most important part here. The <code class="bg-indigo">svgTransform</code> will only accept single value
for the angle value <code>rotate: 45</code>, the rotation will go around the shape's center point by default, again, contrary to the browsers' default value and you can set a <code>transformOrigin</code>
tween option to override the behavior.</p>
<p>The argument for this implementation is that this is something you would expect from regular HTML elements rotation and probably most needed, not to mention the amount of savings in the codebase department.
Let's have a look at a quick demo:</p>
<h4>SVG Rotation</h4>
<p>Our first chapter of the SVG transform is all about rotations, perhaps the most important part here. The <code class="bg-indigo">svgTransform</code> will only accept single value
for the angle value <code>rotate: 45</code>, the rotation will go around the shape's center point by default, again, contrary to the browsers' default value and you can set a <code>transformOrigin</code>
tween option to override the behavior.</p>
<p>The argument for this implementation is that this is something you would expect from regular HTML elements rotation and probably most needed, not to mention the amount of savings in the codebase department.
Let's have a look at a quick demo:</p>
<div class="featurettes">
<svg id="svgRotate" 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-olive" style="transform-origin: 25% 50%;" 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-blue" 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="featurettes">
<svg id="svgRotate" 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-olive" style="transform-origin: 25% 50%;" 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-blue" 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="rotateBtn" class="btn btn-red" href="javascript:void(0)">Start</a>
</div>
</div>
<p>For the first element, the Transform Matrix creates the rotation animation via <code>rotate3d[0,0,360]</code> tween property around the element center coordinate, as we've set <i>transform-origin:25% 50%</i>
to the element's style; this animation doesn't work in IE browsers, while in older versions Firefox the animation is inconsistent. The second element uses the <code>rotate: 360</code> function of the SVG Transform
component and the rotation animation is around the element's own central point without any option, an animation that DO WORK in all SVG enabled browsers.</p>
<div class="example-buttons">
<a id="rotateBtn" class="btn btn-red" href="javascript:void(0)">Start</a>
</div>
</div>
<p>For the first element, the Transform Matrix creates the rotation animation via <code>rotate3d[0,0,360]</code> tween property around the element center coordinate, as we've set <i>transform-origin:25% 50%</i>
to the element's style; this animation doesn't work in IE browsers, while in older versions Firefox the animation is inconsistent. The second element uses the <code>rotate: 360</code> function of the SVG Transform
component and the rotation animation is around the element's own central point without any option, an animation that DO WORK in all SVG enabled browsers.</p>
<p>When for non-SVG elements' transform we could have used values such as <i>center bottom</i> as <code>transformOrigin</code> (also not supported in all modern browsers for SVGs), the entire processing falls
to the browser, however when it comes to SVGs our component here will compute the <code>transformOrigin</code> tween option value accordingly to use the shape's <code>.getBBox()</code> value to determine
for instance the coordinates for <i>25% 75%</i> position or <i>center top</i>.</p>
<p>When for non-SVG elements' transform we could have used values such as <i>center bottom</i> as <code>transformOrigin</code> (also not supported in all modern browsers for SVGs), the entire processing falls
to the browser, however when it comes to SVGs our component here will compute the <code>transformOrigin</code> tween option value accordingly to use the shape's <code>.getBBox()</code> value to determine
for instance the coordinates for <i>25% 75%</i> position or <i>center top</i>.</p>
<p>In other cases you may want to rotate shapes around the center point of the parent <code>&lt;svg></code> or <code>&lt;g></code> element, and we use it's <code>.getBBox()</code> to determine the <i>50% 50%</i>
coordinate, so here's how to deal with it:</p>
<p>In other cases you may want to rotate shapes around the center point of the parent <code>&lt;svg></code> or <code>&lt;g></code> element, and we use it's <code>.getBBox()</code> to determine the <i>50% 50%</i>
coordinate, so here's how to deal with it:</p>
<pre><code class="language-javascript">// rotate around parent svg's "50% 50%" coordinate as transform-origin
// get the bounding box of the parent element
@ -223,166 +223,166 @@ var OriginY = svgBB.height * 50 / 100 - translation[1];
var rotationTween = KUTE.to(element, {svgTransform: {rotate: 150}}, { transformOrigin: [OriginX, OriginY]} );
</code></pre>
<div class="featurettes">
<svg id="svgRotate1" 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-olive" style="transform-origin: 50% 50%;" 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-blue" 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="featurettes">
<svg id="svgRotate1" 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-olive" style="transform-origin: 50% 50%;" 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-blue" 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="rotateBtn1" class="btn btn-red" href="javascript:void(0)">Start</a>
</div>
</div>
<p>Same as the above example, the first element is rotated by the <b>Transform Matrix</b> component and is using <i>transform-origin: 50% 50%;</i> styling, while the second element is rotated by the <b>SVG Transform</b>
component with the above calculated transform-origin.</p>
<div class="example-buttons">
<a id="rotateBtn1" class="btn btn-red" href="javascript:void(0)">Start</a>
</div>
</div>
<p>Same as the above example, the first element is rotated by the <b>Transform Matrix</b> component and is using <i>transform-origin: 50% 50%;</i> styling, while the second element is rotated by the <b>SVG Transform</b>
component with the above calculated transform-origin.</p>
<h4>SVG Translation</h4>
<p>In this example we'll have a look at translations, so when setting <code>translate: [150,0]</code>, the first value is X (horizontal) coordinate to which the shape will translate to and the second value is
Y (vertical) coordinate for translation. When <code>translate: 150</code> notation is used, the script will understand that's the X value and the Y value is 0 just like for the regular HTML elements
transformation. Let's have a look at a quick demo:</p>
<div class="featurettes">
<svg id="svgTranslate" 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-green" style="transform-origin: 25% 50%;" 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-orange" 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>
<h4>SVG Translation</h4>
<p>In this example we'll have a look at translations, so when setting <code>translate: [150,0]</code>, the first value is X (horizontal) coordinate to which the shape will translate to and the second value is
Y (vertical) coordinate for translation. When <code>translate: 150</code> notation is used, the script will understand that's the X value and the Y value is 0 just like for the regular HTML elements
transformation. Let's have a look at a quick demo:</p>
<div class="featurettes">
<svg id="svgTranslate" 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-green" style="transform-origin: 25% 50%;" 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-orange" 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="translateBtn" class="btn btn-blue" href="javascript:void(0)">Start</a>
</div>
</div>
<p>The first element uses the Transform Matrix <code>translate3d: [580,0,0]</code> function, while 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>
<div class="example-buttons">
<a id="translateBtn" class="btn btn-blue" href="javascript:void(0)">Start</a>
</div>
</div>
<p>The first element uses the Transform Matrix <code>translate3d: [580,0,0]</code> function, while 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 we have: <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>
<div class="featurettes">
<svg id="svgSkew" 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-yellow" style="transform-origin: 25% 50%;" 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>
<h4>SVG Skew</h4>
<p>For skews we have: <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>
<div class="featurettes">
<svg id="svgSkew" 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-yellow" style="transform-origin: 25% 50%;" 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="skewBtn" class="btn btn-red" href="javascript:void(0)">Start</a>
</div>
</div>
<p>The first tween skews the shape on both X and Y axes in a chain via Transform Matrix <code>skew:[-15,-15]</code> function and the second tween skews the shape on X and Y axes via the <code class="bg-indigo">svgTransform</code> functions <code>skewX:15</code> and
<code>skewY:15</code> tween properties. You will notice translation kicking in to set the transform origin.</p>
<div class="example-buttons">
<a id="skewBtn" class="btn btn-red" href="javascript:void(0)">Start</a>
</div>
</div>
<p>The first tween skews the shape on both X and Y axes in a chain via Transform Matrix <code>skew:[-15,-15]</code> function and the second tween skews the shape on X and Y axes via the <code class="bg-indigo">svgTransform</code> functions <code>skewX:15</code> and
<code>skewY:15</code> tween properties. You will notice translation kicking in to set the transform origin.</p>
<h4>SVG Scaling</h4>
<p>Another transform example for SVGs is the scale. Unlike translations, for scale animation the component 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" style="transform-origin: 25% 50%;" 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-olive" 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>
<h4>SVG Scaling</h4>
<p>Another transform example for SVGs is the scale. Unlike translations, for scale animation the component 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" style="transform-origin: 25% 50%;" 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-olive" 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="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> via <b>Transform Matrix</b> component and it's <code>scale3d:[1.5,1.5,1]</code> function, 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> of the shape box. A similar case as with the skews.</p>
<div class="example-buttons">
<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> via <b>Transform Matrix</b> component and it's <code>scale3d:[1.5,1.5,1]</code> function, 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> of the shape box. A similar case as with the skews.</p>
<h4>Mixed SVG Transform Functions</h4>
<p>Our last transform example for SVG Transform is the mixed transformation. Just like for the other examples the component 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" style="transform-origin: 25% 50%;" 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>
<h4>Mixed SVG Transform Functions</h4>
<p>Our last transform example for SVG Transform is the mixed transformation. Just like for the other examples the component 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" style="transform-origin: 25% 50%;" 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 component 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>
<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 component 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>Chained SVG Transform</h4>
<p>The <b>SVG Transform</b> does not work with SVG specific chained transform functions right away (do not confuse with tween chain), Ana Tudor explains best <a href="https://css-tricks.com/transforms-on-svg-elements/">here</a>,
but if your SVG elements only use this feature to set a custom <code>transform-origin</code>, it should look like this:</p>
<h4>Chained SVG Transform</h4>
<p>The <b>SVG Transform</b> does not work with SVG specific chained transform functions right away (do not confuse with tween chain), Ana Tudor explains best <a href="https://css-tricks.com/transforms-on-svg-elements/">here</a>,
but if your SVG elements only use this feature to set a custom <code>transform-origin</code>, it should look like this:</p>
<pre><code class="language-markup">&lt;svg>
&lt;circle transform="translate(150,150) rotate(45) scale(1.2) translate(-150,-150)" r="20">&lt;/circle>
&lt;circle transform="translate(150,150) rotate(45) scale(1.2) translate(-150,-150)" r="20">&lt;/circle>
&lt;/svg>
</code></pre>
<p>In this case I would recommend using the values of the first translation as <code>transformOrigin</code> for your tween built with the <code>.fromTo()</code> method like so:</p>
<p>In this case I would recommend using the values of the first translation as <code>transformOrigin</code> for your tween built with the <code>.fromTo()</code> method like so:</p>
<pre><code class="language-javascript">// a possible workaround for animating a SVG element that uses chained transform functions
KUTE.fromTo(element,
{svgTransform : { translate: 0, rotate: 45, scale: 0.5 }}, // we asume the current translation is zero on both X &amp; Y axis
{svgTransform : { translate: 450, rotate: 0, scale: 1.5 }}, // we will translate the X to a 450 value and scale to 1.5
{transformOrigin: [150,150]} // tween options use the transform-origin of the target SVG element
{svgTransform : { translate: 0, rotate: 45, scale: 0.5 }}, // we asume the current translation is zero on both X &amp; Y axis
{svgTransform : { translate: 450, rotate: 0, scale: 1.5 }}, // we will translate the X to a 450 value and scale to 1.5
{transformOrigin: [150,150]} // tween options use the transform-origin of the target SVG element
).start();
</code></pre>
<p>Before you hit the <kbd>Start</kbd> button, make sure to check the <code>transform</code> attribute value. The below tween will reset the element's transform attribute to original value when the animation is complete.</p>
<div class="featurettes">
<svg id="svgChained" class="example-box-model example-box" style="overflow: visible;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 513" xmlns:xml="http://www.w3.org/XML/1998/namespace" xml:space="preserve" version="1.1">
<path class="bg-blue"
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"
transform="translate(256,256) rotate(45) scale(0.5) translate(-256,-256)"></path>
</svg>
<p>Before you hit the <kbd>Start</kbd> button, make sure to check the <code>transform</code> attribute value. The below tween will reset the element's transform attribute to original value when the animation is complete.</p>
<div class="featurettes">
<svg id="svgChained" class="example-box-model example-box" style="overflow: visible;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 513" xmlns:xml="http://www.w3.org/XML/1998/namespace" xml:space="preserve" version="1.1">
<path class="bg-blue"
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"
transform="translate(256,256) rotate(45) scale(0.5) translate(-256,-256)"></path>
</svg>
<div class="example-buttons">
<a id="chainedBtn" class="btn btn-lime" href="javascript:void(0)">Start</a>
</div>
</div>
<p>This way we make sure to count the real current transform-origin and produce a consistent animation with the SVG coordinate system, just as the above example showcases.</p>
<div class="example-buttons">
<a id="chainedBtn" class="btn btn-lime" href="javascript:void(0)">Start</a>
</div>
</div>
<p>This way we make sure to count the real current transform-origin and produce a consistent animation with the SVG coordinate system, just as the above example showcases.</p>
<h3>Notes</h3>
<ul>
<li>The <b>SVG Transform</b> component is successfuly handling all possible combinations of transform functions, and <b>always uses same order of transform functions</b>: <code>translate</code>,
<code>rotate</code>, <code>skewX</code>, <code>skewY</code> and <code>scale</code> to keep animation consistent and with same aspect as for CSS3 transforms on non-SVG elements.</li>
<li>Keep in mind that the SVG transform functionss will use the center of a shape as transform origin by default, contrary to the SVG draft.</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 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>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> tween property does not support 3D transforms, because they are not supported in all SVG enabled browsers.</li>
<li>The <b>SVG Transform</b> component cannot work with the <code>transformOrigin</code> set to an <b>SVGElement</b> via CSS, you must always use a it's specific option.</li>
<li>The component can be combined with the <a href="htmlAttributes.html">HTML Attributes</a> component to enable even more advanced/complex animations for SVG elements.</li>
<li>Keep in mind that older browsers like Internet Explorer 8 and below as well as stock browser from Android 4.3 and below <a href="http://caniuse.com/#search=svg" target="_blank">do not support inline SVG</a>
so make sure to fiter your SVG tweens properly.</li>
<li>While you can still use regular CSS3 transforms for SVG elements, everything is fine with Google Chrome, Opera and other webkit browsers, but older Firefox versions struggle with the percentage based
<code>transformOrigin</code> values and ALL Internet Explorer versions have no implementation for CSS3 transforms on SVG elements, which means that the SVG Transform component will become a fallback
component to handle legacy browsers in the future. Guess who's taking over :)</li>
<li>This component is bundled with the <i>demo/src/kute-extra.js</i> file.</li>
<h3>Notes</h3>
<ul>
<li>The <b>SVG Transform</b> component is successfuly handling all possible combinations of transform functions, and <b>always uses same order of transform functions</b>: <code>translate</code>,
<code>rotate</code>, <code>skewX</code>, <code>skewY</code> and <code>scale</code> to keep animation consistent and with same aspect as for CSS3 transforms on non-SVG elements.</li>
<li>Keep in mind that the SVG transform functionss will use the center of a shape as transform origin by default, contrary to the SVG draft.</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 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>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> tween property does not support 3D transforms, because they are not supported in all SVG enabled browsers.</li>
<li>The <b>SVG Transform</b> component cannot work with the <code>transformOrigin</code> set to an <b>SVGElement</b> via CSS, you must always use a it's specific option.</li>
<li>The component can be combined with the <a href="htmlAttributes.html">HTML Attributes</a> component to enable even more advanced/complex animations for SVG elements.</li>
<li>Keep in mind that older browsers like Internet Explorer 8 and below as well as stock browser from Android 4.3 and below <a href="http://caniuse.com/#search=svg" target="_blank">do not support inline SVG</a>
so make sure to fiter your SVG tweens properly.</li>
<li>While you can still use regular CSS3 transforms for SVG elements, everything is fine with Google Chrome, Opera and other webkit browsers, but older Firefox versions struggle with the percentage based
<code>transformOrigin</code> values and ALL Internet Explorer versions have no implementation for CSS3 transforms on SVG elements, which means that the SVG Transform component will become a fallback
component to handle legacy browsers in the future. Guess who's taking over :)</li>
<li>This component is bundled with the <i>demo/src/kute-extra.js</i> file.</li>
</ul>
</div>
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2020 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
</ul>
</div>
<!-- /.site-wrapper -->
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2021 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
</div>
<!-- /.site-wrapper -->
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute-extra.js"></script>
<script src="./assets/js/prism.js"></script>
<script src="./assets/js/scripts.js"></script>
<script src="./assets/js/svgTransform.js"></script>
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute-extra.js"></script>
<script src="./assets/js/prism.js"></script>
<script src="./assets/js/scripts.js"></script>
<script src="./assets/js/svgTransform.js"></script>
</body>

View file

@ -1,158 +1,158 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="The Text Properties component for KUTE.js allows you to animate CSS properties related to typography on most browsers.">
<meta name="keywords" content="text properties,font-size,line-height,letter-spacing,kute.js,animation,javascript animation,tweening engine,animation engine,JavaScript,Native JavaScript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="The Text Properties component for KUTE.js allows you to animate CSS properties related to typography on most browsers.">
<meta name="keywords" content="text properties,font-size,line-height,letter-spacing,kute.js,animation,javascript animation,tweening engine,animation engine,JavaScript,Native JavaScript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<title>KUTE.js Text Properties</title>
<title>KUTE.js Text Properties</title>
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
<style></style>
<style></style>
</head>
<body>
<div class="site-wrapper">
<div class="site-wrapper">
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-space">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li class="active"><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-between">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li class="active"><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</div>
</nav>
</div>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div class="content-wrap">
<h2 class="head-title">Text Properties</h2>
<p class="condensed lead">The component that animates the typographic CSS properties of a target content <b>Element</b> on most browsers.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<h2 class="head-title">Text Properties</h2>
<p class="condensed lead">The component that animates the typographic CSS properties of a target content <b>Element</b> on most browsers.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<div class="columns">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">Animate the text size or spacing properties of a target text element.</p>
</div>
<div class="col9 border">
<p class="condensed lead">The KUTE.js <b>Text Properties</b> component enables animation for typography related CSS properties of content element targets
on most browsers.</p>
<p>This small and simple component can be used to create various attention seekers for any content elements such as <b>HTMLHeadingElement</b>,
<b>HTMLParagraphElement</b>, <b>HTMLUListElement</b> or any other, as well as for entire content blocks.</p>
<p>You can either animate an entire string or content block or split your string into words or letters and create a simple animation with one or more of
the following properties:</p>
</div>
<div class="columns">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">Animate the text size or spacing properties of a target text element.</p>
</div>
<div class="col9 border">
<p class="condensed lead">The KUTE.js <b>Text Properties</b> component enables animation for typography related CSS properties of content element targets
on most browsers.</p>
<p>This small and simple component can be used to create various attention seekers for any content elements such as <b>HTMLHeadingElement</b>,
<b>HTMLParagraphElement</b>, <b>HTMLUListElement</b> or any other, as well as for entire content blocks.</p>
<p>You can either animate an entire string or content block or split your string into words or letters and create a simple animation with one or more of
the following properties:</p>
</div>
</div>
</div>
</div>
<div class="content-wrap">
<div class="content-wrap">
<h3>Supported Properties</h3>
<h3>Supported Properties</h3>
<ul>
<li><kbd class="bg-olive">fontSize</kbd> allows you to animate the <code>font-size</code> for a target element.</li>
<li><kbd class="bg-olive">lineHeight</kbd> allows you to animate the <code>line-height</code> for a target element.</li>
<li><kbd class="bg-olive">letterSpacing</kbd> allows you to animate the <code>letter-spacing</code> for a target element.</li>
<li><kbd class="bg-olive">wordSpacing</kbd> allows you to animate the <code>word-spacing</code> for a target element.</li>
</ul>
<ul>
<li><kbd class="bg-olive">fontSize</kbd> allows you to animate the <code>font-size</code> for a target element.</li>
<li><kbd class="bg-olive">lineHeight</kbd> allows you to animate the <code>line-height</code> for a target element.</li>
<li><kbd class="bg-olive">letterSpacing</kbd> allows you to animate the <code>letter-spacing</code> for a target element.</li>
<li><kbd class="bg-olive">wordSpacing</kbd> allows you to animate the <code>word-spacing</code> for a target element.</li>
</ul>
<h3>Example</h3>
<h3>Example</h3>
<pre><code class="language-javascript">let tween1 = KUTE.to('selector1',{fontSize:'200%'})
let tween2 = KUTE.to('selector1',{lineHeight:24})
let tween3 = KUTE.to('selector1',{letterSpacing:50})
let tween3 = KUTE.to('selector1',{wordSpacing:50})
</code></pre>
<div id="textProperties" class="featurettes" style="height: 152px">
<h1 class="example-item">Howdy!</h1>
<div class="example-buttons"><a class="btn btn-pink" href="javascript:void(0)">Start</a></div>
</div>
<h3>Notes</h3>
<ul>
<li>Be sure to check the <a href="./assets/js/textProperties.js">textProperties.js</a> for a more in-depth review of the above example.</li>
<li>Similar to box model properties, the text properties are also layout modifiers, they will push the layout around forcing unwanted re-paint work. To avoid re-paint, you
can use a fixed height for the target element's container, as we used in our example here, or set your text to <code>position:absolute</code>.</li>
<li>The component is only included in the <i>demo/src/kute-extra.js</i> file.</li>
</ul>
</div>
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2020 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
<div id="textProperties" class="featurettes" style="height: 152px">
<h1 class="example-item">Howdy!</h1>
<div class="example-buttons"><a class="btn btn-pink" href="javascript:void(0)">Start</a></div>
</div>
</footer>
<h3>Notes</h3>
<ul>
<li>Be sure to check the <a href="./assets/js/textProperties.js">textProperties.js</a> for a more in-depth review of the above example.</li>
<li>Similar to box model properties, the text properties are also layout modifiers, they will push the layout around forcing unwanted re-paint work. To avoid re-paint, you
can use a fixed height for the target element's container, as we used in our example here, or set your text to <code>position:absolute</code>.</li>
<li>The component is only included in the <i>demo/src/kute-extra.js</i> file.</li>
</ul>
</div>
<!-- /.site-wrapper -->
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2021 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute-extra.min.js"></script>
<script src="./assets/js/prism.js"></script>
</div>
<!-- /.site-wrapper -->
<script src="./assets/js/textProperties.js"></script>
<script src="./assets/js/scripts.js"></script>
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute-extra.min.js"></script>
<script src="./assets/js/prism.js"></script>
<script src="./assets/js/textProperties.js"></script>
<script src="./assets/js/scripts.js"></script>
</body>
</html>

View file

@ -43,7 +43,7 @@
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-space">
<div class="nav-wrapper d-flex align-items-center justify-content-between">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
@ -240,7 +240,7 @@ tweenObjects.start();
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2020 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
<p>&copy; 2015 - 2021 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>

View file

@ -2,147 +2,147 @@
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="The Transform Functions component for KUTE.js enable regular transform animations.">
<meta name="keywords" content="css3 transform,transform functions,transform,kute,kute.js,animation,javascript animation,tweening engine,animation engine,JavaScript,Native JavaScript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="The Transform Functions component for KUTE.js enable regular transform animations.">
<meta name="keywords" content="css3 transform,transform functions,transform,kute,kute.js,animation,javascript animation,tweening engine,animation engine,JavaScript,Native JavaScript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<title>KUTE.js Transform Functions</title>
<title>KUTE.js Transform Functions</title>
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
</head>
<body>
<div class="site-wrapper">
<div class="site-wrapper">
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-space">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li class="active"><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-between">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li class="active"><a href="transformFunctions.html">Transform Functions</a></li>
<li><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</div>
</nav>
</div>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div class="content-wrap">
<h2 class="head-title">Transform Functions</h2>
<p class="condensed lead">The component covers most important 2D and 3D <i>transform</i> functions as described in the <a href="http://www.w3.org/TR/css3-transforms/" target="_blank">W3 specification</a>,
completelly reworked for improved performance and faster value processing.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<h2 class="head-title">Transform Functions</h2>
<p class="condensed lead">The component covers most important 2D and 3D <i>transform</i> functions as described in the <a href="http://www.w3.org/TR/css3-transforms/" target="_blank">W3 specification</a>,
completelly reworked for improved performance and faster value processing.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<div class="columns">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">The component to cover animation for most <b>transform</b> functions with improved performance and faster value processing.</p>
</div>
<div class="col9 border">
<p class="lead condensed">The KUTE.js <b>Transform Functions</b> enables animation for the CSS3 <b>transform</b> style on <b>Element</b> targets on modern browsers. For specific legacy browsers there is another
component called <b>Transform Legacy</b> you will find in the source folders.</p>
<p>Starting with KUTE.js version 2.0, you can set the <b>perspective</b> function as a tween property, while you can still rely on a parent's perspective but for less performance.</p>
<p>All the previous perspective related options have been removed. The <b>transform</b> CSS3 property itself no longer uses preffixes like <b>webkit</b>, <b>moz</b> or <b>ms</b> since all major
browsers are standardized.</p>
<p>In comparison with previous versions, the component expects that input values are already <b>px</b> and <b>deg</b> based and no longer transforms <b>%</b> percent based values into <b>px</b> based or <b>rad</b>
based angles into <b>deg</b> based. This makes the execution faster and more consistent.</p>
<p>The component will stack all transform functions for translations, rotations and skews to shorthand functions to optimize performance and minimize value processing.</p>
</div>
<div class="columns">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">The component to cover animation for most <b>transform</b> functions with improved performance and faster value processing.</p>
</div>
<div class="col9 border">
<p class="lead condensed">The KUTE.js <b>Transform Functions</b> enables animation for the CSS3 <b>transform</b> style on <b>Element</b> targets on modern browsers. For specific legacy browsers there is another
component called <b>Transform Legacy</b> you will find in the source folders.</p>
<p>Starting with KUTE.js version 2.0, you can set the <b>perspective</b> function as a tween property, while you can still rely on a parent's perspective but for less performance.</p>
<p>All the previous perspective related options have been removed. The <b>transform</b> CSS3 property itself no longer uses preffixes like <b>webkit</b>, <b>moz</b> or <b>ms</b> since all major
browsers are standardized.</p>
<p>In comparison with previous versions, the component expects that input values are already <b>px</b> and <b>deg</b> based and no longer transforms <b>%</b> percent based values into <b>px</b> based or <b>rad</b>
based angles into <b>deg</b> based. This makes the execution faster and more consistent.</p>
<p>The component will stack all transform functions for translations, rotations and skews to shorthand functions to optimize performance and minimize value processing.</p>
</div>
</div>
</div>
</div>
<div class="content-wrap">
<div class="content-wrap">
<h3>3D Transform</h3>
<ul>
<li><kbd class="bg-blue">perspective</kbd> function creates a 3D perspective for a target element transformation. EG. <code>perspective:400</code> to apply a 400px perspective. <kbd class="bg-lime">IE10+</kbd></li>
<li><kbd class="bg-blue">translateX</kbd> function is for horizontal translation. EG. <code>translateX:150</code> to translate an element 150px to the right. <kbd class="bg-lime">IE10+</kbd></li>
<li><kbd class="bg-blue">translateY</kbd> function is for vertical translation. EG. <code>translateY:-250</code> to translate an element 250px towards the top. <kbd class="bg-lime">IE10+</kbd></li>
<li><kbd class="bg-blue">translateZ</kbd> function is for translation on the Z axis in a given 3D field. EG. <code>translateZ:-250</code> to translate an element 250px away from the viewer, making it
appear smaller. This function can be combined with the <code>perspective</code> function to take effect or the parent's perspective; the smaller perspective value, the deeper translation. <kbd class="bg-lime">IE10+</kbd></li>
<li><kbd class="bg-blue">translate3d</kbd> function is for movement on all axes in a given 3D field. EG. <code>translate3d:[-150,200,150]</code> to translate an element 150px to the left, 200px
to the bottom and 150px closer to the viewer, making it larger. When third value is used, it requires using a <code>perspective</code>. <kbd class="bg-lime">IE10+</kbd></li>
<li><kbd class="bg-blue">rotateX</kbd> function rotates an element on the X axis in a given 3D field. Eg. <code>rotateX:250</code> will rotate an element clockwise by 250 degrees. Requires perspective.
<kbd class="bg-lime">IE10+</kbd></li>
<li><kbd class="bg-blue">rotateY</kbd> function rotates an element on the Y axis in a given 3D field. Eg. <code>rotateY:-150</code> will rotate an element counter-clockwise by 150 degrees.
Requires perspective. <kbd class="bg-lime">IE10+</kbd></li>
<li><kbd class="bg-blue">rotateZ</kbd> function rotates an element on the Z axis and is the equivalent of the 2D rotation. Eg. <code>rotateZ:-150</code> will rotate an element counter-clockwise by 150 degrees on X axis.
<kbd class="bg-lime">IE10+</kbd></li>
<li><kbd class="bg-blue">rotate3d</kbd> is a <b>tween property</b>, which combines the above <code>rotateX</code>, <code>rotateY</code>, and <code>rotateZ</code> functions and rotates an element on all axes. Obviously this is NOT
equivalent with the <code>rotate3d(vectorX,vectorY,vectorZ,angle)</code> shorthand function, this is only an optimization implemented for performance reasons and hopefully for your convenience.
Eg. <code>rotate3d:[-150,80,90]</code> will rotate an element counter-clockwise by 150 degrees on X axis, 80 degrees on Y axis and 90 degrees on Z axis. The X and Y axis require a <code>perspective</code>.
<kbd class="bg-lime">IE10+</kbd></li>
<li><kbd class="bg-red">matrix3d</kbd> and <kbd class="bg-red">scale3d</kbd> functions are not supported by this component, but they are implemented in the <a href="transformMatrix.html">transformMatrix</a> component.</li>
</ul>
<h3>3D Transform</h3>
<ul>
<li><kbd class="bg-blue">perspective</kbd> function creates a 3D perspective for a target element transformation. EG. <code>perspective:400</code> to apply a 400px perspective. <kbd class="bg-lime">IE10+</kbd></li>
<li><kbd class="bg-blue">translateX</kbd> function is for horizontal translation. EG. <code>translateX:150</code> to translate an element 150px to the right. <kbd class="bg-lime">IE10+</kbd></li>
<li><kbd class="bg-blue">translateY</kbd> function is for vertical translation. EG. <code>translateY:-250</code> to translate an element 250px towards the top. <kbd class="bg-lime">IE10+</kbd></li>
<li><kbd class="bg-blue">translateZ</kbd> function is for translation on the Z axis in a given 3D field. EG. <code>translateZ:-250</code> to translate an element 250px away from the viewer, making it
appear smaller. This function can be combined with the <code>perspective</code> function to take effect or the parent's perspective; the smaller perspective value, the deeper translation. <kbd class="bg-lime">IE10+</kbd></li>
<li><kbd class="bg-blue">translate3d</kbd> function is for movement on all axes in a given 3D field. EG. <code>translate3d:[-150,200,150]</code> to translate an element 150px to the left, 200px
to the bottom and 150px closer to the viewer, making it larger. When third value is used, it requires using a <code>perspective</code>. <kbd class="bg-lime">IE10+</kbd></li>
<li><kbd class="bg-blue">rotateX</kbd> function rotates an element on the X axis in a given 3D field. Eg. <code>rotateX:250</code> will rotate an element clockwise by 250 degrees. Requires perspective.
<kbd class="bg-lime">IE10+</kbd></li>
<li><kbd class="bg-blue">rotateY</kbd> function rotates an element on the Y axis in a given 3D field. Eg. <code>rotateY:-150</code> will rotate an element counter-clockwise by 150 degrees.
Requires perspective. <kbd class="bg-lime">IE10+</kbd></li>
<li><kbd class="bg-blue">rotateZ</kbd> function rotates an element on the Z axis and is the equivalent of the 2D rotation. Eg. <code>rotateZ:-150</code> will rotate an element counter-clockwise by 150 degrees on X axis.
<kbd class="bg-lime">IE10+</kbd></li>
<li><kbd class="bg-blue">rotate3d</kbd> is a <b>tween property</b>, which combines the above <code>rotateX</code>, <code>rotateY</code>, and <code>rotateZ</code> functions and rotates an element on all axes. Obviously this is NOT
equivalent with the <code>rotate3d(vectorX,vectorY,vectorZ,angle)</code> shorthand function, this is only an optimization implemented for performance reasons and hopefully for your convenience.
Eg. <code>rotate3d:[-150,80,90]</code> will rotate an element counter-clockwise by 150 degrees on X axis, 80 degrees on Y axis and 90 degrees on Z axis. The X and Y axis require a <code>perspective</code>.
<kbd class="bg-lime">IE10+</kbd></li>
<li><kbd class="bg-red">matrix3d</kbd> and <kbd class="bg-red">scale3d</kbd> functions are not supported by this component, but they are implemented in the <a href="transformMatrix.html">transformMatrix</a> component.</li>
</ul>
<h3>2D Transform</h3>
<ul>
<li><kbd class="bg-blue">translate</kbd> function is for movement on X and Y axis. EG. <code>translate:[-150,200]</code> to translate an element 150px to the left, 200px to the bottom. <kbd class="bg-lime">IE9+</kbd></li>
<li><kbd class="bg-blue">rotate</kbd> function rotates an element on the Z axis. Eg. <code>rotate:250</code> will rotate an element clockwise by 250 degrees. <kbd class="bg-lime">IE9+</kbd></li>
<li><kbd class="bg-blue">skewX</kbd> function will apply a shear on X axis to a target element. Eg. <code>skewX:50</code> will skew a target element on X axis by 50 degrees. <kbd class="bg-lime">IE9+</kbd></li>
<li><kbd class="bg-blue">skewY</kbd> function will apply a shear on X axis to a target element. Eg. <code>skewX:50</code> will skew a target element on X axis by 50 degrees. <kbd class="bg-lime">IE9+</kbd></li>
<li><kbd class="bg-blue">skew</kbd> function will apply a shear on both X and Y axes to a target element. Eg. <code>skew:[50,50]</code> will skew a target element on X axis by 50 degrees and 50 degrees on Y axis.
<kbd class="bg-lime">IE9+</kbd></li>
<li><kbd class="bg-blue">scale</kbd> function will scale a target element on all axes. Eg. <code>scale:1.5</code> will scale up a target element by 50%. <kbd class="bg-lime">IE9+</kbd></li>
<li><kbd class="bg-red">matrix</kbd> is not supported by this component, but is implemented in the <a href="transformMatrix.html">transformMatrix</a> component.</li>
</ul>
<p>As a quick note, all input values for <kbd class="bg-blue">translate</kbd>, <kbd class="bg-blue">rotate</kbd> or single axis translation, skew or rotation will be all stacked into <kbd class="bg-blue">translate3d</kbd>,
<kbd class="bg-blue">skew</kbd> and <kbd class="bg-blue">rotate3d</kbd> respectivelly; this is to further improve performance on modern browsers.</p>
<h3>2D Transform</h3>
<ul>
<li><kbd class="bg-blue">translate</kbd> function is for movement on X and Y axis. EG. <code>translate:[-150,200]</code> to translate an element 150px to the left, 200px to the bottom. <kbd class="bg-lime">IE9+</kbd></li>
<li><kbd class="bg-blue">rotate</kbd> function rotates an element on the Z axis. Eg. <code>rotate:250</code> will rotate an element clockwise by 250 degrees. <kbd class="bg-lime">IE9+</kbd></li>
<li><kbd class="bg-blue">skewX</kbd> function will apply a shear on X axis to a target element. Eg. <code>skewX:50</code> will skew a target element on X axis by 50 degrees. <kbd class="bg-lime">IE9+</kbd></li>
<li><kbd class="bg-blue">skewY</kbd> function will apply a shear on X axis to a target element. Eg. <code>skewX:50</code> will skew a target element on X axis by 50 degrees. <kbd class="bg-lime">IE9+</kbd></li>
<li><kbd class="bg-blue">skew</kbd> function will apply a shear on both X and Y axes to a target element. Eg. <code>skew:[50,50]</code> will skew a target element on X axis by 50 degrees and 50 degrees on Y axis.
<kbd class="bg-lime">IE9+</kbd></li>
<li><kbd class="bg-blue">scale</kbd> function will scale a target element on all axes. Eg. <code>scale:1.5</code> will scale up a target element by 50%. <kbd class="bg-lime">IE9+</kbd></li>
<li><kbd class="bg-red">matrix</kbd> is not supported by this component, but is implemented in the <a href="transformMatrix.html">transformMatrix</a> component.</li>
</ul>
<p>As a quick note, all input values for <kbd class="bg-blue">translate</kbd>, <kbd class="bg-blue">rotate</kbd> or single axis translation, skew or rotation will be all stacked into <kbd class="bg-blue">translate3d</kbd>,
<kbd class="bg-blue">skew</kbd> and <kbd class="bg-blue">rotate3d</kbd> respectivelly; this is to further improve performance on modern browsers.</p>
<h3>Translations</h3>
<h3>Translations</h3>
<pre><code class="language-javascript">var tween1 = KUTE.fromTo('selector1',{translate:0},{translate:250}); // or translate:[x,y] for both axes
var tween2 = KUTE.fromTo('selector2',{translateX:0},{translateX:-250});
@ -150,21 +150,21 @@ var tween3 = KUTE.fromTo('selector3',{translate3d:[0,0,0]},{translate3d:[0,250,0
var tween4 = KUTE.fromTo('selector4',{perspective:400,translateY:0},{perspective:200,translateY:-100});
</code></pre>
<div id="translate-examples" class="featurettes">
<div class="example-item example-box bg-indigo">2D</div>
<div class="example-item example-box bg-olive">X</div>
<div class="example-item example-box bg-pink">Y</div>
<div class="example-item example-box bg-red">Z</div>
<div id="translate-examples" class="featurettes">
<div class="example-item example-box bg-indigo">2D</div>
<div class="example-item example-box bg-olive">X</div>
<div class="example-item example-box bg-pink">Y</div>
<div class="example-item example-box bg-red">Z</div>
<div class="example-buttons">
<a class="btn btn-blue" href="javascript:void(0)">Start</a>
</div>
<div class="example-buttons">
<a class="btn btn-blue" href="javascript:void(0)">Start</a>
</div>
</div>
<p>As you can see in your browsers console, for all animations <code>translate3d</code> is used, as explained above. Also the first example that's using the 2D <code>translate</code> for both vertical
and horizontal axis even if we only set X axis.</p>
<p>As you can see in your browsers console, for all animations <code>translate3d</code> is used, as explained above. Also the first example that's using the 2D <code>translate</code> for both vertical
and horizontal axis even if we only set X axis.</p>
<h3>Rotations</h3>
<h3>Rotations</h3>
<pre><code class="language-javascript">var tween1 = KUTE.fromTo('selector1',{rotate:0},{rotate:-720});
var tween2 = KUTE.fromTo('selector2',{rotateX:0},{rotateX:200});
@ -172,129 +172,129 @@ var tween3 = KUTE.fromTo('selector3',{perspective:100,rotate3d:[0,0,0]},{perspec
var tween4 = KUTE.fromTo('selector4',{rotateZ:0},{rotateZ:360});
</code></pre>
<div id="rotExamples" class="featurettes">
<div class="example-item example-box bg-blue">2D</div>
<div class="example-item example-box bg-indigo">X</div>
<div class="example-item example-box bg-olive">Y</div>
<div class="example-item example-box bg-pink">Z</div>
<div class="example-buttons">
<a class="btn btn-green" href="javascript:void(0)">Start</a>
</div>
<div id="rotExamples" class="featurettes">
<div class="example-item example-box bg-blue">2D</div>
<div class="example-item example-box bg-indigo">X</div>
<div class="example-item example-box bg-olive">Y</div>
<div class="example-item example-box bg-pink">Z</div>
<div class="example-buttons">
<a class="btn btn-green" href="javascript:void(0)">Start</a>
</div>
<p>The <code>rotateX</code> and <code>rotateY</code> are 3D based rotations, so they require a perspective in order to make the browser render proper 3D layers, but in the example they animate different because only the second, Y axis, uses the
<code>perspective</code> function. The rotation on Z axis does not require a perspective. Unlike translations, you can stack all axis rotation for your animation, but we will see that in a later example.</p>
</div>
<p>The <code>rotateX</code> and <code>rotateY</code> are 3D based rotations, so they require a perspective in order to make the browser render proper 3D layers, but in the example they animate different because only the second, Y axis, uses the
<code>perspective</code> function. The rotation on Z axis does not require a perspective. Unlike translations, you can stack all axis rotation for your animation, but we will see that in a later example.</p>
<h3>Skews</h3>
<h3>Skews</h3>
<pre><code class="language-javascript">var tween1 = KUTE.fromTo('selector1',{skewX:0},{skewX:20});
var tween2 = KUTE.fromTo('selector2',{skew:[0,0]},{skew:[0,45]});
</code></pre>
<div id="skewExamples" class="featurettes">
<div class="example-item example-box bg-teal">X</div>
<div class="example-item example-box bg-green">Y</div>
<div id="skewExamples" class="featurettes">
<div class="example-item example-box bg-teal">X</div>
<div class="example-item example-box bg-green">Y</div>
<div class="example-buttons">
<a class="btn btn-yellow" href="javascript:void(0)">Start</a>
</div>
<div class="example-buttons">
<a class="btn btn-yellow" href="javascript:void(0)">Start</a>
</div>
</div>
<h3>Mixed Transformations</h3>
<p>The current specification does not support animating different transform properties with multiple tween objects at the same time, you must stack them all together into a single object. See the example below:</p>
<h3>Mixed Transformations</h3>
<p>The current specification does not support animating different transform properties with multiple tween objects at the same time, you must stack them all together into a single object. See the example below:</p>
<pre><code class="language-javascript">var tween1 = KUTE.fromTo('selector1',{rotateX:0},{rotateX:20}).start();
<pre><code class="language-javascript">var tween1 = KUTE.fromTo('selector1',{rotateX:0},{rotateX:20}).start();
var tween2 = KUTE.fromTo('selector1',{skewY:0},{skewY:45}).start();
</code></pre>
<p>If you check the <a href="http://codepen.io/thednp/pen/avZrYo" target="_blank">test here</a>, you will notice that only the <code>skewY</code> is going to work and no rotation. Now let's do this properly.</p>
<p>If you check the <a href="http://codepen.io/thednp/pen/avZrYo" target="_blank">test here</a>, you will notice that only the <code>skewY</code> is going to work and no rotation. Now let's do this properly.</p>
<pre><code class="language-javascript">var tween1 = KUTE.fromTo(
'selector1', // element
{pespective:200,translateX:0, rotateX:0, rotateY:0, rotateZ:0}, // from
{pespective:200,translateX:250, rotateX:360, rotateY:15, rotateZ:5} // to
'selector1', // element
{pespective:200,translateX:0, rotateX:0, rotateY:0, rotateZ:0}, // from
{pespective:200,translateX:250, rotateX:360, rotateY:15, rotateZ:5} // to
);
var tween2 = KUTE.fromTo(
'selector2', // element
{translateX:0, rotateX:0, rotateY:0, rotateZ:0}, // from
{translateX:-250, rotateX:360, rotateY:15, rotateZ:5} // to
'selector2', // element
{translateX:0, rotateX:0, rotateY:0, rotateZ:0}, // from
{translateX:-250, rotateX:360, rotateY:15, rotateZ:5} // to
);
</code></pre>
<div id="mixTransforms" class="featurettes" style="perspective: 400px;">
<div class="example-item example-box bg-pink" style="line-height: 50px; font-size: 25px;">self perspective 200px</div>
<div class="example-item example-box bg-orange" style="line-height: 50px; font-size: 25px;">parent perspective 400px</div>
<div id="mixTransforms" class="featurettes" style="perspective: 400px;">
<div class="example-item example-box bg-pink" style="line-height: 50px; font-size: 25px;">self perspective 200px</div>
<div class="example-item example-box bg-orange" style="line-height: 50px; font-size: 25px;">parent perspective 400px</div>
<div class="example-buttons">
<a class="btn btn-olive" href="javascript:void(0)">Start</a>
</div>
<div class="example-buttons">
<a class="btn btn-olive" href="javascript:void(0)">Start</a>
</div>
<p>Note in this example, the first tween object uses the element's <code>perspective</code> while the second relies on the parent's perspective.</p>
<h3>Chained Transformations</h3>
<p>KUTE.js has the ability to stack transform functions in a way to improve performance and optimize your workflow. In that idea the <code>.to()</code> method can be the right choice for most of your
animation needs and especially to link animations together because it has the ability to check the current values of the transform functions found in the element's inline styling, mostly from previous
tween animation, and use them as start values for the next animation. OK now, let's see a side by side comparison with 4 elements:</p>
<div id="chainedTweens" class="featurettes">
<div class="example-item example-box bg-gray" style="font-size: 30px">FROMTO</div>
<div class="example-item example-box bg-olive" style="font-size: 30px">FROMTO</div>
<div class="example-item example-box bg-gray" style="font-size: 30px">TO</div>
<div class="example-item example-box bg-blue" style="font-size: 30px">TO</div>
<div class="example-buttons">
<a class="btn btn-blue" href="#">Start</a>
</div>
</div>
<h4>Observations</h4>
<ul>
<li>The example hopefully demostrates what the animation looks like with different combinations of transform functions and how to combine them to optimize your workflow, size on disk as well as to how
to link animations together in a smooth continuous animation.</li>
<li>No matter the input values, the component will always stack translations into <code>translate3d</code> and rotations into <code>rotate3d</code>.</li>
<li>The first box uses a regular <code class="bg-gray">.fromTo()</code> object, from point A to B and back to A, with the exact coordinates we want.</li>
<li>The second box is also using <code class="bg-olive">.fromTo()</code> object, but using all values for all tweens at all times, so we gave the animation a sense of continuity.</li>
<li>The third box uses the <code class="bg-gray">.to()</code> method, and will try and continue animation from last animation, but we "forgot" to keep track on the rotation of the X axis.</li>
<li>The last box also uses the <code class="bg-blue">.to()</code> method, and uses all values and reproduce the animation of the second box exactly, but with nearly half the code.</li>
</ul>
<h3>Notes</h3>
<ul>
<li>This demo page should work with IE10+ browsers.</li>
<li>The order of the transform functions/properties is always the same: <code>perspective</code>, <code>translation</code>, <code>rotation</code>, <code>skew</code>, <code>scale</code>, this way we can prevent
jumpy/janky animations; one of the reasons is consistency in all transform based components and another reason is the order of execution from the draft for
<a href="https://drafts.csswg.org/css-transforms-2/#recomposing-to-a-3d-matrix">matrix3d recomposition</a>.</li>
<li>Tests reveal that an element's own perspective produce better performance than using the parent's perspective. Also having both will severelly punish the animation performance, so keep that in mind
when you work on optimizing your code. </li>
<li>Use single axis transform functions like <code>translateX</code> when you want to animate the Y and Z axes back to ZERO, but in a convenient way.</li>
<li>Use shorthand functions like <code>translate3d</code> when you want to animate / keep multiple axes.</li>
<li>Shorthand functions like <code>translate3d</code> or <code>rotate3d</code> tween property generally not only improve performance, but will also minimize the code size. Eg. <code>translateX:150</code>,
<code>translateY:200</code>, <code>translateZ:50</code> => <code>translate3d:[150,200,50]</code> is quite the difference.</li>
<li>On larger amount of elements animating chains, the <code>.fromTo()</code> method is fastest, and you will have more work to do as well, but will eliminate any delay / syncronization issue that may occur.</li>
<li>This component is bundled with the <i>demo/src/kute-base.js</i> and the standard <i>kute.js</i> distribution files.</li>
</ul>
</div>
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2020 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
<p>Note in this example, the first tween object uses the element's <code>perspective</code> while the second relies on the parent's perspective.</p>
<h3>Chained Transformations</h3>
<p>KUTE.js has the ability to stack transform functions in a way to improve performance and optimize your workflow. In that idea the <code>.to()</code> method can be the right choice for most of your
animation needs and especially to link animations together because it has the ability to check the current values of the transform functions found in the element's inline styling, mostly from previous
tween animation, and use them as start values for the next animation. OK now, let's see a side by side comparison with 4 elements:</p>
<div id="chainedTweens" class="featurettes">
<div class="example-item example-box bg-gray" style="font-size: 30px">FROMTO</div>
<div class="example-item example-box bg-olive" style="font-size: 30px">FROMTO</div>
<div class="example-item example-box bg-gray" style="font-size: 30px">TO</div>
<div class="example-item example-box bg-blue" style="font-size: 30px">TO</div>
<div class="example-buttons">
<a class="btn btn-blue" href="#">Start</a>
</div>
</div>
<h4>Observations</h4>
<ul>
<li>The example hopefully demostrates what the animation looks like with different combinations of transform functions and how to combine them to optimize your workflow, size on disk as well as to how
to link animations together in a smooth continuous animation.</li>
<li>No matter the input values, the component will always stack translations into <code>translate3d</code> and rotations into <code>rotate3d</code>.</li>
<li>The first box uses a regular <code class="bg-gray">.fromTo()</code> object, from point A to B and back to A, with the exact coordinates we want.</li>
<li>The second box is also using <code class="bg-olive">.fromTo()</code> object, but using all values for all tweens at all times, so we gave the animation a sense of continuity.</li>
<li>The third box uses the <code class="bg-gray">.to()</code> method, and will try and continue animation from last animation, but we "forgot" to keep track on the rotation of the X axis.</li>
<li>The last box also uses the <code class="bg-blue">.to()</code> method, and uses all values and reproduce the animation of the second box exactly, but with nearly half the code.</li>
</ul>
<h3>Notes</h3>
<ul>
<li>This demo page should work with IE10+ browsers.</li>
<li>The order of the transform functions/properties is always the same: <code>perspective</code>, <code>translation</code>, <code>rotation</code>, <code>skew</code>, <code>scale</code>, this way we can prevent
jumpy/janky animations; one of the reasons is consistency in all transform based components and another reason is the order of execution from the draft for
<a href="https://drafts.csswg.org/css-transforms-2/#recomposing-to-a-3d-matrix">matrix3d recomposition</a>.</li>
<li>Tests reveal that an element's own perspective produce better performance than using the parent's perspective. Also having both will severelly punish the animation performance, so keep that in mind
when you work on optimizing your code. </li>
<li>Use single axis transform functions like <code>translateX</code> when you want to animate the Y and Z axes back to ZERO, but in a convenient way.</li>
<li>Use shorthand functions like <code>translate3d</code> when you want to animate / keep multiple axes.</li>
<li>Shorthand functions like <code>translate3d</code> or <code>rotate3d</code> tween property generally not only improve performance, but will also minimize the code size. Eg. <code>translateX:150</code>,
<code>translateY:200</code>, <code>translateZ:50</code> => <code>translate3d:[150,200,50]</code> is quite the difference.</li>
<li>On larger amount of elements animating chains, the <code>.fromTo()</code> method is fastest, and you will have more work to do as well, but will eliminate any delay / syncronization issue that may occur.</li>
<li>This component is bundled with the <i>demo/src/kute-base.js</i> and the standard <i>kute.js</i> distribution files.</li>
</ul>
</div>
<!-- /.site-wrapper -->
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2021 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
<!-- <script src="./src/polyfill-legacy.min.js"></script> -->
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute.js"></script>
<!-- <script src="../dist/kute.js"></script> -->
<script src="./assets/js/prism.js"></script>
</div>
<!-- /.site-wrapper -->
<script src="./assets/js/transformFunctions.js"></script>
<script src="./assets/js/scripts.js"></script>
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<!-- <script src="./src/polyfill-legacy.min.js"></script> -->
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute.min.js"></script>
<!-- <script src="../dist/kute.js"></script> -->
<script src="./assets/js/prism.js"></script>
<script src="./assets/js/transformFunctions.js"></script>
<script src="./assets/js/scripts.js"></script>
</body>
</html>

View file

@ -1,142 +1,142 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="The transformFunctions component for KUTE.js to enable your regular transform animations.">
<meta name="keywords" content="css3 transform matrix,transform,matrix3d,kute,kute.js,animation,javascript animation,tweening engine,animation engine,JavaScript,Native JavaScript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
<meta name="description" content="The transformFunctions component for KUTE.js to enable your regular transform animations.">
<meta name="keywords" content="css3 transform matrix,transform,matrix3d,kute,kute.js,animation,javascript animation,tweening engine,animation engine,JavaScript,Native JavaScript,vanilla javascript,jQuery">
<meta name="author" content="dnp_theme">
<link rel="shortcut icon" href="./assets/img/favicon.ico">
<link rel="apple-touch-icon" href="./assets/img/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,800|Roboto+Condensed:400,800" rel="stylesheet">
<title>KUTE.js Transform Matrix</title>
<title>KUTE.js Transform Matrix</title>
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- RESET CSS -->
<link type="text/css" href="./assets/css/reset.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- DEMO KUTE CSS -->
<link type="text/css" href="./assets/css/kute.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
<!-- Synthax highlighter -->
<link href="./assets/css/prism.css" rel="stylesheet">
</head>
<body>
<div class="site-wrapper">
<div class="site-wrapper">
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-space">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li class="active"><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
<div class="navbar-wrapper">
<div class="content-wrap">
<nav class="navbar">
<a href="index.html"><h1>KUTE.<span>js</span></h1></a>
<div class="nav-wrapper d-flex align-items-center justify-content-between">
<ul class="nav">
<li class="btn-group active"><a href="#" data-function="toggle">Components <span class="caret"></span></a>
<ul class="subnav">
<li><a href="transformFunctions.html">Transform Functions</a></li>
<li class="active"><a href="transformMatrix.html">Transform Matrix</a></li>
<li><a href="svgTransform.html">SVG Transform</a></li>
<li><a href="svgMorph.html">SVG Morph</a></li>
<li><a href="svgCubicMorph.html">SVG Cubic Morph</a></li>
<li><a href="svgDraw.html">SVG Draw</a></li>
<li><a href="filterEffects.html">Filter Effects</a></li>
<li><a href="borderRadius.html">Border Radius</a></li>
<li><a href="htmlAttributes.html">HTML Attributes</a></li>
<li><a href="shadowProperties.html">Shadow Properties</a></li>
<li><a href="colorProperties.html">Color Properties</a></li>
<li><a href="boxModel.html">Box Model</a></li>
<li><a href="clipProperty.html">Clip Property</a></li>
<li><a href="backgroundPosition.html">Background Position</a></li>
<li><a href="textProperties.html">Text Properties</a></li>
<li><a href="opacityProperty.html">Opacity Property</a></li>
<li><a href="scrollProperty.html">Scroll Property</a></li>
<li><a href="textWrite.html">Text Write</a></li>
</ul>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
<li><a href="https://github.com/thednp/kute.js/wiki">Wiki</a></li>
</ul>
<ul id="share">
<li>
<a class="facebook-link" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Facebook">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M1008 511.996c0 247.56-181.381 452.76-418.5 490v-346.62h115.561l22-143.381h-137.561v-93.1c0-39.221 19.221-77.461 80.82-77.461h62.561v-122s-56.762-9.68-111.041-9.68c-113.34 0-187.34 68.66-187.34 192.961v109.279h-126v143.381h126v346.62c-237.12-37.24-418.5-242.44-418.5-490 0-274 222-496 496-496s496 222 496 496z" fill="currentColor"></path></svg>
</a>
</li>
<li>
<a class="twitter-link" target="_blank" href="https://twitter.com/intent/tweet?text=Spread the word about %23KUTEJS animation engine by @dnp_theme and download here http://thednp.github.io/kute.js/index.html" title="Share KUTE.js on Twitter">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path class="icon-demo" d="M886.579 306.995c0.41 8.294 0.563 16.691 0.563 24.986 0 255.488-194.406 549.99-549.888 549.99-109.21 0-210.739-32-296.294-86.886 15.155 1.792 30.515 2.714 46.08 2.714 90.624 0 173.926-30.925 240.026-82.688-84.531-1.587-155.955-57.395-180.531-134.195 11.776 2.202 23.91 3.379 36.352 3.379 17.664 0 34.765-2.304 50.944-6.707-88.422-17.818-155.034-95.898-155.034-189.594 0-0.819 0-1.587 0-2.406 26.061 14.49 55.91 23.194 87.552 24.218-51.866-34.714-86.016-93.798-86.016-160.922 0-35.379 9.523-68.608 26.214-97.178 95.283 116.992 237.773 193.894 398.387 201.984-3.277-14.182-4.966-28.877-4.966-44.083 0-106.701 86.477-193.178 193.229-193.178 55.603 0 105.83 23.398 141.107 60.979 43.981-8.704 85.35-24.781 122.726-46.899-14.438 45.107-45.107 82.995-84.992 106.906 39.117-4.71 76.288-15.002 111.002-30.413-25.907 38.81-58.675 72.806-96.461 99.994z" fill="currentColor"></path></svg>
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
</nav>
</div>
</div>
<div class="content-wrap">
<h2 class="head-title">Transform Matrix</h2>
<p class="condensed lead">The component covers all 3D <i>transform</i> functions and renders the update with either <i>matrix()</i> or <i>matrix3d()</i> functions, depending on the
functions used and their values. The notation is also fairly easy to use and familiar with other components.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<h2 class="head-title">Transform Matrix</h2>
<p class="condensed lead">The component covers all 3D <i>transform</i> functions and renders the update with either <i>matrix()</i> or <i>matrix3d()</i> functions, depending on the
functions used and their values. The notation is also fairly easy to use and familiar with other components.</p>
</div>
<div class="featurettes dark">
<div class="content-wrap">
<div class="columns">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">The brand new component to enable complex <b>transform</b> animations of the future.</p>
</div>
<div class="col9 border">
<p class="lead condensed">The KUTE.js <b>Transform Matrix</b> component covers animation for the CSS3 <b>transform</b> style on <b>Element</b> targets but with a different implementation.</p>
<ul>
<li>The notation is a little different because we have a different supported functions/properties set, and the value processing function needs to differentiate the two components.</li>
<li>The 2D transform functions like <b>rotate</b>, <b>translate</b> or <b>scale</b> have been dropped to enable faster value processing and improved performance. The component is
geared towards the future of web development with this very specific purpose in mind.</li>
<li>Most importantly we have the update function which implements the <a href="https://developer.mozilla.org/en-US/docs/Web/API/DOMMatrix">DOMMatrix()</a> API for smooth animation at no
performance cost, which is different from other libraries that use a <b>webkitCSSMatrix</b> polyfill and lose performance.</li>
<li>The script is robust, simple and light in size. It's simply a matter of taste when choosing between the two transform components.</li>
</ul>
<p>The component was developed for more complex transform animations and comes with additional supported transform functions. According to the W3 draft, the <b>DOMMatrix</b> API will merge the
fallback <b>webkitCSSMatrix</b> API and the <b>SVGMatrix</b> API together, so awesome is yet to come.</p>
<p>Due to execution complexity and other performance considerations, and similar to the <a href="transformFunctions.html">Transform Functions</a> component, this component provides support for a custom
<b>rotate3d[X,Y,Z]</b> tween property which is different from CSS3 standard <b>rotate3d(x,y,z,Angle)</b> shorthand function.</p>
<p>In certain situations you can also use functions like <b>scaleX</b>, <b>rotateY</b> or <b>translateZ</b> for convenience, but the component will always stack translations
into <b>translate3d</b>, all scale axes into <b>scale3d</b>, all rotations into <b>rotate3d</b> and both skews into <b>skew</b>.</p>
</div>
<div class="columns">
<div class="col3">
<h3 class="border text-right">Overview</h3>
<p class="condensed text-right">The brand new component to enable complex <b>transform</b> animations of the future.</p>
</div>
<div class="col9 border">
<p class="lead condensed">The KUTE.js <b>Transform Matrix</b> component covers animation for the CSS3 <b>transform</b> style on <b>Element</b> targets but with a different implementation.</p>
<ul>
<li>The notation is a little different because we have a different supported functions/properties set, and the value processing function needs to differentiate the two components.</li>
<li>The 2D transform functions like <b>rotate</b>, <b>translate</b> or <b>scale</b> have been dropped to enable faster value processing and improved performance. The component is
geared towards the future of web development with this very specific purpose in mind.</li>
<li>Most importantly we have the update function which implements the <a href="https://developer.mozilla.org/en-US/docs/Web/API/DOMMatrix">DOMMatrix()</a> API for smooth animation at no
performance cost, which is different from other libraries that use a <b>webkitCSSMatrix</b> polyfill and lose performance.</li>
<li>The script is robust, simple and light in size. It's simply a matter of taste when choosing between the two transform components.</li>
</ul>
<p>The component was developed for more complex transform animations and comes with additional supported transform functions. According to the W3 draft, the <b>DOMMatrix</b> API will merge the
fallback <b>webkitCSSMatrix</b> API and the <b>SVGMatrix</b> API together, so awesome is yet to come.</p>
<p>Due to execution complexity and other performance considerations, and similar to the <a href="transformFunctions.html">Transform Functions</a> component, this component provides support for a custom
<b>rotate3d[X,Y,Z]</b> tween property which is different from CSS3 standard <b>rotate3d(x,y,z,Angle)</b> shorthand function.</p>
<p>In certain situations you can also use functions like <b>scaleX</b>, <b>rotateY</b> or <b>translateZ</b> for convenience, but the component will always stack translations
into <b>translate3d</b>, all scale axes into <b>scale3d</b>, all rotations into <b>rotate3d</b> and both skews into <b>skew</b>.</p>
</div>
</div>
</div>
</div>
<div class="content-wrap">
<h3>3D Transform</h3>
<ul>
<li><kbd class="bg-indigo">perspective</kbd> function creates a 3D perspective for a target element transformation. EG. <code>perspective:400</code> to apply a 400px perspective.</li>
<li><kbd class="bg-indigo">translateX</kbd> function is for horizontal translation. EG. <code>translateX:150</code> to translate an element 150px to the right.</li>
<li><kbd class="bg-indigo">translateY</kbd> function is for vertical translation. EG. <code>translateY:-250</code> to translate an element 250px towards the top.</li>
<li><kbd class="bg-indigo">translateZ</kbd> function is for translation on the Z axis in a given 3D field. EG. <code>translateZ:-250</code> to translate an element 250px away from the viewer, making it
appear smaller. This function can be combined with the <code>perspective</code> function to take effect or the parent's perspective; the smaller perspective value, the deeper translation.</li>
<li><kbd class="bg-indigo">translate3d</kbd> shorthand function is for translation on all the axes in a given 3D field. EG. <code>translate3d:[-150,200,150]</code> to translate an element 150px to the left, 200px
to the bottom and 150px closer to the viewer, making it larger. When third value is used, it requires using a <code>perspective</code>.</li>
<li><kbd class="bg-indigo">rotateX</kbd> function rotates an element on the X axis in a given 3D field. Eg. <code>rotateX:250</code> will rotate an element clockwise by 250 degrees on X axis.
Requires perspective.</li>
<li><kbd class="bg-indigo">rotateY</kbd> function rotates an element on the Y axis in a given 3D field. Eg. <code>rotateY:-150</code> will rotate an element counter-clockwise by 150 degrees on Y axis.
Requires perspective.</li>
<li><kbd class="bg-indigo">rotateZ</kbd> function rotates an element on the Z axis and is the equivalent of the 2D rotation. Eg. <code>rotateZ:90</code> will rotate an element clockwise by 90 degrees on Z axis.</li>
<li><kbd class="bg-indigo">rotate3d</kbd> is a <b>tween property</b>, which combines the above <code>rotateX</code>, <code>rotateY</code>, and <code>rotateZ</code> functions and rotates an element on all axes.
Eg. <code>rotate3d:[250,-150,90]</code> will produce the same effect as the three above combined. The X and Y axes require a <code>perspective</code>.</li>
<li><kbd class="bg-indigo">skewX</kbd> function will apply a shear to a target element on the X axis. Eg. <code>skewX:50</code> will skew the element by 50 degrees on X axis.</li>
<li><kbd class="bg-indigo">skewY</kbd> function will apply a shear to a target element on the Y axis. Eg. <code>skewY:-50</code> will skew the element by -50 degrees on Y axis.</li>
<li><kbd class="bg-indigo">skew</kbd> shorthand function will apply a shear on both X and Y axes to a target element. Eg. <code>skew:[50,50]</code> will skew a target element on X axis by 50 degrees and 50 degrees on Y axis.</li>
<li><kbd class="bg-indigo">scaleX</kbd> function will scale the X axis of a target element. Eg. <code>scaleX:1.5</code> will increase the scale of a target element on the X axis by 50%.</li>
<li><kbd class="bg-indigo">scaleY</kbd> function will scale the Y axis of a target element. Eg. <code>scaleY:0.5</code> will decrease the scale of a target element on the Y axis by 50%.</li>
<li><kbd class="bg-indigo">scaleZ</kbd> function will scale the Z axis of a target element. Eg. <code>scaleZ:0.75</code> will decrease the scale of a target element on the Z axis by 25%.</li>
<li><kbd class="bg-indigo">scale3d</kbd> function will scale a target element on all axes. Eg. <code>scale3d:[1.5,0.5,0.75]</code> will produce the same effect as the 3 above combined.</li>
<li><kbd class="bg-blue">matrix</kbd> and <kbd class="bg-blue">matrix3d</kbd> are not supported CSS3 transform functions or tween properties, but the results of the update function.</li>
</ul>
<div class="content-wrap">
<h3>3D Transform</h3>
<ul>
<li><kbd class="bg-indigo">perspective</kbd> function creates a 3D perspective for a target element transformation. EG. <code>perspective:400</code> to apply a 400px perspective.</li>
<li><kbd class="bg-indigo">translateX</kbd> function is for horizontal translation. EG. <code>translateX:150</code> to translate an element 150px to the right.</li>
<li><kbd class="bg-indigo">translateY</kbd> function is for vertical translation. EG. <code>translateY:-250</code> to translate an element 250px towards the top.</li>
<li><kbd class="bg-indigo">translateZ</kbd> function is for translation on the Z axis in a given 3D field. EG. <code>translateZ:-250</code> to translate an element 250px away from the viewer, making it
appear smaller. This function can be combined with the <code>perspective</code> function to take effect or the parent's perspective; the smaller perspective value, the deeper translation.</li>
<li><kbd class="bg-indigo">translate3d</kbd> shorthand function is for translation on all the axes in a given 3D field. EG. <code>translate3d:[-150,200,150]</code> to translate an element 150px to the left, 200px
to the bottom and 150px closer to the viewer, making it larger. When third value is used, it requires using a <code>perspective</code>.</li>
<li><kbd class="bg-indigo">rotateX</kbd> function rotates an element on the X axis in a given 3D field. Eg. <code>rotateX:250</code> will rotate an element clockwise by 250 degrees on X axis.
Requires perspective.</li>
<li><kbd class="bg-indigo">rotateY</kbd> function rotates an element on the Y axis in a given 3D field. Eg. <code>rotateY:-150</code> will rotate an element counter-clockwise by 150 degrees on Y axis.
Requires perspective.</li>
<li><kbd class="bg-indigo">rotateZ</kbd> function rotates an element on the Z axis and is the equivalent of the 2D rotation. Eg. <code>rotateZ:90</code> will rotate an element clockwise by 90 degrees on Z axis.</li>
<li><kbd class="bg-indigo">rotate3d</kbd> is a <b>tween property</b>, which combines the above <code>rotateX</code>, <code>rotateY</code>, and <code>rotateZ</code> functions and rotates an element on all axes.
Eg. <code>rotate3d:[250,-150,90]</code> will produce the same effect as the three above combined. The X and Y axes require a <code>perspective</code>.</li>
<li><kbd class="bg-indigo">skewX</kbd> function will apply a shear to a target element on the X axis. Eg. <code>skewX:50</code> will skew the element by 50 degrees on X axis.</li>
<li><kbd class="bg-indigo">skewY</kbd> function will apply a shear to a target element on the Y axis. Eg. <code>skewY:-50</code> will skew the element by -50 degrees on Y axis.</li>
<li><kbd class="bg-indigo">skew</kbd> shorthand function will apply a shear on both X and Y axes to a target element. Eg. <code>skew:[50,50]</code> will skew a target element on X axis by 50 degrees and 50 degrees on Y axis.</li>
<li><kbd class="bg-indigo">scaleX</kbd> function will scale the X axis of a target element. Eg. <code>scaleX:1.5</code> will increase the scale of a target element on the X axis by 50%.</li>
<li><kbd class="bg-indigo">scaleY</kbd> function will scale the Y axis of a target element. Eg. <code>scaleY:0.5</code> will decrease the scale of a target element on the Y axis by 50%.</li>
<li><kbd class="bg-indigo">scaleZ</kbd> function will scale the Z axis of a target element. Eg. <code>scaleZ:0.75</code> will decrease the scale of a target element on the Z axis by 25%.</li>
<li><kbd class="bg-indigo">scale3d</kbd> function will scale a target element on all axes. Eg. <code>scale3d:[1.5,0.5,0.75]</code> will produce the same effect as the 3 above combined.</li>
<li><kbd class="bg-blue">matrix</kbd> and <kbd class="bg-blue">matrix3d</kbd> are not supported CSS3 transform functions or tween properties, but the results of the update function.</li>
</ul>
<h3>Example</h3>
<p>Now let's have a look at the notation and a quick example:</p>
<h3>Example</h3>
<p>Now let's have a look at the notation and a quick example:</p>
<pre><code class="language-javascript">let mx1 = KUTE.to('el1', { transform: { translate3d:[-50,-50,-50]} })
let mx2 = KUTE.to('el2', { transform: { perspective: 100, translateX: -50, rotateX:-180} })
@ -144,71 +144,71 @@ let mx3 = KUTE.to('el3', { transform: { translate3d:[-50,-50,-50], skew:[-15,-15
let mx4 = KUTE.to('el4', { transform: { translate3d:[-50,-50,-50], rotate3d:[0,-360,0], scaleX:0.5 } })
</code></pre>
<div id="matrix-examples" class="featurettes" style="perspective: 400px">
<div class="example-item example-box bg-indigo">MX1</div>
<div class="example-item example-box bg-olive">MX2</div>
<div class="example-item example-box bg-pink">MX3</div>
<div class="example-item example-box bg-red">MX4</div>
<div id="matrix-examples" class="featurettes" style="perspective: 400px">
<div class="example-item example-box bg-indigo">MX1</div>
<div class="example-item example-box bg-olive">MX2</div>
<div class="example-item example-box bg-pink">MX3</div>
<div class="example-item example-box bg-red">MX4</div>
<div class="example-buttons">
<a class="btn btn-blue" href="javascript:void(0)">Start</a>
</div>
<div class="example-buttons">
<a class="btn btn-blue" href="javascript:void(0)">Start</a>
</div>
<p>So the second element uses it's own perspective but notice that the parent perspective also apply. This case must be avoided in order to keep performance in check: one perspective is best.</p>
</div>
<p>So the second element uses it's own perspective but notice that the parent perspective also apply. This case must be avoided in order to keep performance in check: one perspective is best.</p>
<h3>Chained Transformations</h3>
<p>Similar to the <a href="transformFunctions.html">other component</a> the Transform Matrix component will produce the same visual experience, but with the <code>matrix3d</code> function.</p>
<div id="chainedTweens" class="featurettes">
<div class="example-item example-box bg-gray" style="font-size: 30px">FROMTO</div>
<div class="example-item example-box bg-olive" style="font-size: 30px">FROMTO</div>
<div class="example-item example-box bg-gray" style="font-size: 30px">TO</div>
<div class="example-item example-box bg-indigo" style="font-size: 30px">TO</div>
<h3>Chained Transformations</h3>
<p>Similar to the <a href="transformFunctions.html">other component</a> the Transform Matrix component will produce the same visual experience, but with the <code>matrix3d</code> function.</p>
<div id="chainedTweens" class="featurettes">
<div class="example-item example-box bg-gray" style="font-size: 30px">FROMTO</div>
<div class="example-item example-box bg-olive" style="font-size: 30px">FROMTO</div>
<div class="example-item example-box bg-gray" style="font-size: 30px">TO</div>
<div class="example-item example-box bg-indigo" style="font-size: 30px">TO</div>
<div class="example-buttons">
<a class="btn btn-blue" href="#">Start</a>
</div>
<div class="example-buttons">
<a class="btn btn-blue" href="#">Start</a>
</div>
<h3>Notes</h3>
<ul>
<li>This demo page should work with IE10+ browsers.</li>
<li>Why no support for the <code>matrix3d</code> function? Simple: we can of course interpolate 16 numbers super fast, but we won't be able to rotate on any axis above 360 degrees.
As <a href="https://stackoverflow.com/a/39870758/803358">explained here</a>, surely for performance reasons the browsers won't try and compute angles above 360 degrees, but simplify
the number crunching because a 370 degree rotation is visualy identical with a 10 degree rotation.</li>
<li>The component does NOT include any scripting for matrix decomposition/unmatrix, after several years of research I came to the conclusion that there is no such thing to be reliable.
Such a feature would allow us to kick start animations directly from <code>matrix3d</code> string/array values, but considering the size of this component, I let you draw the conclusions.</li>
<li>Despite the "limitations", we have some tricks available: the <code>fromTo()</code> method will never fail and it's much better when performance and sync are a must, and for <code>to()</code>
method we're storing the values from previous animations to have them ready and available for the next chained animation.</li>
<li>The performance of this component is identical with the <b>Transform Functions</b> component, which is crazy and awesome, all that thanks to the <b>DOMMatrix</b> API built into our modern browsers.
If that's not good enough, the API will automatically switch from <code>matrix3d</code> to <code>matrix</code> and vice-versa whenever needed to save power. Neat?</li>
<li>The <code>rotate3d</code> property makes alot more sense for this component since the <b>DOMMatrix</b> <code>rotate(angleX,angleY,angleZ)</code> method works exactly the same, while the
<code>rotate3d(vectorX,vectorY,vectorZ,angle)</code> function is a thing of the past, according to <a href="https://css-tricks.com/">Chris Coyier</a> nobody use it.</li>
<li>Since the component fully utilize the <b>DOMMatrix</b> API, with fallback to each browser compatible API, some browsers still have in 2020 an incomplete CSS3Matrix API, for instance privacy browsers
like Tor won't work with rotations properly for some reason, other proprietary mobile browsers may suffer from same symptoms. In these cases a correction polyfill is required.</li>
<li>This component is bundled with the <i>demo/src/kute-extra.js</i> distribution file.</li>
</ul>
</div>
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2020 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
<h3>Notes</h3>
<ul>
<li>This demo page should work with IE10+ browsers.</li>
<li>Why no support for the <code>matrix3d</code> function? Simple: we can of course interpolate 16 numbers super fast, but we won't be able to rotate on any axis above 360 degrees.
As <a href="https://stackoverflow.com/a/39870758/803358">explained here</a>, surely for performance reasons the browsers won't try and compute angles above 360 degrees, but simplify
the number crunching because a 370 degree rotation is visualy identical with a 10 degree rotation.</li>
<li>The component does NOT include any scripting for matrix decomposition/unmatrix, after several years of research I came to the conclusion that there is no such thing to be reliable.
Such a feature would allow us to kick start animations directly from <code>matrix3d</code> string/array values, but considering the size of this component, I let you draw the conclusions.</li>
<li>Despite the "limitations", we have some tricks available: the <code>fromTo()</code> method will never fail and it's much better when performance and sync are a must, and for <code>to()</code>
method we're storing the values from previous animations to have them ready and available for the next chained animation.</li>
<li>The performance of this component is identical with the <b>Transform Functions</b> component, which is crazy and awesome, all that thanks to the <b>DOMMatrix</b> API built into our modern browsers.
If that's not good enough, the API will automatically switch from <code>matrix3d</code> to <code>matrix</code> and vice-versa whenever needed to save power. Neat?</li>
<li>The <code>rotate3d</code> property makes alot more sense for this component since the <b>DOMMatrix</b> <code>rotate(angleX,angleY,angleZ)</code> method works exactly the same, while the
<code>rotate3d(vectorX,vectorY,vectorZ,angle)</code> function is a thing of the past, according to <a href="https://css-tricks.com/">Chris Coyier</a> nobody use it.</li>
<li>Since the component fully utilize the <b>DOMMatrix</b> API, with fallback to each browser compatible API, some browsers still have in 2020 an incomplete CSS3Matrix API, for instance privacy browsers
like Tor won't work with rotations properly for some reason, other proprietary mobile browsers may suffer from same symptoms. In these cases a correction polyfill is required.</li>
<li>This component is bundled with the <i>demo/src/kute-extra.js</i> distribution file.</li>
</ul>
</div>
<!-- /.site-wrapper -->
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<!-- FOOTER -->
<footer>
<div class="content-wrap">
<p class="pull-right"><a id="toTop" href="#">Back to top</a></p>
<p>&copy; 2015 - 2021 &middot; <a href="https://github.com/thednp">thednp</a>.</p>
</div>
</footer>
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute-extra.min.js"></script>
<script src="./assets/js/prism.js"></script>
</div>
<!-- /.site-wrapper -->
<script src="./assets/js/transformMatrix.js"></script>
<script src="./assets/js/scripts.js"></script>
<!-- JavaScript =============================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute-extra.min.js"></script>
<script src="./assets/js/prism.js"></script>
<script src="./assets/js/transformMatrix.js"></script>
<script src="./assets/js/scripts.js"></script>
</body>
</html>

5622
dist/kute.esm.js vendored

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

5094
dist/kute.js vendored

File diff suppressed because it is too large Load diff

4
dist/kute.min.js vendored

File diff suppressed because one or more lines are too long

215
dist/polyfill.js vendored
View file

@ -1,93 +1,140 @@
/*!
* KUTE.js Polyfill v2.0.9 (http://thednp.github.io/kute.js)
* Copyright 2015-2020 © thednp
* KUTE.js Polyfill v2.1.1-alpha1 (http://thednp.github.io/kute.js)
* Copyright 2015-2021 © thednp
* Licensed under MIT (https://github.com/thednp/bootstrap.native/blob/master/LICENSE)
*/
"use strict";
if (!Array.from) {
Array.from = (function () {
var toStr = Object.prototype.toString;
var isCallable = function (fn) {
return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
};
var toInteger = function (value) {
var number = Number(value);
if (isNaN(number)) { return 0; }
if (number === 0 || !isFinite(number)) { return number; }
return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
};
var maxSafeInteger = Math.pow(2, 53) - 1;
var toLength = function (value) {
var len = toInteger(value);
return Math.min(Math.max(len, 0), maxSafeInteger);
};
return function from(arrayLike) {
var C = this, items = Object(arrayLike);
if (arrayLike == null) {
throw new TypeError('Array.from requires an array-like object - not null or undefined');
}
var mapFn = arguments.length > 1 ? arguments[1] : void undefined, T;
if (typeof mapFn !== 'undefined') {
if (!isCallable(mapFn)) {
throw new TypeError('Array.from: when provided, the second argument must be a function');
}
if (arguments.length > 2) {
T = arguments[2];
}
}
var len = toLength(items.length);
var A = isCallable(C) ? Object(new C(len)) : new Array(len);
var k = 0;
var kValue;
while (k < len) {
kValue = items[k];
if (mapFn) {
A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
} else {
A[k] = kValue;
}
k += 1;
}
A.length = len;
return A;
}
}());
if (!Array.from) {
Array.from = (function () {
var toStr = Object.prototype.toString;
var isCallable = function (fn) {
return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
};
var toInteger = function (value) {
var number = Number(value);
if (isNaN(number)) { return 0; }
if (number === 0 || !isFinite(number)) { return number; }
return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
};
var maxSafeInteger = Math.pow(2, 53) - 1;
var toLength = function (value) {
var len = toInteger(value);
return Math.min(Math.max(len, 0), maxSafeInteger);
};
return function from(arrayLike/*, mapFn, thisArg */) {
var C = this, items = Object(arrayLike);
if (arrayLike == null) {
throw new TypeError('Array.from requires an array-like object - not null or undefined');
}
var mapFn = arguments.length > 1 ? arguments[1] : void undefined, T;
if (typeof mapFn !== 'undefined') {
if (!isCallable(mapFn)) {
throw new TypeError('Array.from: when provided, the second argument must be a function');
}
if (arguments.length > 2) {
T = arguments[2];
}
}
var len = toLength(items.length);
var A = isCallable(C) ? Object(new C(len)) : new Array(len);
var k = 0;
var kValue;
while (k < len) {
kValue = items[k];
if (mapFn) {
A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
} else {
A[k] = kValue;
}
k += 1;
}
A.length = len;
return A;
}
}());
}
if (!Array.prototype.includes) {
Array.prototype.includes = function(searchElement ) {
var O = Object(this);
var len = parseInt(O.length) || 0;
if (len === 0) {
return false;
}
var n = parseInt(arguments[1]) || 0;
var k;
if (n >= 0) {
k = n;
} else {
k = len + n;
if (k < 0) {k = 0;}
}
var currentElement;
while (k < len) {
currentElement = O[k];
if (searchElement === currentElement ||
(searchElement !== searchElement && currentElement !== currentElement)) {
return true;
}
k++;
}
return false;
};
// https://github.com/jonathantneal/array-flat-polyfill/blob/master/src/polyfill-flat.js
if (!Array.prototype.flat) {
Object.defineProperty(Array.prototype, 'flat', {
configurable: true,
value: function flat () {
var depth = isNaN(arguments[0]) ? 1 : Number(arguments[0]);
return depth ? Array.prototype.reduce.call(this, function (acc, cur) {
if (Array.isArray(cur)) {
acc.push.apply(acc, flat.call(cur, depth - 1));
} else {
acc.push(cur);
}
return acc;
}, []) : Array.prototype.slice.call(this);
},
writable: true
});
}
if (!String.prototype.includes) {
String.prototype.includes = function(search, start) {
if (search instanceof RegExp) {
throw TypeError('first argument must not be a RegExp');
}
if (start === undefined) { start = 0; }
return this.indexOf(search, start) !== -1;
};
if (!Array.prototype.includes) {
Array.prototype.includes = function(searchElement /*, fromIndex*/ ) {
var O = Object(this);
var len = parseInt(O.length) || 0;
if (len === 0) {
return false;
}
var n = parseInt(arguments[1]) || 0;
var k;
if (n >= 0) {
k = n;
} else {
k = len + n;
if (k < 0) {k = 0;}
}
var currentElement;
while (k < len) {
currentElement = O[k];
if (searchElement === currentElement ||
(searchElement !== searchElement && currentElement !== currentElement)) {
return true;
}
k++;
}
return false;
};
}
if (!String.prototype.includes) {
String.prototype.includes = function(search, start) {
if (search instanceof RegExp) {
throw TypeError('first argument must not be a RegExp');
}
if (start === undefined) { start = 0; }
return this.indexOf(search, start) !== -1;
};
}
if (!Number.isFinite) {
Number.isFinite = function(value) {
return typeof value === 'number'
&& isFinite(value);
};
}
if (!Number.isInteger) {
Number.isInteger = function(value) {
return typeof value === 'number'
&& isFinite(value)
&& Math.floor(value) === value;
};
}
if (!Number.isNaN) {
Number.isNaN = function(value) {
return typeof value === 'number'
&& value !== value;
};
}

View file

@ -1,3 +1,3 @@
// KUTE.js Polyfill v2.0.9 | 2020 © thednp | MIT-License
// KUTE.js Polyfill v2.1.1-alpha1 | 2021 © thednp | MIT-License
"use strict";
var r,t,n,e;Array.from||(Array.from=(r=Object.prototype.toString,t=function(t){return"function"==typeof t||"[object Function]"===r.call(t)},n=Math.pow(2,53)-1,e=function(r){var t=function(r){var t=Number(r);return isNaN(t)?0:0!==t&&isFinite(t)?(t>0?1:-1)*Math.floor(Math.abs(t)):t}(r);return Math.min(Math.max(t,0),n)},function(r){var n=this,o=Object(r);if(null==r)throw new TypeError("Array.from requires an array-like object - not null or undefined");var i,a=arguments.length>1?arguments[1]:void 0;if(void 0!==a){if(!t(a))throw new TypeError("Array.from: when provided, the second argument must be a function");arguments.length>2&&(i=arguments[2])}for(var u,f=e(o.length),c=t(n)?Object(new n(f)):new Array(f),p=0;p<f;)u=o[p],c[p]=a?void 0===i?a(u,p):a.call(i,u,p):u,p+=1;return c.length=f,c})),Array.prototype.includes||(Array.prototype.includes=function(r){var t=Object(this),n=parseInt(t.length)||0;if(0===n)return!1;var e,o,i=parseInt(arguments[1])||0;for(i>=0?e=i:(e=n+i)<0&&(e=0);e<n;){if(r===(o=t[e])||r!=r&&o!=o)return!0;e++}return!1}),String.prototype.includes||(String.prototype.includes=function(r,t){if(r instanceof RegExp)throw TypeError("first argument must not be a RegExp");return void 0===t&&(t=0),-1!==this.indexOf(r,t)});
var r,t,e,n;Array.from||(Array.from=(r=Object.prototype.toString,t=function(t){return"function"==typeof t||"[object Function]"===r.call(t)},e=Math.pow(2,53)-1,n=function(r){var t=function(r){var t=Number(r);return isNaN(t)?0:0!==t&&isFinite(t)?(t>0?1:-1)*Math.floor(Math.abs(t)):t}(r);return Math.min(Math.max(t,0),e)},function(r){var e=this,i=Object(r);if(null==r)throw new TypeError("Array.from requires an array-like object - not null or undefined");var o,a=arguments.length>1?arguments[1]:void 0;if(void 0!==a){if(!t(a))throw new TypeError("Array.from: when provided, the second argument must be a function");arguments.length>2&&(o=arguments[2])}for(var u,f=n(i.length),p=t(e)?Object(new e(f)):new Array(f),c=0;c<f;)u=i[c],p[c]=a?void 0===o?a(u,c):a.call(o,u,c):u,c+=1;return p.length=f,p})),Array.prototype.flat||Object.defineProperty(Array.prototype,"flat",{configurable:!0,value:function r(){var t=isNaN(arguments[0])?1:Number(arguments[0]);return t?Array.prototype.reduce.call(this,(function(e,n){return Array.isArray(n)?e.push.apply(e,r.call(n,t-1)):e.push(n),e}),[]):Array.prototype.slice.call(this)},writable:!0}),Array.prototype.includes||(Array.prototype.includes=function(r){var t=Object(this),e=parseInt(t.length)||0;if(0===e)return!1;var n,i,o=parseInt(arguments[1])||0;for(o>=0?n=o:(n=e+o)<0&&(n=0);n<e;){if(r===(i=t[n])||r!=r&&i!=i)return!0;n++}return!1}),String.prototype.includes||(String.prototype.includes=function(r,t){if(r instanceof RegExp)throw TypeError("first argument must not be a RegExp");return void 0===t&&(t=0),-1!==this.indexOf(r,t)}),Number.isFinite||(Number.isFinite=function(r){return"number"==typeof r&&isFinite(r)}),Number.isInteger||(Number.isInteger=function(r){return"number"==typeof r&&isFinite(r)&&Math.floor(r)===r}),Number.isNaN||(Number.isNaN=function(r){return"number"==typeof r&&r!=r});

View file

@ -1,29 +1,34 @@
{
"name": "kute.js",
"version": "2.0.9",
"description": "JavaScript animation engine of the future is called KUTE.js.",
"version": "2.2.3",
"description": "JavaScript animation engine",
"main": "dist/kute.min.js",
"module": "dist/kute.esm.js",
"jsnext": "src/index.js",
"types": "types/index.d.ts",
"files": [
"dist/*.{js,map}",
"src/**/*.{js,map}",
"src/*.{js,map}"
"dist",
"types",
"src"
],
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"help": "rollup --help",
"build": "npm-run-all --parallel copy-build build-*",
"build1": "npm-run-all --parallel copy-build build-*",
"build": "npm run lint:js && npm-run-all --parallel copy-build build-*",
"custom": "rollup -c --environment",
"copy-build": "rollup -c --environment INPUTFILE:src/index.js,OUTPUTFILE:demo/src/kute.min.js,DIST:standard,MIN:true,FORMAT:umd -c",
"fix:js": "eslint src/ --config .eslintrc --fix",
"lint:js": "eslint src/ --config .eslintrc",
"copy-build": "rollup --environment OUTPUTFILE:demo/src/kute.min.js,DIST:standard,MIN:true,FORMAT:umd -c",
"build-standard": "rollup --environment DIST:standard,MIN:false,FORMAT:umd -c",
"build:ts": "tsc -d",
"build-standard-min": "rollup --environment DIST:standard,MIN:true,FORMAT:umd -c",
"build-standard-esm": "rollup --environment DIST:standard,MIN:false,FORMAT:esm -c",
"build-standard-esm-min": "rollup --environment DIST:standard,MIN:true,FORMAT:esm -c",
"build-base": "rollup --environment DIST:base,MIN:false,FORMAT:umd -c",
"build-base-min": "rollup --environment DIST:base,MIN:true,FORMAT:umd -c",
"build-extra": "rollup --environment DIST:extra,MIN:false,FORMAT:umd -c",
"build-extra-min": "rollup --environment DIST:extra,MIN:true,FORMAT:umd -c",
"build-base": "rollup --environment OUTPUTFILE:demo/src/kute-base.js,DIST:base,MIN:false,FORMAT:umd -c",
"build-base-min": "rollup --environment OUTPUTFILE:demo/src/kute-base.min.js,DIST:base,MIN:true,FORMAT:umd -c",
"build-extra": "rollup --environment OUTPUTFILE:demo/src/kute-extra.js,DIST:extra,MIN:false,FORMAT:umd -c",
"build-extra-min": "rollup --environment OUTPUTFILE:demo/src/kute-extra.min.js,DIST:extra,MIN:true,FORMAT:umd -c",
"polyfill": "npm-run-all --parallel polyfill-unminified polyfill-minified copy-polyfill copy-polyfill-legacy",
"copy-polyfill-legacy": "rollup --environment INPUTFILE:src/util/polyfill-legacy.js,OUTPUTFILE:demo/src/polyfill-legacy.min.js,MIN:true -c rollup.polyfill.js",
"copy-polyfill": "rollup --environment OUTPUTFILE:demo/src/polyfill.min.js,MIN:true -c rollup.polyfill.js",
@ -54,17 +59,22 @@
},
"homepage": "http://thednp.github.io/kute.js",
"dependencies": {
"cubic-bezier-easing": "^1.0.2",
"minifill": "^0.0.13",
"shorter-js": "^0.1.0"
"cubic-bezier-easing": "^1.0.18",
"minifill": "^0.0.16",
"shorter-js": "^0.2.6",
"svg-path-commander": "0.1.23"
},
"devDependencies": {
"@rollup/plugin-buble": "^0.21.3",
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^7.1.3",
"@rollup/plugin-node-resolve": "^9.0.0",
"eslint": "^7.22.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-vue": "^7.7.0",
"npm-run-all": "^4.1.5",
"rollup": "^1.32.1",
"rollup-plugin-cleanup": "^3.1.1",
"rollup-plugin-terser": "^5.3.0"
"rollup": "^2.38.4",
"rollup-plugin-terser": "^7.0.2",
"typescript": "^4.5.2"
}
}

View file

@ -2,7 +2,6 @@
import buble from '@rollup/plugin-buble'
import {terser} from 'rollup-plugin-terser'
import node from '@rollup/plugin-node-resolve'
import cleanup from 'rollup-plugin-cleanup'
import json from '@rollup/plugin-json'
import * as pkg from "./package.json"
@ -24,7 +23,7 @@ const banner =
const miniBanner = `// KUTE.js ${NAME} v${pkg.version} | ${pkg.author} © ${year} | ${pkg.license}-License`
INPUTFILE = INPUTFILE ? INPUTFILE : (DIST === 'standard' ? 'src/index.js' : 'src/index-'+DIST+'.js')
OUTPUTFILE = OUTPUTFILE ? OUTPUTFILE : ('demo/src/kute'+(DIST!=='standard'?'-'+DIST:'')+(FORMAT==='esm'?'.esm':'')+(MIN?'.min':'')+'.js')
OUTPUTFILE = OUTPUTFILE ? OUTPUTFILE : ('dist/kute'+(DIST!=='standard'?'-'+DIST:'')+(FORMAT==='esm'?'.esm':'')+(MIN?'.min':'')+'.js')
const OUTPUT = {
file: OUTPUTFILE,
@ -32,16 +31,18 @@ const OUTPUT = {
}
const PLUGINS = [
node({mainFields: ['jsnext', 'module']}),
node({mainFields: ['jsnext','module'], dedupe: ['svg-path-commander']}) ,
json(),
buble(),
]
if (FORMAT!=='esm'){
PLUGINS.push(buble({objectAssign: 'Object.assign'}));
}
if (MIN){
PLUGINS.push(terser({output: {preamble: miniBanner}}));
} else {
OUTPUT.banner = banner;
PLUGINS.push(cleanup());
}
if (FORMAT!=='esm') {

View file

@ -3,7 +3,6 @@ import buble from '@rollup/plugin-buble'
import node from '@rollup/plugin-node-resolve'
import json from '@rollup/plugin-json'
import {terser} from 'rollup-plugin-terser'
import cleanup from 'rollup-plugin-cleanup'
import * as pkg from "./package.json";
// set headers
@ -34,7 +33,6 @@ const PLUGINS = [
node(),
json(),
buble(),
cleanup()
]
if (MIN){

View file

@ -1,116 +1,137 @@
import supportedProperties from '../objects/supportedProperties.js'
import defaultValues from '../objects/defaultValues.js'
import defaultOptions from '../objects/defaultOptions.js'
import prepareProperty from '../objects/prepareProperty.js'
import prepareStart from '../objects/prepareStart.js'
import onStart from '../objects/onStart.js'
import onComplete from '../objects/onComplete.js'
import crossCheck from '../objects/crossCheck.js'
import linkProperty from '../objects/linkProperty.js'
import Util from '../objects/util.js'
import Interpolate from '../objects/interpolate.js'
// Animation class
// * builds KUTE components
// * populate KUTE objects
// * AnimatonBase creates a KUTE.js build for pre-made Tween objects
// * AnimatonDevelopment can help you debug your new components
export default class Animation {
constructor(Component){
try {
if ( Component.component in supportedProperties ) {
console.error(`KUTE.js - ${Component.component} already registered`);
} else if ( Component.property in defaultValues ) {
console.error(`KUTE.js - ${Component.property} already registered`);
} else {
this.setComponent(Component)
}
} catch(e){
console.error(e)
}
}
setComponent(Component){
const propertyInfo = this
const ComponentName = Component.component
// const Objects = { defaultValues, defaultOptions, Interpolate, linkProperty, Util }
const Functions = { prepareProperty, prepareStart, onStart, onComplete, crossCheck }
const Category = Component.category
const Property = Component.property
const Length = Component.properties && Component.properties.length || Component.subProperties && Component.subProperties.length
// {property,defaultvalue,defaultOptions,Interpolate,functions} // single property
// {category,properties,defaultvalues,defaultOptions,Interpolate,functions} // category colors, boxModel, borderRadius
// {property,subProperties,defaultvalues,defaultOptions,Interpolate,functions} // property with multiple sub properties. Eg transform, filter
// {category,subProperties,defaultvalues,defaultOptions,Interpolate,functions} // property with multiple sub properties. Eg attr
// set supported category/property
supportedProperties[ComponentName] = Component.properties || Component.subProperties || Component.property
// set defaultValues
if ('defaultValue' in Component){ // value 0 will invalidate
defaultValues[ Property ] = Component.defaultValue
// minimal info
propertyInfo.supports = `${Property} property`
} else if (Component.defaultValues) {
for (const dv in Component.defaultValues) {
defaultValues[dv] = Component.defaultValues[dv]
}
// minimal info
propertyInfo.supports = `${Length||Property} ${Property||Category} properties`
}
// set additional options
if (Component.defaultOptions) {
for (const op in Component.defaultOptions) {
defaultOptions[op] = Component.defaultOptions[op]
}
}
// set functions
if (Component.functions) {
for (const fn in Functions) {
if (fn in Component.functions) {
if (typeof (Component.functions[fn]) === 'function' ) {
// !Functions[fn][ Category||Property ] && (Functions[fn][ Category||Property ] = Component.functions[fn])
!Functions[fn][ComponentName] && (Functions[fn][ComponentName] = {})
!Functions[fn][ComponentName][ Category||Property ] && (Functions[fn][ComponentName][ Category||Property ] = Component.functions[fn])
} else {
for ( const ofn in Component.functions[fn] ){
// !Functions[fn][ofn] && (Functions[fn][ofn] = Component.functions[fn][ofn])
!Functions[fn][ComponentName] && (Functions[fn][ComponentName] = {})
!Functions[fn][ComponentName][ofn] && (Functions[fn][ComponentName][ofn] = Component.functions[fn][ofn])
}
}
}
}
}
// set component interpolate
if (Component.Interpolate) {
for (const fn in Component.Interpolate) {
const compIntObj = Component.Interpolate[fn]
if ( typeof(compIntObj) === 'function' && !Interpolate[fn] ) {
Interpolate[fn] = compIntObj;
} else {
for ( const sfn in compIntObj ) {
if ( typeof(compIntObj[sfn]) === 'function' && !Interpolate[fn] ) {
Interpolate[fn] = compIntObj[sfn];
}
}
}
}
linkProperty[ComponentName] = Component.Interpolate
}
// set component util
if (Component.Util) {
for (const fn in Component.Util){
!Util[fn] && (Util[fn] = Component.Util[fn])
}
}
return propertyInfo
}
}
import supportedProperties from '../objects/supportedProperties';
import defaultValues from '../objects/defaultValues';
import defaultOptions from '../objects/defaultOptions';
import prepareProperty from '../objects/prepareProperty';
import prepareStart from '../objects/prepareStart';
import onStart from '../objects/onStart';
import onComplete from '../objects/onComplete';
import crossCheck from '../objects/crossCheck';
import linkProperty from '../objects/linkProperty';
import Util from '../objects/util';
import Interpolate from '../objects/interpolate';
/**
* Animation Class
*
* Registers components by populating KUTE.js objects and makes sure
* no duplicate component / property is allowed.
*/
export default class Animation {
/**
* @constructor
* @param {KUTE.fullComponent} Component
*/
constructor(Component) {
try {
if (Component.component in supportedProperties) {
throw Error(`KUTE - ${Component.component} already registered`);
} else if (Component.property in defaultValues) {
throw Error(`KUTE - ${Component.property} already registered`);
}
} catch (e) {
throw Error(e);
}
const propertyInfo = this;
const ComponentName = Component.component;
// const Objects = { defaultValues, defaultOptions, Interpolate, linkProperty, Util }
const Functions = {
prepareProperty, prepareStart, onStart, onComplete, crossCheck,
};
const Category = Component.category;
const Property = Component.property;
const Length = (Component.properties && Component.properties.length)
|| (Component.subProperties && Component.subProperties.length);
// single property
// {property,defaultvalue,defaultOptions,Interpolate,functions}
// category colors, boxModel, borderRadius
// {category,properties,defaultvalues,defaultOptions,Interpolate,functions}
// property with multiple sub properties. Eg transform, filter
// {property,subProperties,defaultvalues,defaultOptions,Interpolate,functions}
// property with multiple sub properties. Eg htmlAttributes
// {category,subProperties,defaultvalues,defaultOptions,Interpolate,functions}
// set supported category/property
supportedProperties[ComponentName] = Component.properties
|| Component.subProperties || Component.property;
// set defaultValues
if ('defaultValue' in Component) { // value 0 will invalidate
defaultValues[Property] = Component.defaultValue;
// minimal info
propertyInfo.supports = `${Property} property`;
} else if (Component.defaultValues) {
Object.keys(Component.defaultValues).forEach((dv) => {
defaultValues[dv] = Component.defaultValues[dv];
});
// minimal info
propertyInfo.supports = `${Length || Property} ${Property || Category} properties`;
}
// set additional options
if (Component.defaultOptions) {
// Object.keys(Component.defaultOptions).forEach((op) => {
// defaultOptions[op] = Component.defaultOptions[op];
// });
Object.assign(defaultOptions, Component.defaultOptions);
}
// set functions
if (Component.functions) {
Object.keys(Functions).forEach((fn) => {
if (fn in Component.functions) {
if (typeof (Component.functions[fn]) === 'function') {
// if (!Functions[fn][ Category||Property ]) {
// Functions[fn][ Category||Property ] = Component.functions[fn];
// }
if (!Functions[fn][ComponentName]) Functions[fn][ComponentName] = {};
if (!Functions[fn][ComponentName][Category || Property]) {
Functions[fn][ComponentName][Category || Property] = Component.functions[fn];
}
} else {
Object.keys(Component.functions[fn]).forEach((ofn) => {
// !Functions[fn][ofn] && (Functions[fn][ofn] = Component.functions[fn][ofn])
if (!Functions[fn][ComponentName]) Functions[fn][ComponentName] = {};
if (!Functions[fn][ComponentName][ofn]) {
Functions[fn][ComponentName][ofn] = Component.functions[fn][ofn];
}
});
}
}
});
}
// set component interpolation functions
if (Component.Interpolate) {
Object.keys(Component.Interpolate).forEach((fni) => {
const compIntObj = Component.Interpolate[fni];
if (typeof (compIntObj) === 'function' && !Interpolate[fni]) {
Interpolate[fni] = compIntObj;
} else {
Object.keys(compIntObj).forEach((sfn) => {
if (typeof (compIntObj[sfn]) === 'function' && !Interpolate[fni]) {
Interpolate[fni] = compIntObj[sfn];
}
});
}
});
linkProperty[ComponentName] = Component.Interpolate;
}
// set component util
if (Component.Util) {
Object.keys(Component.Util).forEach((fnu) => {
if (!Util[fnu]) Util[fnu] = Component.Util[fnu];
});
}
return propertyInfo;
}
}

View file

@ -1,76 +1,97 @@
import supportedProperties from '../objects/supportedProperties.js'
import defaultOptions from '../objects/defaultOptions.js'
import onStart from '../objects/onStart.js'
import onComplete from '../objects/onComplete.js'
import linkProperty from '../objects/linkProperty.js'
import Util from '../objects/util.js'
import Interpolate from '../objects/interpolate.js'
// Animation class
export default class AnimationBase {
constructor(Component){
return this.setComponent(Component)
}
setComponent(Component){
const ComponentName = Component.component
// const Objects = { defaultValues, defaultOptions, Interpolate, linkProperty }
const Functions = { onStart, onComplete }
const Category = Component.category
const Property = Component.property
// set supported category/property
supportedProperties[ComponentName] = Component.properties || Component.subProperties || Component.property
// set additional options
if (Component.defaultOptions) {
for (const op in Component.defaultOptions) {
defaultOptions[op] = Component.defaultOptions[op]
}
}
// set functions
if (Component.functions) {
for (const fn in Functions) {
if (fn in Component.functions) {
if ( typeof (Component.functions[fn]) === 'function' ) {
// !Functions[fn][ Category||Property ] && (Functions[fn][ Category||Property ] = Component.functions[fn])
!Functions[fn][ComponentName] && (Functions[fn][ComponentName] = {})
!Functions[fn][ComponentName][ Category||Property ] && (Functions[fn][ComponentName][ Category||Property ] = Component.functions[fn])
} else {
for ( const ofn in Component.functions[fn] ){
// !Functions[fn][ofn] && (Functions[fn][ofn] = Component.functions[fn][ofn])
!Functions[fn][ComponentName] && (Functions[fn][ComponentName] = {})
!Functions[fn][ComponentName][ofn] && (Functions[fn][ComponentName][ofn] = Component.functions[fn][ofn])
}
}
}
}
}
// set interpolate
if (Component.Interpolate) {
for (const fn in Component.Interpolate) {
const compIntObj = Component.Interpolate[fn]
if ( typeof(compIntObj) === 'function' && !Interpolate[fn] ) {
Interpolate[fn] = compIntObj;
} else {
for ( const sfn in compIntObj ) {
if ( typeof(compIntObj[sfn]) === 'function' && !Interpolate[fn] ) {
Interpolate[fn] = compIntObj[sfn];
}
}
}
}
linkProperty[ComponentName] = Component.Interpolate
}
// set component util
if (Component.Util) {
for (const fn in Component.Util){
!Util[fn] && (Util[fn] = Component.Util[fn])
}
}
return {name:ComponentName}
}
}
import supportedProperties from '../objects/supportedProperties';
import defaultOptions from '../objects/defaultOptions';
import onStart from '../objects/onStart';
import onComplete from '../objects/onComplete';
import linkProperty from '../objects/linkProperty';
import Util from '../objects/util';
import Interpolate from '../objects/interpolate';
/**
* Animation Base Class
*
* Registers components by populating KUTE.js objects and makes sure
* no duplicate component / property is allowed.
*
* This class only registers the minimal amount of component information
* required to enable components animation, which means value processing
* as well as `to()` and `allTo()` methods are not supported.
*/
export default class AnimationBase {
/**
* @class
* @param {KUTE.baseComponent} Component
*/
constructor(Component) {
const ComponentName = Component.component;
// const Objects = { defaultValues, defaultOptions, Interpolate, linkProperty }
const Functions = { onStart, onComplete };
const Category = Component.category;
const Property = Component.property;
// ESLint
this._ = 0;
// set supported category/property
supportedProperties[ComponentName] = Component.properties
|| Component.subProperties || Component.property;
// set additional options
if (Component.defaultOptions) {
// Object.keys(Component.defaultOptions).forEach((op) => {
// defaultOptions[op] = Component.defaultOptions[op];
// });
Object.assign(defaultOptions, Component.defaultOptions);
}
// set functions
if (Component.functions) {
Object.keys(Functions).forEach((fn) => {
if (fn in Component.functions) {
if (typeof (Component.functions[fn]) === 'function') {
// if (!Functions[fn][ Category||Property ]) {
// Functions[fn][ Category||Property ] = Component.functions[fn];
// }
if (!Functions[fn][ComponentName]) Functions[fn][ComponentName] = {};
if (!Functions[fn][ComponentName][Category || Property]) {
Functions[fn][ComponentName][Category || Property] = Component.functions[fn];
}
} else {
Object.keys(Component.functions[fn]).forEach((ofn) => {
// if (!Functions[fn][ofn]) Functions[fn][ofn] = Component.functions[fn][ofn];
if (!Functions[fn][ComponentName]) Functions[fn][ComponentName] = {};
if (!Functions[fn][ComponentName][ofn]) {
Functions[fn][ComponentName][ofn] = Component.functions[fn][ofn];
}
});
}
}
});
}
// set interpolate
if (Component.Interpolate) {
Object.keys(Component.Interpolate).forEach((fni) => {
const compIntObj = Component.Interpolate[fni];
if (typeof (compIntObj) === 'function' && !Interpolate[fni]) {
Interpolate[fni] = compIntObj;
} else {
Object.keys(compIntObj).forEach((sfn) => {
if (typeof (compIntObj[sfn]) === 'function' && !Interpolate[fni]) {
Interpolate[fni] = compIntObj[sfn];
}
});
}
});
linkProperty[ComponentName] = Component.Interpolate;
}
// set component util
if (Component.Util) {
Object.keys(Component.Util).forEach((fnu) => {
if (!Util[fnu]) Util[fnu] = Component.Util[fnu];
});
}
return { name: ComponentName };
}
}

View file

@ -1,103 +1,137 @@
import prepareProperty from '../objects/prepareProperty.js'
import prepareStart from '../objects/prepareStart.js'
import onStart from '../objects/onStart.js'
import onComplete from '../objects/onComplete.js'
import crossCheck from '../objects/crossCheck.js'
import Interpolate from '../objects/interpolate.js'
import Animation from './animation.js'
// AnimationDevelopment class
export default class AnimationDevelopment extends Animation {
constructor(...args){
super(...args)
}
setComponent(Component){
super.setComponent(Component)
const propertyInfo = this
// const Objects = { defaultValues, defaultOptions, Interpolate, linkProperty, Util }
const Functions = { prepareProperty,prepareStart,onStart,onComplete,crossCheck }
const Category = Component.category
const Property = Component.property
const Length = Component.properties && Component.properties.length || Component.subProperties && Component.subProperties.length
// set defaultValues
if ('defaultValue' in Component){ // value 0 will invalidate
propertyInfo.supports = `${Property} property`
propertyInfo.defaultValue = `${(Component.defaultValue+'').length?"YES":"not set or incorrect"}`
} else if (Component.defaultValues) {
propertyInfo.supports = `${Length||Property} ${Property||Category} properties`
propertyInfo.defaultValues = Object.keys(Component.defaultValues).length === Length ? `YES` : `Not set or incomplete`
}
// set additional options
if (Component.defaultOptions) {
propertyInfo.extends = []
for (const op in Component.defaultOptions) {
propertyInfo.extends.push(op)
}
propertyInfo.extends.length ? propertyInfo.extends = `with <${propertyInfo.extends.join(', ')}> new option(s)` : delete propertyInfo.extends
}
// set functions
if (Component.functions) {
propertyInfo.interface = []
propertyInfo.render = []
propertyInfo.warning = []
for (const fn in Functions) {
if (fn in Component.functions) {
fn === 'prepareProperty' ? propertyInfo.interface.push(`fromTo()`) : 0
fn === 'prepareStart' ? propertyInfo.interface.push(`to()`) : 0
fn === 'onStart' ? propertyInfo.render = `can render update` : 0
} else {
fn === 'prepareProperty' ? propertyInfo.warning.push(`fromTo()`) : 0
fn === 'prepareStart' ? propertyInfo.warning.push(`to()`) : 0
fn === 'onStart' ? propertyInfo.render = `no function to render update` : 0
}
}
propertyInfo.interface.length ? propertyInfo.interface = `${Category||Property} can use [${propertyInfo.interface.join(', ')}] method(s)` : delete propertyInfo.uses
propertyInfo.warning.length ? propertyInfo.warning = `${Category||Property} can't use [${propertyInfo.warning.join(', ')}] method(s) because values aren't processed` : delete propertyInfo.warning
}
// register Interpolation functions
if (Component.Interpolate) {
propertyInfo.uses = []
propertyInfo.adds = []
for (const fn in Component.Interpolate) {
const compIntObj = Component.Interpolate[fn]
// register new Interpolation functions
if ( typeof(compIntObj) === 'function' ) {
if ( !Interpolate[fn] ) {
propertyInfo.adds.push(`${fn}`)
}
propertyInfo.uses.push(`${fn}`)
} else {
for ( const sfn in compIntObj ) {
if ( typeof(compIntObj[sfn]) === 'function' && !Interpolate[fn] ) {
propertyInfo.adds.push(`${sfn}`)
}
propertyInfo.uses.push(`${sfn}`)
}
}
}
propertyInfo.uses.length ? propertyInfo.uses = `[${propertyInfo.uses.join(', ')}] interpolation function(s)` : delete propertyInfo.uses
propertyInfo.adds.length ? propertyInfo.adds = `new [${propertyInfo.adds.join(', ')}] interpolation function(s)` : delete propertyInfo.adds
} else {
propertyInfo.critical = `For ${Property||Category} no interpolation function[s] is set`
}
// set component util
if (Component.Util) {
propertyInfo.hasUtil = Object.keys(Component.Util).join(',')
}
return propertyInfo
}
}
import prepareProperty from '../objects/prepareProperty';
import prepareStart from '../objects/prepareStart';
import onStart from '../objects/onStart';
import onComplete from '../objects/onComplete';
import crossCheck from '../objects/crossCheck';
import Interpolate from '../objects/interpolate';
import Animation from './animation';
/**
* Animation Development Class
*
* Registers components by populating KUTE.js objects and makes sure
* no duplicate component / property is allowed.
*
* In addition to the default class, this one provides more component
* information to help you with custom component development.
*/
export default class AnimationDevelopment extends Animation {
/**
*
* @param {KUTE.fullComponent} args
*/
constructor(Component) {
super(Component);
const propertyInfo = this;
// const Objects = { defaultValues, defaultOptions, Interpolate, linkProperty, Util }
const Functions = {
prepareProperty, prepareStart, onStart, onComplete, crossCheck,
};
const Category = Component.category;
const Property = Component.property;
const Length = (Component.properties && Component.properties.length)
|| (Component.subProperties && Component.subProperties.length);
// set defaultValues
if ('defaultValue' in Component) { // value 0 will invalidate
propertyInfo.supports = `${Property} property`;
propertyInfo.defaultValue = `${(`${Component.defaultValue}`).length ? 'YES' : 'not set or incorrect'}`;
} else if (Component.defaultValues) {
propertyInfo.supports = `${Length || Property} ${Property || Category} properties`;
propertyInfo.defaultValues = Object.keys(Component.defaultValues).length === Length ? 'YES' : 'Not set or incomplete';
}
// set additional options
if (Component.defaultOptions) {
propertyInfo.extends = [];
Object.keys(Component.defaultOptions).forEach((op) => {
propertyInfo.extends.push(op);
});
if (propertyInfo.extends.length) {
propertyInfo.extends = `with <${propertyInfo.extends.join(', ')}> new option(s)`;
} else {
delete propertyInfo.extends;
}
}
// set functions
if (Component.functions) {
propertyInfo.interface = [];
propertyInfo.render = [];
propertyInfo.warning = [];
Object.keys(Functions).forEach((fnf) => {
if (fnf in Component.functions) {
if (fnf === 'prepareProperty') propertyInfo.interface.push('fromTo()');
if (fnf === 'prepareStart') propertyInfo.interface.push('to()');
if (fnf === 'onStart') propertyInfo.render = 'can render update';
} else {
if (fnf === 'prepareProperty') propertyInfo.warning.push('fromTo()');
if (fnf === 'prepareStart') propertyInfo.warning.push('to()');
if (fnf === 'onStart') propertyInfo.render = 'no function to render update';
}
});
if (propertyInfo.interface.length) {
propertyInfo.interface = `${Category || Property} can use [${propertyInfo.interface.join(', ')}] method(s)`;
} else {
delete propertyInfo.uses;
}
if (propertyInfo.warning.length) {
propertyInfo.warning = `${Category || Property} can't use [${propertyInfo.warning.join(', ')}] method(s) because values aren't processed`;
} else {
delete propertyInfo.warning;
}
}
// register Interpolation functions
if (Component.Interpolate) {
propertyInfo.uses = [];
propertyInfo.adds = [];
Object.keys(Component.Interpolate).forEach((fni) => {
const compIntObj = Component.Interpolate[fni];
// register new Interpolation functions
if (typeof (compIntObj) === 'function') {
if (!Interpolate[fni]) {
propertyInfo.adds.push(`${fni}`);
}
propertyInfo.uses.push(`${fni}`);
} else {
Object.keys(compIntObj).forEach((sfn) => {
if (typeof (compIntObj[sfn]) === 'function' && !Interpolate[fni]) {
propertyInfo.adds.push(`${sfn}`);
}
propertyInfo.uses.push(`${sfn}`);
});
}
});
if (propertyInfo.uses.length) {
propertyInfo.uses = `[${propertyInfo.uses.join(', ')}] interpolation function(s)`;
} else {
delete propertyInfo.uses;
}
if (propertyInfo.adds.length) {
propertyInfo.adds = `new [${propertyInfo.adds.join(', ')}] interpolation function(s)`;
} else {
delete propertyInfo.adds;
}
} else {
propertyInfo.critical = `For ${Property || Category} no interpolation function[s] is set`;
}
// set component util
if (Component.Util) {
propertyInfo.hasUtil = Object.keys(Component.Util).join(',');
}
return propertyInfo;
}
}

View file

@ -1,46 +1,57 @@
import defaultValues from '../objects/defaultValues.js'
import Components from '../objects/components.js'
import getStyleForProperty from '../process/getStyleForProperty.js'
import numbers from '../interpolation/numbers.js'
import trueDimension from '../util/trueDimension.js'
import {onStartBgPos} from './backgroundPositionBase.js'
// const bgPosProp = { property : 'backgroundPosition', defaultValue: [0,0], interpolators: {numbers} }, functions = { prepareStart, prepareProperty, onStart }
// Component Functions
function getBgPos(prop){
return getStyleForProperty(this.element,prop) || defaultValues[prop];
}
function prepareBgPos(prop,value){
if ( value instanceof Array ){
const x = trueDimension(value[0]).v,
y = trueDimension(value[1]).v;
return [ x !== NaN ? x : 50, y !== NaN ? y : 50 ];
} else {
let posxy = value.replace(/top|left/g,0).replace(/right|bottom/g,100).replace(/center|middle/g,50);
posxy = posxy.split(/(\,|\s)/g);
posxy = posxy.length === 2 ? posxy : [posxy[0],50];
return [ trueDimension(posxy[0]).v, trueDimension(posxy[1]).v ];
}
}
// All Component Functions
const bgPositionFunctions = {
prepareStart: getBgPos,
prepareProperty: prepareBgPos,
onStart: onStartBgPos
}
// Component Full Object
const BackgroundPosition = {
component: 'backgroundPositionProp',
property: 'backgroundPosition',
defaultValue: [50,50],
Interpolate: {numbers},
functions: bgPositionFunctions,
Util: {trueDimension}
}
export default BackgroundPosition
Components.BackgroundPosition = BackgroundPosition
import defaultValues from '../objects/defaultValues';
import getStyleForProperty from '../process/getStyleForProperty';
import numbers from '../interpolation/numbers';
import trueDimension from '../util/trueDimension';
import { onStartBgPos } from './backgroundPositionBase';
// Component Functions
/**
* Returns the property computed style.
* @param {string} prop the property
* @returns {string} the property computed style
*/
function getBgPos(prop/* , value */) {
return getStyleForProperty(this.element, prop) || defaultValues[prop];
}
/**
* Returns the property tween object.
* @param {string} _ the property name
* @param {string} value the property value
* @returns {number[]} the property tween object
*/
function prepareBgPos(/* prop, */_, value) {
if (value instanceof Array) {
const x = trueDimension(value[0]).v;
const y = trueDimension(value[1]).v;
return [!Number.isNaN(x * 1) ? x : 50, !Number.isNaN(y * 1) ? y : 50];
}
let posxy = value.replace(/top|left/g, 0)
.replace(/right|bottom/g, 100)
.replace(/center|middle/g, 50);
posxy = posxy.split(/(,|\s)/g);
posxy = posxy.length === 2 ? posxy : [posxy[0], 50];
return [trueDimension(posxy[0]).v, trueDimension(posxy[1]).v];
}
// All Component Functions
const bgPositionFunctions = {
prepareStart: getBgPos,
prepareProperty: prepareBgPos,
onStart: onStartBgPos,
};
// Component Full Object
const BackgroundPosition = {
component: 'backgroundPositionProp',
property: 'backgroundPosition',
defaultValue: [50, 50],
Interpolate: { numbers },
functions: bgPositionFunctions,
Util: { trueDimension },
};
export default BackgroundPosition;

View file

@ -1,22 +1,26 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
// const bgPosProp = { property : 'backgroundPosition', defaultValue: [0,0], interpolators: {numbers} }, functions = { prepareStart, prepareProperty, onStart }
// Component Functions
export function onStartBgPos(prop){
if ( this.valuesEnd[prop] && !KUTE[prop]) { // opacity could be 0
KUTE[prop] = (elem, a, b, v) => {
elem.style[prop] = `${(numbers(a[0],b[0],v)*100>>0)/100}% ${((numbers(a[1],b[1],v)*100>>0)/100)}%`;
}
}
}
// Component Base Object
const baseBgPosOps = {
component: 'baseBackgroundPosition',
property: 'backgroundPosition',
Interpolate: {numbers},
functions: {onStart: onStartBgPos}
}
export default baseBgPosOps
import KEC from '../objects/kute';
import numbers from '../interpolation/numbers';
// Component Functions
/**
* Sets the property update function.
* @param {string} prop the property name
*/
export function onStartBgPos(prop) {
if (this.valuesEnd[prop] && !KEC[prop]) {
KEC[prop] = (elem, a, b, v) => {
/* eslint-disable -- no-bitwise & no-param-reassign impossible to satisfy */
elem.style[prop] = `${(numbers(a[0], b[0], v) * 100 >> 0) / 100}% ${((numbers(a[1], b[1], v) * 100 >> 0) / 100)}%`;
/* eslint-enable -- no-bitwise & no-param-reassign impossible to satisfy */
};
}
}
// Component Base Object
const BackgroundPositionBase = {
component: 'baseBackgroundPosition',
property: 'backgroundPosition',
Interpolate: { numbers },
functions: { onStart: onStartBgPos },
};
export default BackgroundPositionBase;

View file

@ -1,48 +1,58 @@
import defaultValues from '../objects/defaultValues.js'
import Components from '../objects/components.js'
import getStyleForProperty from '../process/getStyleForProperty.js'
import trueDimension from '../util/trueDimension.js'
import units from '../interpolation/units.js'
import {radiusOnStartFn} from './borderRadiusBase.js'
// const borderRadius = { category : 'borderRadius', properties : [..], defaultValues: {..}, interpolation: {units} }
// Component Properties
const radiusProps = ['borderRadius', 'borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomLeftRadius', 'borderBottomRightRadius']
const radiusValues = {}
radiusProps.map(x => radiusValues[x] = 0);
// Component Functions
const radiusOnStart = {}
radiusProps.forEach(tweenProp => {
radiusOnStart[tweenProp] = radiusOnStartFn
});
export function getRadius(tweenProp){
return getStyleForProperty(this.element,tweenProp) || defaultValues[tweenProp];
}
export function prepareRadius(tweenProp,value){
return trueDimension(value);
}
// All Component Functions
export const radiusFunctions = {
prepareStart: getRadius,
prepareProperty: prepareRadius,
onStart: radiusOnStart
}
// Full Component
const BorderRadius = {
component: 'borderRadiusProperties',
category: 'borderRadius',
properties: radiusProps,
defaultValues: radiusValues,
Interpolate: {units},
functions: radiusFunctions,
Util: {trueDimension}
}
export default BorderRadius
Components.BorderRadiusProperties = BorderRadius
import defaultValues from '../objects/defaultValues';
import getStyleForProperty from '../process/getStyleForProperty';
import trueDimension from '../util/trueDimension';
import units from '../interpolation/units';
import { radiusOnStartFn } from './borderRadiusBase';
// Component Properties
const radiusProps = [
'borderRadius',
'borderTopLeftRadius', 'borderTopRightRadius',
'borderBottomLeftRadius', 'borderBottomRightRadius'];
const radiusValues = {};
radiusProps.forEach((x) => { radiusValues[x] = 0; });
// Component Functions
const radiusOnStart = {};
radiusProps.forEach((tweenProp) => {
radiusOnStart[tweenProp] = radiusOnStartFn;
});
/**
* Returns the current property computed style.
* @param {string} tweenProp the property name
* @returns {string} the property computed style
*/
export function getRadius(tweenProp) {
return getStyleForProperty(this.element, tweenProp) || defaultValues[tweenProp];
}
/**
* Returns the property tween object.
* @param {string} value the property value
* @returns {{v: number, u: string}} the property tween object
*/
export function prepareRadius(/* tweenProp, */_, value) {
return trueDimension(value);
}
// All Component Functions
export const radiusFunctions = {
prepareStart: getRadius,
prepareProperty: prepareRadius,
onStart: radiusOnStart,
};
// Full Component
const BorderRadius = {
component: 'borderRadiusProperties',
category: 'borderRadius',
properties: radiusProps,
defaultValues: radiusValues,
Interpolate: { units },
functions: radiusFunctions,
Util: { trueDimension },
};
export default BorderRadius;

View file

@ -1,29 +1,43 @@
import KUTE from '../objects/kute.js'
import units from '../interpolation/units.js'
// const borderRadius = { category : 'borderRadius', properties : [..], defaultValues: {..}, interpolation: {units} }
// Component Properties
const radiusProps = ['borderRadius', 'borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomLeftRadius', 'borderBottomRightRadius']
// Component Functions
export function radiusOnStartFn(tweenProp){
if (tweenProp in this.valuesEnd && !KUTE[tweenProp]) {
KUTE[tweenProp] = (elem, a, b, v) => {
elem.style[tweenProp] = units(a.v,b.v,b.u,v);
}
}
}
const radiusOnStart = {}
radiusProps.forEach(tweenProp => {
radiusOnStart[tweenProp] = radiusOnStartFn
});
// Base Component
const baseBorderRadius = {
component: 'baseBorderRadius',
category: 'borderRadius',
Interpolate: {units},
functions: {onStart: radiusOnStart}
}
export default baseBorderRadius
import KEC from '../objects/kute';
import units from '../interpolation/units';
/* borderRadius = {
category: 'borderRadius',
properties : [..],
defaultValues: {..},
interpolation: {units}
} */
// Component Properties
const radiusProps = [
'borderRadius',
'borderTopLeftRadius', 'borderTopRightRadius',
'borderBottomLeftRadius', 'borderBottomRightRadius',
];
// Component Functions
/**
* Sets the property update function.
* @param {string} tweenProp the property name
*/
export function radiusOnStartFn(tweenProp) {
if (tweenProp in this.valuesEnd && !KEC[tweenProp]) {
KEC[tweenProp] = (elem, a, b, v) => {
// eslint-disable-next-line no-param-reassign -- impossible to satisfy
elem.style[tweenProp] = units(a.v, b.v, b.u, v);
};
}
}
const radiusOnStart = {};
radiusProps.forEach((tweenProp) => {
radiusOnStart[tweenProp] = radiusOnStartFn;
});
// Base Component
const BorderRadiusBase = {
component: 'baseBorderRadius',
category: 'borderRadius',
Interpolate: { units },
functions: { onStart: radiusOnStart },
};
export default BorderRadiusBase;

View file

@ -1,46 +1,57 @@
import defaultValues from '../objects/defaultValues.js'
import Components from '../objects/components.js'
import getStyleForProperty from '../process/getStyleForProperty.js'
import trueDimension from '../util/trueDimension.js'
import numbers from '../interpolation/numbers.js'
import {boxModelOnStart} from './boxModelBase.js'
// Component Properties
const boxModelProperties = ['top', 'left', 'width', 'height', 'right', 'bottom', 'minWidth', 'minHeight', 'maxWidth', 'maxHeight',
'padding', 'paddingTop','paddingBottom', 'paddingLeft', 'paddingRight',
'margin', 'marginTop','marginBottom', 'marginLeft', 'marginRight',
'borderWidth', 'borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth', 'outlineWidth']
const boxModelValues = {}
boxModelProperties.map(x => boxModelValues[x] = 0);
// Component Functions
function getBoxModel(tweenProp){
return getStyleForProperty(this.element,tweenProp) || defaultValues[tweenProp];
}
function prepareBoxModel(tweenProp,value){
const boxValue = trueDimension(value), offsetProp = tweenProp === 'height' ? 'offsetHeight' : 'offsetWidth';
return boxValue.u === '%' ? boxValue.v * this.element[offsetProp] / 100 : boxValue.v;
}
const boxPropsOnStart = {}
boxModelProperties.map(x => boxPropsOnStart[x] = boxModelOnStart );
// All Component Functions
const boxModelFunctions = {
prepareStart: getBoxModel,
prepareProperty: prepareBoxModel,
onStart: boxPropsOnStart
}
// Component Full Component
const boxModel = {
component: 'boxModelProperties',
category: 'boxModel',
properties: boxModelProperties,
defaultValues: boxModelValues,
Interpolate: {numbers},
functions: boxModelFunctions
}
export default boxModel
Components.BoxModelProperties = boxModel
import defaultValues from '../objects/defaultValues';
import getStyleForProperty from '../process/getStyleForProperty';
import trueDimension from '../util/trueDimension';
import numbers from '../interpolation/numbers';
import { boxModelOnStart } from './boxModelBase';
// Component Properties
const boxModelProperties = ['top', 'left', 'width', 'height', 'right', 'bottom', 'minWidth', 'minHeight', 'maxWidth', 'maxHeight',
'padding', 'paddingTop', 'paddingBottom', 'paddingLeft', 'paddingRight',
'margin', 'marginTop', 'marginBottom', 'marginLeft', 'marginRight',
'borderWidth', 'borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth', 'outlineWidth'];
const boxModelValues = {};
boxModelProperties.forEach((x) => { boxModelValues[x] = 0; });
// Component Functions
/**
* Returns the current property computed style.
* @param {string} tweenProp the property name
* @returns {string} computed style for property
*/
function getBoxModel(tweenProp) {
return getStyleForProperty(this.element, tweenProp) || defaultValues[tweenProp];
}
/**
* Returns the property tween object.
* @param {string} tweenProp the property name
* @param {string} value the property value
* @returns {number} the property tween object
*/
function prepareBoxModel(tweenProp, value) {
const boxValue = trueDimension(value); const
offsetProp = tweenProp === 'height' ? 'offsetHeight' : 'offsetWidth';
return boxValue.u === '%' ? (boxValue.v * this.element[offsetProp]) / 100 : boxValue.v;
}
const boxPropsOnStart = {};
boxModelProperties.forEach((x) => { boxPropsOnStart[x] = boxModelOnStart; });
// All Component Functions
const boxModelFunctions = {
prepareStart: getBoxModel,
prepareProperty: prepareBoxModel,
onStart: boxPropsOnStart,
};
// Component Full Component
const BoxModel = {
component: 'boxModelProperties',
category: 'boxModel',
properties: boxModelProperties,
defaultValues: boxModelValues,
Interpolate: { numbers },
functions: boxModelFunctions,
};
export default BoxModel;

View file

@ -1,28 +1,37 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
// Component Functions
export function boxModelOnStart(tweenProp){
if (tweenProp in this.valuesEnd && !KUTE[tweenProp]) {
KUTE[tweenProp] = (elem, a, b, v) => {
elem.style[tweenProp] = `${v > 0.99 || v < 0.01 ? ((numbers(a,b,v)*10)>>0)/10 : (numbers(a,b,v) ) >> 0}px`;
// elem.style[tweenProp] = `${(numbers(a,b,v) ) >> 0}px`;
}
}
}
// Component Base Props
const baseBoxProps = ['top','left','width','height']
const baseBoxOnStart = {}
baseBoxProps.map(x=>baseBoxOnStart[x] = boxModelOnStart)
// Component Base
const baseBoxModel = {
component: 'baseBoxModel',
category: 'boxModel',
properties: baseBoxProps,
Interpolate: {numbers},
functions: {onStart: baseBoxOnStart}
}
export default baseBoxModel
import KEC from '../objects/kute';
import numbers from '../interpolation/numbers';
// Component Functions
/**
* Sets the update function for the property.
* @param {string} tweenProp the property name
*/
export function boxModelOnStart(tweenProp) {
if (tweenProp in this.valuesEnd && !KEC[tweenProp]) {
KEC[tweenProp] = (elem, a, b, v) => {
/* eslint-disable no-param-reassign -- impossible to satisfy */
/* eslint-disable no-bitwise -- impossible to satisfy */
elem.style[tweenProp] = `${v > 0.99 || v < 0.01
? ((numbers(a, b, v) * 10) >> 0) / 10
: (numbers(a, b, v)) >> 0}px`;
/* eslint-enable no-bitwise */
/* eslint-enable no-param-reassign */
};
}
}
// Component Base Props
const baseBoxProps = ['top', 'left', 'width', 'height'];
const baseBoxOnStart = {};
baseBoxProps.forEach((x) => { baseBoxOnStart[x] = boxModelOnStart; });
// Component Base
const BoxModelBase = {
component: 'baseBoxModel',
category: 'boxModel',
properties: baseBoxProps,
Interpolate: { numbers },
functions: { onStart: baseBoxOnStart },
};
export default BoxModelBase;

View file

@ -1,44 +1,56 @@
import defaultValues from '../objects/defaultValues.js'
import Components from '../objects/components.js'
import getStyleForProperty from '../process/getStyleForProperty.js'
import trueDimension from '../util/trueDimension.js'
import numbers from '../interpolation/numbers.js'
import {boxModelOnStart} from './boxModelBase.js'
// Component Functions
function getBoxModel(tweenProp){
return getStyleForProperty(this.element,tweenProp) || defaultValues[tweenProp];
}
function prepareBoxModel(tweenProp,value){
const boxValue = trueDimension(value), offsetProp = tweenProp === 'height' ? 'offsetHeight' : 'offsetWidth';
return boxValue.u === '%' ? boxValue.v * this.element[offsetProp] / 100 : boxValue.v;
}
// Component Base Props
const essentialBoxProps = ['top','left','width','height']
const essentialBoxPropsValues = {top:0,left:0,width:0,height:0}
const essentialBoxOnStart = {}
essentialBoxProps.map(x=>essentialBoxOnStart[x] = boxModelOnStart)
// All Component Functions
const essentialBoxModelFunctions = {
prepareStart: getBoxModel,
prepareProperty: prepareBoxModel,
onStart: essentialBoxOnStart
}
// Component Essential
const essentialBoxModel = {
component: 'essentialBoxModel',
category: 'boxModel',
properties: essentialBoxProps,
defaultValues: essentialBoxPropsValues,
Interpolate: {numbers},
functions: essentialBoxModelFunctions,
Util:{trueDimension}
}
export default essentialBoxModel
Components.BoxModelEssential = essentialBoxModel
import defaultValues from '../objects/defaultValues';
import getStyleForProperty from '../process/getStyleForProperty';
import trueDimension from '../util/trueDimension';
import numbers from '../interpolation/numbers';
import { boxModelOnStart } from './boxModelBase';
// Component Functions
/**
* Returns the current property computed style.
* @param {string} tweenProp the property name
* @returns {string} computed style for property
*/
function getBoxModel(tweenProp) {
return getStyleForProperty(this.element, tweenProp) || defaultValues[tweenProp];
}
/**
* Returns the property tween object.
* @param {string} tweenProp the property name
* @param {string} value the property name
* @returns {number} the property tween object
*/
function prepareBoxModel(tweenProp, value) {
const boxValue = trueDimension(value);
const offsetProp = tweenProp === 'height' ? 'offsetHeight' : 'offsetWidth';
return boxValue.u === '%' ? (boxValue.v * this.element[offsetProp]) / 100 : boxValue.v;
}
// Component Base Props
const essentialBoxProps = ['top', 'left', 'width', 'height'];
const essentialBoxPropsValues = {
top: 0, left: 0, width: 0, height: 0,
};
const essentialBoxOnStart = {};
essentialBoxProps.forEach((x) => { essentialBoxOnStart[x] = boxModelOnStart; });
// All Component Functions
const essentialBoxModelFunctions = {
prepareStart: getBoxModel,
prepareProperty: prepareBoxModel,
onStart: essentialBoxOnStart,
};
// Component Essential
const BoxModelEssential = {
component: 'essentialBoxModel',
category: 'boxModel',
properties: essentialBoxProps,
defaultValues: essentialBoxPropsValues,
Interpolate: { numbers },
functions: essentialBoxModelFunctions,
Util: { trueDimension },
};
export default BoxModelEssential;

View file

@ -1,43 +1,52 @@
import Components from '../objects/components.js'
import getStyleForProperty from '../process/getStyleForProperty.js'
import trueDimension from '../util/trueDimension.js'
import numbers from '../interpolation/numbers.js'
import {onStartClip} from './clipPropertyBase.js'
// Component Functions
function getClip(tweenProp,v){
const currentClip = getStyleForProperty(this.element,tweenProp),
width = getStyleForProperty(this.element,'width'),
height = getStyleForProperty(this.element,'height');
return !/rect/.test(currentClip) ? [0, width, height, 0] : currentClip;
}
function prepareClip(tweenProp,value) {
if ( value instanceof Array ){
return [ trueDimension(value[0]), trueDimension(value[1]), trueDimension(value[2]), trueDimension(value[3]) ];
} else {
var clipValue = value.replace(/rect|\(|\)/g,'');
clipValue = /\,/g.test(clipValue) ? clipValue.split(/\,/g) : clipValue.split(/\s/g);
return [ trueDimension(clipValue[0]), trueDimension(clipValue[1]), trueDimension(clipValue[2]), trueDimension(clipValue[3]) ];
}
}
// All Component Functions
const clipFunctions = {
prepareStart: getClip,
prepareProperty: prepareClip,
onStart: onStartClip
}
// Component Full
const clipProperty = {
component: 'clipProperty',
property: 'clip',
defaultValue: [0,0,0,0],
Interpolate: {numbers},
functions: clipFunctions,
Util: {trueDimension}
}
export default clipProperty
Components.ClipProperty = clipProperty
import getStyleForProperty from '../process/getStyleForProperty';
import trueDimension from '../util/trueDimension';
import numbers from '../interpolation/numbers';
import { onStartClip } from './clipPropertyBase';
// Component Functions
/**
* Returns the current property computed style.
* @param {string} tweenProp the property name
* @returns {string | number[]} computed style for property
*/
function getClip(tweenProp/* , value */) {
const { element } = this;
const currentClip = getStyleForProperty(element, tweenProp);
const width = getStyleForProperty(element, 'width');
const height = getStyleForProperty(element, 'height');
return !/rect/.test(currentClip) ? [0, width, height, 0] : currentClip;
}
/**
* Returns the property tween object.
* @param {string} _ the property name
* @param {string} value the property value
* @returns {number[]} the property tween object
*/
function prepareClip(/* tweenProp, */_, value) {
if (value instanceof Array) {
return value.map((x) => trueDimension(x));
}
let clipValue = value.replace(/rect|\(|\)/g, '');
clipValue = /,/g.test(clipValue) ? clipValue.split(',') : clipValue.split(/\s/);
return clipValue.map((x) => trueDimension(x));
}
// All Component Functions
const clipFunctions = {
prepareStart: getClip,
prepareProperty: prepareClip,
onStart: onStartClip,
};
// Component Full
const ClipProperty = {
component: 'clipProperty',
property: 'clip',
defaultValue: [0, 0, 0, 0],
Interpolate: { numbers },
functions: clipFunctions,
Util: { trueDimension },
};
export default ClipProperty;

View file

@ -1,27 +1,36 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
// Component Functions
export function onStartClip(tweenProp) {
if ( this.valuesEnd[tweenProp] && !KUTE[tweenProp]) {
KUTE[tweenProp] = (elem, a, b, v) => {
var h = 0, cl = [];
for (h;h<4;h++){
var c1 = a[h].v, c2 = b[h].v, cu = b[h].u || 'px';
cl[h] = ((numbers(c1,c2,v)*100 >> 0)/100) + cu;
}
elem.style.clip = `rect(${cl})`;
}
}
}
// Component Base
const baseClip = {
component: 'baseClip',
property: 'clip',
// defaultValue: [0,0,0,0],
Interpolate: {numbers},
functions: {onStart:onStartClip}
}
export default baseClip
import KEC from '../objects/kute';
import numbers from '../interpolation/numbers';
// Component Functions
/**
* Sets the property update function.
* @param {string} tweenProp the property name
*/
export function onStartClip(tweenProp) {
if (this.valuesEnd[tweenProp] && !KEC[tweenProp]) {
KEC[tweenProp] = (elem, a, b, v) => {
let h = 0; const
cl = [];
for (h; h < 4; h += 1) {
const c1 = a[h].v;
const c2 = b[h].v;
const cu = b[h].u || 'px';
// eslint-disable-next-line no-bitwise -- impossible to satisfy
cl[h] = ((numbers(c1, c2, v) * 100 >> 0) / 100) + cu;
}
// eslint-disable-next-line no-param-reassign -- impossible to satisfy
elem.style.clip = `rect(${cl})`;
};
}
}
// Component Base
const ClipPropertyBase = {
component: 'baseClip',
property: 'clip',
// defaultValue: [0,0,0,0],
Interpolate: { numbers },
functions: { onStart: onStartClip },
};
export default ClipPropertyBase;

View file

@ -1,51 +1,65 @@
import defaultValues from '../objects/defaultValues.js'
import Components from '../objects/components.js'
import getStyleForProperty from '../process/getStyleForProperty.js'
import trueColor from '../util/trueColor.js'
import numbers from '../interpolation/numbers.js'
import colors from '../interpolation/colors.js'
import {onStartColors} from './colorPropertiesBase.js'
// Component Interpolation
// Component Properties
// supported formats
// 'hex', 'rgb', 'rgba' '#fff' 'rgb(0,0,0)' / 'rgba(0,0,0,0)' 'red' (IE9+)
const supportedColors = ['color', 'backgroundColor','borderColor', 'borderTopColor', 'borderRightColor', 'borderBottomColor', 'borderLeftColor', 'outlineColor']
const defaultColors = {}
supportedColors.map(tweenProp => {
defaultColors[tweenProp] = '#000'
});
// Component Functions
const colorsOnStart = {}
supportedColors.map(x => colorsOnStart[x] = onStartColors)
function getColor(prop,value) {
return getStyleForProperty(this.element,prop) || defaultValues[prop];
}
function prepareColor(prop,value) {
return trueColor(value);
}
// All Component Functions
const colorFunctions = {
prepareStart: getColor,
prepareProperty: prepareColor,
onStart: colorsOnStart
}
// Component Full
const colorProperties = {
component: 'colorProperties',
category: 'colors',
properties: supportedColors,
defaultValues: defaultColors,
Interpolate: {numbers,colors},
functions: colorFunctions,
Util: {trueColor}
}
export default colorProperties
Components.ColorProperties = colorProperties
import defaultValues from '../objects/defaultValues';
import getStyleForProperty from '../process/getStyleForProperty';
import trueColor from '../util/trueColor';
import numbers from '../interpolation/numbers';
import colors from '../interpolation/colors';
import { onStartColors } from './colorPropertiesBase';
// Component Properties
// supported formats
// 'hex', 'rgb', 'rgba' '#fff' 'rgb(0,0,0)' / 'rgba(0,0,0,0)' 'red' (IE9+)
const supportedColors = [
'color', 'backgroundColor', 'outlineColor',
'borderColor', 'borderTopColor', 'borderRightColor',
'borderBottomColor', 'borderLeftColor',
];
const defaultColors = {};
supportedColors.forEach((tweenProp) => {
defaultColors[tweenProp] = '#000';
});
// Component Functions
const colorsOnStart = {};
supportedColors.forEach((x) => {
colorsOnStart[x] = onStartColors;
});
/**
* Returns the current property computed style.
* @param {string} prop the property name
* @returns {string} property computed style
*/
function getColor(prop/* , value */) {
return getStyleForProperty(this.element, prop) || defaultValues[prop];
}
/**
* Returns the property tween object.
* @param {string} _ the property name
* @param {string} value the property value
* @returns {KUTE.colorObject} the property tween object
*/
function prepareColor(/* prop, */_, value) {
return trueColor(value);
}
// All Component Functions
const colorFunctions = {
prepareStart: getColor,
prepareProperty: prepareColor,
onStart: colorsOnStart,
};
// Component Full
const colorProperties = {
component: 'colorProperties',
category: 'colors',
properties: supportedColors,
defaultValues: defaultColors,
Interpolate: { numbers, colors },
functions: colorFunctions,
Util: { trueColor },
};
export default colorProperties;

View file

@ -1,35 +1,45 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
import colors from '../interpolation/colors.js'
// Component Interpolation
// rgba1, rgba2, progress
// Component Properties
// supported formats
// 'hex', 'rgb', 'rgba' '#fff' 'rgb(0,0,0)' / 'rgba(0,0,0,0)' 'red' (IE9+)
const supportedColors = ['color', 'backgroundColor','borderColor', 'borderTopColor', 'borderRightColor', 'borderBottomColor', 'borderLeftColor', 'outlineColor']
// Component Functions
export function onStartColors(tweenProp){
if (this.valuesEnd[tweenProp] && !KUTE[tweenProp]) {
KUTE[tweenProp] = (elem, a, b, v) => {
elem.style[tweenProp] = colors(a,b,v);
}
}
}
const colorsOnStart = {}
supportedColors.map(x => colorsOnStart[x] = onStartColors)
// Component Base
export const baseColors = {
component: 'baseColors',
category: 'colors',
// properties: supportedColors,
// defaultValues: defaultColors,
Interpolate: {numbers,colors},
functions: {onStart:colorsOnStart}
}
export default baseColors
import KEC from '../objects/kute';
import numbers from '../interpolation/numbers';
import colors from '../interpolation/colors';
// Component Interpolation
// rgba1, rgba2, progress
// Component Properties
// supported formats
// 'hex', 'rgb', 'rgba' '#fff' 'rgb(0,0,0)' / 'rgba(0,0,0,0)' 'red' (IE9+)
const supportedColors = [
'color', 'backgroundColor', 'outlineColor',
'borderColor',
'borderTopColor', 'borderRightColor',
'borderBottomColor', 'borderLeftColor',
];
// Component Functions
/**
* Sets the property update function.
* @param {string} tweenProp the property name
*/
export function onStartColors(tweenProp) {
if (this.valuesEnd[tweenProp] && !KEC[tweenProp]) {
KEC[tweenProp] = (elem, a, b, v) => {
// eslint-disable-next-line no-param-reassign
elem.style[tweenProp] = colors(a, b, v);
};
}
}
const colorsOnStart = {};
supportedColors.forEach((x) => { colorsOnStart[x] = onStartColors; });
// Component Base
export const baseColors = {
component: 'baseColors',
category: 'colors',
// properties: supportedColors,
// defaultValues: defaultColors,
Interpolate: { numbers, colors },
functions: { onStart: colorsOnStart },
};
export default baseColors;

View file

@ -1,79 +1,95 @@
import KUTE from '../objects/kute.js'
import getInlineStyle from '../process/getInlineStyle.js'
import defaultValues from '../objects/defaultValues.js'
import Components from '../objects/components.js'
import trueProperty from '../util/trueProperty.js'
import numbers from '../interpolation/numbers.js'
// Component Const
const transformProperty = trueProperty('transform');
const supportTransform = transformProperty in document.body.style ? 1 : 0;
// Component Functions
function getComponentCurrentValue(tweenProp,value){
let currentTransform = getInlineStyle(this.element);
let left = this.element.style.left;
let top = this.element.style.top;
let x = supportTransform && currentTransform.translate ? currentTransform.translate[0]
: isFinite(left*1) ? left
: defaultValues.move[0];
let y = supportTransform && currentTransform.translate ? currentTransform.translate[1]
: isFinite(top*1) ? top
: defaultValues.move[1];
return [x,y]
}
function prepareComponentValue(tweenProp,value){
let x = isFinite(value*1) ? parseInt(value) : parseInt(value[0]) || 0;
let y = parseInt(value[1]) || 0;
return [ x, y ]
}
export function onStartComponent(tweenProp,value){
if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) {
if (supportTransform){
KUTE[tweenProp] = (elem, a, b, v) => {
elem.style[transformProperty] = 'translate('+numbers(a[0],b[0],v)+'px,'+numbers(a[1],b[1],v)+'px)';
}
} else {
KUTE[tweenProp] = (elem, a, b, v) => {
if (a[0]||b[0]) {
elem.style.left = numbers(a[0],b[0],v)+'px';
}
if (a[1]||b[1]) {
elem.style.top = numbers(a[1],b[1],v)+'px';
}
}
}
}
}
// All Component Functions
const componentFunctions = {
prepareStart: getComponentCurrentValue,
prepareProperty: prepareComponentValue,
onStart: onStartComponent
}
// Base Component
export const baseCrossBrowserMove = {
component: 'baseCrossBrowserMove',
property: 'move',
Interpolate: {numbers},
functions: {onStart:onStartComponent}
}
// Full Component
const crossBrowserMove = {
component: 'crossBrowserMove',
property: 'move',
defaultValue: [0,0],
Interpolate: {numbers},
functions: componentFunctions,
Util: {trueProperty}
}
export default crossBrowserMove
Components.CrossBrowserMove = crossBrowserMove
import KEC from '../objects/kute';
import getInlineStyle from '../process/getInlineStyle';
import defaultValues from '../objects/defaultValues';
import trueProperty from '../util/trueProperty';
import numbers from '../interpolation/numbers';
// Component Const
const transformProperty = trueProperty('transform');
const supportTransform = transformProperty in document.body.style ? 1 : 0;
// Component Functions
/**
* Returns the property current style.
*/
function getComponentCurrentValue(/* tweenProp, value */) {
const currentTransform = getInlineStyle(this.element);
const { left } = this.element.style;
const { top } = this.element.style;
let x = 0;
let y = 0;
if (supportTransform && currentTransform.translate) {
[x, y] = currentTransform.translate;
} else {
x = Number.isFinite(left * 1) ? left : defaultValues.move[0];
y = Number.isFinite(top * 1) ? top : defaultValues.move[1];
}
return [x, y];
}
/**
* Returns the property tween object.
* @param {string} _ property name
* @param {string} value property value
* @returns {number[]} the property tween object
*/
function prepareComponentValue(/* tweenProp */_, value) {
const x = Number.isFinite(value * 1) ? parseInt(value, 10) : parseInt(value[0], 10) || 0;
const y = parseInt(value[1], 10) || 0;
return [x, y];
}
/**
* Sets the property update function.
* @param {string} tweenProp the `path` property
*/
export function onStartComponent(tweenProp/* , value */) {
if (!KEC[tweenProp] && this.valuesEnd[tweenProp]) {
if (supportTransform) {
KEC[tweenProp] = (elem, a, b, v) => {
/* eslint-disable-next-line no-param-reassign -- impossible to satisfy */
elem.style[transformProperty] = `translate(${numbers(a[0], b[0], v)}px,${numbers(a[1], b[1], v)}px)`;
};
} else {
KEC[tweenProp] = (elem, a, b, v) => {
if (a[0] || b[0]) {
/* eslint-disable-next-line no-param-reassign -- impossible to satisfy */
elem.style.left = `${numbers(a[0], b[0], v)}px`;
}
if (a[1] || b[1]) {
/* eslint-disable-next-line no-param-reassign -- impossible to satisfy */
elem.style.top = `${numbers(a[1], b[1], v)}px`;
}
};
}
}
}
// All Component Functions
const componentFunctions = {
prepareStart: getComponentCurrentValue,
prepareProperty: prepareComponentValue,
onStart: onStartComponent,
};
// Base Component
export const baseCrossBrowserMove = {
component: 'baseCrossBrowserMove',
property: 'move',
Interpolate: { numbers },
functions: { onStart: onStartComponent },
};
// Full Component
const crossBrowserMove = {
component: 'crossBrowserMove',
property: 'move',
defaultValue: [0, 0],
Interpolate: { numbers },
functions: componentFunctions,
Util: { trueProperty },
};
export default crossBrowserMove;

View file

@ -1,134 +1,201 @@
import getStyleForProperty from '../process/getStyleForProperty.js'
import defaultValues from '../objects/defaultValues.js'
import Components from '../objects/components.js'
import trueColor from '../util/trueColor.js'
import numbers from '../interpolation/numbers.js'
import colors from '../interpolation/colors.js'
import {dropShadow,onStartFilter} from './filterEffectsBase.js'
// const filterEffects = { property : 'filter', subProperties: {}, defaultValue: {}, interpolators: {} }, functions = { prepareStart, prepareProperty, onStart, crossCheck }
// Component Util
function replaceDashNamespace(str){
return str.replace('-r','R').replace('-s','S')
}
function parseDropShadow (shadow){
let newShadow
if (shadow.length === 3) { // [h-shadow, v-shadow, color]
newShadow = [shadow[0], shadow[1], 0, shadow[2] ];
} else if (shadow.length === 4) { // ideal [<offset-x>, <offset-y>, <blur-radius>, <color>]
newShadow = [shadow[0], shadow[1], shadow[2], shadow[3]];
}
// make sure the values are ready to tween
for (let i=0;i<3;i++){
newShadow[i] = parseFloat(newShadow[i]);
}
// also the color must be a rgb object
newShadow[3] = trueColor(newShadow[3]);
return newShadow;
}
function parseFilterString(currentStyle){
let result = {}
let fnReg = /(([a-z].*?)\(.*?\))(?=\s([a-z].*?)\(.*?\)|\s*$)/g
let matches = currentStyle.match(fnReg);
const fnArray = currentStyle !== 'none' ? matches : 'none'
if (fnArray instanceof Array) {
for (let j=0, jl = fnArray.length; j<jl; j++){
let p = fnArray[j].trim().split(/\((.+)/);
let pp = replaceDashNamespace(p[0]);
if ( pp === 'dropShadow' ) {
let shadowColor = p[1].match(/(([a-z].*?)\(.*?\))(?=\s(.*?))/)[0]
let params = p[1].replace(shadowColor,'').split(/\s/).map(parseFloat)
result[pp] = params.filter((el)=>!isNaN(el)).concat(shadowColor);
} else {
result[pp] = p[1].replace(/\'|\"|\)/g,'');
}
}
}
return result
}
// Component Functions
function getFilter(tweenProp,value) {
let currentStyle = getStyleForProperty(this.element,tweenProp),
filterObject = parseFilterString(currentStyle), fnp
for (let fn in value){
fnp = replaceDashNamespace(fn)
if ( !filterObject[fnp] ){
filterObject[fnp] = defaultValues[tweenProp][fn]
}
}
return filterObject;
}
function prepareFilter(tweenProp,value) {
let filterObject = {}, fnp
// {opacity: [0-100%], blur: [0-Nem], saturate: [0-N%], invert: 0, grayscale: [0-100%], brightness: [0-N%], contrast: [0-N%], sepia: [0-N%], 'hueRotate': [0-Ndeg], 'dropShadow': [0,0,0,(r:0,g:0,b:0)], url:''},
// {opacity: 100, blur: 0, saturate: 100, invert: 0, grayscale: 0, brightness: 100, contrast: 100, sepia: 0, 'hueRotate':0, 'dropShadow': 0, url:''},
for (let fn in value){
fnp = replaceDashNamespace(fn)
if ( /hue/.test(fn) ) {
filterObject[fnp] = parseFloat(value[fn])
} else if ( /drop/.test(fn) ) {
filterObject[fnp] = parseDropShadow(value[fn])
} else if ( fn === 'url' ) {
filterObject[fn] = value[fn]
// } else if ( /blur|opacity|grayscale|sepia/.test(fn) ) {
} else {
filterObject[fn] = parseFloat(value[fn])
}
}
return filterObject;
}
function crossCheckFilter(tweenProp){
if ( this.valuesEnd[tweenProp] ) {
for (const fn in this.valuesStart[tweenProp]){
if (!this.valuesEnd[tweenProp][fn]){
this.valuesEnd[tweenProp][fn] = this.valuesStart[tweenProp][fn]
}
}
}
}
// All Component Functions
const filterFunctions = {
prepareStart: getFilter,
prepareProperty: prepareFilter,
onStart: onStartFilter,
crossCheck: crossCheckFilter
}
// Full Component
const filterEffects = {
component: 'filterEffects',
property: 'filter',
// subProperties: ['blur', 'brightness','contrast','dropShadow','hueRotate','grayscale','invert','opacity','saturate','sepia','url'], // opacity function interfere with opacityProperty
defaultValue: {opacity: 100, blur: 0, saturate: 100, grayscale: 0, brightness: 100, contrast: 100, sepia: 0, invert: 0, hueRotate:0, dropShadow: [0,0,0,{r:0,g:0,b:0}], url:''},
Interpolate: {
opacity: numbers,
blur: numbers,
saturate: numbers,
grayscale: numbers,
brightness: numbers,
contrast: numbers,
sepia: numbers,
invert: numbers,
hueRotate: numbers,
dropShadow: {numbers,colors,dropShadow}
},
functions: filterFunctions,
Util: {parseDropShadow,parseFilterString,replaceDashNamespace,trueColor}
}
export default filterEffects
Components.FilterEffects = filterEffects
import getStyleForProperty from '../process/getStyleForProperty';
import defaultValues from '../objects/defaultValues';
import trueColor from '../util/trueColor';
import numbers from '../interpolation/numbers';
import colors from '../interpolation/colors';
import { dropshadow, onStartFilter } from './filterEffectsBase';
/* filterEffects = {
property: 'filter',
subProperties: {},
defaultValue: {},
interpolators: {},
functions = { prepareStart, prepareProperty, onStart, crossCheck }
} */
// Component Util
/**
* Returns camelCase filter sub-property.
* @param {string} str source string
* @returns {string} camelCase property name
*/
function replaceDashNamespace(str) {
return str.replace('-r', 'R').replace('-s', 'S');
}
/**
* Returns `drop-shadow` sub-property object.
* @param {(string | number)[]} shadow and `Array` with `drop-shadow` parameters
* @returns {KUTE.filterList['dropShadow']} the expected `drop-shadow` values
*/
function parseDropShadow(shadow) {
let newShadow;
if (shadow.length === 3) { // [h-shadow, v-shadow, color]
newShadow = [shadow[0], shadow[1], 0, shadow[2]];
} else if (shadow.length === 4) { // ideal [<offset-x>, <offset-y>, <blur-radius>, <color>]
newShadow = [shadow[0], shadow[1], shadow[2], shadow[3]];
}
// make sure the values are ready to tween
for (let i = 0; i < 3; i += 1) {
newShadow[i] = parseFloat(newShadow[i]);
}
// also the color must be a rgb object
newShadow[3] = trueColor(newShadow[3]);
return newShadow;
}
/**
* Returns an array with current filter sub-properties values.
* @param {string} currentStyle the current filter computed style
* @returns {{[x: string]: number}} the filter tuple
*/
function parseFilterString(currentStyle) {
const result = {};
const fnReg = /(([a-z].*?)\(.*?\))(?=\s([a-z].*?)\(.*?\)|\s*$)/g;
const matches = currentStyle.match(fnReg);
const fnArray = currentStyle !== 'none' ? matches : 'none';
if (fnArray instanceof Array) {
for (let j = 0, jl = fnArray.length; j < jl; j += 1) {
const p = fnArray[j].trim().split(/\((.+)/);
const pp = replaceDashNamespace(p[0]);
if (pp === 'dropShadow') {
const shadowColor = p[1].match(/(([a-z].*?)\(.*?\))(?=\s(.*?))/)[0];
const params = p[1].replace(shadowColor, '').split(/\s/).map(parseFloat);
result[pp] = params.filter((el) => !Number.isNaN(el)).concat(shadowColor);
} else {
result[pp] = p[1].replace(/'|"|\)/g, '');
}
}
}
return result;
}
// Component Functions
/**
* Returns the current property computed style.
* @param {string} tweenProp the property name
* @param {string} value the property value
* @returns {string} computed style for property
*/
function getFilter(tweenProp, value) {
const currentStyle = getStyleForProperty(this.element, tweenProp);
const filterObject = parseFilterString(currentStyle);
let fnp;
Object.keys(value).forEach((fn) => {
fnp = replaceDashNamespace(fn);
if (!filterObject[fnp]) {
filterObject[fnp] = defaultValues[tweenProp][fn];
}
});
return filterObject;
}
/**
* Returns the property tween object.
* @param {string} _ the property name
* @param {string} value the property name
* @returns {KUTE.filterList} the property tween object
*/
function prepareFilter(/* tweenProp, */_, value) {
const filterObject = {};
let fnp;
// property: range | default
// opacity: [0-100%] | 100
// blur: [0-Nem] | 0
// saturate: [0-N%] | 100
// invert: [0-100%] | 0
// grayscale: [0-100%] | 0
// brightness: [0-N%] | 100
// contrast: [0-N%] | 100
// sepia: [0-N%] | 0
// 'hueRotate': [0-Ndeg] | 0
// 'dropShadow': [0,0,0,(r:0,g:0,b:0)] | 0
// url: '' | ''
Object.keys(value).forEach((fn) => {
fnp = replaceDashNamespace(fn);
if (/hue/.test(fn)) {
filterObject[fnp] = parseFloat(value[fn]);
} else if (/drop/.test(fn)) {
filterObject[fnp] = parseDropShadow(value[fn]);
} else if (fn === 'url') {
filterObject[fn] = value[fn];
// } else if ( /blur|opacity|grayscale|sepia/.test(fn) ) {
} else {
filterObject[fn] = parseFloat(value[fn]);
}
});
return filterObject;
}
/**
* Adds missing sub-properties in `valuesEnd` from `valuesStart`.
* @param {string} tweenProp the property name
*/
function crossCheckFilter(tweenProp) {
if (this.valuesEnd[tweenProp]) {
Object.keys(this.valuesStart[tweenProp]).forEach((fn) => {
if (!this.valuesEnd[tweenProp][fn]) {
this.valuesEnd[tweenProp][fn] = this.valuesStart[tweenProp][fn];
}
});
}
}
// All Component Functions
const filterFunctions = {
prepareStart: getFilter,
prepareProperty: prepareFilter,
onStart: onStartFilter,
crossCheck: crossCheckFilter,
};
// Full Component
const filterEffects = {
component: 'filterEffects',
property: 'filter',
// opacity function interfere with opacityProperty
// subProperties: [
// 'blur', 'brightness','contrast','dropShadow',
// 'hueRotate','grayscale','invert','opacity','saturate','sepia','url'
// ],
defaultValue: {
opacity: 100,
blur: 0,
saturate: 100,
grayscale: 0,
brightness: 100,
contrast: 100,
sepia: 0,
invert: 0,
hueRotate: 0,
dropShadow: [0, 0, 0, { r: 0, g: 0, b: 0 }],
url: '',
},
Interpolate: {
opacity: numbers,
blur: numbers,
saturate: numbers,
grayscale: numbers,
brightness: numbers,
contrast: numbers,
sepia: numbers,
invert: numbers,
hueRotate: numbers,
dropShadow: { numbers, colors, dropshadow },
},
functions: filterFunctions,
Util: {
parseDropShadow, parseFilterString, replaceDashNamespace, trueColor,
},
};
export default filterEffects;

View file

@ -1,58 +1,74 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
import colors from '../interpolation/colors.js'
// const filterEffects = { property : 'filter', subProperties: {}, defaultValue: {}, interpolators: {} }, functions = { prepareStart, prepareProperty, onStart, crossCheck }
// Component Interpolation
export function dropShadow(a,b,v){
let params = [], unit = 'px'
for (let i=0; i<3; i++){
params[i] = ((numbers(a[i],b[i],v) * 100 >>0) /100) + unit
}
return `drop-shadow(${params.concat( colors(a[3],b[3],v) ).join(' ') })`
}
// Component Functions
export function onStartFilter(tweenProp) {
if ( this.valuesEnd[tweenProp] && !KUTE[tweenProp]) {
KUTE[tweenProp] = (elem, a, b, v) => {
a.dropShadow||b.dropShadow && console.log(dropShadow(a.dropShadow,b.dropShadow,v))
elem.style[tweenProp] = (b.url ? `url(${b.url})` : '')
+ (a.opacity||b.opacity ? `opacity(${((numbers(a.opacity,b.opacity,v) * 100)>>0)/100}%)` : '')
+ (a.blur||b.blur ? `blur(${((numbers(a.blur,b.blur,v) * 100)>>0)/100}em)` : '')
+ (a.saturate||b.saturate ? `saturate(${((numbers(a.saturate,b.saturate,v) * 100)>>0)/100}%)` : '')
+ (a.invert||b.invert ? `invert(${((numbers(a.invert,b.invert,v) * 100)>>0)/100}%)` : '')
+ (a.grayscale||b.grayscale ? `grayscale(${((numbers(a.grayscale,b.grayscale,v) * 100)>>0)/100}%)` : '')
+ (a.hueRotate||b.hueRotate ? `hue-rotate(${((numbers(a.hueRotate,b.hueRotate,v) * 100)>>0)/100 }deg)` : '')
+ (a.sepia||b.sepia ? `sepia(${((numbers(a.sepia,b.sepia,v) * 100)>>0)/100 }%)` : '')
+ (a.brightness||b.brightness ? `brightness(${((numbers(a.brightness,b.brightness,v) * 100)>>0)/100 }%)` : '')
+ (a.contrast||b.contrast ? `contrast(${((numbers(a.contrast,b.contrast,v) * 100)>>0)/100 }%)` : '')
+ (a.dropShadow||b.dropShadow ? dropShadow(a.dropShadow,b.dropShadow,v) : '')
}
}
}
// Base Component
const baseFilter = {
component: 'baseFilter',
property: 'filter',
// subProperties: ['blur', 'brightness','contrast','dropShadow','hueRotate','grayscale','invert','opacity','saturate','sepia','url'], // opacity function interfere with opacityProperty
// defaultValue: {opacity: 100, blur: 0, saturate: 100, grayscale: 0, brightness: 100, contrast: 100, sepia: 0, invert: 0, hueRotate:0, dropShadow: [0,0,0,{r:0,g:0,b:0}], url:''},
Interpolate: {
opacity: numbers,
blur: numbers,
saturate: numbers,
grayscale: numbers,
brightness: numbers,
contrast: numbers,
sepia: numbers,
invert: numbers,
hueRotate: numbers,
dropShadow: {numbers,colors,dropShadow}
},
functions: {onStart:onStartFilter}
}
export default baseFilter
import KEC from '../objects/kute';
import numbers from '../interpolation/numbers';
import colors from '../interpolation/colors';
// Component Interpolation
/**
* Sets the `drop-shadow` sub-property update function.
* * disimbiguation `dropshadow` interpolation function and `dropShadow` property
* @param {string} tweenProp the property name
*/
export function dropshadow(a, b, v) {
const params = [];
const unit = 'px';
for (let i = 0; i < 3; i += 1) {
// eslint-disable-next-line no-bitwise
params[i] = ((numbers(a[i], b[i], v) * 100 >> 0) / 100) + unit;
}
return `drop-shadow(${params.concat(colors(a[3], b[3], v)).join(' ')})`;
}
// Component Functions
/**
* Sets the property update function.
* @param {string} tweenProp the property name
*/
export function onStartFilter(tweenProp) {
if (this.valuesEnd[tweenProp] && !KEC[tweenProp]) {
KEC[tweenProp] = (elem, a, b, v) => {
/* eslint-disable-next-line no-param-reassign -- impossible to satisfy */
elem.style[tweenProp] = (b.url ? `url(${b.url})` : '')
/* eslint-disable no-bitwise -- impossible to satisfy */
+ (a.opacity || b.opacity ? `opacity(${((numbers(a.opacity, b.opacity, v) * 100) >> 0) / 100}%)` : '')
+ (a.blur || b.blur ? `blur(${((numbers(a.blur, b.blur, v) * 100) >> 0) / 100}em)` : '')
+ (a.saturate || b.saturate ? `saturate(${((numbers(a.saturate, b.saturate, v) * 100) >> 0) / 100}%)` : '')
+ (a.invert || b.invert ? `invert(${((numbers(a.invert, b.invert, v) * 100) >> 0) / 100}%)` : '')
+ (a.grayscale || b.grayscale ? `grayscale(${((numbers(a.grayscale, b.grayscale, v) * 100) >> 0) / 100}%)` : '')
+ (a.hueRotate || b.hueRotate ? `hue-rotate(${((numbers(a.hueRotate, b.hueRotate, v) * 100) >> 0) / 100}deg)` : '')
+ (a.sepia || b.sepia ? `sepia(${((numbers(a.sepia, b.sepia, v) * 100) >> 0) / 100}%)` : '')
+ (a.brightness || b.brightness ? `brightness(${((numbers(a.brightness, b.brightness, v) * 100) >> 0) / 100}%)` : '')
+ (a.contrast || b.contrast ? `contrast(${((numbers(a.contrast, b.contrast, v) * 100) >> 0) / 100}%)` : '')
+ (a.dropShadow || b.dropShadow ? dropshadow(a.dropShadow, b.dropShadow, v) : '');
/* eslint-enable no-bitwise -- impossible to satisfy */
};
}
}
// Base Component
const baseFilter = {
component: 'baseFilter',
property: 'filter',
// opacity function interfere with opacityProperty
// subProperties: ['blur', 'brightness','contrast','dropShadow',
// 'hueRotate','grayscale','invert','opacity','saturate','sepia','url'],
// defaultValue: {
// opacity: 100, blur: 0, saturate: 100, grayscale: 0,
// brightness: 100, contrast: 100, sepia: 0, invert: 0, hueRotate:0,
// dropShadow: [0,0,0,{r:0,g:0,b:0}], url:''
// },
Interpolate: {
opacity: numbers,
blur: numbers,
saturate: numbers,
grayscale: numbers,
brightness: numbers,
contrast: numbers,
sepia: numbers,
invert: numbers,
hueRotate: numbers,
dropShadow: { numbers, colors, dropshadow },
},
functions: { onStart: onStartFilter },
};
export default baseFilter;

View file

@ -1,93 +1,131 @@
import defaultValues from '../objects/defaultValues.js'
import onStart from '../objects/onStart.js'
import Components from '../objects/components.js'
import trueColor from '../util/trueColor.js'
import trueDimension from '../util/trueDimension.js'
import numbers from '../interpolation/numbers.js'
import colors from '../interpolation/colors.js'
import {attributes,onStartAttr} from './htmlAttributesBase.js'
// Component Name
let ComponentName = 'htmlAttributes'
// Component Properties
const svgColors = ['fill','stroke','stop-color'];
// Component Util
function replaceUppercase (a) { return a.replace(/[A-Z]/g, "-$&").toLowerCase(); }
// Component Functions
export function getAttr(tweenProp,value){
const attrStartValues = {};
for (const attr in value){
const attribute = replaceUppercase(attr).replace(/_+[a-z]+/,''); // get the value for 'fill-opacity' not fillOpacity, also 'width' not the internal 'width_px'
const currentValue = this.element.getAttribute(attribute);
attrStartValues[attribute] = svgColors.includes(attribute) ? (currentValue || 'rgba(0,0,0,0)') : (currentValue || (/opacity/i.test(attr) ? 1 : 0));
}
return attrStartValues;
}
export function prepareAttr(tweenProp,attrObj){ // attr (string),attrObj (object)
const attributesObject = {};
for ( const p in attrObj ) {
const prop = replaceUppercase(p);
const regex = /(%|[a-z]+)$/;
const currentValue = this.element.getAttribute(prop.replace(/_+[a-z]+/,''));
if ( !svgColors.includes(prop)) {
if ( currentValue !== null && regex.test(currentValue) ) { // attributes set with unit suffixes
const unit = trueDimension(currentValue).u || trueDimension(attrObj[p]).u;
const suffix = /%/.test(unit) ? '_percent' : `_${unit}`;
onStart[ComponentName][prop+suffix] = function(tp) { // most "unknown" attributes cannot register into onStart, so we manually add them
if ( this.valuesEnd[tweenProp] && this.valuesEnd[tweenProp][tp] && !(tp in attributes) ) {
attributes[tp] = (elem, p, a, b, v) => {
const _p = p.replace(suffix,'');
elem.setAttribute(_p, ( (numbers(a.v,b.v,v)*1000>>0)/1000) + b.u );
}
}
}
attributesObject[prop+suffix] = trueDimension(attrObj[p]);
} else if ( !regex.test(attrObj[p]) || currentValue === null || currentValue !== null && !regex.test(currentValue) ) {
onStart[ComponentName][prop] = function(tp) { // most "unknown" attributes cannot register into onStart, so we manually add them
if ( this.valuesEnd[tweenProp] && this.valuesEnd[tweenProp][tp] && !(tp in attributes) ) {
attributes[tp] = (elem, oneAttr, a, b, v) => {
elem.setAttribute(oneAttr, (numbers(a,b,v) * 1000 >> 0) / 1000 );
}
}
}
attributesObject[prop] = parseFloat(attrObj[p]);
}
} else { // colors
onStart[ComponentName][prop] = function(tp) { // most "unknown" attributes cannot register into onStart, so we manually add them
if ( this.valuesEnd[tweenProp] && this.valuesEnd[tweenProp][tp] && !(tp in attributes) ) {
attributes[tp] = (elem, oneAttr, a, b, v) => {
elem.setAttribute(oneAttr, colors(a,b,v));
}
}
}
attributesObject[prop] = trueColor(attrObj[p]) || defaultValues.htmlAttributes[p];
}
}
return attributesObject;
}
// All Component Functions
const attrFunctions = {
prepareStart: getAttr,
prepareProperty: prepareAttr,
onStart: onStartAttr
}
// Component Full
const htmlAttributes = {
component: ComponentName,
property: 'attr',
subProperties: ['fill','stroke','stop-color','fill-opacity','stroke-opacity'], // the Animation class will need some values to validate this Object attribute
defaultValue: {fill : 'rgb(0,0,0)', stroke: 'rgb(0,0,0)', 'stop-color': 'rgb(0,0,0)', opacity: 1, 'stroke-opacity': 1,'fill-opacity': 1}, // same here
Interpolate: { numbers,colors },
functions: attrFunctions,
// export to global for faster execution
Util: { replaceUppercase, trueColor, trueDimension }
}
export default htmlAttributes
Components.HTMLAttributes = htmlAttributes
import defaultValues from '../objects/defaultValues';
import onStart from '../objects/onStart';
import trueColor from '../util/trueColor';
import trueDimension from '../util/trueDimension';
import numbers from '../interpolation/numbers';
import colors from '../interpolation/colors';
import { attributes, onStartAttr } from './htmlAttributesBase';
// Component Name
const ComponentName = 'htmlAttributes';
// Component Properties
const svgColors = ['fill', 'stroke', 'stop-color'];
// Component Util
/**
* Returns non-camelcase property name.
* @param {string} a the camelcase property name
* @returns {string} the non-camelcase property name
*/
function replaceUppercase(a) { return a.replace(/[A-Z]/g, '-$&').toLowerCase(); }
// Component Functions
/**
* Returns the current attribute value.
* @param {string} _ the property name
* @param {string} value the property value
* @returns {{[x:string]: string}} attribute value
*/
export function getAttr(/* tweenProp, */_, value) {
const attrStartValues = {};
Object.keys(value).forEach((attr) => {
// get the value for 'fill-opacity' not fillOpacity
// also 'width' not the internal 'width_px'
const attribute = replaceUppercase(attr).replace(/_+[a-z]+/, '');
const currentValue = this.element.getAttribute(attribute);
attrStartValues[attribute] = svgColors.includes(attribute)
? (currentValue || 'rgba(0,0,0,0)')
: (currentValue || (/opacity/i.test(attr) ? 1 : 0));
});
return attrStartValues;
}
/**
* Returns the property tween object.
* @param {string} tweenProp the property name
* @param {string} attrObj the property value
* @returns {number} the property tween object
*/
export function prepareAttr(tweenProp, attrObj) { // attr (string),attrObj (object)
const attributesObject = {};
Object.keys(attrObj).forEach((p) => {
const prop = replaceUppercase(p);
const regex = /(%|[a-z]+)$/;
const currentValue = this.element.getAttribute(prop.replace(/_+[a-z]+/, ''));
if (!svgColors.includes(prop)) {
// attributes set with unit suffixes
if (currentValue !== null && regex.test(currentValue)) {
const unit = trueDimension(currentValue).u || trueDimension(attrObj[p]).u;
const suffix = /%/.test(unit) ? '_percent' : `_${unit}`;
// most "unknown" attributes cannot register into onStart, so we manually add them
onStart[ComponentName][prop + suffix] = (tp) => {
if (this.valuesEnd[tweenProp] && this.valuesEnd[tweenProp][tp] && !(tp in attributes)) {
attributes[tp] = (elem, oneAttr, a, b, v) => {
const _p = oneAttr.replace(suffix, '');
/* eslint no-bitwise: ["error", { "allow": [">>"] }] */
elem.setAttribute(_p, ((numbers(a.v, b.v, v) * 1000 >> 0) / 1000) + b.u);
};
}
};
attributesObject[prop + suffix] = trueDimension(attrObj[p]);
} else if (!regex.test(attrObj[p]) || currentValue === null
|| (currentValue !== null && !regex.test(currentValue))) {
// most "unknown" attributes cannot register into onStart, so we manually add them
onStart[ComponentName][prop] = (tp) => {
if (this.valuesEnd[tweenProp] && this.valuesEnd[tweenProp][tp] && !(tp in attributes)) {
attributes[tp] = (elem, oneAttr, a, b, v) => {
elem.setAttribute(oneAttr, (numbers(a, b, v) * 1000 >> 0) / 1000);
};
}
};
attributesObject[prop] = parseFloat(attrObj[p]);
}
} else { // colors
// most "unknown" attributes cannot register into onStart, so we manually add them
onStart[ComponentName][prop] = (tp) => {
if (this.valuesEnd[tweenProp] && this.valuesEnd[tweenProp][tp] && !(tp in attributes)) {
attributes[tp] = (elem, oneAttr, a, b, v) => {
elem.setAttribute(oneAttr, colors(a, b, v));
};
}
};
attributesObject[prop] = trueColor(attrObj[p]) || defaultValues.htmlAttributes[p];
}
});
return attributesObject;
}
// All Component Functions
const attrFunctions = {
prepareStart: getAttr,
prepareProperty: prepareAttr,
onStart: onStartAttr,
};
// Component Full
const htmlAttributes = {
component: ComponentName,
property: 'attr',
// the Animation class will need some values to validate this Object attribute
subProperties: ['fill', 'stroke', 'stop-color', 'fill-opacity', 'stroke-opacity'],
defaultValue: {
fill: 'rgb(0,0,0)',
stroke: 'rgb(0,0,0)',
'stop-color': 'rgb(0,0,0)',
opacity: 1,
'stroke-opacity': 1,
'fill-opacity': 1, // same here
},
Interpolate: { numbers, colors },
functions: attrFunctions,
// export to global for faster execution
Util: { replaceUppercase, trueColor, trueDimension },
};
export default htmlAttributes;

View file

@ -1,39 +1,59 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
import colors from '../interpolation/colors.js'
// Component Name
let ComponentName = 'baseHTMLAttributes'
// Component Special
let attributes = {};
export {attributes}
export const onStartAttr = {
attr : function(tweenProp){
if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) {
KUTE[tweenProp] = (elem, vS, vE, v) => {
for ( const oneAttr in vE ){
KUTE.attributes[oneAttr](elem,oneAttr,vS[oneAttr],vE[oneAttr],v);
}
}
}
},
attributes : function(tweenProp){
if (!KUTE[tweenProp] && this.valuesEnd.attr) {
KUTE[tweenProp] = attributes
}
}
}
// Component Base
const baseAttributes = {
component: ComponentName,
property: 'attr',
// subProperties: ['fill','stroke','stop-color','fill-opacity','stroke-opacity'], // the Animation class will need some values to validate this Object attribute
// defaultValue: {fill : 'rgb(0,0,0)', stroke: 'rgb(0,0,0)', 'stop-color': 'rgb(0,0,0)', opacity: 1, 'stroke-opacity': 1,'fill-opacity': 1}, // same here
Interpolate: { numbers,colors },
functions: {onStart:onStartAttr}
}
export default baseAttributes
import KEC from '../objects/kute';
import numbers from '../interpolation/numbers';
import colors from '../interpolation/colors';
// Component Name
const ComponentName = 'baseHTMLAttributes';
// Component Special
const attributes = {};
export { attributes };
export const onStartAttr = {
/**
* onStartAttr.attr
*
* Sets the sub-property update function.
* @param {string} tweenProp the property name
*/
attr(tweenProp) {
if (!KEC[tweenProp] && this.valuesEnd[tweenProp]) {
KEC[tweenProp] = (elem, vS, vE, v) => {
Object.keys(vE).forEach((oneAttr) => {
KEC.attributes[oneAttr](elem, oneAttr, vS[oneAttr], vE[oneAttr], v);
});
};
}
},
/**
* onStartAttr.attributes
*
* Sets the update function for the property.
* @param {string} tweenProp the property name
*/
attributes(tweenProp) {
if (!KEC[tweenProp] && this.valuesEnd.attr) {
KEC[tweenProp] = attributes;
}
},
};
// Component Base
const baseAttributes = {
component: ComponentName,
property: 'attr',
// the Animation class will need some values to validate this Object attribute
// subProperties: ['fill','stroke','stop-color','fill-opacity','stroke-opacity'],
// defaultValue:
// fill : 'rgb(0,0,0)',
// stroke: 'rgb(0,0,0)',
// 'stop-color': 'rgb(0,0,0)',
// opacity: 1,
// 'stroke-opacity': 1,
// 'fill-opacity': 1 // same here
// },
Interpolate: { numbers, colors },
functions: { onStart: onStartAttr },
};
export default baseAttributes;

View file

@ -1,34 +1,41 @@
import getStyleForProperty from '../process/getStyleForProperty.js'
import Components from '../objects/components.js'
import numbers from '../interpolation/numbers.js'
import {onStartOpacity} from './opacityPropertyBase.js'
// const opacityProperty = { property : 'opacity', defaultValue: 1, interpolators: {numbers} }, functions = { prepareStart, prepareProperty, onStart }
// Component Functions
function getOpacity(tweenProp){
return getStyleForProperty(this.element,tweenProp)
}
function prepareOpacity(tweenProp,value){
return parseFloat(value); // opacity always FLOAT
}
// All Component Functions
const opacityFunctions = {
prepareStart: getOpacity,
prepareProperty: prepareOpacity,
onStart: onStartOpacity
}
// Full Component
const opacityProperty = {
component: 'opacityProperty',
property: 'opacity',
defaultValue: 1,
Interpolate: {numbers},
functions: opacityFunctions
}
export default opacityProperty
Components.OpacityProperty = opacityProperty
import getStyleForProperty from '../process/getStyleForProperty';
import numbers from '../interpolation/numbers';
import { onStartOpacity } from './opacityPropertyBase';
// Component Functions
/**
* Returns the current property computed style.
* @param {string} tweenProp the property name
* @returns {string} computed style for property
*/
function getOpacity(tweenProp/* , value */) {
return getStyleForProperty(this.element, tweenProp);
}
/**
* Returns the property tween object.
* @param {string} _ the property name
* @param {string} value the property value
* @returns {number} the property tween object
*/
function prepareOpacity(/* tweenProp, */_, value) {
return parseFloat(value); // opacity always FLOAT
}
// All Component Functions
const opacityFunctions = {
prepareStart: getOpacity,
prepareProperty: prepareOpacity,
onStart: onStartOpacity,
};
// Full Component
const OpacityProperty = {
component: 'opacityProperty',
property: 'opacity',
defaultValue: 1,
Interpolate: { numbers },
functions: opacityFunctions,
};
export default OpacityProperty;

View file

@ -1,24 +1,36 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
// const opacityProperty = { property : 'opacity', defaultValue: 1, interpolators: {numbers} }, functions = { prepareStart, prepareProperty, onStart }
// Component Functions
export function onStartOpacity(tweenProp){
if ( tweenProp in this.valuesEnd && !KUTE[tweenProp]) { // opacity could be 0
KUTE[tweenProp] = (elem, a, b, v) => {
elem.style[tweenProp] = ((numbers(a,b,v) * 1000)>>0)/1000;
}
}
}
// Base Component
const baseOpacity = {
component: 'baseOpacity',
property: 'opacity',
// defaultValue: 1,
Interpolate: {numbers},
functions: {onStart: onStartOpacity}
}
export default baseOpacity
import KEC from '../objects/kute';
import numbers from '../interpolation/numbers';
/* opacityProperty = {
property: 'opacity',
defaultValue: 1,
interpolators: {numbers},
functions = { prepareStart, prepareProperty, onStart }
} */
// Component Functions
/**
* Sets the property update function.
* @param {string} tweenProp the property name
*/
export function onStartOpacity(tweenProp/* , value */) {
// opacity could be 0 sometimes, we need to check regardless
if (tweenProp in this.valuesEnd && !KEC[tweenProp]) {
KEC[tweenProp] = (elem, a, b, v) => {
/* eslint-disable */
elem.style[tweenProp] = ((numbers(a, b, v) * 1000) >> 0) / 1000;
/* eslint-enable */
};
}
}
// Base Component
const OpacityPropertyBase = {
component: 'baseOpacity',
property: 'opacity',
// defaultValue: 1,
Interpolate: { numbers },
functions: { onStart: onStartOpacity },
};
export default OpacityPropertyBase;

View file

@ -1,38 +1,59 @@
import Components from '../objects/components.js'
import numbers from '../interpolation/numbers.js'
import supportPassive from 'shorter-js/src/boolean/supportPassive.js'
import {scrollContainer,onStartScroll,onCompleteScroll,scrollIn,scrollOut,getScrollTargets,preventScroll,toggleScrollEvents} from './scrollPropertyBase.js'
// Component Functions
function getScroll(){
this.element = ('scroll' in this.valuesEnd) && (!this.element || this.element === window) ? scrollContainer : this.element;
return this.element === scrollContainer ? (window.pageYOffset || scrollContainer.scrollTop) : this.element.scrollTop;
}
function prepareScroll(prop,value){
return parseInt(value);
}
// All Component Functions
const scrollFunctions = {
prepareStart: getScroll,
prepareProperty: prepareScroll,
onStart: onStartScroll,
onComplete: onCompleteScroll
}
// Full Component
const scrollProperty = {
component: 'scrollProperty',
property: 'scroll',
defaultValue: 0,
Interpolate: {numbers},
functions: scrollFunctions,
// export stuff to global
Util: { preventScroll, scrollIn, scrollOut, getScrollTargets, toggleScrollEvents, supportPassive }
}
export default scrollProperty
Components.ScrollProperty = scrollProperty
import numbers from '../interpolation/numbers';
import {
scrollContainer,
onStartScroll,
onCompleteScroll,
scrollIn,
scrollOut,
getScrollTargets,
preventScroll,
toggleScrollEvents,
} from './scrollPropertyBase';
// Component Functions
/**
* Returns the current property computed style.
* @returns {number} computed style for property
*/
function getScroll() {
this.element = ('scroll' in this.valuesEnd) && (!this.element || this.element === window)
? scrollContainer : this.element;
return this.element === scrollContainer
? (window.pageYOffset || scrollContainer.scrollTop)
: this.element.scrollTop;
}
/**
* Returns the property tween object.
* @param {string} _ the property name
* @param {string} value the property value
* @returns {number} the property tween object
*/
function prepareScroll(/* prop, */_, value) {
return parseInt(value, 10);
}
// All Component Functions
const scrollFunctions = {
prepareStart: getScroll,
prepareProperty: prepareScroll,
onStart: onStartScroll,
onComplete: onCompleteScroll,
};
// Full Component
const ScrollProperty = {
component: 'scrollProperty',
property: 'scroll',
defaultValue: 0,
Interpolate: { numbers },
functions: scrollFunctions,
// export stuff to global
Util: {
preventScroll, scrollIn, scrollOut, getScrollTargets, toggleScrollEvents,
},
};
export default ScrollProperty;

View file

@ -1,79 +1,113 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
import supportPassive from 'shorter-js/src/boolean/supportPassive.js'
import mouseHoverEvents from 'shorter-js/src/strings/mouseHoverEvents.js'
import supportTouch from 'shorter-js/src/boolean/supportTouch.js'
// Component Util
// events preventing scroll
const touchOrWheel = supportTouch ? 'touchstart' : 'mousewheel'
// true scroll container
// very important and specific to the component
export const scrollContainer = navigator && /(EDGE|Mac)/i.test(navigator.userAgent) ? document.body : document.documentElement
// scroll event options
// it's important to stop propagating when animating scroll
const passiveHandler = supportPassive ? { passive: false } : false
// prevent mousewheel or touch events while tweening scroll
export function preventScroll(e) {
this.scrolling && e.preventDefault()
}
export function getScrollTargets(){
let el = this.element
return el === scrollContainer ? { el: document, st: document.body } : { el: el, st: el}
}
export function toggleScrollEvents(action,element){
element[action]( mouseHoverEvents[0], preventScroll, passiveHandler);
element[action]( touchOrWheel, preventScroll, passiveHandler);
}
export function scrollIn(){
let targets = getScrollTargets.call(this)
if ( 'scroll' in this.valuesEnd && !targets.el.scrolling) {
targets.el.scrolling = 1;
toggleScrollEvents('addEventListener',targets.el)
targets.st.style.pointerEvents = 'none'
}
}
export function scrollOut(){ //prevent scroll when tweening scroll
let targets = getScrollTargets.call(this)
if ( 'scroll' in this.valuesEnd && targets.el.scrolling) {
targets.el.scrolling = 0;
toggleScrollEvents('removeEventListener',targets.el)
targets.st.style.pointerEvents = ''
}
}
// Component Functions
export function onStartScroll(tweenProp){
if ( tweenProp in this.valuesEnd && !KUTE[tweenProp]) { // checking 0 will NOT add the render function
this.element = ('scroll' in this.valuesEnd) && (!this.element || this.element === window) ? scrollContainer : this.element;
scrollIn.call(this);
KUTE[tweenProp] = (elem, a, b, v) => {
elem.scrollTop = (numbers(a,b,v))>>0;
};
}
}
export function onCompleteScroll(tweenProp){
scrollOut.call(this)
}
// Base Component
const baseScroll = {
component: 'baseScroll',
property: 'scroll',
// defaultValue: 0,
Interpolate: {numbers},
functions: {
onStart: onStartScroll,
onComplete: onCompleteScroll
},
// unfortunatelly scroll needs all them no matter the packaging
Util: { preventScroll, scrollIn, scrollOut, getScrollTargets, supportPassive }
}
export default baseScroll
import passiveHandler from 'shorter-js/src/misc/passiveHandler';
import mouseHoverEvents from 'shorter-js/src/strings/mouseHoverEvents';
import supportTouch from 'shorter-js/src/boolean/supportTouch';
import numbers from '../interpolation/numbers';
import KEC from '../objects/kute';
// Component Util
// events preventing scroll
const touchOrWheel = supportTouch ? 'touchstart' : 'mousewheel';
// true scroll container
// very important and specific to the component
export const scrollContainer = navigator && /(EDGE|Mac)/i.test(navigator.userAgent)
? document.body
: document.documentElement;
/**
* Prevent further scroll events until scroll animation is over.
* @param {Event} e event object
*/
export function preventScroll(e) {
if (this.scrolling) e.preventDefault();
}
/**
* Returns the scroll element / target.
* @returns {{el: Element, st: Element}}
*/
export function getScrollTargets() {
const el = this.element;
return el === scrollContainer ? { el: document, st: document.body } : { el, st: el };
}
/**
* Toggles scroll prevention callback on scroll events.
* @param {string} action addEventListener / removeEventListener
* @param {Element} element target
*/
export function toggleScrollEvents(action, element) {
element[action](mouseHoverEvents[0], preventScroll, passiveHandler);
element[action](touchOrWheel, preventScroll, passiveHandler);
}
/**
* Action performed before scroll animation start.
*/
export function scrollIn() {
const targets = getScrollTargets.call(this);
if ('scroll' in this.valuesEnd && !targets.el.scrolling) {
targets.el.scrolling = 1;
toggleScrollEvents('addEventListener', targets.el);
targets.st.style.pointerEvents = 'none';
}
}
/**
* Action performed when scroll animation ends.
*/
export function scrollOut() { // prevent scroll when tweening scroll
const targets = getScrollTargets.call(this);
if ('scroll' in this.valuesEnd && targets.el.scrolling) {
targets.el.scrolling = 0;
toggleScrollEvents('removeEventListener', targets.el);
targets.st.style.pointerEvents = '';
}
}
// Component Functions
/**
* * Sets the scroll target.
* * Adds the scroll prevention event listener.
* * Sets the property update function.
* @param {string} tweenProp the property name
*/
export function onStartScroll(tweenProp) {
// checking 0 will NOT add the render function
if (tweenProp in this.valuesEnd && !KEC[tweenProp]) {
this.element = ('scroll' in this.valuesEnd) && (!this.element || this.element === window)
? scrollContainer : this.element;
scrollIn.call(this);
KEC[tweenProp] = (elem, a, b, v) => {
/* eslint-disable */
elem.scrollTop = (numbers(a, b, v)) >> 0;
/* eslint-enable */
};
}
}
/**
* Removes the scroll prevention event listener.
*/
export function onCompleteScroll(/* tweenProp */) {
scrollOut.call(this);
}
// Base Component
const ScrollPropertyBase = {
component: 'baseScroll',
property: 'scroll',
// defaultValue: 0,
Interpolate: { numbers },
functions: {
onStart: onStartScroll,
onComplete: onCompleteScroll,
},
// unfortunatelly scroll needs all them no matter the packaging
Util: {
preventScroll, scrollIn, scrollOut, getScrollTargets,
},
};
export default ScrollPropertyBase;

View file

@ -1,93 +1,127 @@
import defaultValues from '../objects/defaultValues.js'
import Components from '../objects/components.js'
import getStyleForProperty from '../process/getStyleForProperty.js'
import trueColor from '../util/trueColor.js'
import numbers from '../interpolation/numbers.js'
import colors from '../interpolation/colors.js'
import {onStartShadow} from './shadowPropertiesBase.js'
// Component Properties
const shadowProps = ['boxShadow','textShadow']
// Component Util
// box-shadow: none | h-shadow v-shadow blur spread color inset|initial|inherit
// text-shadow: none | offset-x offset-y blur-radius color |initial|inherit
// utility function to process values accordingly
// numbers must be floats and color must be rgb object
function processShadowArray (shadow,tweenProp){
let newShadow, i;
if (shadow.length === 3) { // [h-shadow, v-shadow, color]
newShadow = [shadow[0], shadow[1], 0, 0, shadow[2], 'none'];
} else if (shadow.length === 4) { // [h-shadow, v-shadow, color, inset] | [h-shadow, v-shadow, blur, color]
newShadow = /inset|none/.test(shadow[3]) ? [shadow[0], shadow[1], 0, 0, shadow[2], shadow[3]] : [shadow[0], shadow[1], shadow[2], 0, shadow[3], 'none'];
} else if (shadow.length === 5) { // [h-shadow, v-shadow, blur, color, inset] | [h-shadow, v-shadow, blur, spread, color]
newShadow = /inset|none/.test(shadow[4]) ? [shadow[0], shadow[1], shadow[2], 0, shadow[3], shadow[4]] : [shadow[0], shadow[1], shadow[2], shadow[3], shadow[4], 'none'];
} else if (shadow.length === 6) { // ideal [h-shadow, v-shadow, blur, spread, color, inset]
newShadow = shadow;
}
// make sure the values are ready to tween
for (i=0;i<4;i++){
newShadow[i] = parseFloat(newShadow[i]);
}
// also the color must be a rgb object
newShadow[4] = trueColor(newShadow[4]);
// return tweenProp === 'boxShadow' ? newShadow : [newShadow[0],newShadow[1],newShadow[2],newShadow[4]];
newShadow = tweenProp === 'boxShadow' ? newShadow : newShadow.filter((x,i)=>[0,1,2,4].indexOf(i)>-1);
return newShadow;
}
// Component Functions
export function getShadow(tweenProp,value){
let cssShadow = getStyleForProperty(this.element,tweenProp);
return /^none$|^initial$|^inherit$|^inset$/.test(cssShadow) ? defaultValues[tweenProp] : cssShadow; // '0px 0px 0px 0px rgb(0,0,0)'
}
export function prepareShadow(tweenProp,value) {
// [horizontal, vertical, blur, spread, color: {r:0,g:0,b:0}, inset]
// parseProperty for boxShadow, builds basic structure with ready to tween values
if (typeof value === 'string'){
let currentColor, inset = 'none';
// a full RegEx for color strings
const colRegEx = /(\s?(?:#(?:[\da-f]{3}){1,2}|rgba?\(\d{1,3},\s*\d{1,3},\s*\d{1,3}\))\s?)/gi
// make sure to always have the inset last if possible
inset = /inset/.test(value) ? 'inset' : inset;
value = /inset/.test(value) ? value.replace(/(\s+inset|inset+\s)/g,'') : value;
// also getComputedStyle often returns color first "rgb(0, 0, 0) 15px 15px 6px 0px inset"
currentColor = value.match(colRegEx);
value = value.replace(currentColor[0],'').split(' ').concat([currentColor[0].replace(/\s/g,'')],[inset]);
value = processShadowArray(value,tweenProp);
} else if (value instanceof Array){
value = processShadowArray(value,tweenProp);
}
return value;
}
const shadowPropOnStart = {}
shadowProps.map(x=>shadowPropOnStart[x]=onStartShadow)
// All Component Functions
const shadowFunctions = {
prepareStart: getShadow,
prepareProperty: prepareShadow,
onStart: shadowPropOnStart
}
// Component Full
const shadowProperties = {
component: 'shadowProperties',
properties: shadowProps,
defaultValues: {boxShadow :'0px 0px 0px 0px rgb(0,0,0)', textShadow: '0px 0px 0px rgb(0,0,0)'},
Interpolate: {numbers,colors},
functions: shadowFunctions,
Util: { processShadowArray, trueColor }
}
export default shadowProperties
Components.ShadowProperties = shadowProperties
import defaultValues from '../objects/defaultValues';
import getStyleForProperty from '../process/getStyleForProperty';
import trueColor from '../util/trueColor';
import numbers from '../interpolation/numbers';
import colors from '../interpolation/colors';
import { onStartShadow } from './shadowPropertiesBase';
// Component Properties
const shadowProps = ['boxShadow', 'textShadow'];
// Component Util
/**
* Return the box-shadow / text-shadow tween object.
* * box-shadow: none | h-shadow v-shadow blur spread color inset|initial|inherit
* * text-shadow: none | offset-x offset-y blur-radius color |initial|inherit
* * numbers must be floats and color must be rgb object
*
* @param {(number | string)[]} shadow an `Array` with shadow parameters
* @param {string} tweenProp the property name
* @returns {KUTE.shadowObject} the property tween object
*/
function processShadowArray(shadow, tweenProp) {
let newShadow;
// [h-shadow, v-shadow, color]
if (shadow.length === 3) {
newShadow = [shadow[0], shadow[1], 0, 0, shadow[2], 'none'];
// [h-shadow, v-shadow, color, inset] | [h-shadow, v-shadow, blur, color]
} else if (shadow.length === 4) {
newShadow = /inset|none/.test(shadow[3])
? [shadow[0], shadow[1], 0, 0, shadow[2], shadow[3]]
: [shadow[0], shadow[1], shadow[2], 0, shadow[3], 'none'];
// [h-shadow, v-shadow, blur, color, inset] | [h-shadow, v-shadow, blur, spread, color]
} else if (shadow.length === 5) {
newShadow = /inset|none/.test(shadow[4])
? [shadow[0], shadow[1], shadow[2], 0, shadow[3], shadow[4]]
: [shadow[0], shadow[1], shadow[2], shadow[3], shadow[4], 'none'];
// ideal [h-shadow, v-shadow, blur, spread, color, inset]
} else if (shadow.length === 6) {
newShadow = shadow;
}
// make sure the values are ready to tween
for (let i = 0; i < 4; i += 1) {
newShadow[i] = parseFloat(newShadow[i]);
}
// also the color must be a rgb object
newShadow[4] = trueColor(newShadow[4]);
newShadow = tweenProp === 'boxShadow'
? newShadow
: newShadow.filter((_, i) => [0, 1, 2, 4].includes(i));
return newShadow;
}
// Component Functions
/**
* Returns the current property computed style.
* @param {string} tweenProp the property name
* @returns {string} computed style for property
*/
export function getShadow(tweenProp/* , value */) {
const cssShadow = getStyleForProperty(this.element, tweenProp);
// '0px 0px 0px 0px rgb(0,0,0)'
return /^none$|^initial$|^inherit$|^inset$/.test(cssShadow)
? defaultValues[tweenProp]
: cssShadow;
}
/**
* Returns the property tween object.
* @param {string} tweenProp the property name
* @param {string} propValue the property value
* @returns {KUTE.shadowObject} the property tween object
*/
export function prepareShadow(tweenProp, propValue) {
// [horizontal, vertical, blur, spread, color: {r:0,g:0,b:0}, inset]
// parseProperty for boxShadow, builds basic structure with ready to tween values
let value = propValue;
if (typeof value === 'string') {
let inset = 'none';
// a full RegEx for color strings
const colRegEx = /(\s?(?:#(?:[\da-f]{3}){1,2}|rgba?\(\d{1,3},\s*\d{1,3},\s*\d{1,3}\))\s?)/gi;
const currentColor = value.match(colRegEx);
// make sure to always have the inset last if possible
inset = /inset/.test(value) ? 'inset' : inset;
value = /inset/.test(value) ? value.replace(/(\s+inset|inset+\s)/g, '') : value;
// also getComputedStyle often returns color first "rgb(0, 0, 0) 15px 15px 6px 0px inset"
value = value.replace(currentColor[0], '').split(' ').concat([currentColor[0].replace(/\s/g, '')], [inset]);
value = processShadowArray(value, tweenProp);
} else if (value instanceof Array) {
value = processShadowArray(value, tweenProp);
}
return value;
}
const shadowPropOnStart = {};
shadowProps.forEach((x) => { shadowPropOnStart[x] = onStartShadow; });
// All Component Functions
const shadowFunctions = {
prepareStart: getShadow,
prepareProperty: prepareShadow,
onStart: shadowPropOnStart,
};
// Component Full
const ShadowProperties = {
component: 'shadowProperties',
properties: shadowProps,
defaultValues: {
boxShadow: '0px 0px 0px 0px rgb(0,0,0)',
textShadow: '0px 0px 0px rgb(0,0,0)',
},
Interpolate: { numbers, colors },
functions: shadowFunctions,
Util: { processShadowArray, trueColor },
};
export default ShadowProperties;

View file

@ -1,38 +1,46 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
import colors from '../interpolation/colors.js'
// Component Properties
const shadowProps = ['boxShadow','textShadow']
// Component Functions
export function onStartShadow(tweenProp) {
if ( this.valuesEnd[tweenProp] && !KUTE[tweenProp]) {
KUTE[tweenProp] = (elem, a, b, v) => {
// let's start with the numbers | set unit | also determine inset
let params = [], unit = 'px', sl = tweenProp === 'textShadow' ? 3 : 4,
colA = sl === 3 ? a[3] : a[4], colB = sl === 3 ? b[3] : b[4],
inset = a[5] && a[5] !== 'none' || b[5] && b[5] !== 'none' ? ' inset' : false;
for (let i=0; i<sl; i++){
params.push( ((numbers( a[i], b[i], v ) * 1000 >> 0) / 1000) + unit );
}
// the final piece of the puzzle, the DOM update
elem.style[tweenProp] = inset ? colors(colA,colB,v) + params.join(' ') + inset
: colors(colA,colB,v) + params.join(' ');
}
}
}
const shadowPropOnStart = {}
shadowProps.map(x=>shadowPropOnStart[x]=onStartShadow)
// Component Base
const baseShadow = {
component: 'baseShadow',
// properties: shadowProps,
// defaultValues: {boxShadow :'0px 0px 0px 0px rgb(0,0,0)', textShadow: '0px 0px 0px 0px rgb(0,0,0)'},
Interpolate: {numbers,colors},
functions: {onStart: shadowPropOnStart}
}
export default baseShadow
import KEC from '../objects/kute';
import numbers from '../interpolation/numbers';
import colors from '../interpolation/colors';
// Component Properties
const shadowProps = ['boxShadow', 'textShadow'];
// Component Functions
/**
* Sets the property update function.
* @param {string} tweenProp the property name
*/
export function onStartShadow(tweenProp) {
if (this.valuesEnd[tweenProp] && !KEC[tweenProp]) {
KEC[tweenProp] = (elem, a, b, v) => {
// let's start with the numbers | set unit | also determine inset
const params = [];
const unit = 'px';
const sl = tweenProp === 'textShadow' ? 3 : 4;
const colA = sl === 3 ? a[3] : a[4];
const colB = sl === 3 ? b[3] : b[4];
const inset = (a[5] && a[5] !== 'none') || (b[5] && b[5] !== 'none') ? ' inset' : false;
for (let i = 0; i < sl; i += 1) {
/* eslint no-bitwise: ["error", { "allow": [">>"] }] */
params.push(((numbers(a[i], b[i], v) * 1000 >> 0) / 1000) + unit);
}
// the final piece of the puzzle, the DOM update
// eslint-disable-next-line no-param-reassign -- impossible to satisfy
elem.style[tweenProp] = inset
? colors(colA, colB, v) + params.join(' ') + inset
: colors(colA, colB, v) + params.join(' ');
};
}
}
const shadowPropOnStart = {};
shadowProps.forEach((x) => { shadowPropOnStart[x] = onStartShadow; });
// Component Base
const ShadowPropertiesBase = {
component: 'baseShadow',
Interpolate: { numbers, colors },
functions: { onStart: shadowPropOnStart },
};
export default ShadowPropertiesBase;

View file

@ -1,663 +1,229 @@
import Components from '../objects/components.js'
import selector from '../util/selector.js'
import numbers from '../interpolation/numbers.js'
import {toPathString,onStartCubicMorph} from './svgCubicMorphBase.js'
// const SVGMorph = { property : 'path', defaultValue: [], interpolators: {numbers} }, functions = { prepareStart, prepareProperty, onStart, crossCheck }
// Component Util
const INVALID_INPUT = 'Invalid path value'
/* Raphael.js - path (https://github.com/DmitryBaranovskiy/raphael)
* Copyright © 2008-2013 Dmitry Baranovskiy (http://dmitrybaranovskiy.github.io/raphael/)
* Copyright © 2008-2013 Sencha Labs (http://sencha.com)
* Licensed under the MIT (http://dmitrybaranovskiy.github.io/raphael/license.html) license.
* KUTE.js modifications
* - parsePathString is now moved outside of main functions
* - processPath moved outside pathToAbsolute function body
* - fixArc moved outside path2curve function body
* - fixM moved outside path2curve function body
* - minor fixes like "a != b" => "a !== b", various undefined/unused variables
*/
// http://schepers.cc/getting-to-the-point
function catmullRom2bezier(crp, z) {
const d = [];
for (let i = 0, iLen = crp.length; iLen - 2 * !z > i; i += 2) {
const p = [
{x: +crp[i - 2], y: +crp[i - 1]},
{x: +crp[i], y: +crp[i + 1]},
{x: +crp[i + 2], y: +crp[i + 3]},
{x: +crp[i + 4], y: +crp[i + 5]}
];
if (z) {
if (!i) {
p[0] = {x: +crp[iLen - 2], y: +crp[iLen - 1]};
} else if (iLen - 4 == i) {
p[3] = {x: +crp[0], y: +crp[1]};
} else if (iLen - 2 == i) {
p[2] = {x: +crp[0], y: +crp[1]};
p[3] = {x: +crp[2], y: +crp[3]};
}
} else {
if (iLen - 4 == i) {
p[3] = p[2];
} else if (!i) {
p[0] = {x: +crp[i], y: +crp[i + 1]};
}
}
d.push(["C",
(-p[0].x + 6 * p[1].x + p[2].x) / 6,
(-p[0].y + 6 * p[1].y + p[2].y) / 6,
(p[1].x + 6 * p[2].x - p[3].x) / 6,
(p[1].y + 6*p[2].y - p[3].y) / 6,
p[2].x,
p[2].y
])
}
return d
}
function ellipsePath(x, y, rx, ry, a) {
if (a == null && ry == null) {
ry = rx;
}
x = +x;
y = +y;
rx = +rx;
ry = +ry;
let res;
if (a != null) {
const rad = Math.PI / 180,
x1 = x + rx * Math.cos(-ry * rad),
x2 = x + rx * Math.cos(-a * rad),
y1 = y + rx * Math.sin(-ry * rad),
y2 = y + rx * Math.sin(-a * rad);
res = [["M", x1, y1], ["A", rx, rx, 0, +(a - ry > 180), 0, x2, y2]];
} else {
res = [
["M", x, y],
["m", 0, -ry],
["a", rx, ry, 0, 1, 1, 0, 2 * ry],
["a", rx, ry, 0, 1, 1, 0, -2 * ry],
["z"]
];
}
return res;
}
// Parses given path string into an array of arrays of path segments
function parsePathString(pathString) {
if (!pathString) {
return null;
}
if( pathString instanceof Array ) {
return pathString;
} else {
// tracer minifier cannot compute this string for some reason
// let spaces = "\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029";
let spaces = `\\${("x09|x0a|x0b|x0c|x0d|x20|xa0|u1680|u180e|u2000|u2001|u2002|u2003|u2004|u2005|u2006|u2007|u2008|u2009|u200a|u202f|u205f|u3000|u2028|u2029").split('|').join('\\')}`,
pathCommand = new RegExp(`([a-z])[${spaces},]*((-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?[${spaces}]*,?[${spaces}]*)+)`, `ig`),
pathValues = new RegExp(`(-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?)[${spaces}]*,?[${spaces}]*`, `ig`),
paramCounts = {a: 7, c: 6, o: 2, h: 1, l: 2, m: 2, r: 4, q: 4, s: 4, t: 2, v: 1, u: 3, z: 0},
data = [];
pathString.replace(pathCommand, (a, b, c) => {
let params = [], name = b.toLowerCase();
c.replace(pathValues, (a, b) => {
b && params.push(+b);
});
if (name == "m" && params.length > 2) {
data.push([b].concat(params.splice(0, 2)));
name = "l";
b = b == "m" ? "l" : "L";
}
if (name == "o" && params.length == 1) {
data.push([b, params[0]]);
}
if (name == "r") {
data.push([b].concat(params));
} else while (params.length >= paramCounts[name]) {
data.push([b].concat(params.splice(0, paramCounts[name])));
if (!paramCounts[name]) {
break;
}
}
});
return data;
}
}
function pathToAbsolute(pathArray) {
pathArray = parsePathString(pathArray);
if (!pathArray || !pathArray.length) {
return [["M", 0, 0]];
}
let res = [], x = 0, y = 0, mx = 0, my = 0, start = 0, pa0;
if (pathArray[0][0] === "M") {
x = +pathArray[0][1];
y = +pathArray[0][2];
mx = x;
my = y;
start++;
res[0] = ["M", x, y];
}
const crz = pathArray.length === 3 &&
pathArray[0][0] === "M" &&
pathArray[1][0].toUpperCase() === "R" &&
pathArray[2][0].toUpperCase() === "Z";
for (let r, pa, i = start, ii = pathArray.length; i < ii; i++) {
res.push(r = []);
pa = pathArray[i];
pa0 = pa[0];
if (pa0 !== pa0.toUpperCase()) {
r[0] = pa0.toUpperCase();
switch (r[0]) {
case "A":
r[1] = pa[1];
r[2] = pa[2];
r[3] = pa[3];
r[4] = pa[4];
r[5] = pa[5];
r[6] = +pa[6] + x;
r[7] = +pa[7] + y;
break;
case "V":
r[1] = +pa[1] + y;
break;
case "H":
r[1] = +pa[1] + x;
break;
case "R":
var dots = [x, y].concat(pa.slice(1));
for (var j = 2, jj = dots.length; j < jj; j++) {
dots[j] = +dots[j] + x;
dots[++j] = +dots[j] + y;
}
res.pop();
res = res.concat(catmullRom2bezier(dots, crz));
break;
case "O":
res.pop();
dots = ellipsePath(x, y, pa[1], pa[2]);
dots.push(dots[0]);
res = res.concat(dots);
break;
case "U":
res.pop();
res = res.concat(ellipsePath(x, y, pa[1], pa[2], pa[3]));
r = ["U"].concat(res[res.length - 1].slice(-2));
break;
case "M":
mx = +pa[1] + x;
my = +pa[2] + y;
default:
for (j = 1, jj = pa.length; j < jj; j++) {
r[j] = +pa[j] + ((j % 2) ? x : y);
}
}
} else if (pa0 == "R") {
dots = [x, y].concat(pa.slice(1));
res.pop();
res = res.concat(catmullRom2bezier(dots, crz));
r = ["R"].concat(pa.slice(-2));
} else if (pa0 == "O") {
res.pop();
dots = ellipsePath(x, y, pa[1], pa[2]);
dots.push(dots[0]);
res = res.concat(dots);
} else if (pa0 == "U") {
res.pop();
res = res.concat(ellipsePath(x, y, pa[1], pa[2], pa[3]));
r = ["U"].concat(res[res.length - 1].slice(-2));
} else {
for (let k = 0, kk = pa.length; k < kk; k++) {
r[k] = pa[k];
}
}
pa0 = pa0.toUpperCase();
if (pa0 != "O") {
switch (r[0]) {
case "Z":
x = +mx;
y = +my;
break;
case "H":
x = r[1];
break;
case "V":
y = r[1];
break;
case "M":
mx = r[r.length - 2];
my = r[r.length - 1];
default:
x = r[r.length - 2];
y = r[r.length - 1];
}
}
}
return res
}
function l2c(x1, y1, x2, y2) {
return [x1, y1, x2, y2, x2, y2];
}
function q2c(x1, y1, ax, ay, x2, y2) {
const _13 = 1 / 3;
const _23 = 2 / 3;
return [
_13 * x1 + _23 * ax,
_13 * y1 + _23 * ay,
_13 * x2 + _23 * ax,
_13 * y2 + _23 * ay,
x2,
y2
]
}
// for more information of where this math came from visit:
// http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
function a2c(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) {
const _120 = Math.PI * 120 / 180, rad = Math.PI / 180 * (+angle || 0);
let res = [], xy, f1, f2, cx, cy;
function rotateVector(x, y, rad) {
const X = x * Math.cos(rad) - y * Math.sin(rad),
Y = x * Math.sin(rad) + y * Math.cos(rad);
return {x: X, y: Y};
}
if (!recursive) {
xy = rotateVector(x1, y1, -rad);
x1 = xy.x;
y1 = xy.y;
xy = rotateVector(x2, y2, -rad);
x2 = xy.x;
y2 = xy.y;
// const cos = Math.cos(Math.PI / 180 * angle);
// const sin = Math.sin(Math.PI / 180 * angle);
let x = (x1 - x2) / 2, y = (y1 - y2) / 2, h = (x * x) / (rx * rx) + (y * y) / (ry * ry);
if (h > 1) {
h = Math.sqrt(h);
rx = h * rx;
ry = h * ry;
}
let rx2 = rx * rx,
ry2 = ry * ry,
k = (large_arc_flag == sweep_flag ? -1 : 1)
* Math.sqrt(Math.abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x)
/ (rx2 * y * y + ry2 * x * x)));
cx = k * rx * y / ry + (x1 + x2) / 2,
cy = k * -ry * x / rx + (y1 + y2) / 2;
f1 = Math.asin(((y1 - cy) / ry).toFixed(9)),
f2 = Math.asin(((y2 - cy) / ry).toFixed(9));
f1 = x1 < cx ? Math.PI - f1 : f1;
f2 = x2 < cx ? Math.PI - f2 : f2;
f1 < 0 && (f1 = Math.PI * 2 + f1);
f2 < 0 && (f2 = Math.PI * 2 + f2);
if (sweep_flag && f1 > f2) {
f1 = f1 - Math.PI * 2;
}
if (!sweep_flag && f2 > f1) {
f2 = f2 - Math.PI * 2;
}
} else {
f1 = recursive[0];
f2 = recursive[1];
cx = recursive[2];
cy = recursive[3];
}
let df = f2 - f1;
if (Math.abs(df) > _120) {
const f2old = f2, x2old = x2, y2old = y2;
f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1);
x2 = cx + rx * Math.cos(f2);
y2 = cy + ry * Math.sin(f2);
res = a2c(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]);
}
df = f2 - f1;
const c1 = Math.cos(f1),
s1 = Math.sin(f1),
c2 = Math.cos(f2),
s2 = Math.sin(f2),
t = Math.tan(df / 4),
hx = 4 / 3 * rx * t,
hy = 4 / 3 * ry * t,
m1 = [x1, y1],
m2 = [x1 + hx * s1, y1 - hy * c1],
m3 = [x2 + hx * s2, y2 - hy * c2],
m4 = [x2, y2];
m2[0] = 2 * m1[0] - m2[0];
m2[1] = 2 * m1[1] - m2[1];
if (recursive) {
return [m2, m3, m4].concat(res);
} else {
res = [m2, m3, m4].concat(res).join().split(",");
const newres = [];
for (let i = 0, ii = res.length; i < ii; i++) {
newres[i] = i % 2 ? rotateVector(res[i - 1], res[i], rad).y : rotateVector(res[i], res[i + 1], rad).x;
}
return newres;
}
}
function processPath (path, d, pcom) {
let nx, ny;
if (!path) {
return ["C", d.x, d.y, d.x, d.y, d.x, d.y];
}
!(path[0] in {T: 1, Q: 1}) && (d.qx = d.qy = null);
switch (path[0]) {
case "M":
d.X = path[1];
d.Y = path[2];
break;
case "A":
path = ["C"].concat(a2c.apply(0, [d.x, d.y].concat(path.slice(1))));
break;
case "S":
if (pcom == "C" || pcom == "S") { // In "S" case we have to take into account, if the previous command is C/S.
nx = d.x * 2 - d.bx; // And reflect the previous
ny = d.y * 2 - d.by; // command's control point relative to the current point.
}
else { // or some else or nothing
nx = d.x;
ny = d.y;
}
path = ["C", nx, ny].concat(path.slice(1));
break;
case "T":
if (pcom == "Q" || pcom == "T") { // In "T" case we have to take into account, if the previous command is Q/T.
d.qx = d.x * 2 - d.qx; // And make a reflection similar
d.qy = d.y * 2 - d.qy; // to case "S".
}
else { // or something else or nothing
d.qx = d.x;
d.qy = d.y;
}
path = ["C"].concat(q2c(d.x, d.y, d.qx, d.qy, path[1], path[2]));
break;
case "Q":
d.qx = path[1];
d.qy = path[2];
path = ["C"].concat(q2c(d.x, d.y, path[1], path[2], path[3], path[4]));
break;
case "L":
path = ["C"].concat(l2c(d.x, d.y, path[1], path[2]));
break;
case "H":
path = ["C"].concat(l2c(d.x, d.y, path[1], d.y));
break;
case "V":
path = ["C"].concat(l2c(d.x, d.y, d.x, path[1]));
break;
case "Z":
path = ["C"].concat(l2c(d.x, d.y, d.X, d.Y));
break;
}
path.map((x,i)=>i?x.toFixed(3):x)
return path;
}
function fixM (path1, path2, a1, a2, i) {
if (path1 && path2 && path1[i][0] === "M" && path2[i][0] !== "M") {
path2.splice(i, 0, ["M", a2.x, a2.y]);
a1.bx = 0;
a1.by = 0;
a1.x = path1[i][1];
a1.y = path1[i][2];
// ii = Math.max(p.length, p2 && p2.length || 0);
}
}
function fixArc (p, p2, pcoms1, pcoms2, i) {
if (p[i].length > 7) {
p[i].shift();
const pi = p[i];
while (pi.length) {
pcoms1[i] = "A"; // if created multiple C:s, their original seg is saved
p2 && (pcoms2[i] = "A"); // the same as above
p.splice(i++, 0, ["C"].concat(pi.splice(0, 6)));
}
p.splice(i, 1);
}
}
function path2curve(path, path2) {
const p = pathToAbsolute(path), // holder for previous path command of original path
p2 = path2 && pathToAbsolute(path2),
// p2 = path2 ? pathToAbsolute(path2) : pathToAbsolute('M0,0L0,0'),
attrs = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null},
attrs2 = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null};
// path commands of original path p
// path commands of original path p2
// temporary holder for original path command
let pcoms1 = [], pcoms2 = [], pfirst = "", pcom = "";
for (let i = 0, ii = Math.max(p.length, p2 && p2.length || 0); i < ii; i++) {
p[i] && (pfirst = p[i][0]); // save current path command
if (pfirst !== "C") { // C is not saved yet, because it may be result of conversion
pcoms1[i] = pfirst; // Save current path command
i && ( pcom = pcoms1[i - 1]); // Get previous path command pcom
}
p[i] = processPath(p[i], attrs, pcom); // Previous path command is inputted to processPath
// A is the only command
// which may produce multiple C:s
// so we have to make sure that C is also C in original path
if (pcoms1[i] !== "A" && pfirst === "C") pcoms1[i] = "C";
// fixArc(p, i); // fixArc adds also the right amount of A:s to pcoms1
fixArc(p, p2, pcoms1, pcoms2, i); // fixArc adds also the right amount of A:s to pcoms1 fixArc (p, p2, pcoms1, pcoms2, i) {
ii = Math.max(p.length, p2 && p2.length || 0);
if (p2) { // the same procedures is done to p2
p2[i] && (pfirst = p2[i][0]);
if (pfirst !== "C") {
pcoms2[i] = pfirst;
i && (pcom = pcoms2[i - 1]);
}
p2[i] = processPath(p2[i], attrs2, pcom);
if (pcoms2[i] !== "A" && pfirst === "C") {
pcoms2[i] = "C";
}
// fixArc(p2, i);
fixArc(p2, p, pcoms2, pcoms1, i); // fixArc (p, p2, pcoms1, pcoms2, i) {
ii = Math.max(p.length, p2 && p2.length || 0);
}
fixM(p, p2, attrs, attrs2, i);
p2 && fixM(p2, p, attrs2, attrs, i);
ii = Math.max(p.length, p2 && p2.length || 0);
const seg = p[i],
seg2 = p2 && p2[i],
seglen = seg.length,
seg2len = p2 && seg2.length;
attrs.x = seg[seglen - 2];
attrs.y = seg[seglen - 1];
attrs.bx = parseFloat(seg[seglen - 4]) || attrs.x;
attrs.by = parseFloat(seg[seglen - 3]) || attrs.y;
attrs2.bx = p2 && (parseFloat(seg2[seg2len - 4]) || attrs2.x);
attrs2.by = p2 && (parseFloat(seg2[seg2len - 3]) || attrs2.y);
attrs2.x = p2 && seg2[seg2len - 2];
attrs2.y = p2 && seg2[seg2len - 1];
}
return p2 ? [p, p2] : p;
}
function createPath (path) { // create a <path> when glyph
const np = document.createElementNS('http://www.w3.org/2000/svg','path'),
d = path instanceof SVGElement ? path.getAttribute('d') : path
np.setAttribute('d',d);
return np
}
function getSegments(curveArray) {
let result = []
curveArray.map((seg, i) => {
result[i] = {
x: seg[seg[0] === 'M' ? 1 : 5],
y: seg[seg[0] === 'M' ? 2 : 6],
seg: seg
}
})
return result
}
function reverseCurve(path){
let newSegments = [],
oldSegments = getSegments(path),
segsCount = oldSegments.length,
pointCount = segsCount - 1,
oldSegIdx = pointCount,
oldSegs = []
oldSegments.map((p,i)=>{
if (i === 0||oldSegments[oldSegIdx].seg[0] === 'M') {
newSegments[i] = ['M',oldSegments[oldSegIdx].x,oldSegments[oldSegIdx].y]
} else {
oldSegIdx = pointCount - i > 0 ? pointCount - i : pointCount;
oldSegs = oldSegments[oldSegIdx].seg
newSegments[i] = [oldSegs[0], oldSegs[5],oldSegs[6],oldSegs[3],oldSegs[4], oldSegs[1], oldSegs[2]]
}
})
return newSegments
}
function getRotationSegments(s,idx) {
let newSegments = [], segsCount = s.length, pointCount = segsCount - 1
s.map((p,i)=>{
let oldSegIdx = idx + i;
if (i===0 || s[oldSegIdx] && s[oldSegIdx].seg[0] === 'M') {
newSegments[i] = ['M',s[oldSegIdx].x,s[oldSegIdx].y]
} else {
if (oldSegIdx >= segsCount) oldSegIdx -= pointCount;
newSegments[i] = s[oldSegIdx].seg
}
})
return newSegments
}
function getRotations(a) {
let startSegments = getSegments(a), rotations = [];
startSegments.map((s,i)=>{rotations[i] = getRotationSegments(startSegments,i)})
return rotations
}
function getRotatedCurve(a,b) {
let startSegments = getSegments(a),
endSegments = getSegments(b),
segsCount = startSegments.length,
pointCount = segsCount - 1,
linePaths = [],
lineLengths = [],
rotations = getRotations(a);
rotations.map((r,i)=>{
let sumLensSqrd = 0, linePath = createPath('M0,0L0,0');
for (let j = 0; j < pointCount; j++) {
let linePt1 = startSegments[(i + j) % pointCount];
let linePt2 = endSegments[ j % pointCount];
let linePathStr = `M${linePt1.x},${linePt1.y}L${linePt2.x},${linePt2.y}`;
linePath.setAttribute('d',linePathStr);
sumLensSqrd += Math.pow(linePath.getTotalLength(),2);
linePaths[j] = linePath;
}
lineLengths[i] = sumLensSqrd
sumLensSqrd = 0
})
let computedIndex = lineLengths.indexOf(Math.min.apply(null,lineLengths)),
newPath = rotations[computedIndex];
return newPath
}
// Component Functions
function getCubicMorph(tweenProp){
return this.element.getAttribute('d');
}
function prepareCubicMorph(tweenProp,value){
// get path d attribute or create a path from string value
let pathObject = {},
el = value instanceof SVGElement ? value : /^\.|^\#/.test(value) ? selector(value) : null,
pathReg = new RegExp('\\n','ig'); // remove newlines, they break some JSON strings
try {
// make sure to return pre-processed values
if ( typeof(value) === 'object' && value.curve ) {
return value;
} else if ( el && /path|glyph/.test(el.tagName) ) {
pathObject.original = el.getAttribute('d').replace(pathReg,'');
// } else if (!el && /m|z|c|l|v|q|[0-9]|\,/gi.test(value)) { // maybe it's a string path already
} else if (!el && typeof(value) === 'string') { // maybe it's a string path already
pathObject.original = value.replace(pathReg,'');
}
return pathObject;
}
catch(e){
throw TypeError(`KUTE.js - ${INVALID_INPUT} ${e}`)
}
}
function crossCheckCubicMorph(tweenProp){
if (this.valuesEnd[tweenProp]) {
let pathCurve1 = this.valuesStart[tweenProp].curve,
pathCurve2 = this.valuesEnd[tweenProp].curve
if ( !pathCurve1 || !pathCurve2 || ( pathCurve1 && pathCurve2 && pathCurve1[0][0] === 'M' && pathCurve1.length !== pathCurve2.length) ) {
let path1 = this.valuesStart[tweenProp].original,
path2 = this.valuesEnd[tweenProp].original,
curves = path2curve(path1,path2)
let curve0 = this._reverseFirstPath ? reverseCurve.call(this,curves[0]) : curves[0],
curve1 = this._reverseSecondPath ? reverseCurve.call(this,curves[1]) : curves[1]
curve0 = getRotatedCurve.call(this,curve0,curve1)
this.valuesStart[tweenProp].curve = curve0;
this.valuesEnd[tweenProp].curve = curve1;
}
}
}
// All Component Functions
const svgCubicMorphFunctions = {
prepareStart: getCubicMorph,
prepareProperty: prepareCubicMorph,
onStart: onStartCubicMorph,
crossCheck: crossCheckCubicMorph
}
// Component Full
const svgCubicMorph = {
component: 'svgCubicMorph',
property: 'path',
defaultValue: [],
Interpolate: {numbers,toPathString},
functions: svgCubicMorphFunctions,
// export utils to global for faster execution
Util: {
l2c, q2c, a2c, catmullRom2bezier, ellipsePath,
path2curve, pathToAbsolute, toPathString, parsePathString,
getRotatedCurve, getRotations,
getRotationSegments, reverseCurve, getSegments, createPath
}
}
export default svgCubicMorph
Components.SVGCubicMorph = svgCubicMorph
import parsePathString from 'svg-path-commander/src/parser/parsePathString';
import pathToAbsolute from 'svg-path-commander/src/convert/pathToAbsolute';
import pathToCurve from 'svg-path-commander/src/convert/pathToCurve';
import pathToString from 'svg-path-commander/src/convert/pathToString';
import reverseCurve from 'svg-path-commander/src/process/reverseCurve';
import getDrawDirection from 'svg-path-commander/src/util/getDrawDirection';
import clonePath from 'svg-path-commander/src/process/clonePath';
import splitCubic from 'svg-path-commander/src/process/splitCubic';
import splitPath from 'svg-path-commander/src/process/splitPath';
import fixPath from 'svg-path-commander/src/process/fixPath';
import segmentCubicFactory from 'svg-path-commander/src/util/segmentCubicFactory';
import distanceSquareRoot from 'svg-path-commander/src/math/distanceSquareRoot';
import { onStartCubicMorph } from './svgCubicMorphBase';
import numbers from '../interpolation/numbers';
import selector from '../util/selector';
// Component Util
/**
* Returns first `pathArray` from multi-paths path.
* @param {SVGPathCommander.pathArray | string} source the source `pathArray` or string
* @returns {KUTE.curveSpecs[]} an `Array` with a custom tuple for `equalizeSegments`
*/
function getCurveArray(source) {
return pathToCurve(splitPath(source)[0])
.map((segment, i, pathArray) => {
const segmentData = i && [...pathArray[i - 1].slice(-2), ...segment.slice(1)];
const curveLength = i ? segmentCubicFactory(...segmentData) : 0;
let subsegs;
if (i) {
// must be [segment,segment]
subsegs = curveLength ? splitCubic(segmentData) : [segment, segment];
} else {
subsegs = [segment];
}
return {
s: segment,
ss: subsegs,
l: curveLength,
};
});
}
/**
* Returns two `curveArray` with same amount of segments.
* @param {SVGPathCommander.curveArray} path1 the first `curveArray`
* @param {SVGPathCommander.curveArray} path2 the second `curveArray`
* @param {number} TL the maximum `curveArray` length
* @returns {SVGPathCommander.curveArray[]} equalized segments
*/
function equalizeSegments(path1, path2, TL) {
const c1 = getCurveArray(path1);
const c2 = getCurveArray(path2);
const L1 = c1.length;
const L2 = c2.length;
const l1 = c1.filter((x) => x.l).length;
const l2 = c2.filter((x) => x.l).length;
const m1 = c1.filter((x) => x.l).reduce((a, { l }) => a + l, 0) / l1 || 0;
const m2 = c2.filter((x) => x.l).reduce((a, { l }) => a + l, 0) / l2 || 0;
const tl = TL || Math.max(L1, L2);
const mm = [m1, m2];
const dif = [tl - L1, tl - L2];
let canSplit = 0;
const result = [c1, c2]
.map((x, i) => (x.l === tl
? x.map((y) => y.s)
: x.map((y, j) => {
canSplit = j && dif[i] && y.l >= mm[i];
dif[i] -= canSplit ? 1 : 0;
return canSplit ? y.ss : [y.s];
}).flat()));
return result[0].length === result[1].length
? result
: equalizeSegments(result[0], result[1], tl);
}
/**
* Returns all possible path rotations for `curveArray`.
* @param {SVGPathCommander.curveArray} a the source `curveArray`
* @returns {SVGPathCommander.curveArray[]} all rotations for source
*/
function getRotations(a) {
const segCount = a.length;
const pointCount = segCount - 1;
return a.map((_, idx) => a.map((__, i) => {
let oldSegIdx = idx + i;
let seg;
if (i === 0 || (a[oldSegIdx] && a[oldSegIdx][0] === 'M')) {
seg = a[oldSegIdx];
return ['M', ...seg.slice(-2)];
}
if (oldSegIdx >= segCount) oldSegIdx -= pointCount;
return a[oldSegIdx];
}));
}
/**
* Returns the `curveArray` rotation for the best morphing animation.
* @param {SVGPathCommander.curveArray} a the target `curveArray`
* @param {SVGPathCommander.curveArray} b the reference `curveArray`
* @returns {SVGPathCommander.curveArray} the best `a` rotation
*/
function getRotatedCurve(a, b) {
const segCount = a.length - 1;
const lineLengths = [];
let computedIndex = 0;
let sumLensSqrd = 0;
const rotations = getRotations(a);
rotations.forEach((_, i) => {
a.slice(1).forEach((__, j) => {
sumLensSqrd += distanceSquareRoot(a[(i + j) % segCount].slice(-2), b[j % segCount].slice(-2));
});
lineLengths[i] = sumLensSqrd;
sumLensSqrd = 0;
});
computedIndex = lineLengths.indexOf(Math.min.apply(null, lineLengths));
return rotations[computedIndex];
}
// Component Functions
/**
* Returns the current `d` attribute value.
* @returns {string}
*/
function getCubicMorph(/* tweenProp, value */) {
return this.element.getAttribute('d');
}
/**
* Returns the property tween object.
* @see KUTE.curveObject
*
* @param {string} _ is the `path` property name, not needed
* @param {string | KUTE.curveObject} value the `path` property value
* @returns {KUTE.curveObject}
*/
function prepareCubicMorph(/* tweenProp, */_, value) {
// get path d attribute or create a path from string value
const pathObject = {};
// remove newlines, they break some JSON strings
const pathReg = new RegExp('\\n', 'ig');
let el = null;
if (value instanceof SVGElement) {
el = value;
} else if (/^\.|^#/.test(value)) {
el = selector(value);
}
// make sure to return pre-processed values
if (typeof (value) === 'object' && value.curve) {
return value;
} if (el && /path|glyph/.test(el.tagName)) {
pathObject.original = el.getAttribute('d').replace(pathReg, '');
// maybe it's a string path already
} else if (!el && typeof (value) === 'string') {
pathObject.original = value.replace(pathReg, '');
}
return pathObject;
}
/**
* Enables the `to()` method by preparing the tween object in advance.
* @param {string} tweenProp is `path` tween property, but it's not needed
*/
function crossCheckCubicMorph(tweenProp/** , value */) {
if (this.valuesEnd[tweenProp]) {
const pathCurve1 = this.valuesStart[tweenProp].curve;
const pathCurve2 = this.valuesEnd[tweenProp].curve;
if (!pathCurve1 || !pathCurve2
|| (pathCurve1 && pathCurve2 && pathCurve1[0][0] === 'M' && pathCurve1.length !== pathCurve2.length)) {
const path1 = this.valuesStart[tweenProp].original;
const path2 = this.valuesEnd[tweenProp].original;
const curves = equalizeSegments(path1, path2);
const curve0 = getDrawDirection(curves[0]) !== getDrawDirection(curves[1])
? reverseCurve(curves[0])
: clonePath(curves[0]);
this.valuesStart[tweenProp].curve = curve0;
this.valuesEnd[tweenProp].curve = getRotatedCurve(curves[1], curve0);
}
}
}
// All Component Functions
const svgCubicMorphFunctions = {
prepareStart: getCubicMorph,
prepareProperty: prepareCubicMorph,
onStart: onStartCubicMorph,
crossCheck: crossCheckCubicMorph,
};
// Component Full
const svgCubicMorph = {
component: 'svgCubicMorph',
property: 'path',
defaultValue: [],
Interpolate: { numbers, pathToString },
functions: svgCubicMorphFunctions,
// export utils to global for faster execution
Util: {
pathToCurve,
pathToAbsolute,
pathToString,
parsePathString,
getRotatedCurve,
getRotations,
equalizeSegments,
reverseCurve,
clonePath,
getDrawDirection,
segmentCubicFactory,
splitCubic,
splitPath,
fixPath,
getCurveArray,
},
};
export default svgCubicMorph;

View file

@ -1,44 +1,38 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
// const SVGMorph = { property : 'path', defaultValue: [], interpolators: {numbers} }, functions = { prepareStart, prepareProperty, onStart, crossCheck }
// Component Interpolation
export function toPathString(pathArray) {
let newPath = pathArray.map( (c) => {
if (typeof(c) === 'string') {
return c
} else {
let c0 = c.shift();
return c0 + c.join(',')
}
})
return newPath.join('');
}
// Component Functions
export function onStartCubicMorph(tweenProp){
if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) {
KUTE[tweenProp] = function(elem,a,b,v){
let curve = [], path1 = a.curve, path2 = b.curve;
for(let i=0, l=path2.length; i<l; i++) { // each path command
curve.push([path1[i][0]]);
for(var j=1,l2=path1[i].length;j<l2;j++) { // each command coordinate
curve[i].push( (numbers(path1[i][j], path2[i][j], v) * 1000 >>0)/1000 );
}
}
elem.setAttribute("d", v === 1 ? b.original : toPathString(curve) );
}
}
}
// Component Base
const baseSvgCubicMorph = {
component: 'baseSVGCubicMorph',
property: 'path',
// defaultValue: [],
Interpolate: {numbers,toPathString},
functions: {onStart:onStartCubicMorph}
}
export default baseSvgCubicMorph
import pathToString from 'svg-path-commander/src/convert/pathToString';
import KEC from '../objects/kute';
import numbers from '../interpolation/numbers';
// Component Functions
/**
* Sets the property update function.
* @param {string} tweenProp the `path` property
*/
export function onStartCubicMorph(tweenProp) {
if (!KEC[tweenProp] && this.valuesEnd[tweenProp]) {
KEC[tweenProp] = function updateMorph(elem, a, b, v) {
const curve = [];
const path1 = a.curve;
const path2 = b.curve;
for (let i = 0, l = path2.length; i < l; i += 1) { // each path command
curve.push([path1[i][0]]);
for (let j = 1, l2 = path1[i].length; j < l2; j += 1) { // each command coordinate
/* eslint-disable-next-line no-bitwise -- impossible to satisfy */
curve[i].push((numbers(path1[i][j], path2[i][j], v) * 1000 >> 0) / 1000);
}
}
elem.setAttribute('d', v === 1 ? b.original : pathToString(curve));
};
}
}
// Component Base
const baseSvgCubicMorph = {
component: 'baseSVGCubicMorph',
property: 'path',
// defaultValue: [],
Interpolate: { numbers, pathToString },
functions: { onStart: onStartCubicMorph },
};
export default baseSvgCubicMorph;

View file

@ -1,145 +1,210 @@
import Components from '../objects/components.js'
import getStyleForProperty from '../process/getStyleForProperty.js'
import numbers from '../interpolation/numbers.js'
import {onStartDraw} from './svgDrawBase.js'
// const svgDraw = { property : 'draw', defaultValue, Interpolate: {numbers} }, functions = { prepareStart, prepareProperty, onStart }
// Component Util
function percent (v,l) {
return parseFloat(v) / 100 * l
}
// http://stackoverflow.com/a/30376660
function getRectLength(el) { // returns the length of a Rect
let w = el.getAttribute('width'),
h = el.getAttribute('height');
return (w*2)+(h*2);
}
function getPolyLength(el) {
// getPolygonLength / getPolylineLength - return the length of the Polygon / Polyline
const points = el.getAttribute('points').split(' ');
let len = 0;
if (points.length > 1) {
const coord = p => {
const c = p.split(',');
if (c.length != 2) { return; } // return undefined
if (isNaN(c[0]) || isNaN(c[1])) { return; }
return [parseFloat(c[0]), parseFloat(c[1])];
};
const dist = (c1, c2) => {
if (c1 != undefined && c2 != undefined) {
return Math.sqrt((c2[0] - c1[0]) ** 2 + (c2[1] - c1[1]) ** 2);
}
return 0;
};
if (points.length > 2) {
for (let i=0; i<points.length-1; i++) {
len += dist(coord(points[i]), coord(points[i+1]));
}
}
len += el.tagName === 'polygon' ? dist(coord(points[0]), coord(points[points.length - 1])) : 0;
}
return len;
}
function getLineLength(el) { // return the length of the line
const x1 = el.getAttribute('x1');
const x2 = el.getAttribute('x2');
const y1 = el.getAttribute('y1');
const y2 = el.getAttribute('y2');
return Math.sqrt((x2 - x1) ** 2+(y2 - y1) ** 2);
}
function getCircleLength(el) { // return the length of the circle
const r = el.getAttribute('r');
return 2 * Math.PI * r;
}
function getEllipseLength(el) { // returns the length of an ellipse
const 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;
}
function getTotalLength(el) { // returns the result of any of the below functions
if (/rect/.test(el.tagName)) {
return getRectLength(el);
} else if (/circle/.test(el.tagName)) {
return getCircleLength(el);
} else if (/ellipse/.test(el.tagName)) {
return getEllipseLength(el);
} else if (/polygon|polyline/.test(el.tagName)) {
return getPolyLength(el);
} else if (/line/.test(el.tagName)) {
return getLineLength(el);
}
}
function getDraw(e,v) {
let length = /path|glyph/.test(e.tagName) ? e.getTotalLength() : getTotalLength(e),
start, end, d, o;
if ( v instanceof Object ) {
return v;
} else if (typeof v === 'string') {
v = v.split(/\,|\s/);
start = /%/.test(v[0]) ? percent(v[0].trim(),length) : parseFloat(v[0]);
end = /%/.test(v[1]) ? percent(v[1].trim(),length) : parseFloat(v[1]);
} else if (typeof v === 'undefined') {
o = parseFloat(getStyleForProperty(e,'stroke-dashoffset'));
d = getStyleForProperty(e,'stroke-dasharray').split(/\,/);
start = 0-o;
end = parseFloat(d[0]) + start || length;
}
return { s: start, e: end, l: length };
}
function resetDraw(elem) {
elem.style.strokeDashoffset = ``;
elem.style.strokeDasharray = ``;
}
// Component Functions
function getDrawValue(){
return getDraw(this.element);
}
function prepareDraw(a,o){
return getDraw(this.element,o);
}
// All Component Functions
const svgDrawFunctions = {
prepareStart: getDrawValue,
prepareProperty: prepareDraw,
onStart: onStartDraw
}
// Component Full
const svgDraw = {
component: 'svgDraw',
property: 'draw',
defaultValue: '0% 0%',
Interpolate: {numbers},
functions: svgDrawFunctions,
// Export to global for faster execution
Util: {
getRectLength,
getPolyLength,
getLineLength,
getCircleLength,
getEllipseLength,
getTotalLength,
resetDraw,
getDraw,
percent
}
}
export default svgDraw
Components.SVGDraw = svgDraw
import getStyleForProperty from '../process/getStyleForProperty';
import numbers from '../interpolation/numbers';
import { onStartDraw } from './svgDrawBase';
// Component Util
/**
* Convert a `<path>` length percent value to absolute.
* @param {string} v raw value
* @param {number} l length value
* @returns {number} the absolute value
*/
function percent(v, l) {
return (parseFloat(v) / 100) * l;
}
/**
* Returns the `<rect>` length.
* It doesn't compute `rx` and / or `ry` of the element.
* @see http://stackoverflow.com/a/30376660
* @param {SVGRectElement} el target element
* @returns {number} the `<rect>` length
*/
function getRectLength(el) {
const w = el.getAttribute('width');
const h = el.getAttribute('height');
return (w * 2) + (h * 2);
}
/**
* Returns the `<polyline>` / `<polygon>` length.
* @param {SVGPolylineElement | SVGPolygonElement} el target element
* @returns {number} the element length
*/
function getPolyLength(el) {
const points = el.getAttribute('points').split(' ');
let len = 0;
if (points.length > 1) {
const coord = (p) => {
const c = p.split(',');
if (c.length !== 2) { return 0; } // return undefined
if (Number.isNaN(c[0] * 1) || Number.isNaN(c[1] * 1)) { return 0; }
return [parseFloat(c[0]), parseFloat(c[1])];
};
const dist = (c1, c2) => {
if (c1 !== undefined && c2 !== undefined) {
return Math.sqrt((c2[0] - c1[0]) ** 2 + (c2[1] - c1[1]) ** 2);
}
return 0;
};
if (points.length > 2) {
for (let i = 0; i < points.length - 1; i += 1) {
len += dist(coord(points[i]), coord(points[i + 1]));
}
}
len += el.tagName === 'polygon'
? dist(coord(points[0]), coord(points[points.length - 1])) : 0;
}
return len;
}
/**
* Returns the `<line>` length.
* @param {SVGLineElement} el target element
* @returns {number} the element length
*/
function getLineLength(el) {
const x1 = el.getAttribute('x1');
const x2 = el.getAttribute('x2');
const y1 = el.getAttribute('y1');
const y2 = el.getAttribute('y2');
return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
}
/**
* Returns the `<circle>` length.
* @param {SVGCircleElement} el target element
* @returns {number} the element length
*/
function getCircleLength(el) {
const r = el.getAttribute('r');
return 2 * Math.PI * r;
}
// returns the length of an ellipse
/**
* Returns the `<ellipse>` length.
* @param {SVGEllipseElement} el target element
* @returns {number} the element length
*/
function getEllipseLength(el) {
const rx = el.getAttribute('rx');
const ry = el.getAttribute('ry');
const len = 2 * rx;
const wid = 2 * ry;
return ((Math.sqrt(0.5 * ((len * len) + (wid * wid)))) * (Math.PI * 2)) / 2;
}
/**
* Returns the shape length.
* @param {SVGPathCommander.shapeTypes} el target element
* @returns {number} the element length
*/
function getTotalLength(el) {
if (el.tagName === 'rect') {
return getRectLength(el);
} if (el.tagName === 'circle') {
return getCircleLength(el);
} if (el.tagName === 'ellipse') {
return getEllipseLength(el);
} if (['polygon', 'polyline'].includes(el.tagName)) {
return getPolyLength(el);
} if (el.tagName === 'line') {
return getLineLength(el);
}
// ESLint
return 0;
}
/**
* Returns the property tween object.
* @param {SVGPathCommander.shapeTypes} element the target element
* @param {string | KUTE.drawObject} value the property value
* @returns {KUTE.drawObject} the property tween object
*/
function getDraw(element, value) {
const length = /path|glyph/.test(element.tagName)
? element.getTotalLength()
: getTotalLength(element);
let start;
let end;
let dasharray;
let offset;
if (value instanceof Object && Object.keys(value).every((v) => ['s', 'e', 'l'].includes(v))) {
return value;
} if (typeof value === 'string') {
const v = value.split(/,|\s/);
start = /%/.test(v[0]) ? percent(v[0].trim(), length) : parseFloat(v[0]);
end = /%/.test(v[1]) ? percent(v[1].trim(), length) : parseFloat(v[1]);
} else if (typeof value === 'undefined') {
offset = parseFloat(getStyleForProperty(element, 'stroke-dashoffset'));
dasharray = getStyleForProperty(element, 'stroke-dasharray').split(',');
start = 0 - offset;
end = parseFloat(dasharray[0]) + start || length;
}
return { s: start, e: end, l: length };
}
/**
* Reset CSS properties associated with the `draw` property.
* @param {SVGPathCommander.shapeTypes} element target
*/
function resetDraw(elem) {
/* eslint-disable no-param-reassign -- impossible to satisfy */
elem.style.strokeDashoffset = '';
elem.style.strokeDasharray = '';
/* eslint-disable no-param-reassign -- impossible to satisfy */
}
// Component Functions
/**
* Returns the property tween object.
* @returns {KUTE.drawObject} the property tween object
*/
function getDrawValue(/* prop, value */) {
return getDraw(this.element);
}
/**
* Returns the property tween object.
* @param {string} _ the property name
* @param {string | KUTE.drawObject} value the property value
* @returns {KUTE.drawObject} the property tween object
*/
function prepareDraw(_, value) {
return getDraw(this.element, value);
}
// All Component Functions
const svgDrawFunctions = {
prepareStart: getDrawValue,
prepareProperty: prepareDraw,
onStart: onStartDraw,
};
// Component Full
const SvgDrawProperty = {
component: 'svgDraw',
property: 'draw',
defaultValue: '0% 0%',
Interpolate: { numbers },
functions: svgDrawFunctions,
// Export to global for faster execution
Util: {
getRectLength,
getPolyLength,
getLineLength,
getCircleLength,
getEllipseLength,
getTotalLength,
resetDraw,
getDraw,
percent,
},
};
export default SvgDrawProperty;

View file

@ -1,30 +1,35 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
// const svgDraw = { property : 'draw', defaultValue, Interpolate: {numbers} }, functions = { prepareStart, prepareProperty, onStart }
// Component Functions
export function onStartDraw(tweenProp){
if ( tweenProp in this.valuesEnd && !KUTE[tweenProp]) {
KUTE[tweenProp] = (elem,a,b,v) => {
let pathLength = (a.l*100>>0)/100,
start = (numbers(a.s,b.s,v)*100>>0)/100,
end = (numbers(a.e,b.e,v)*100>>0)/100,
offset = 0 - start,
dashOne = end+offset;
elem.style.strokeDashoffset = `${offset}px`;
elem.style.strokeDasharray = `${((dashOne <1 ? 0 : dashOne)*100>>0)/100}px, ${pathLength}px`;
}
}
}
// Component Base
const baseSVGDraw = {
component: 'baseSVGDraw',
property: 'draw',
Interpolate: {numbers},
functions: {onStart:onStartDraw}
}
export default baseSVGDraw
import KEC from '../objects/kute';
import numbers from '../interpolation/numbers';
// Component Functions
/**
* Sets the property update function.
* @param {string} tweenProp the property name
*/
export function onStartDraw(tweenProp) {
if (tweenProp in this.valuesEnd && !KEC[tweenProp]) {
KEC[tweenProp] = (elem, a, b, v) => {
/* eslint-disable no-bitwise -- impossible to satisfy */
const pathLength = (a.l * 100 >> 0) / 100;
const start = (numbers(a.s, b.s, v) * 100 >> 0) / 100;
const end = (numbers(a.e, b.e, v) * 100 >> 0) / 100;
const offset = 0 - start;
const dashOne = end + offset;
// eslint-disable-next-line no-param-reassign -- impossible to satisfy
elem.style.strokeDashoffset = `${offset}px`;
// eslint-disable-next-line no-param-reassign -- impossible to satisfy
elem.style.strokeDasharray = `${((dashOne < 1 ? 0 : dashOne) * 100 >> 0) / 100}px, ${pathLength}px`;
/* eslint-disable no-bitwise -- impossible to satisfy */
};
}
}
// Component Base
const SvgDrawBase = {
component: 'baseSVGDraw',
property: 'draw',
Interpolate: { numbers },
functions: { onStart: onStartDraw },
};
export default SvgDrawBase;

File diff suppressed because it is too large Load diff

View file

@ -1,25 +1,34 @@
import KUTE from '../objects/kute.js'
import coords from '../Interpolation/coords.js'
// const SVGMorph = { property : 'path', defaultValue: [], interpolators: {numbers,coords} }, functions = { prepareStart, prepareProperty, onStart, crossCheck }
// Component functions
export function onStartSVGMorph(tweenProp){
if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) {
KUTE[tweenProp] = (elem, a, b, v) => {
let path1 = a.pathArray, path2 = b.pathArray, len = path2.length, pathString;
pathString = v === 1 ? b.original : `M${coords( path1, path2, len, v ).join('L')}Z`;
elem.setAttribute("d", pathString );
}
}
}
// Component Base
const baseSVGMorph = {
component: 'baseSVGMorph',
property: 'path',
Interpolate: coords,
functions: {onStart:onStartSVGMorph}
}
export default baseSVGMorph
import KEC from '../objects/kute';
import coords from '../interpolation/coords';
/* SVGMorph = {
property: 'path',
defaultValue: [],
interpolators: {numbers,coords} },
functions = { prepareStart, prepareProperty, onStart, crossCheck }
} */
// Component functions
/**
* Sets the property update function.
* @param {string} tweenProp the property name
*/
export function onStartSVGMorph(tweenProp) {
if (!KEC[tweenProp] && this.valuesEnd[tweenProp]) {
KEC[tweenProp] = (elem, a, b, v) => {
const path1 = a.polygon; const path2 = b.polygon;
const len = path2.length;
elem.setAttribute('d', (v === 1 ? b.original : `M${coords(path1, path2, len, v).join('L')}Z`));
};
}
}
// Component Base
const SVGMorphBase = {
component: 'baseSVGMorph',
property: 'path',
Interpolate: coords,
functions: { onStart: onStartSVGMorph },
};
export default SVGMorphBase;

View file

@ -1,130 +1,196 @@
import numbers from '../interpolation/numbers.js'
import Components from '../objects/components.js'
import {svgTransformOnStart} from './svgTransformBase.js'
// const svgTransform = { property : 'svgTransform', subProperties, defaultValue, Interpolate: {numbers}, functions }
// Component Util
function parseStringOrigin (origin, {x, width}) {
return /[a-zA-Z]/.test(origin) && !/px/.test(origin)
? origin.replace(/top|left/,0).replace(/right|bottom/,100).replace(/center|middle/,50)
: /%/.test(origin) ? (x + parseFloat(origin) * width / 100) : parseFloat(origin);
}
// helper function that turns transform value from string to object
function parseTransformString (a) {
const d = a && /\)/.test(a) ? a.substring(0, a.length-1).split(/\)\s|\)/) : 'none', c = {};
if (d instanceof Array) {
for (let j=0, jl = d.length; j<jl; j++){
const p = d[j].trim().split('(');
c[p[0]] = p[1];
}
}
return c;
}
function parseTransformSVG (p,v){
const svgTransformObject = {};
// by default the transformOrigin is "50% 50%" of the shape box
const bb = this.element.getBBox();
const cx = bb.x + bb.width/2;
const cy = bb.y + bb.height/2;
let origin = this._transformOrigin;
let translation;
origin = typeof (origin) !== 'undefined' ? (origin.constructor === Array ? origin : origin.split(/\s/)) : [cx,cy];
origin[0] = typeof origin[0] === 'number' ? origin[0] : parseStringOrigin(origin[0],bb);
origin[1] = typeof origin[1] === 'number' ? origin[1] : parseStringOrigin(origin[1],bb);
svgTransformObject.origin = origin;
for ( const i in v ) { // populate the valuesStart and / or valuesEnd
if (i === 'rotate'){
svgTransformObject[i] = typeof v[i] === 'number' ? v[i] : v[i] instanceof Array ? v[i][0] : v[i].split(/\s/)[0]*1;
} else if (i === 'translate'){
translation = v[i] instanceof Array ? v[i] : /\,|\s/.test(v[i]) ? v[i].split(',') : [v[i],0];
svgTransformObject[i] = [translation[0]*1||0, translation[1]*1||0];
} else if (/skew/.test(i)) {
svgTransformObject[i] = v[i]*1||0;
} else if (i === 'scale'){
svgTransformObject[i] = parseFloat(v[i])||1;
}
}
return svgTransformObject;
}
// Component Functions
function prepareSvgTransform(p,v){
return parseTransformSVG.call(this,p,v);
}
// returns an obect with current transform attribute value
function getStartSvgTransform (tweenProp,value) {
const transformObject = {};
const currentTransform = parseTransformString(this.element.getAttribute('transform'));
for (const i in value) {
// find a value in current attribute value or add a default value
transformObject[i] = i in currentTransform ? currentTransform[i] : (i==='scale'?1:0);
}
return transformObject;
}
function svgTransformCrossCheck(prop) {
if (!this._resetStart) return; // fix since 1.6.1 for fromTo() method
if ( this.valuesEnd[prop] ) {
let valuesStart = this.valuesStart[prop];
let valuesEnd = this.valuesEnd[prop];
const currentTransform = parseTransformSVG.call(this, prop, parseTransformString(this.element.getAttribute('transform')) );
// populate the valuesStart first
for ( const i in currentTransform ) {
valuesStart[i] = currentTransform[i];
}
// now try to determine the REAL translation
const parentSVG = this.element.ownerSVGElement;
const startMatrix = parentSVG.createSVGTransformFromMatrix(
parentSVG.createSVGMatrix()
.translate(-valuesStart.origin[0],-valuesStart.origin[1]) // - origin
.translate('translate' in valuesStart ? valuesStart.translate[0] : 0,'translate' in valuesStart ? valuesStart.translate[1] : 0) // the current translate
.rotate(valuesStart.rotate||0).skewX(valuesStart.skewX||0).skewY(valuesStart.skewY||0).scale(valuesStart.scale||1)// the other functions
.translate(+valuesStart.origin[0],+valuesStart.origin[1]) // + origin
);
valuesStart.translate = [startMatrix.matrix.e,startMatrix.matrix.f]; // finally the translate we're looking for
// copy existing and unused properties to the valuesEnd
for ( const i in valuesStart) {
if ( !(i in valuesEnd) || i==='origin') {
valuesEnd[i] = valuesStart[i];
}
}
}
}
// All Component Functions
export const svgTransformFunctions = {
prepareStart: getStartSvgTransform,
prepareProperty: prepareSvgTransform,
onStart: svgTransformOnStart,
crossCheck: svgTransformCrossCheck
}
// Component Full
export const svgTransform = {
component: 'svgTransformProperty',
property: 'svgTransform',
// subProperties: ['translate','rotate','skewX','skewY','scale'],
defaultOptions: {transformOrigin:'50% 50%'},
defaultValue: {translate:0, rotate:0, skewX:0, skewY:0, scale:1},
Interpolate: {numbers},
functions: svgTransformFunctions,
// export utils to globals for faster execution
Util: { parseStringOrigin, parseTransformString, parseTransformSVG }
}
export default svgTransform
Components.SVGTransformProperty = svgTransform
import numbers from '../interpolation/numbers';
import { svgTransformOnStart } from './svgTransformBase';
// Component Util
/**
* Returns a correct transform origin consistent with the shape bounding box.
* @param {string} origin transform origin string
* @param {SVGPathCommander.pathBBox} bbox path bounding box
* @returns {number}
*/
function parseStringOrigin(origin, bbox) {
let result;
const { x, width } = bbox;
if (/[a-z]/i.test(origin) && !/px/.test(origin)) {
result = origin.replace(/top|left/, 0)
.replace(/right|bottom/, 100)
.replace(/center|middle/, 50);
} else {
result = /%/.test(origin) ? (x + (parseFloat(origin) * width) / 100) : parseFloat(origin);
}
return result;
}
/**
* Parse SVG transform string and return an object.
* @param {string} a transform string
* @returns {Object<string, (string | number)>}
*/
function parseTransformString(a) {
const c = {};
const d = a && /\)/.test(a)
? a.substring(0, a.length - 1).split(/\)\s|\)/)
: 'none';
if (d instanceof Array) {
for (let j = 0, jl = d.length; j < jl; j += 1) {
const [prop, val] = d[j].trim().split('(');
c[prop] = val;
}
}
return c;
}
/**
* Returns the SVG transform tween object.
* @param {string} _ property name
* @param {Object<string, (string | number)>} v property value object
* @returns {KUTE.transformSVGObject} the SVG transform tween object
*/
function parseTransformSVG(/* prop */_, v) {
/** @type {KUTE.transformSVGObject} */
const svgTransformObject = {};
// by default the transformOrigin is "50% 50%" of the shape box
const bb = this.element.getBBox();
const cx = bb.x + bb.width / 2;
const cy = bb.y + bb.height / 2;
let origin = this._transformOrigin;
let translation;
if (typeof (origin) !== 'undefined') {
origin = origin instanceof Array ? origin : origin.split(/\s/);
} else {
origin = [cx, cy];
}
origin[0] = typeof origin[0] === 'number' ? origin[0] : parseStringOrigin(origin[0], bb);
origin[1] = typeof origin[1] === 'number' ? origin[1] : parseStringOrigin(origin[1], bb);
svgTransformObject.origin = origin;
// populate the valuesStart and / or valuesEnd
Object.keys(v).forEach((i) => {
if (i === 'rotate') {
if (typeof v[i] === 'number') {
svgTransformObject[i] = v[i];
} else if (v[i] instanceof Array) {
[svgTransformObject[i]] = v[i];
} else {
svgTransformObject[i] = v[i].split(/\s/)[0] * 1;
}
} else if (i === 'translate') {
if (v[i] instanceof Array) {
translation = v[i];
} else if (/,|\s/.test(v[i])) {
translation = v[i].split(',');
} else {
translation = [v[i], 0];
}
svgTransformObject[i] = [translation[0] * 1 || 0, translation[1] * 1 || 0];
} else if (/skew/.test(i)) {
svgTransformObject[i] = v[i] * 1 || 0;
} else if (i === 'scale') {
svgTransformObject[i] = parseFloat(v[i]) || 1;
}
});
return svgTransformObject;
}
// Component Functions
/**
* Returns the property tween object.
* @param {string} prop the property name
* @param {string} value the property value
* @returns {KUTE.transformSVGObject} the property tween object
*/
function prepareSvgTransform(prop, value) {
return parseTransformSVG.call(this, prop, value);
}
/**
* Returns an object with the current transform attribute value.
* @param {string} _ the property name
* @param {string} value the property value
* @returns {string} current transform object
*/
function getStartSvgTransform(/* tweenProp */_, value) {
const transformObject = {};
const currentTransform = parseTransformString(this.element.getAttribute('transform'));
// find a value in current attribute value or add a default value
Object.keys(value).forEach((j) => {
const scaleValue = j === 'scale' ? 1 : 0;
transformObject[j] = j in currentTransform ? currentTransform[j] : scaleValue;
});
return transformObject;
}
function svgTransformCrossCheck(prop) {
if (!this._resetStart) return; // fix since 1.6.1 for fromTo() method
if (this.valuesEnd[prop]) {
const valuesStart = this.valuesStart[prop];
const valuesEnd = this.valuesEnd[prop];
const currentTransform = parseTransformSVG.call(this, prop,
parseTransformString(this.element.getAttribute('transform')));
// populate the valuesStart first
Object.keys(currentTransform).forEach((tp) => {
valuesStart[tp] = currentTransform[tp];
});
// now try to determine the REAL translation
const parentSVG = this.element.ownerSVGElement;
const startMatrix = parentSVG.createSVGTransformFromMatrix(
parentSVG.createSVGMatrix()
.translate(-valuesStart.origin[0], -valuesStart.origin[1]) // - origin
.translate('translate' in valuesStart // the current translate
? valuesStart.translate[0] : 0, 'translate' in valuesStart ? valuesStart.translate[1]
: 0)
.rotate(valuesStart.rotate || 0)
.skewX(valuesStart.skewX || 0)
.skewY(valuesStart.skewY || 0)
.scale(valuesStart.scale || 1)// the other functions
.translate(+valuesStart.origin[0], +valuesStart.origin[1]), // + origin
);
// finally the translate we're looking for
valuesStart.translate = [startMatrix.matrix.e, startMatrix.matrix.f];
// copy existing and unused properties to the valuesEnd
Object.keys(valuesStart).forEach((s) => {
if (!(s in valuesEnd) || s === 'origin') {
valuesEnd[s] = valuesStart[s];
}
});
}
}
// All Component Functions
export const svgTransformFunctions = {
prepareStart: getStartSvgTransform,
prepareProperty: prepareSvgTransform,
onStart: svgTransformOnStart,
crossCheck: svgTransformCrossCheck,
};
// Component Full
export const svgTransform = {
component: 'svgTransformProperty',
property: 'svgTransform',
// subProperties: ['translate','rotate','skewX','skewY','scale'],
defaultOptions: { transformOrigin: '50% 50%' },
defaultValue: {
translate: 0, rotate: 0, skewX: 0, skewY: 0, scale: 1,
},
Interpolate: { numbers },
functions: svgTransformFunctions,
// export utils to globals for faster execution
Util: { parseStringOrigin, parseTransformString, parseTransformSVG },
};
export default svgTransform;

View file

@ -1,54 +1,63 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
// const svgTransform = { property : 'svgTransform', subProperties, defaultValue, Interpolate: {numbers}, functions }
// Component Functions
export function svgTransformOnStart (tweenProp){
if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) {
KUTE[tweenProp] = (l, a, b, v) => {
let x = 0;
let y = 0;
let tmp;
const deg = Math.PI/180;
const scale = 'scale' in b ? numbers(a.scale,b.scale,v) : 1;
const rotate = 'rotate' in b ? numbers(a.rotate,b.rotate,v) : 0;
const sin = Math.sin(rotate*deg);
const cos = Math.cos(rotate*deg);
const skewX = 'skewX' in b ? numbers(a.skewX,b.skewX,v) : 0;
const skewY = 'skewY' in b ? numbers(a.skewY,b.skewY,v) : 0;
const complex = rotate||skewX||skewY||scale!==1 || 0;
// start normalizing the translation, we start from last to first (from last chained translation)
// the normalized translation will handle the transformOrigin tween option and makes sure to have a consistent transformation
x -= complex ? b.origin[0] : 0;y -= complex ? b.origin[1] : 0; // we start with removing transformOrigin from translation
x *= scale;y *= scale; // we now apply the scale
y += skewY ? x*Math.tan(skewY*deg) : 0;x += skewX ? y*Math.tan(skewX*deg) : 0; // now we apply skews
tmp = cos*x - sin*y; // apply rotation as well
y = rotate ? sin*x + cos*y : y;x = rotate ? tmp : x;
x += 'translate' in b ? numbers(a.translate[0],b.translate[0],v) : 0; // now we apply the actual translation
y += 'translate' in b ? numbers(a.translate[1],b.translate[1],v) : 0;
x += complex ? b.origin[0] : 0;y += complex ? b.origin[1] : 0; // normalizing ends with the addition of the transformOrigin to the translation
// finally we apply the transform attribute value
l.setAttribute('transform', ( x||y ? (`translate(${(x*1000>>0)/1000}${y ? (`,${(y*1000>>0)/1000}`) : ''})`) : '' )
+( rotate ? `rotate(${(rotate*1000>>0)/1000})` : '' )
+( skewX ? `skewX(${(skewX*1000>>0)/1000})` : '' )
+( skewY ? `skewY(${(skewY*1000>>0)/1000})` : '' )
+( scale !== 1 ? `scale(${(scale*1000>>0)/1000})` : '' ) );
}
}
}
// Component Base
const baseSVGTransform = {
component: 'baseSVGTransform',
property: 'svgTransform',
// subProperties: ['translate','rotate','skewX','skewY','scale'],
// defaultValue: {translate:0, rotate:0, skewX:0, skewY:0, scale:1},
defaultOptions: {transformOrigin:'50% 50%'},
Interpolate: {numbers},
functions: {onStart:svgTransformOnStart}
}
export default baseSVGTransform
import KEC from '../objects/kute';
import numbers from '../interpolation/numbers';
// Component Functions
/**
* Sets the property update function.
* @param {string} tweenProp the property name
*/
export function svgTransformOnStart(tweenProp) {
if (!KEC[tweenProp] && this.valuesEnd[tweenProp]) {
KEC[tweenProp] = (l, a, b, v) => {
let x = 0;
let y = 0;
const deg = Math.PI / 180;
const scale = 'scale' in b ? numbers(a.scale, b.scale, v) : 1;
const rotate = 'rotate' in b ? numbers(a.rotate, b.rotate, v) : 0;
const sin = Math.sin(rotate * deg);
const cos = Math.cos(rotate * deg);
const skewX = 'skewX' in b ? numbers(a.skewX, b.skewX, v) : 0;
const skewY = 'skewY' in b ? numbers(a.skewY, b.skewY, v) : 0;
const complex = rotate || skewX || skewY || scale !== 1 || 0;
// start normalizing the translation, we start from last to first
// (from last chained translation)
// the normalized translation will handle the transformOrigin tween option
// and makes sure to have a consistent transformation
// we start with removing transformOrigin from translation
x -= complex ? b.origin[0] : 0; y -= complex ? b.origin[1] : 0;
x *= scale; y *= scale; // we now apply the scale
// now we apply skews
y += skewY ? x * Math.tan(skewY * deg) : 0; x += skewX ? y * Math.tan(skewX * deg) : 0;
const cxsy = cos * x - sin * y; // apply rotation as well
y = rotate ? sin * x + cos * y : y; x = rotate ? cxsy : x;
// now we apply the actual translation
x += 'translate' in b ? numbers(a.translate[0], b.translate[0], v) : 0;
y += 'translate' in b ? numbers(a.translate[1], b.translate[1], v) : 0;
// normalizing ends with the addition of the transformOrigin to the translation
x += complex ? b.origin[0] : 0; y += complex ? b.origin[1] : 0;
// finally we apply the transform attribute value
/* eslint no-bitwise: ["error", { "allow": [">>"] }] */
l.setAttribute('transform', (x || y ? (`translate(${(x * 1000 >> 0) / 1000}${y ? (`,${(y * 1000 >> 0) / 1000}`) : ''})`) : '')
+ (rotate ? `rotate(${(rotate * 1000 >> 0) / 1000})` : '')
+ (skewX ? `skewX(${(skewX * 1000 >> 0) / 1000})` : '')
+ (skewY ? `skewY(${(skewY * 1000 >> 0) / 1000})` : '')
+ (scale !== 1 ? `scale(${(scale * 1000 >> 0) / 1000})` : ''));
};
}
}
// Component Base
const baseSVGTransform = {
component: 'baseSVGTransform',
property: 'svgTransform',
// subProperties: ['translate','rotate','skewX','skewY','scale'],
// defaultValue: {translate:0, rotate:0, skewX:0, skewY:0, scale:1},
defaultOptions: { transformOrigin: '50% 50%' },
Interpolate: { numbers },
functions: { onStart: svgTransformOnStart },
};
export default baseSVGTransform;

View file

@ -1,45 +1,55 @@
import defaultValues from '../objects/defaultValues.js'
import Components from '../objects/components.js'
import getStyleForProperty from '../process/getStyleForProperty.js'
import trueDimension from '../util/trueDimension.js'
import units from '../interpolation/units.js'
import {textPropOnStart} from './textPropertiesBase.js'
// const textProperties = { category : 'textProperties', defaultValues: [], interpolators: {units} }, functions = { prepareStart, prepareProperty, onStart:{} }
// Component Properties
const textProps = ['fontSize','lineHeight','letterSpacing','wordSpacing']
const textOnStart = {}
// Component Functions
textProps.forEach(tweenProp => {
textOnStart[tweenProp] = textPropOnStart
})
export function getTextProp(prop) {
return getStyleForProperty(this.element,prop) || defaultValues[prop];
}
export function prepareTextProp(prop,value) {
return trueDimension(value);
}
// All Component Functions
const textPropFunctions = {
prepareStart: getTextProp,
prepareProperty: prepareTextProp,
onStart: textOnStart
}
// Component Full
const textProperties = {
component: 'textProperties',
category: 'textProperties',
properties: textProps,
defaultValues: {fontSize:0,lineHeight:0,letterSpacing:0,wordSpacing:0},
Interpolate: {units},
functions: textPropFunctions,
Util: {trueDimension}
}
export default textProperties
Components.TextProperties = textProperties
import defaultValues from '../objects/defaultValues';
import getStyleForProperty from '../process/getStyleForProperty';
import trueDimension from '../util/trueDimension';
import units from '../interpolation/units';
import { textPropOnStart } from './textPropertiesBase';
// Component Properties
const textProps = ['fontSize', 'lineHeight', 'letterSpacing', 'wordSpacing'];
const textOnStart = {};
// Component Functions
textProps.forEach((tweenProp) => {
textOnStart[tweenProp] = textPropOnStart;
});
/**
* Returns the current property computed style.
* @param {string} prop the property name
* @returns {string} computed style for property
*/
export function getTextProp(prop/* , value */) {
return getStyleForProperty(this.element, prop) || defaultValues[prop];
}
/**
* Returns the property tween object.
* @param {string} _ the property name
* @param {string} value the property value
* @returns {number} the property tween object
*/
export function prepareTextProp(/* prop */_, value) {
return trueDimension(value);
}
// All Component Functions
const textPropFunctions = {
prepareStart: getTextProp,
prepareProperty: prepareTextProp,
onStart: textOnStart,
};
// Component Full
const TextProperties = {
component: 'textProperties',
category: 'textProperties',
properties: textProps,
defaultValues: {
fontSize: 0, lineHeight: 0, letterSpacing: 0, wordSpacing: 0,
},
Interpolate: { units },
functions: textPropFunctions,
Util: { trueDimension },
};
export default TextProperties;

View file

@ -1,31 +1,35 @@
import KUTE from '../objects/kute.js'
import units from '../interpolation/units.js'
// const opacity = { category : 'textProperties', defaultValues: [], interpolators: {units} }, functions = { prepareStart, prepareProperty, onStart:{} }
// Component Properties
const textProperties = ['fontSize','lineHeight','letterSpacing','wordSpacing']
const textOnStart = {}
export function textPropOnStart(tweenProp){
if (this.valuesEnd[tweenProp] && !KUTE[tweenProp]) {
KUTE[tweenProp] = (elem,a,b,v) => {
elem.style[tweenProp] = units(a.v,b.v,b.u,v);
}
}
}
textProperties.forEach(tweenProp => {
textOnStart[tweenProp] = textPropOnStart
})
// Component Base
const baseTextProperties = {
component: 'baseTextProperties',
category: 'textProps',
// properties: textProperties,
// defaultValues: {fontSize:0,lineHeight:0,letterSpacing:0,wordSpacing:0},
Interpolate: {units},
functions: {onStart:textOnStart}
}
export default baseTextProperties
import KEC from '../objects/kute';
import units from '../interpolation/units';
// Component Properties
const textProperties = ['fontSize', 'lineHeight', 'letterSpacing', 'wordSpacing'];
const textOnStart = {};
/**
* Sets the property update function.
* @param {string} tweenProp the property name
*/
export function textPropOnStart(tweenProp) {
if (this.valuesEnd[tweenProp] && !KEC[tweenProp]) {
KEC[tweenProp] = (elem, a, b, v) => {
// eslint-disable-next-line no-param-reassign -- impossible to satisfy
elem.style[tweenProp] = units(a.v, b.v, b.u, v);
};
}
}
textProperties.forEach((tweenProp) => {
textOnStart[tweenProp] = textPropOnStart;
});
// Component Base
const TextPropertiesBase = {
component: 'baseTextProperties',
category: 'textProps',
// properties: textProperties,
// defaultValues: {fontSize:0,lineHeight:0,letterSpacing:0,wordSpacing:0},
Interpolate: { units },
functions: { onStart: textOnStart },
};
export default TextPropertiesBase;

View file

@ -1,159 +1,188 @@
import connect from '../objects/connect.js'
import Components from '../objects/components.js'
import numbers from '../interpolation/numbers.js'
import {onStartWrite,charSet} from './textWriteBase.js'
// Component Util
// utility for multi-child targets
// wrapContentsSpan returns an [Element] with the SPAN.tagName and a desired class
function wrapContentsSpan(el,classNAME){
let textWriteWrapper;
let newElem;
if ( typeof(el) === 'string' ) {
newElem = document.createElement('SPAN')
newElem.innerHTML = el
newElem.className = classNAME
return newElem
} else if (!el.children.length || el.children.length && el.children[0].className !== classNAME ) {
let elementInnerHTML = el.innerHTML
textWriteWrapper = document.createElement('SPAN')
textWriteWrapper.className = classNAME
textWriteWrapper.innerHTML = elementInnerHTML
el.appendChild(textWriteWrapper)
el.innerHTML = textWriteWrapper.outerHTML
} else if (el.children.length && el.children[0].className === classNAME){
textWriteWrapper = el.children[0]
}
return textWriteWrapper
}
function getTextPartsArray(el,classNAME){
let elementsArray = []
if (el.children.length) {
let textParts = [];
let remainingMarkup = el.innerHTML;
let wrapperParts;
for ( let i=0, l = el.children.length, currentChild, childOuter, unTaggedContent; i<l; i++) {
currentChild = el.children[i]
childOuter = currentChild.outerHTML
wrapperParts = remainingMarkup.split(childOuter)
if (wrapperParts[0] !== '') {
unTaggedContent = wrapContentsSpan(wrapperParts[0],classNAME)
textParts.push( unTaggedContent )
remainingMarkup = remainingMarkup.replace(wrapperParts[0],'')
} else if (wrapperParts[1] !== '') {
unTaggedContent = wrapContentsSpan(wrapperParts[1].split('<')[0],classNAME)
textParts.push( unTaggedContent )
remainingMarkup = remainingMarkup.replace(wrapperParts[0].split('<')[0],'')
}
!currentChild.classList.contains(classNAME) && currentChild.classList.add(classNAME)
textParts.push( currentChild )
remainingMarkup = remainingMarkup.replace(childOuter,'')
}
if (remainingMarkup!==''){
let unTaggedRemaining = wrapContentsSpan(remainingMarkup,classNAME)
textParts.push( unTaggedRemaining )
}
elementsArray = elementsArray.concat(textParts)
} else {
elementsArray = elementsArray.concat([wrapContentsSpan(el,classNAME)])
}
return elementsArray
}
function setSegments(target,newText){
const oldTargetSegs = getTextPartsArray( target,'text-part');
const newTargetSegs = getTextPartsArray( wrapContentsSpan( newText ), 'text-part' );
target.innerHTML = ''
target.innerHTML += oldTargetSegs.map(s=>{ s.className += ' oldText'; return s.outerHTML }).join('')
target.innerHTML += newTargetSegs.map(s=>{ s.className += ' newText'; return s.outerHTML.replace(s.innerHTML,'') }).join('')
return [oldTargetSegs,newTargetSegs]
}
export function createTextTweens(target,newText,options){
if (target.playing) return;
options = options || {}
options.duration = options.duration === 'auto' ? 'auto' : isFinite(options.duration*1) ? options.duration*1 : 1000;
const segs = setSegments(target,newText);
const oldTargetSegs = segs[0];
const newTargetSegs = segs[1];
let oldTargets = [].slice.call(target.getElementsByClassName('oldText')).reverse();
let newTargets = [].slice.call(target.getElementsByClassName('newText'));
let textTween = [], totalDelay = 0
textTween = textTween.concat(oldTargets.map((el,i) => {
options.duration = options.duration === 'auto' ? oldTargetSegs[i].innerHTML.length * 75 : options.duration;
options.delay = totalDelay;
options.onComplete = null
totalDelay += options.duration
return new connect.tween(el, {text:el.innerHTML}, {text:''}, options );
}));
textTween = textTween.concat(newTargets.map((el,i)=> {
const onComplete = () => {target.innerHTML = newText, target.playing = false};
options.duration = options.duration === 'auto' ? newTargetSegs[i].innerHTML.length * 75 : options.duration;
options.delay = totalDelay;
options.onComplete = i === newTargetSegs.length-1 ? onComplete : null
totalDelay += options.duration
return new connect.tween(el, {text:''}, {text:newTargetSegs[i].innerHTML}, options );
}));
textTween.start = function(){
!target.playing && textTween.map(tw=>tw.start()) && (target.playing = true)
}
return textTween
}
// Component Functions
function getWrite(tweenProp,value){
return this.element.innerHTML;
}
function prepareText(tweenProp,value) {
if( tweenProp === 'number' ) {
return parseFloat(value)
} else {
// empty strings crash the update function
return value === '' ? ' ' : value
}
}
// All Component Functions
export const textWriteFunctions = {
prepareStart: getWrite,
prepareProperty: prepareText,
onStart: onStartWrite
}
// const textWrite = { category : 'textWrite', defaultValues: {}, interpolators: {numbers} }, functions = { prepareStart, prepareProperty, onStart }
// Full Component
export const textWrite = {
component: 'textWriteProperties',
category: 'textWrite',
properties: ['text','number'],
defaultValues: {text: ' ',numbers:'0'},
defaultOptions: { textChars: 'alpha' },
Interpolate: {numbers},
functions: textWriteFunctions,
// export to global for faster execution
Util: { charSet, createTextTweens }
}
export default textWrite
Components.TextWriteProperties = textWrite
import connect from '../objects/connect';
import numbers from '../interpolation/numbers';
import { onStartWrite, charSet } from './textWriteBase';
// Component Util
// utility for multi-child targets
// wrapContentsSpan returns an [Element] with the SPAN.tagName and a desired class
function wrapContentsSpan(el, classNAME) {
let textWriteWrapper;
let newElem;
if (typeof (el) === 'string') {
newElem = document.createElement('SPAN');
newElem.innerHTML = el;
newElem.className = classNAME;
return newElem;
}
if (!el.children.length || (el.children.length && el.children[0].className !== classNAME)) {
const elementInnerHTML = el.innerHTML;
textWriteWrapper = document.createElement('SPAN');
textWriteWrapper.className = classNAME;
textWriteWrapper.innerHTML = elementInnerHTML;
/* eslint-disable no-param-reassign -- impossible to satisfy */
el.appendChild(textWriteWrapper);
el.innerHTML = textWriteWrapper.outerHTML;
/* eslint-enable no-param-reassign -- impossible to satisfy */
} else if (el.children.length && el.children[0].className === classNAME) {
[textWriteWrapper] = el.children;
}
return textWriteWrapper;
}
function getTextPartsArray(el, classNAME) {
let elementsArray = [];
const len = el.children.length;
if (len) {
const textParts = [];
let remainingMarkup = el.innerHTML;
let wrapperParts;
for (let i = 0, currentChild, childOuter, unTaggedContent; i < len; i += 1) {
currentChild = el.children[i];
childOuter = currentChild.outerHTML;
wrapperParts = remainingMarkup.split(childOuter);
if (wrapperParts[0] !== '') {
unTaggedContent = wrapContentsSpan(wrapperParts[0], classNAME);
textParts.push(unTaggedContent);
remainingMarkup = remainingMarkup.replace(wrapperParts[0], '');
} else if (wrapperParts[1] !== '') {
unTaggedContent = wrapContentsSpan(wrapperParts[1].split('<')[0], classNAME);
textParts.push(unTaggedContent);
remainingMarkup = remainingMarkup.replace(wrapperParts[0].split('<')[0], '');
}
if (!currentChild.classList.contains(classNAME)) currentChild.classList.add(classNAME);
textParts.push(currentChild);
remainingMarkup = remainingMarkup.replace(childOuter, '');
}
if (remainingMarkup !== '') {
const unTaggedRemaining = wrapContentsSpan(remainingMarkup, classNAME);
textParts.push(unTaggedRemaining);
}
elementsArray = elementsArray.concat(textParts);
} else {
elementsArray = elementsArray.concat([wrapContentsSpan(el, classNAME)]);
}
return elementsArray;
}
function setSegments(target, newText) {
const oldTargetSegs = getTextPartsArray(target, 'text-part');
const newTargetSegs = getTextPartsArray(wrapContentsSpan(newText), 'text-part');
/* eslint-disable no-param-reassign */
target.innerHTML = '';
target.innerHTML += oldTargetSegs.map((s) => { s.className += ' oldText'; return s.outerHTML; }).join('');
target.innerHTML += newTargetSegs.map((s) => { s.className += ' newText'; return s.outerHTML.replace(s.innerHTML, ''); }).join('');
/* eslint-enable no-param-reassign */
return [oldTargetSegs, newTargetSegs];
}
export function createTextTweens(target, newText, ops) {
if (target.playing) return false;
const options = ops || {};
options.duration = 1000;
if (ops.duration === 'auto') {
options.duration = 'auto';
} else if (Number.isFinite(ops.duration * 1)) {
options.duration = ops.duration * 1;
}
const TweenContructor = connect.tween;
const segs = setSegments(target, newText);
const oldTargetSegs = segs[0];
const newTargetSegs = segs[1];
const oldTargets = [].slice.call(target.getElementsByClassName('oldText')).reverse();
const newTargets = [].slice.call(target.getElementsByClassName('newText'));
let textTween = [];
let totalDelay = 0;
textTween = textTween.concat(oldTargets.map((el, i) => {
options.duration = options.duration === 'auto'
? oldTargetSegs[i].innerHTML.length * 75
: options.duration;
options.delay = totalDelay;
options.onComplete = null;
totalDelay += options.duration;
return new TweenContructor(el, { text: el.innerHTML }, { text: '' }, options);
}));
textTween = textTween.concat(newTargets.map((el, i) => {
function onComplete() {
/* eslint-disable no-param-reassign */
target.innerHTML = newText;
target.playing = false;
/* eslint-enable no-param-reassign */
}
options.duration = options.duration === 'auto' ? newTargetSegs[i].innerHTML.length * 75 : options.duration;
options.delay = totalDelay;
options.onComplete = i === newTargetSegs.length - 1 ? onComplete : null;
totalDelay += options.duration;
return new TweenContructor(el, { text: '' }, { text: newTargetSegs[i].innerHTML }, options);
}));
textTween.start = function startTweens() {
if (!target.playing) {
textTween.forEach((tw) => tw.start());
// eslint-disable-next-line no-param-reassign
target.playing = true;
}
};
return textTween;
}
// Component Functions
/**
* Returns the current element `innerHTML`.
* @returns {string} computed style for property
*/
function getWrite(/* tweenProp, value */) {
return this.element.innerHTML;
}
/**
* Returns the property tween object.
* @param {string} tweenProp the property name
* @param {string} value the property value
* @returns {number | string} the property tween object
*/
function prepareText(tweenProp, value) {
if (tweenProp === 'number') {
return parseFloat(value);
}
// empty strings crash the update function
return value === '' ? ' ' : value;
}
// All Component Functions
export const textWriteFunctions = {
prepareStart: getWrite,
prepareProperty: prepareText,
onStart: onStartWrite,
};
// Full Component
export const TextWrite = {
component: 'textWriteProperties',
category: 'textWrite',
properties: ['text', 'number'],
defaultValues: { text: ' ', number: '0' },
defaultOptions: { textChars: 'alpha' },
Interpolate: { numbers },
functions: textWriteFunctions,
// export to global for faster execution
Util: { charSet, createTextTweens },
};
export default TextWrite;

View file

@ -1,78 +1,102 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
import defaultOptions from '../objects/defaultOptions.js'
// Component Values
const lowerCaseAlpha = String("abcdefghijklmnopqrstuvwxyz").split(""), // lowercase
upperCaseAlpha = String("abcdefghijklmnopqrstuvwxyz").toUpperCase().split(""), // uppercase
nonAlpha = String("~!@#$%^&*()_+{}[];'<>,./?\=-").split(""), // symbols
numeric = String("0123456789").split(""), // numeric
alphaNumeric = lowerCaseAlpha.concat(upperCaseAlpha,numeric), // alpha numeric
allTypes = alphaNumeric.concat(nonAlpha); // all caracters
const charSet = {
alpha: lowerCaseAlpha, // lowercase
upper: upperCaseAlpha, // uppercase
symbols: nonAlpha, // symbols
numeric: numeric,
alphanumeric: alphaNumeric,
all: allTypes,
}
export {charSet}
// Component Functions
export const onStartWrite = {
text: function(tweenProp){
if ( !KUTE[tweenProp] && this.valuesEnd[tweenProp] ) {
let chars = this._textChars,
charsets = chars in charSet ? charSet[chars]
: chars && chars.length ? chars
: charSet[defaultOptions.textChars]
KUTE[tweenProp] = function(elem,a,b,v) {
let initialText = '',
endText = '',
firstLetterA = a.substring(0),
firstLetterB = b.substring(0),
pointer = charsets[(Math.random() * charsets.length)>>0];
if (a === ' ') {
endText = firstLetterB.substring(Math.min(v * firstLetterB.length, firstLetterB.length)>>0, 0 );
elem.innerHTML = v < 1 ? ( ( endText + pointer ) ) : (b === '' ? ' ' : b);
} else if (b === ' ') {
initialText = firstLetterA.substring(0, Math.min((1-v) * firstLetterA.length, firstLetterA.length)>>0 );
elem.innerHTML = v < 1 ? ( ( initialText + pointer ) ) : (b === '' ? ' ' : b);
} else {
initialText = firstLetterA.substring(firstLetterA.length, Math.min(v * firstLetterA.length, firstLetterA.length)>>0 );
endText = firstLetterB.substring(0, Math.min(v * firstLetterB.length, firstLetterB.length)>>0 );
elem.innerHTML = v < 1 ? ( (endText + pointer + initialText) ) : (b === '' ? ' ' : b);
}
}
}
},
number: function(tweenProp) {
if ( tweenProp in this.valuesEnd && !KUTE[tweenProp]) { // numbers can be 0
KUTE[tweenProp] = (elem, a, b, v) => {
elem.innerHTML = numbers(a, b, v)>>0;
}
}
}
}
// Base Component
export const baseTextWrite = {
component: 'baseTextWrite',
category: 'textWrite',
// properties: ['text','number'],
// defaultValues: {text: ' ',numbers:'0'},
defaultOptions: { textChars: 'alpha' },
Interpolate: {numbers},
functions: {onStart:onStartWrite},
// export to global for faster execution
Util: { charSet }
}
export default baseTextWrite
import KEC from '../objects/kute';
import numbers from '../interpolation/numbers';
import defaultOptions from '../objects/defaultOptions';
// Component Values
const lowerCaseAlpha = String('abcdefghijklmnopqrstuvwxyz').split(''); // lowercase
const upperCaseAlpha = String('abcdefghijklmnopqrstuvwxyz').toUpperCase().split(''); // uppercase
const nonAlpha = String("~!@#$%^&*()_+{}[];'<>,./?=-").split(''); // symbols
const numeric = String('0123456789').split(''); // numeric
const alphaNumeric = lowerCaseAlpha.concat(upperCaseAlpha, numeric); // alpha numeric
const allTypes = alphaNumeric.concat(nonAlpha); // all caracters
const charSet = {
alpha: lowerCaseAlpha, // lowercase
upper: upperCaseAlpha, // uppercase
symbols: nonAlpha, // symbols
numeric,
alphanumeric: alphaNumeric,
all: allTypes,
};
export { charSet };
// Component Functions
export const onStartWrite = {
/**
* onStartWrite.text
*
* Sets the property update function.
* @param {string} tweenProp the property name
*/
text(tweenProp) {
if (!KEC[tweenProp] && this.valuesEnd[tweenProp]) {
const chars = this._textChars;
let charsets = charSet[defaultOptions.textChars];
if (chars in charSet) {
charsets = charSet[chars];
} else if (chars && chars.length) {
charsets = chars;
}
KEC[tweenProp] = (elem, a, b, v) => {
let initialText = '';
let endText = '';
const finalText = b === '' ? ' ' : b;
const firstLetterA = a.substring(0);
const firstLetterB = b.substring(0);
/* eslint-disable */
const pointer = charsets[(Math.random() * charsets.length) >> 0];
if (a === ' ') {
endText = firstLetterB
.substring(Math.min(v * firstLetterB.length, firstLetterB.length) >> 0, 0);
elem.innerHTML = v < 1 ? ((endText + pointer)) : finalText;
} else if (b === ' ') {
initialText = firstLetterA
.substring(0, Math.min((1 - v) * firstLetterA.length, firstLetterA.length) >> 0);
elem.innerHTML = v < 1 ? ((initialText + pointer)) : finalText;
} else {
initialText = firstLetterA
.substring(firstLetterA.length,
Math.min(v * firstLetterA.length, firstLetterA.length) >> 0);
endText = firstLetterB
.substring(0, Math.min(v * firstLetterB.length, firstLetterB.length) >> 0);
elem.innerHTML = v < 1 ? ((endText + pointer + initialText)) : finalText;
}
/* eslint-enable */
};
}
},
/**
* onStartWrite.number
*
* Sets the property update function.
* @param {string} tweenProp the property name
*/
number(tweenProp) {
if (tweenProp in this.valuesEnd && !KEC[tweenProp]) { // numbers can be 0
KEC[tweenProp] = (elem, a, b, v) => {
/* eslint-disable */
elem.innerHTML = numbers(a, b, v) >> 0;
/* eslint-enable */
};
}
},
};
// Base Component
export const TextWriteBase = {
component: 'baseTextWrite',
category: 'textWrite',
// properties: ['text','number'],
// defaultValues: {text: ' ',numbers:'0'},
defaultOptions: { textChars: 'alpha' },
Interpolate: { numbers },
functions: { onStart: onStartWrite },
// export to global for faster execution
Util: { charSet },
};
export default TextWriteBase;

View file

@ -1,109 +1,152 @@
import defaultValues from '../objects/defaultValues.js'
import Components from '../objects/components.js'
import getInlineStyle from '../process/getInlineStyle.js'
import perspective from '../interpolation/perspective.js'
import translate3d from '../interpolation/translate3d.js'
import rotate3d from '../interpolation/rotate3d.js'
import translate from '../interpolation/translate.js'
import rotate from '../interpolation/rotate.js'
import scale from '../interpolation/scale.js'
import skew from '../interpolation/skew.js'
import {onStartTransform} from './transformFunctionsBase.js'
// const transformFunctions = { property : 'transform', subProperties, defaultValues, Interpolate: {translate,rotate,skew,scale}, functions } // same to svg transform, attr
// the component developed for modern browsers supporting non-prefixed transform
// Component Functions
function getTransform(tweenProperty,value){
const currentStyle = getInlineStyle(this.element);
return currentStyle[tweenProperty] ? currentStyle[tweenProperty] : defaultValues[tweenProperty];
}
function prepareTransform(prop,obj){
let prepAxis = ['X', 'Y', 'Z'], // coordinates
transformObject = {},
translateArray = [], rotateArray = [], skewArray = [],
arrayFunctions = ['translate3d','translate','rotate3d','skew']
for (const x in obj) {
let pv = typeof obj[x] === 'object' && obj[x].length ? obj[x].map(v=>parseInt(v)) : parseInt(obj[x]);
if (arrayFunctions.includes(x)) {
let propId = x === 'translate' || x === 'rotate' ? `${x}3d` : x;
transformObject[propId] = x === 'skew' ? (pv.length ? [pv[0]||0, pv[1]||0] : [pv||0,0] )
: x === 'translate' ? (pv.length ? [pv[0]||0, pv[1]||0, pv[2]||0] : [pv||0,0,0] )
: [pv[0]||0, pv[1]||0,pv[2]||0] // translate3d | rotate3d
} else if ( /[XYZ]/.test(x) ) {
let fn = x.replace(/[XYZ]/,''),
fnId = fn === 'skew' ? fn : `${fn}3d`,
fnLen = fn === 'skew' ? 2 : 3,
fnArray = fn === 'translate' ? translateArray
: fn === 'rotate' ? rotateArray
: fn === 'skew' ? skewArray : {}
for (let fnIndex = 0; fnIndex < fnLen; fnIndex++) {
const fnAxis = prepAxis[fnIndex];
fnArray[fnIndex] = (`${fn}${fnAxis}` in obj) ? parseInt(obj[`${fn}${fnAxis}`]) : 0;
}
transformObject[fnId] = fnArray;
} else if (x==='rotate') { // rotate
transformObject['rotate3d'] = [0,0,pv]
} else { // scale | perspective
transformObject[x] = x === 'scale' ? parseFloat(obj[x]) : pv
}
}
return transformObject;
}
function crossCheckTransform(tweenProp){
if (this.valuesEnd[tweenProp]) {
if ( this.valuesEnd[tweenProp] ) {
if (this.valuesEnd[tweenProp].perspective && !this.valuesStart[tweenProp].perspective){
this.valuesStart[tweenProp].perspective = this.valuesEnd[tweenProp].perspective
}
}
}
}
// All Component Functions
const transformFunctions = {
prepareStart: getTransform,
prepareProperty: prepareTransform,
onStart: onStartTransform,
crossCheck: crossCheckTransform
}
const supportedTransformProperties = [
'perspective',
'translate3d', 'translateX', 'translateY', 'translateZ', 'translate',
'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'rotate',
'skewX', 'skewY', 'skew',
'scale'
]
const defaultTransformValues = {
perspective: 400,
translate3d : [0,0,0], translateX : 0, translateY : 0, translateZ : 0, translate : [0,0],
rotate3d: [0,0,0], rotateX : 0, rotateY : 0, rotateZ : 0, rotate : 0,
skewX : 0, skewY : 0, skew: [0,0],
scale : 1
}
// Full Component
const transformFunctionsComponent = {
component: 'transformFunctions',
property: 'transform',
subProperties: supportedTransformProperties,
defaultValues: defaultTransformValues,
functions: transformFunctions,
Interpolate: {
perspective: perspective,
translate3d: translate3d,
rotate3d: rotate3d,
translate: translate, rotate: rotate, scale: scale, skew: skew
}
}
export default transformFunctionsComponent
Components.TransformFunctions = transformFunctionsComponent
import defaultValues from '../objects/defaultValues';
import getInlineStyle from '../process/getInlineStyle';
import perspective from '../interpolation/perspective';
import translate3d from '../interpolation/translate3d';
import rotate3d from '../interpolation/rotate3d';
import translate from '../interpolation/translate';
import rotate from '../interpolation/rotate';
import scale from '../interpolation/scale';
import skew from '../interpolation/skew';
import { onStartTransform } from './transformFunctionsBase';
// same to svg transform, attr
// the component developed for modern browsers supporting non-prefixed transform
// Component Functions
/**
* Returns the current property inline style.
* @param {string} tweenProp the property name
* @returns {string} inline style for property
*/
function getTransform(tweenProp/* , value */) {
const currentStyle = getInlineStyle(this.element);
return currentStyle[tweenProp] ? currentStyle[tweenProp] : defaultValues[tweenProp];
}
/**
* Returns the property tween object.
* @param {string} _ the property name
* @param {Object<string, string | number | (string | number)[]>} obj the property value
* @returns {KUTE.transformFObject} the property tween object
*/
function prepareTransform(/* prop, */_, obj) {
const prepAxis = ['X', 'Y', 'Z']; // coordinates
const transformObject = {};
const translateArray = []; const rotateArray = []; const skewArray = [];
const arrayFunctions = ['translate3d', 'translate', 'rotate3d', 'skew'];
Object.keys(obj).forEach((x) => {
const pv = typeof obj[x] === 'object' && obj[x].length
? obj[x].map((v) => parseInt(v, 10))
: parseInt(obj[x], 10);
if (arrayFunctions.includes(x)) {
const propId = x === 'translate' || x === 'rotate' ? `${x}3d` : x;
if (x === 'skew') {
transformObject[propId] = pv.length
? [pv[0] || 0, pv[1] || 0]
: [pv || 0, 0];
} else if (x === 'translate') {
transformObject[propId] = pv.length
? [pv[0] || 0, pv[1] || 0, pv[2] || 0]
: [pv || 0, 0, 0];
} else { // translate3d | rotate3d
transformObject[propId] = [pv[0] || 0, pv[1] || 0, pv[2] || 0];
}
} else if (/[XYZ]/.test(x)) {
const fn = x.replace(/[XYZ]/, '');
const fnId = fn === 'skew' ? fn : `${fn}3d`;
const fnLen = fn === 'skew' ? 2 : 3;
let fnArray = [];
if (fn === 'translate') {
fnArray = translateArray;
} else if (fn === 'rotate') {
fnArray = rotateArray;
} else if (fn === 'skew') {
fnArray = skewArray;
}
for (let fnIndex = 0; fnIndex < fnLen; fnIndex += 1) {
const fnAxis = prepAxis[fnIndex];
fnArray[fnIndex] = (`${fn}${fnAxis}` in obj) ? parseInt(obj[`${fn}${fnAxis}`], 10) : 0;
}
transformObject[fnId] = fnArray;
} else if (x === 'rotate') { // rotate
transformObject.rotate3d = [0, 0, pv];
} else { // scale | perspective
transformObject[x] = x === 'scale' ? parseFloat(obj[x]) : pv;
}
});
return transformObject;
}
/**
* Prepare tween object in advance for `to()` method.
* @param {string} tweenProp the property name
*/
function crossCheckTransform(tweenProp) {
if (this.valuesEnd[tweenProp]) {
if (this.valuesEnd[tweenProp]) {
if (this.valuesEnd[tweenProp].perspective && !this.valuesStart[tweenProp].perspective) {
this.valuesStart[tweenProp].perspective = this.valuesEnd[tweenProp].perspective;
}
}
}
}
// All Component Functions
const transformFunctions = {
prepareStart: getTransform,
prepareProperty: prepareTransform,
onStart: onStartTransform,
crossCheck: crossCheckTransform,
};
const supportedTransformProperties = [
'perspective',
'translate3d', 'translateX', 'translateY', 'translateZ', 'translate',
'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'rotate',
'skewX', 'skewY', 'skew',
'scale',
];
const defaultTransformValues = {
perspective: 400,
translate3d: [0, 0, 0],
translateX: 0,
translateY: 0,
translateZ: 0,
translate: [0, 0],
rotate3d: [0, 0, 0],
rotateX: 0,
rotateY: 0,
rotateZ: 0,
rotate: 0,
skewX: 0,
skewY: 0,
skew: [0, 0],
scale: 1,
};
// Full Component
const TransformFunctions = {
component: 'transformFunctions',
property: 'transform',
subProperties: supportedTransformProperties,
defaultValues: defaultTransformValues,
functions: transformFunctions,
Interpolate: {
perspective,
translate3d,
rotate3d,
translate,
rotate,
scale,
skew,
},
};
export default TransformFunctions;

View file

@ -1,39 +1,45 @@
import KUTE from '../objects/kute.js'
import perspective from '../interpolation/perspective.js'
import translate3d from '../interpolation/translate3d.js'
import rotate3d from '../interpolation/rotate3d.js'
import translate from '../interpolation/translate.js'
import rotate from '../interpolation/rotate.js'
import scale from '../interpolation/scale.js'
import skew from '../interpolation/skew.js'
// const transformFunctions = { property : 'transform', subProperties, defaultValues, Interpolate: {translate,rotate,skew,scale}, functions } // same to svg transform, attr
// Component Functions
export function onStartTransform(tweenProp){
if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) {
KUTE[tweenProp] = (elem, a, b, v) => {
elem.style[tweenProp] =
(a.perspective||b.perspective ? perspective(a.perspective,b.perspective,'px',v) : '') // one side might be 0
+ (a.translate3d ? translate3d(a.translate3d,b.translate3d,'px',v):'') // array [x,y,z]
+ (a.rotate3d ? rotate3d(a.rotate3d,b.rotate3d,'deg',v):'') // array [x,y,z]
+ (a.skew ? skew(a.skew,b.skew,'deg',v):'') // array [x,y]
+ (a.scale||b.scale ? scale(a.scale,b.scale,v):'') // one side might be 0
}
}
}
// Base Component
const BaseTransform = {
component: 'baseTransform',
property: 'transform',
functions: {onStart: onStartTransform},
Interpolate: {
perspective: perspective,
translate3d: translate3d,
rotate3d: rotate3d,
translate: translate, rotate: rotate, scale: scale, skew: skew
}
}
export default BaseTransform
import KEC from '../objects/kute';
import perspective from '../interpolation/perspective';
import translate3d from '../interpolation/translate3d';
import rotate3d from '../interpolation/rotate3d';
import translate from '../interpolation/translate';
import rotate from '../interpolation/rotate';
import scale from '../interpolation/scale';
import skew from '../interpolation/skew';
// Component Functions
/**
* Sets the property update function.
* * same to svgTransform, htmlAttributes
* @param {string} tweenProp the property name
*/
export function onStartTransform(tweenProp) {
if (!KEC[tweenProp] && this.valuesEnd[tweenProp]) {
KEC[tweenProp] = (elem, a, b, v) => {
// eslint-disable-next-line no-param-reassign
elem.style[tweenProp] = (a.perspective || b.perspective ? perspective(a.perspective, b.perspective, 'px', v) : '') // one side might be 0
+ (a.translate3d ? translate3d(a.translate3d, b.translate3d, 'px', v) : '') // array [x,y,z]
+ (a.rotate3d ? rotate3d(a.rotate3d, b.rotate3d, 'deg', v) : '') // array [x,y,z]
+ (a.skew ? skew(a.skew, b.skew, 'deg', v) : '') // array [x,y]
+ (a.scale || b.scale ? scale(a.scale, b.scale, v) : ''); // one side might be 0
};
}
}
// Base Component
const TransformFunctionsBase = {
component: 'baseTransform',
property: 'transform',
functions: { onStart: onStartTransform },
Interpolate: {
perspective,
translate3d,
rotate3d,
translate,
rotate,
scale,
skew,
},
};
export default TransformFunctionsBase;

View file

@ -1,134 +1,172 @@
import defaultValues from '../objects/defaultValues.js'
import Components from '../objects/components.js'
import getInlineStyleLegacy from '../process/getInlineStyleLegacy.js'
import perspective from '../interpolation/perspective.js'
import translate3d from '../interpolation/translate3d.js'
import rotate3d from '../interpolation/rotate3d.js'
import translate from '../interpolation/translate.js'
import rotate from '../interpolation/rotate.js'
import scale from '../interpolation/scale.js'
import skew from '../interpolation/skew.js'
import support3DTransform from 'shorter-js/src/boolean/support3DTransform.js'
import {onStartLegacyTransform} from './transformLegacyBase.js'
import transformProperty from '../util/transformProperty.js'
import supportTransform from '../util/supportLegacyTransform.js'
// const transformFunctions = { property : 'transform', subProperties, defaultValues, Interpolate: {translate,rotate,skew,scale}, functions } // same to svg transform, attr
// the component to handle all kinds of input values and process according to browser supported API,
// the component that handles all browsers IE9+
// Component Functions
function getLegacyTransform(tweenProperty,value){
const currentStyle = getInlineStyleLegacy(this.element);
return currentStyle[tweenProperty] ? currentStyle[tweenProperty] : defaultValues[tweenProperty];
}
function prepareLegacyTransform(prop,obj){
let prepAxis = ['X', 'Y', 'Z'], // coordinates
translateArray = [], rotateArray = [], skewArray = [],
transformObject = {},
arrayFunctions = ['translate3d','translate','rotate3d','skew']
for (const x in obj) {
const pv = typeof(obj[x]) === 'object' && obj[x].length ? obj[x].map(v=>parseInt(v)) : parseInt(obj[x])
if (arrayFunctions.includes(x)) {
if (support3DTransform){
if (x==='translate3d' || x==='rotate3d') {
transformObject[x] = pv
} else if (x==='translate'){
transformObject['translate3d'] = pv.length ? pv.concat(0) : [pv||0,0,0]
} else if (x==='rotate'){
transformObject['rotate3d'] = [0,0,pv||0]
} else if (x==='skew'){
transformObject[x] = pv.length ? pv : [pv||0,0]
}
} else if (supportTransform) {
if (x==='translate3d') {
transformObject['translate'] = [pv[0]||0,pv[1]||0]
} else if (x==='translate' || x==='skew'){
transformObject[x] = pv.length ? pv : [pv||0,0]
} else if (x==='rotate3d'){
transformObject['rotate'] = pv[2]||pv[1]||pv[0]
} else if (x==='rotate'){
transformObject[x] = pv
}
}
} else if ( /[XYZ]/.test(x) ) {
let fn = x.replace(/[XYZ]/,''),
fnId = fn === 'skew' || !support3DTransform ? fn : `${fn}3d`,
fnLen = fn === 'skew' || (!support3DTransform && fn === 'translate') ? 2 : 3,
fnArray = fn === 'translate' ? translateArray
: fn === 'rotate' && support3DTransform ? rotateArray
: fn === 'skew' ? skewArray : {}
for (let fnIndex = 0; fnIndex < fnLen; fnIndex++) {
let fnAxis = prepAxis[fnIndex];
fnArray[fnIndex] = (`${fn}${fnAxis}` in obj) ? parseInt(obj[`${fn}${fnAxis}`]) : 0;
}
transformObject[fnId] = support3DTransform ? fnArray : fn === 'rotate' ? fnArray[2]||fnArray[1]||fnArray[0] : fnArray;
} else if (x==='rotate') { // 2d rotate
let pType = support3DTransform ? 'rotate3d' : 'rotate';
transformObject[pType] = support3DTransform ? [0,0,pv] : pv
} else { // scale | perspective
transformObject[x] = x === 'scale' ? parseFloat(obj[x]) : pv
}
}
return transformObject;
}
function crossCheckLegacyTransform(tweenProp){
if (this.valuesEnd[tweenProp]) {
if ( this.valuesEnd[tweenProp] && support3DTransform) {
if (this.valuesEnd[tweenProp].perspective && !this.valuesStart[tweenProp].perspective){
this.valuesStart[tweenProp].perspective = this.valuesEnd[tweenProp].perspective
}
}
}
}
// All Component Functions
const transformLegacyFunctions = {
prepareStart: getLegacyTransform,
prepareProperty: prepareLegacyTransform,
onStart: onStartLegacyTransform,
crossCheck: crossCheckLegacyTransform
}
const legacyTransformValues = {
perspective: 400,
translate3d: [0,0,0], translateX: 0, translateY: 0, translateZ: 0, translate: [0,0],
rotate3d: [0,0,0], rotateX: 0, rotateY: 0, rotateZ: 0, rotate: 0,
skewX: 0, skewY: 0, skew: [0,0],
scale: 1
}
const legacyTransformProperties = [
'perspective',
'translate3d', 'translateX', 'translateY', 'translateZ', 'translate',
'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'rotate',
'skewX', 'skewY', 'skew',
'scale'
]
// Full Component
const transformLegacyComponent = {
component: 'transformFunctions',
property: 'transform',
subProperties: legacyTransformProperties,
defaultValues: legacyTransformValues,
functions: transformLegacyFunctions,
Interpolate: {
perspective: perspective,
translate3d: translate3d,
rotate3d: rotate3d,
translate: translate, rotate: rotate, scale: scale, skew: skew
},
Util: [transformProperty]
}
export default transformLegacyComponent
Components.TransformLegacy = transformLegacyComponent
import support3DTransform from 'shorter-js/src/boolean/support3DTransform';
import defaultValues from '../objects/defaultValues';
import getInlineStyleLegacy from '../process/getInlineStyleLegacy';
import perspective from '../interpolation/perspective';
import translate3d from '../interpolation/translate3d';
import rotate3d from '../interpolation/rotate3d';
import translate from '../interpolation/translate';
import rotate from '../interpolation/rotate';
import scale from '../interpolation/scale';
import skew from '../interpolation/skew';
import { onStartLegacyTransform } from './transformLegacyBase';
import transformProperty from '../util/transformProperty';
import supportTransform from '../util/supportLegacyTransform';
// same to svg transform, attr
// the component to handle all kinds of input values and process according to browser supported API,
// the component that handles all browsers IE9+
// Component Functions
/**
* Returns the current property inline style.
* @param {string} tweenProperty the property name
* @returns {string} inline style for property
*/
function getLegacyTransform(tweenProperty/* , value */) {
const currentStyle = getInlineStyleLegacy(this.element);
return currentStyle[tweenProperty] ? currentStyle[tweenProperty] : defaultValues[tweenProperty];
}
/**
* Returns the property tween object.
* @param {string} _ the property name
* @param {Object<string, string | number | (string | number)[]>} obj the property value
* @returns {KUTE.transformFObject} the property tween object
*/
function prepareLegacyTransform(/* prop */_, obj) {
const prepAxis = ['X', 'Y', 'Z']; // coordinates
const translateArray = []; const rotateArray = []; const skewArray = [];
const transformObject = {};
const arrayFunctions = ['translate3d', 'translate', 'rotate3d', 'skew'];
Object.keys(obj).forEach((x) => {
const pv = typeof (obj[x]) === 'object' && obj[x].length
? obj[x].map((v) => parseInt(v, 10))
: parseInt(obj[x], 10);
if (arrayFunctions.includes(x)) {
if (support3DTransform) {
if (x === 'translate3d' || x === 'rotate3d') {
transformObject[x] = pv;
} else if (x === 'translate') {
transformObject.translate3d = pv.length ? pv.concat(0) : [pv || 0, 0, 0];
} else if (x === 'rotate') {
transformObject.rotate3d = [0, 0, pv || 0];
} else if (x === 'skew') {
transformObject[x] = pv.length ? pv : [pv || 0, 0];
}
} else if (supportTransform) {
if (x === 'translate3d') {
transformObject.translate = [pv[0] || 0, pv[1] || 0];
} else if (x === 'translate' || x === 'skew') {
transformObject[x] = pv.length ? pv : [pv || 0, 0];
} else if (x === 'rotate3d') {
transformObject.rotate = pv[2] || pv[1] || pv[0];
} else if (x === 'rotate') {
transformObject[x] = pv;
}
}
} else if (/[XYZ]/.test(x)) {
const fn = x.replace(/[XYZ]/, '');
const fnId = fn === 'skew' || !support3DTransform ? fn : `${fn}3d`;
const fnLen = fn === 'skew' || (!support3DTransform && fn === 'translate') ? 2 : 3;
let fnArray = [];
if (fn === 'translate') {
fnArray = translateArray;
} else if (fn === 'rotate') {
fnArray = rotateArray;
} else if (fn === 'skew') {
fnArray = skewArray;
}
for (let fnIndex = 0; fnIndex < fnLen; fnIndex += 1) {
const fnAxis = prepAxis[fnIndex];
fnArray[fnIndex] = (`${fn}${fnAxis}` in obj) ? parseInt(obj[`${fn}${fnAxis}`], 10) : 0;
}
if (support3DTransform) {
transformObject[fnId] = fnArray;
} else {
transformObject[fnId] = fn === 'rotate' ? (fnArray[2] || fnArray[1] || fnArray[0]) : fnArray;
}
} else if (x === 'rotate') { // 2d rotate
const pType = support3DTransform ? 'rotate3d' : 'rotate';
transformObject[pType] = support3DTransform ? [0, 0, pv] : pv;
} else { // scale | perspective
transformObject[x] = x === 'scale' ? parseFloat(obj[x]) : pv;
}
});
return transformObject;
}
/**
* Prepare tween object in advance for `to()` method.
* @param {string} tweenProp the property name
*/
function crossCheckLegacyTransform(tweenProp) {
if (this.valuesEnd[tweenProp]) {
if (this.valuesEnd[tweenProp] && support3DTransform) {
if (this.valuesEnd[tweenProp].perspective && !this.valuesStart[tweenProp].perspective) {
this.valuesStart[tweenProp].perspective = this.valuesEnd[tweenProp].perspective;
}
}
}
}
// All Component Functions
const transformLegacyFunctions = {
prepareStart: getLegacyTransform,
prepareProperty: prepareLegacyTransform,
onStart: onStartLegacyTransform,
crossCheck: crossCheckLegacyTransform,
};
const legacyTransformValues = {
perspective: 400,
translate3d: [0, 0, 0],
translateX: 0,
translateY: 0,
translateZ: 0,
translate: [0, 0],
rotate3d: [0, 0, 0],
rotateX: 0,
rotateY: 0,
rotateZ: 0,
rotate: 0,
skewX: 0,
skewY: 0,
skew: [0, 0],
scale: 1,
};
const legacyTransformProperties = [
'perspective',
'translate3d', 'translateX', 'translateY', 'translateZ', 'translate',
'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'rotate',
'skewX', 'skewY', 'skew',
'scale',
];
// Full Component
const transformLegacyComponent = {
component: 'transformFunctions',
property: 'transform',
subProperties: legacyTransformProperties,
defaultValues: legacyTransformValues,
functions: transformLegacyFunctions,
Interpolate: {
perspective,
translate3d,
rotate3d,
translate,
rotate,
scale,
skew,
},
Util: [transformProperty],
};
export default transformLegacyComponent;

View file

@ -1,56 +1,62 @@
import KUTE from '../objects/kute.js'
import perspective from '../interpolation/perspective.js'
import translate3d from '../interpolation/translate3d.js'
import rotate3d from '../interpolation/rotate3d.js'
import translate from '../interpolation/translate.js'
import rotate from '../interpolation/rotate.js'
import scale from '../interpolation/scale.js'
import skew from '../interpolation/skew.js'
import support3DTransform from 'shorter-js/src/boolean/support3DTransform.js'
import supportTransform from '../util/supportLegacyTransform.js'
import transformProperty from '../util/transformProperty.js'
// const baseLegacyTransform = { property : 'transform', subProperties, defaultValues, Interpolate: {translate,rotate,skew,scale}, functions } // same to svg transform, attr
// the component that handles all browsers IE9+
// Component Functions
export function onStartLegacyTransform(tweenProp){
if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) {
if (support3DTransform){
KUTE[tweenProp] = (elem, a, b, v) => {
elem.style[transformProperty] =
(a.perspective||b.perspective ? perspective(a.perspective,b.perspective,'px',v) : '') // one side might be 0
+ (a.translate3d ? translate3d(a.translate3d,b.translate3d,'px',v):'') // array [x,y,z]
+ (a.rotate3d ? rotate3d(a.rotate3d,b.rotate3d,'deg',v):'') // array [x,y,z]
+ (a.skew ? skew(a.skew,b.skew,'deg',v):'') // array [x,y]
+ (a.scale||b.scale ? scale(a.scale,b.scale,v):'') // one side might be 0
}
} else if (supportTransform) {
KUTE[tweenProp] = (elem, a, b, v) => {
elem.style[transformProperty] =
(a.translate ? translate(a.translate,b.translate,'px',v):'') // array [x,y]
+ ((a.rotate||b.rotate) ? rotate(a.rotate,b.rotate,'deg',v):'') // one side might be 0
+ (a.skew ? skew(a.skew,b.skew,'deg',v):'') // array [x,y]
+ (a.scale||b.scale ? scale(a.scale,b.scale,v):'') // one side might be 0
}
}
}
}
// Base Component
const BaseLegacyTransform = {
component: 'baseLegacyTransform',
property: 'transform',
functions: {onStart: onStartLegacyTransform},
Interpolate: {
perspective: perspective,
translate3d: translate3d,
rotate3d: rotate3d,
translate: translate, rotate: rotate, scale: scale, skew: skew
},
Util: {transformProperty}
}
export default BaseLegacyTransform
import support3DTransform from 'shorter-js/src/boolean/support3DTransform';
import KEC from '../objects/kute';
import perspective from '../interpolation/perspective';
import translate3d from '../interpolation/translate3d';
import rotate3d from '../interpolation/rotate3d';
import translate from '../interpolation/translate';
import rotate from '../interpolation/rotate';
import scale from '../interpolation/scale';
import skew from '../interpolation/skew';
import supportTransform from '../util/supportLegacyTransform';
import transformProperty from '../util/transformProperty';
// same as svgTransform, htmlAttributes
// the component that handles all browsers IE9+
// Component Functions
/**
* Sets the property update function.
* @param {string} tweenProp the property name
*/
export function onStartLegacyTransform(tweenProp) {
if (!KEC[tweenProp] && this.valuesEnd[tweenProp]) {
if (support3DTransform) {
KEC[tweenProp] = (elem, a, b, v) => {
// eslint-disable-next-line no-param-reassign
elem.style[transformProperty] = (a.perspective || b.perspective ? perspective(a.perspective, b.perspective, 'px', v) : '') // one side might be 0
+ (a.translate3d ? translate3d(a.translate3d, b.translate3d, 'px', v) : '') // array [x,y,z]
+ (a.rotate3d ? rotate3d(a.rotate3d, b.rotate3d, 'deg', v) : '') // array [x,y,z]
+ (a.skew ? skew(a.skew, b.skew, 'deg', v) : '') // array [x,y]
+ (a.scale || b.scale ? scale(a.scale, b.scale, v) : ''); // one side might be 0
};
} else if (supportTransform) {
KEC[tweenProp] = (elem, a, b, v) => {
// eslint-disable-next-line no-param-reassign
elem.style[transformProperty] = (a.translate ? translate(a.translate, b.translate, 'px', v) : '') // array [x,y]
+ ((a.rotate || b.rotate) ? rotate(a.rotate, b.rotate, 'deg', v) : '') // one side might be 0
+ (a.skew ? skew(a.skew, b.skew, 'deg', v) : '') // array [x,y]
+ (a.scale || b.scale ? scale(a.scale, b.scale, v) : ''); // one side might be 0
};
}
}
}
// Base Component
const BaseLegacyTransform = {
component: 'baseLegacyTransform',
property: 'transform',
functions: { onStart: onStartLegacyTransform },
Interpolate: {
perspective,
translate3d,
rotate3d,
translate,
rotate,
scale,
skew,
},
Util: { transformProperty },
};
export default BaseLegacyTransform;

View file

@ -1,117 +1,165 @@
import defaultValues from '../objects/defaultValues.js'
import Components from '../objects/components.js'
import numbers from '../interpolation/numbers.js'
import arrays from '../interpolation/arrays.js'
import {onStartTransform} from './transformMatrixBase.js'
// const transformMatrix = { property : 'transform', defaultValue: {}, interpolators: {} }, functions = { prepareStart, prepareProperty, onStart, crossCheck }
// Component name
const matrixComponent = 'transformMatrix'
// Component Functions
function getTransform(tweenProp, value){
let transformObject = {}
if (this.element[matrixComponent]) {
const currentValue = this.element[matrixComponent]
for (const vS in currentValue) {
transformObject[vS] = currentValue[vS]
}
} else {
for (const vE in value){
transformObject[vE] = vE === 'perspective' ? value[vE] : defaultValues.transform[vE]
}
}
return transformObject
}
function prepareTransform(tweenProp,value){
if ( typeof(value) === 'object' && !value.length) {
let transformObject = {},
translate3dObj = {},
rotate3dObj = {},
scale3dObj = {},
skewObj = {},
axis = [{translate3d:translate3dObj},{rotate3d:rotate3dObj},{skew:skewObj},{scale3d:scale3dObj}];
for (const prop in value) {
if ( /3d/.test(prop) && typeof(value[prop]) === 'object' && value[prop].length ){
let pv = value[prop].map( (v) => prop === 'scale3d' ? parseFloat(v) : parseInt(v) )
transformObject[prop] = prop === 'scale3d' ? [pv[0]||1, pv[1]||1, pv[2]||1] : [pv[0]||0, pv[1]||0, pv[2]||0]
} else if ( /[XYZ]/.test(prop) ) {
let obj = /translate/.test(prop) ? translate3dObj
: /rotate/.test(prop) ? rotate3dObj
: /scale/.test(prop) ? scale3dObj
: /skew/.test(prop) ? skewObj : {};
let idx = prop.replace(/translate|rotate|scale|skew/,'').toLowerCase()
obj[idx] = /scale/.test(prop) ? parseFloat(value[prop]) : parseInt(value[prop])
} else if ('skew' === prop ) {
let pv = value[prop].map(v => parseInt(v)||0)
transformObject[prop] = [pv[0]||0, pv[1]||0]
} else { // perspective
transformObject[prop] = parseInt(value[prop]);
}
}
axis.map((o) => {
const tp = Object.keys(o)[0]
const tv = o[tp]
if ( Object.keys(tv).length && !transformObject[tp]) {
transformObject[tp] = tp === 'scale3d' ? [tv.x || 1, tv.y || 1, tv.z || 1]
: tp === 'skew' ? [tv.x || 0, tv.y || 0]
: [tv.x || 0, tv.y || 0, tv.z || 0]; // translate|rotate
}
})
return transformObject;
} else { // string | array
// if ( typeof (value) === 'object' && value.length ) {
// } else if ( typeof (value) === string && value.includes('matrix')) {
// decompose matrix to object
console.error(`KUTE.js - "${value}" is not valid/supported transform function`)
}
}
function onCompleteTransform(tweenProp){
if (this.valuesEnd[tweenProp]) {
this.element[matrixComponent] = {}
for (const tf in this.valuesEnd[tweenProp]){
this.element[matrixComponent][tf] = this.valuesEnd[tweenProp][tf]
}
}
}
function crossCheckTransform(tweenProp){
if (this.valuesEnd[tweenProp]) {
if (this.valuesEnd[tweenProp].perspective && !this.valuesStart[tweenProp].perspective){
this.valuesStart[tweenProp].perspective = this.valuesEnd[tweenProp].perspective
}
}
}
// All Component Functions
const matrixFunctions = {
prepareStart: getTransform,
prepareProperty: prepareTransform,
onStart: onStartTransform,
onComplete: onCompleteTransform,
crossCheck: crossCheckTransform
}
// Component Full Object
const matrixTransform = {
component: matrixComponent,
property: 'transform',
// subProperties: ['perspective','translate3d','translateX','translateY','translateZ','rotate3d','rotateX','rotateY','rotateZ','skew','skewX','skewY','scale3d','scaleX','scaleY','scaleZ'],
defaultValue: {perspective:400,translate3d:[0,0,0],translateX:0,translateY:0,translateZ:0,rotate3d:[0,0,0],rotateX:0,rotateY:0,rotateZ:0,skew:[0,0],skewX:0,skewY:0,scale3d:[1,1,1],scaleX:1,scaleY:1,scaleZ:1},
functions: matrixFunctions,
Interpolate: {
perspective: numbers,
translate3d: arrays,
rotate3d: arrays,
skew: arrays,
scale3d: arrays
}
}
export default matrixTransform
Components.TransformMatrix = matrixTransform
import defaultValues from '../objects/defaultValues';
import numbers from '../interpolation/numbers';
import arrays from '../interpolation/arrays';
import { onStartTransform } from './transformMatrixBase';
// Component name
const matrixComponent = 'transformMatrix';
// Component Functions
/**
* Returns the current transform object.
* @param {string} _ the property name
* @param {string} value the property value
* @returns {KUTE.transformMObject} transform object
*/
function getTransform(/* tweenProp, */_, value) {
const transformObject = {};
const currentValue = this.element[matrixComponent];
if (currentValue) {
Object.keys(currentValue).forEach((vS) => {
transformObject[vS] = currentValue[vS];
});
} else {
Object.keys(value).forEach((vE) => {
transformObject[vE] = vE === 'perspective' ? value[vE] : defaultValues.transform[vE];
});
}
return transformObject;
}
/**
* Returns the property tween object.
* @param {string} _ the property name
* @param {Object<string, string | number | (string | number)[]>} obj the property value
* @returns {KUTE.transformMObject} the property tween object
*/
function prepareTransform(/* tweenProp, */_, value) {
if (typeof (value) === 'object' && !value.length) {
let pv;
const transformObject = {};
const translate3dObj = {};
const rotate3dObj = {};
const scale3dObj = {};
const skewObj = {};
const axis = [{ translate3d: translate3dObj },
{ rotate3d: rotate3dObj },
{ skew: skewObj },
{ scale3d: scale3dObj }];
Object.keys(value).forEach((prop) => {
if (/3d/.test(prop) && typeof (value[prop]) === 'object' && value[prop].length) {
pv = value[prop].map((v) => (prop === 'scale3d' ? parseFloat(v) : parseInt(v, 10)));
transformObject[prop] = prop === 'scale3d' ? [pv[0] || 1, pv[1] || 1, pv[2] || 1] : [pv[0] || 0, pv[1] || 0, pv[2] || 0];
} else if (/[XYZ]/.test(prop)) {
let obj = {};
if (/translate/.test(prop)) {
obj = translate3dObj;
} else if (/rotate/.test(prop)) {
obj = rotate3dObj;
} else if (/scale/.test(prop)) {
obj = scale3dObj;
} else if (/skew/.test(prop)) {
obj = skewObj;
}
const idx = prop.replace(/translate|rotate|scale|skew/, '').toLowerCase();
obj[idx] = /scale/.test(prop) ? parseFloat(value[prop]) : parseInt(value[prop], 10);
} else if (prop === 'skew') {
pv = value[prop].map((v) => parseInt(v, 10) || 0);
transformObject[prop] = [pv[0] || 0, pv[1] || 0];
} else { // perspective
transformObject[prop] = parseInt(value[prop], 10);
}
});
axis.forEach((o) => {
const tp = Object.keys(o)[0];
const tv = o[tp];
if (Object.keys(tv).length && !transformObject[tp]) {
if (tp === 'scale3d') {
transformObject[tp] = [tv.x || 1, tv.y || 1, tv.z || 1];
} else if (tp === 'skew') {
transformObject[tp] = [tv.x || 0, tv.y || 0];
} else { // translate | rotate
transformObject[tp] = [tv.x || 0, tv.y || 0, tv.z || 0];
}
}
});
return transformObject;
} // string | array
// if ( typeof (value) === 'object' && value.length ) {
// } else if ( typeof (value) === string && value.includes('matrix')) {
// decompose matrix to object
throw Error(`KUTE.js - "${value}" is not valid/supported transform function`);
}
/**
* Sets the end values for the next `to()` method call.
* @param {string} tweenProp the property name
*/
function onCompleteTransform(tweenProp) {
if (this.valuesEnd[tweenProp]) {
this.element[matrixComponent] = { ...this.valuesEnd[tweenProp] };
}
}
/**
* Prepare tween object in advance for `to()` method.
* @param {string} tweenProp the property name
*/
function crossCheckTransform(tweenProp) {
if (this.valuesEnd[tweenProp]) {
if (this.valuesEnd[tweenProp].perspective && !this.valuesStart[tweenProp].perspective) {
this.valuesStart[tweenProp].perspective = this.valuesEnd[tweenProp].perspective;
}
}
}
// All Component Functions
const matrixFunctions = {
prepareStart: getTransform,
prepareProperty: prepareTransform,
onStart: onStartTransform,
onComplete: onCompleteTransform,
crossCheck: crossCheckTransform,
};
// Component Full Object
const matrixTransform = {
component: matrixComponent,
property: 'transform',
/* subProperties: [
'perspective', 'translate3d', 'translateX', 'translateY', 'translateZ',
'rotate3d', 'rotateX', 'rotateY', 'rotateZ',
'skew','skewX','skewY',
'scale3d', 'scaleX', 'scaleY', 'scaleZ'], */
defaultValue: {
perspective: 400,
translate3d: [0, 0, 0],
translateX: 0,
translateY: 0,
translateZ: 0,
rotate3d: [0, 0, 0],
rotateX: 0,
rotateY: 0,
rotateZ: 0,
skew: [0, 0],
skewX: 0,
skewY: 0,
scale3d: [1, 1, 1],
scaleX: 1,
scaleY: 1,
scaleZ: 1,
},
functions: matrixFunctions,
Interpolate: {
perspective: numbers,
translate3d: arrays,
rotate3d: arrays,
skew: arrays,
scale3d: arrays,
},
};
export default matrixTransform;

View file

@ -1,62 +1,85 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
import arrays from '../interpolation/arrays.js'
// const transformMatrix = { property : 'transform', defaultValue: {}, interpolators: {} }, functions = { prepareStart, prepareProperty, onStart, crossCheck }
// Component name
const matrixComponent = 'transformMatrixBase'
// Component special
const CSS3Matrix = typeof(DOMMatrix) !== 'undefined' ? DOMMatrix
: typeof(WebKitCSSMatrix) !== 'undefined' ? WebKitCSSMatrix
: typeof(CSSMatrix) !== 'undefined' ? CSSMatrix
: typeof(MSCSSMatrix) !== 'undefined' ? MSCSSMatrix
: null
// Component Functions
export const onStartTransform = {
transform : function(tweenProp) {
if (this.valuesEnd[tweenProp] && !KUTE[tweenProp]) {
KUTE[tweenProp] = (elem, a, b, v) => {
let matrix = new CSS3Matrix(), transformObject = {}
for ( const p in b ) {
transformObject[p] = p === 'perspective' ? numbers(a[p],b[p],v) : arrays(a[p],b[p],v)
}
transformObject.perspective && (matrix.m34 = -1/transformObject.perspective)// set perspective
matrix = transformObject.translate3d ? (matrix.translate(transformObject.translate3d[0],transformObject.translate3d[1],transformObject.translate3d[2])) : matrix // set translate
matrix = transformObject.rotate3d ? (matrix.rotate(transformObject.rotate3d[0],transformObject.rotate3d[1],transformObject.rotate3d[2])) : matrix // set rotation
if (transformObject.skew) { // set skew
matrix = transformObject.skew[0] ? matrix.skewX(transformObject.skew[0]) : matrix;
matrix = transformObject.skew[1] ? matrix.skewY(transformObject.skew[1]) : matrix;
}
matrix = transformObject.scale3d ? (matrix.scale(transformObject.scale3d[0],transformObject.scale3d[1],transformObject.scale3d[2])): matrix // set scale
elem.style[tweenProp] = matrix.toString() // set element style
}
}
},
CSS3Matrix: function(prop) {
if (this.valuesEnd.transform){
!KUTE[prop] && (KUTE[prop] = CSS3Matrix)
}
},
}
// Component Base Object
export const baseMatrixTransform = {
component: matrixComponent,
property: 'transform',
functions: {onStart: onStartTransform},
Interpolate: {
perspective: numbers,
translate3d: arrays,
rotate3d: arrays,
skew: arrays,
scale3d: arrays
}
}
export default baseMatrixTransform
import KEC from '../objects/kute';
import numbers from '../interpolation/numbers';
import arrays from '../interpolation/arrays';
// Component name
const matrixComponent = 'transformMatrixBase';
// Component special
// this component is restricted to modern browsers only
const CSS3Matrix = typeof (DOMMatrix) !== 'undefined' ? DOMMatrix : null;
// Component Functions
export const onStartTransform = {
/**
* Sets the property update function.
* @param {string} tweenProp the property name
*/
transform(tweenProp) {
if (CSS3Matrix && this.valuesEnd[tweenProp] && !KEC[tweenProp]) {
KEC[tweenProp] = (elem, a, b, v) => {
let matrix = new CSS3Matrix();
const tObject = {};
Object.keys(b).forEach((p) => {
tObject[p] = p === 'perspective' ? numbers(a[p], b[p], v) : arrays(a[p], b[p], v);
});
// set perspective
if (tObject.perspective) matrix.m34 = -1 / tObject.perspective;
// set translate
matrix = tObject.translate3d
? matrix.translate(tObject.translate3d[0], tObject.translate3d[1], tObject.translate3d[2])
: matrix;
// set rotation
matrix = tObject.rotate3d
? matrix.rotate(tObject.rotate3d[0], tObject.rotate3d[1], tObject.rotate3d[2])
: matrix;
// set skew
if (tObject.skew) {
matrix = tObject.skew[0] ? matrix.skewX(tObject.skew[0]) : matrix;
matrix = tObject.skew[1] ? matrix.skewY(tObject.skew[1]) : matrix;
}
// set scale
matrix = tObject.scale3d
? matrix.scale(tObject.scale3d[0], tObject.scale3d[1], tObject.scale3d[2])
: matrix;
// set element style
// eslint-disable-next-line no-param-reassign
elem.style[tweenProp] = matrix.toString();
};
}
},
/**
* onStartTransform.CSS3Matrix
*
* Sets the update function for the property.
* @param {string} prop the property name
*/
CSS3Matrix(prop) {
if (CSS3Matrix && this.valuesEnd.transform) {
if (!KEC[prop]) KEC[prop] = CSS3Matrix;
}
},
};
// Component Base Object
export const TransformMatrixBase = {
component: matrixComponent,
property: 'transform',
functions: { onStart: onStartTransform },
Interpolate: {
perspective: numbers,
translate3d: arrays,
rotate3d: arrays,
skew: arrays,
scale3d: arrays,
},
};
export default TransformMatrixBase;

View file

@ -1,2 +1,10 @@
import Tweens from '../objects/tweens.js'
export default (tw) => Tweens.push(tw)
import Tweens from '../objects/tweens';
/**
* KUTE.add(Tween)
*
* @param {KUTE.Tween} tw a new tween to add
*/
const add = (tw) => Tweens.push(tw);
export default add;

View file

@ -1,2 +1,10 @@
import Tweens from '../objects/tweens.js'
export default () => Tweens
import Tweens from '../objects/tweens';
/**
* KUTE.add(Tween)
*
* @return {KUTE.Tween[]} tw a new tween to add
*/
const getAll = () => Tweens;
export default getAll;

View file

@ -1,15 +1,17 @@
import add from './add.js'
import remove from './remove.js'
import getAll from './getAll.js'
import removeAll from './removeAll.js'
import {stop} from './render.js'
import linkInterpolation from './linkInterpolation.js'
export default {
add,
remove,
getAll,
removeAll,
stop,
linkInterpolation
}
import add from './add';
import remove from './remove';
import getAll from './getAll';
import removeAll from './removeAll';
import { stop } from './render';
import linkInterpolation from './linkInterpolation';
const internals = {
add,
remove,
getAll,
removeAll,
stop,
linkInterpolation,
};
export default internals;

Some files were not shown because too many files have changed in this diff Show more