display pics and sections content

This commit is contained in:
Tykayn 2023-04-21 23:27:42 +02:00 committed by tykayn
parent 99d614d83f
commit 0303512b97
112 changed files with 23581 additions and 333 deletions

262
css/boilerplate.css Normal file
View File

@ -0,0 +1,262 @@
/*! HTML5 Boilerplate v8.0.0 | MIT License | https://html5boilerplate.com/ */
/* main.css 2.1.0 | MIT License | https://github.com/h5bp/main.css#readme */
/*
* What follows is the result of much research on cross-browser styling.
* Credit left inline and big thanks to Nicolas Gallagher, Jonathan Neal,
* Kroc Camen, and the H5BP dev community and team.
*/
/* ==========================================================================
Base styles: opinionated defaults
========================================================================== */
html {
font-size: 1em;
line-height: 1.4;
font-family: 'GT Walsheim Pro';
/* or 90% */
text-align: center;
letter-spacing: -0.04em;
/* Secondary 100 */
color: #F9F3F1;
background: #020225;
}
::-moz-selection {
background: #2323ff;
text-shadow: none;
}
::selection {
background: #2323ff;
text-shadow: none;
}
/*
* A better looking default horizontal rule
*/
hr {
display: block;
height: 1px;
border: 0;
border-top: 1px solid #ccc;
margin: 1em 0;
padding: 0;
}
/*
* Remove the gap between audio, canvas, iframes,
* images, videos and the bottom of their containers:
* https://github.com/h5bp/html5-boilerplate/issues/440
*/
audio,
canvas,
iframe,
img,
svg,
video {
vertical-align: middle;
}
/*
* Remove default fieldset styles.
*/
fieldset {
border: 0;
margin: 0;
padding: 0;
}
/*
* Allow only vertical resizing of textareas.
*/
textarea {
resize: vertical;
}
/* ==========================================================================
Author's custom styles
========================================================================== */
/* ==========================================================================
Helper classes
========================================================================== */
/*
* Hide visually and from screen readers
*/
.hidden,
[hidden] {
display: none !important;
}
/*
* Hide only visually, but have it available for screen readers:
* https://snook.ca/archives/html_and_css/hiding-content-for-accessibility
*
* 1. For long content, line feeds are not interpreted as spaces and small width
* causes content to wrap 1 word per line:
* https://medium.com/@jessebeach/beware-smushed-off-screen-accessible-text-5952a4c2cbfe
*/
.sr-only {
border: 0;
clip: rect(0, 0, 0, 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
white-space: nowrap;
width: 1px;
/* 1 */
}
/*
* Extends the .sr-only class to allow the element
* to be focusable when navigated to via the keyboard:
* https://www.drupal.org/node/897638
*/
.sr-only.focusable:active,
.sr-only.focusable:focus {
clip: auto;
height: auto;
margin: 0;
overflow: visible;
position: static;
white-space: inherit;
width: auto;
}
/*
* Hide visually and from screen readers, but maintain layout
*/
.invisible {
visibility: hidden;
}
/*
* Clearfix: contain floats
*
* For modern browsers
* 1. The space content is one way to avoid an Opera bug when the
* `contenteditable` attribute is included anywhere else in the document.
* Otherwise it causes space to appear at the top and bottom of elements
* that receive the `clearfix` class.
* 2. The use of `table` rather than `block` is only necessary if using
* `:before` to contain the top-margins of child elements.
*/
.clearfix::before,
.clearfix::after {
content: " ";
display: table;
}
.clearfix::after {
clear: both;
}
/* ==========================================================================
EXAMPLE Media Queries for Responsive Design.
These examples override the primary ('mobile first') styles.
Modify as content requires.
========================================================================== */
@media only screen and (min-width: 35em) {
/* Style adjustments for viewports that meet the condition */
}
@media print,
(-webkit-min-device-pixel-ratio: 1.25),
(min-resolution: 1.25dppx),
(min-resolution: 120dpi) {
/* Style adjustments for high resolution devices */
}
/* ==========================================================================
Print styles.
Inlined to avoid the additional HTTP request:
https://www.phpied.com/delay-loading-your-print-css/
========================================================================== */
@media print {
*,
*::before,
*::after {
background: #fff !important;
color: #000 !important;
/* Black prints faster */
box-shadow: none !important;
text-shadow: none !important;
}
a,
a:visited {
text-decoration: underline;
}
a[href]::after {
content: " (" attr(href) ")";
}
abbr[title]::after {
content: " (" attr(title) ")";
}
/*
* Don't show links that are fragment identifiers,
* or use the `javascript:` pseudo protocol
*/
a[href^="#"]::after,
a[href^="javascript:"]::after {
content: "";
}
pre {
white-space: pre-wrap !important;
}
pre,
blockquote {
border: 1px solid #999;
page-break-inside: avoid;
}
/*
* Printing Tables:
* https://web.archive.org/web/20180815150934/http://css-discuss.incutio.com/wiki/Printing_Tables
*/
thead {
display: table-header-group;
}
tr,
img {
page-break-inside: avoid;
}
p,
h2,
h3 {
orphans: 3;
widows: 3;
}
h2,
h3 {
page-break-after: avoid;
}
}

View File

@ -1,287 +1,81 @@
/*! HTML5 Boilerplate v8.0.0 | MIT License | https://html5boilerplate.com/ */
/* main.css 2.1.0 | MIT License | https://github.com/h5bp/main.css#readme */
/*
* What follows is the result of much research on cross-browser styling.
* Credit left inline and big thanks to Nicolas Gallagher, Jonathan Neal,
* Kroc Camen, and the H5BP dev community and team.
*/
/* ==========================================================================
Base styles: opinionated defaults
========================================================================== */
html {
font-size: 1em;
line-height: 1.4;
font-family: 'GT Walsheim Pro';
/* or 90% */
text-align: center;
letter-spacing: -0.04em;
/* Secondary 100 */
color: #F9F3F1;
background: #020225;
}
::-moz-selection {
background: #2323ff;
text-shadow: none;
}
::selection {
background: #2323ff;
text-shadow: none;
}
/*
* A better looking default horizontal rule
*/
hr {
display: block;
height: 1px;
border: 0;
border-top: 1px solid #ccc;
margin: 1em 0;
padding: 0;
}
/*
* Remove the gap between audio, canvas, iframes,
* images, videos and the bottom of their containers:
* https://github.com/h5bp/html5-boilerplate/issues/440
*/
audio,
canvas,
iframe,
img,
svg,
video {
vertical-align: middle;
}
/*
* Remove default fieldset styles.
*/
fieldset {
border: 0;
margin: 0;
padding: 0;
}
/*
* Allow only vertical resizing of textareas.
*/
textarea {
resize: vertical;
}
/* ==========================================================================
Author's custom styles
========================================================================== */
/* ==========================================================================
Helper classes
========================================================================== */
/*
* Hide visually and from screen readers
*/
.hidden,
[hidden] {
display: none !important;
}
/*
* Hide only visually, but have it available for screen readers:
* https://snook.ca/archives/html_and_css/hiding-content-for-accessibility
*
* 1. For long content, line feeds are not interpreted as spaces and small width
* causes content to wrap 1 word per line:
* https://medium.com/@jessebeach/beware-smushed-off-screen-accessible-text-5952a4c2cbfe
*/
.sr-only {
border: 0;
clip: rect(0, 0, 0, 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
white-space: nowrap;
width: 1px;
/* 1 */
}
/*
* Extends the .sr-only class to allow the element
* to be focusable when navigated to via the keyboard:
* https://www.drupal.org/node/897638
*/
.sr-only.focusable:active,
.sr-only.focusable:focus {
clip: auto;
height: auto;
margin: 0;
overflow: visible;
position: static;
white-space: inherit;
width: auto;
}
/*
* Hide visually and from screen readers, but maintain layout
*/
.invisible {
visibility: hidden;
}
/*
* Clearfix: contain floats
*
* For modern browsers
* 1. The space content is one way to avoid an Opera bug when the
* `contenteditable` attribute is included anywhere else in the document.
* Otherwise it causes space to appear at the top and bottom of elements
* that receive the `clearfix` class.
* 2. The use of `table` rather than `block` is only necessary if using
* `:before` to contain the top-margins of child elements.
*/
.clearfix::before,
.clearfix::after {
content: " ";
display: table;
}
.clearfix::after {
clear: both;
}
/* ==========================================================================
EXAMPLE Media Queries for Responsive Design.
These examples override the primary ('mobile first') styles.
Modify as content requires.
========================================================================== */
@media only screen and (min-width: 35em) {
/* Style adjustments for viewports that meet the condition */
}
@media print,
(-webkit-min-device-pixel-ratio: 1.25),
(min-resolution: 1.25dppx),
(min-resolution: 120dpi) {
/* Style adjustments for high resolution devices */
}
/* ==========================================================================
Print styles.
Inlined to avoid the additional HTTP request:
https://www.phpied.com/delay-loading-your-print-css/
========================================================================== */
@media print {
*,
*::before,
*::after {
background: #fff !important;
color: #000 !important;
/* Black prints faster */
box-shadow: none !important;
text-shadow: none !important;
}
a,
a:visited {
text-decoration: underline;
}
a[href]::after {
content: " (" attr(href) ")";
}
abbr[title]::after {
content: " (" attr(title) ")";
}
/*
* Don't show links that are fragment identifiers,
* or use the `javascript:` pseudo protocol
*/
a[href^="#"]::after,
a[href^="javascript:"]::after {
content: "";
}
pre {
white-space: pre-wrap !important;
}
pre,
blockquote {
border: 1px solid #999;
page-break-inside: avoid;
}
/*
* Printing Tables:
* https://web.archive.org/web/20180815150934/http://css-discuss.incutio.com/wiki/Printing_Tables
*/
thead {
display: table-header-group;
}
tr,
img {
page-break-inside: avoid;
}
p,
h2,
h3 {
orphans: 3;
widows: 3;
}
h2,
h3 {
page-break-after: avoid;
}
}
@import './boilerplate.css';
/* ==========================================================================
animations
========================================================================== */
body {
position: relative;
top: 0;
left: 0;
}
.container-text{
.margin-auto {
margin: 0 auto;
}
.container-text {
max-width: 360px;
}
.container-text-md{
.container-text-md {
max-width: 500px;
}
.container-text-lg{
.container-text-lg {
max-width: 1062px;
}
/******** all sections *********/
#content-1 h2,
#content-2 h2,
#content-3 h2,
#content-4 h2
{
margin-left: 10vw;
}
main nav {
position: fixed;
top: 0;
left: 0;
padding: 24px;
font-family: 'GT Walsheim Pro', Arial;
font-style: normal;
font-weight: 400;
font-size: 24px;
line-height: 130%;
/* or 31px */
text-align: center;
/* Secondary 100 */
color: #FFFDFC;
width: 100%;
}
.burger-menu {
width: 150px;
float: left;
}
.nav-main {
text-align: center;
top: 54px;
color: #FFFDFC;
width: 100%;
height: 54px;
}
main section {
height: 100vh;
width: 100vw;
font-family: 'GT Walsheim Pro';
font-family: 'GT Walsheim Pro', Arial;
}
main section h2{
font-family: 'GT Walsheim Pro';
main section h2 {
font-family: 'GT Walsheim Pro', Arial;
font-style: normal;
font-weight: 600;
font-size: 60px;
@ -292,45 +86,58 @@ main section h2{
/* Secondary 100 */
color: #FFFDFC;
padding-top: 33vh;
}
/******** section 1 *********/
#main_title_container {
text-align:center;
width: 100vw;
}
#main_title {
font-size: 5rem;
color: white;
box-sizing: border-box;
background: url('/img/sesame.png') no-repeat;
background-size: contain;
position: absolute;
width: 1563.51px;
height: 261.66px;
left: 54.27px;
top: 166.75px;
position: relative;
height: 35vh;
width: 95vw;
max-width: 1200px;
margin: 0 auto;
/* Transparency_200 */
background: rgba(248, 243, 241, 0.1);
backdrop-filter: blur(7.5px);
}
#cover {
background: url('/img/BG 1.png') no-repeat;
background-size: cover;
}
#cover .hand{
#hand {
background: url('/img/hand 1.png');
background-size: cover;
position: absolute;
width: 100vw;
min-height: 100vh;
left: 1px;
top: -2px;
}
#cover p {
#cover h2 {
position: absolute;
width: 360px;
height: 240px;
left: 660px;
top: 480px;
top: 10vh;
left: 42vw;
/* Subtitle/desktop_1 */
font-family: 'GT Walsheim Pro', Arial;
font-style: normal;
font-weight: 600;
font-size: 2rem;
font-size: 40px;
line-height: 120%;
/* or 48px */
@ -345,35 +152,52 @@ main section h2{
box-sizing: border-box;
position: relative;
left: 0%;
left: 0;
right: 0;
top: calc(3/4 * 100%);
top: calc(1 / 3 * 100vh);
bottom: 0;
width: 150px;
height: 150px;
padding: 1rem;
color: white;
font-family: 'GT Walsheim Pro';
font-family: 'GT Walsheim Pro', Arial;
font-style: normal;
font-weight: 400;
font-size: 18px;
line-height: 26px;
background: linear-gradient(329.49deg, rgba(255, 216, 244, 0) 34.06%, rgba(255, 207, 242, 0.2) 77.26%);
backdrop-filter: blur(2.95635px);
backdrop-filter: blur(2.96px);
/* Note: backdrop-filter has minimal browser support */
border-radius: 100%;
}
/************ section 2 ************/
#welcome .color-emphasis{
#welcome h2 {
font-weight: 600;
font-size: 100px;
line-height: 90px;
/* or 90% */
text-align: center;
letter-spacing: -0.04em;
/* Secondary 100 */
color: #F9F3F1;
}
#welcome .color-emphasis {
color: #1E33DA;
}
#welcome .phone-container{
#welcome .phone-container {
background: url('/img/section2_phone.png');
background-size: cover;
}
#content .color-emphasis{
#content .color-emphasis {
width: 1680px;
height: 35px;
@ -396,7 +220,8 @@ main section h2{
flex-grow: 0;
}
#content_all{
#content_all {
background: url('/img/bg_content.png');
background-size: cover;
}

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 B

BIN
img/sesame.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 KiB

View File

@ -26,33 +26,35 @@
<body>
<main class="has-text-centered">
<div class="fixed-nav is-fixed-top columns">
<div class="burger-menu column is-2">
<div class="icon-burger"></div>
<span>Menu</span>
<section id="cover" class="has-text-centerd">
<div id="hand"></div>
<div id="main_title_container" class="margin-auto">
<div id="main_title" class="margin-auto">
<h1 class="is-hidden">Sesame</h1>
</div>
<h2 class="container-text margin-auto">
We focus on online conversion to help brands sell better and more.
</h2>
<a href="#open" class="button">Scroll</a>
</div>
<div class="nav-main column is-10 has-text-centered">
Open Sesame
</div>
</div>
<section id="cover">
<div class="hand"></div>
<h1 id="main_title">Sesame</h1>
<h2 class="container-text">
We focus on online conversion to help brands sell better and more.
</h2>
<button class="button">Scroll</button>
</section>
<section id="welcome">
<h2 class="container-text-md">
<h2 class="margin-auto container-text-lg">
We come from
<span class="color-emphasis">
the most immersive e-commerce market
</span>
the most immersive e-commerce market
</span>
in the world.
</h2>
<img src="/img/phone_watches.png" alt="phone watches" class="phone-watches-1">
<img src="/img/phone_watches.png" alt="phone watches" class="phone-watches-2">
<img src="/img/phone_watches.png" alt="phone watches" class="phone-watches-3">
<img src="/img/phone_watches.png" alt="phone watches" class="phone-watches-4">
</section>
<section id="open">
<h2>
@ -83,7 +85,7 @@
</section>
<section id="content-2">
<section id="content-2" class="flip-from-right">
<div class="container-text">
<h2>Motion &
@ -94,22 +96,62 @@
</p>
</div>
<button>More infos</button>
<div class="phone-container"></div>
<div class="phone-container">
<img src="/img/phone_clothes.png" alt="phone">
</div>
</section>
<section id="content-3"></section>
<section id="content-4"></section>
<section id="content-5"></section>
<section id="content-3" class="flip-from-left">
<h2>Motion &
3D design</h2>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed in tortor egestas, rutrum elit at, fringilla felis.
Mauris nec erat rutrum, ultrices turpis laoreet, faucibus ante. Vestibulum.
</p>
</div>
<button>More infos</button>
<div class="phone-container">
<img src="/img/phone_glasses.png" alt="phone">
</div>
</section>
<section id="content-4" class="flip-from-right">
<h2>Motion &
3D design</h2>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed in tortor egestas, rutrum elit at, fringilla felis.
Mauris nec erat rutrum, ultrices turpis laoreet, faucibus ante. Vestibulum.
</p>
</div>
<button>More infos</button>
<div class="phone-container">
<img src="/img/phone_face.png" alt="phone">
</div>
</section>
<section id="content-5" class="flip-from-left">
<h2>Motion &
3D design</h2>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed in tortor egestas, rutrum elit at, fringilla felis.
Mauris nec erat rutrum, ultrices turpis laoreet, faucibus ante. Vestibulum.
</p>
</div>
<button>More infos</button>
<div class="phone-container">
<img src="/img/phone_clothes.png" alt="phone">
</div>
</section>
<!-- other section-->
<section id="popover" class="is-hidden">
<div class="phone-container"></div>
<div id="text">
<h2>
<span id="colored">
<span id="colored">
Premium
</span>
Premium
</span>
<span>
& Campaign
</span>
& Campaign
</span>
</h2>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed in tortor egestas, rutrum elit at, fringilla felis.
@ -117,9 +159,25 @@
</p>
</div>
</section>
<nav class="fixed-nav is-fixed-top">
<div class="burger-menu is-2">
<div class="icon-burger"></div>
<span>Menu</span>
</div>
<div class="nav-main is-10 has-text-centered">
Open Sesame
</div>
</nav>
</main>
<script src="js/vendor/modernizr-3.11.2.min.js"></script>
<script src="js/vendor/ScrollMagic.min.js"></script>
<!--<script src="js/vendor/plugins/animation.gsap.min.js"></script>-->
<!--<script src="js/vendor/plugins/debug.addIndicators.min.js"></script>-->
<!--<script src="js/vendor/plugins/jquery.ScrollMagic.min.js"></script>-->
<!--<script src="js/vendor/plugins/animation.velocity.min.js"></script>-->
<script src="js/vendor/anime.min.js"></script>
<!--<script src="js/vendor/ScrollMagic.min.js"></script>-->
<script src="js/plugins.js"></script>
<script src="js/main.js"></script>

BIN
js/anime-master.zip Normal file

Binary file not shown.

View File

@ -0,0 +1,38 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

View File

@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

5
js/anime-master/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
.DS_Store
*.log
node_modules

1
js/anime-master/CNAME Normal file
View File

@ -0,0 +1 @@
animejs.com

View File

@ -0,0 +1,9 @@
The MIT License
Copyright (c) 2019 Julian Garnier
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

109
js/anime-master/README.md Normal file
View File

@ -0,0 +1,109 @@
<h1 align="center">
<a href="https://animejs.com"><img src="/documentation/assets/img/animejs-v3-header-animation.gif" width="250"/></a>
<br>
anime.js
</h1>
<h4 align="center">JavaScript animation engine | <a href="https://animejs.com" target="_blank">animejs.com</a></h4>
<p align="center">
<a href="https://www.npmjs.com/package/animejs" rel="nofollow"><img src="https://camo.githubusercontent.com/011820ee25bf1d3ddaf635d869903b98eccaeae7/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f616e696d656a732e7376673f7374796c653d666c61742d737175617265" alt="npm version" data-canonical-src="https://img.shields.io/npm/v/animejs.svg?style=flat-square" style="max-width:100%;"></a>
<a href="https://www.npmjs.com/package/animejs" rel="nofollow"><img src="https://camo.githubusercontent.com/3e9b69d51aee25fad784a3097676696096621d47/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f646d2f616e696d656a732e7376673f7374796c653d666c61742d737175617265" alt="npm downloads" data-canonical-src="https://img.shields.io/npm/dm/animejs.svg?style=flat-square" style="max-width:100%;"></a>
</p>
<blockquote align="center">
<em>Anime.js</em> (<code>/ˈæn.ə.meɪ/</code>) is a lightweight JavaScript animation library with a simple, yet powerful API.<br>
It works with CSS properties, SVG, DOM attributes and JavaScript Objects.
</blockquote>
<p align="center">
<a href="#getting-started">Getting started</a>&nbsp;|&nbsp;<a href="#documentation">Documentation</a>&nbsp;|&nbsp;<a href="#demos-and-examples">Demos and examples</a>&nbsp;|&nbsp;<a href="#browser-support">Browser support</a>
</p>
## Getting started
### Download
Via npm
```bash
$ npm install animejs --save
```
or manual [download](https://github.com/juliangarnier/anime/archive/master.zip).
### Usage
#### ES6 modules
```javascript
import anime from 'animejs/lib/anime.es.js';
```
#### CommonJS
```javascript
const anime = require('animejs');
```
#### File include
Link `anime.min.js` in your HTML :
```html
<script src="anime.min.js"></script>
```
### Hello world
```javascript
anime({
targets: 'div',
translateX: 250,
rotate: '1turn',
backgroundColor: '#FFF',
duration: 800
});
```
## [Documentation](https://animejs.com/documentation/)
* [Targets](https://animejs.com/documentation/#cssSelector)
* [Properties](https://animejs.com/documentation/#cssProperties)
* [Property parameters](https://animejs.com/documentation/#duration)
* [Animation parameters](https://animejs.com/documentation/#direction)
* [Values](https://animejs.com/documentation/#unitlessValue)
* [Keyframes](https://animejs.com/documentation/#animationKeyframes)
* [Staggering](https://animejs.com/documentation/#staggeringBasics)
* [Timeline](https://animejs.com/documentation/#timelineBasics)
* [Controls](https://animejs.com/documentation/#playPause)
* [Callbacks and promises](https://animejs.com/documentation/#update)
* [SVG Animations](https://animejs.com/documentation/#motionPath)
* [Easing functions](https://animejs.com/documentation/#linearEasing)
* [Helpers](https://animejs.com/documentation/#remove)
## [Demos and examples](http://codepen.io/collection/b392d3a52d6abf5b8d9fda4e4cab61ab/)
* [CodePen demos and examples](http://codepen.io/collection/b392d3a52d6abf5b8d9fda4e4cab61ab/)
* [juliangarnier.com](http://juliangarnier.com)
* [animejs.com](https://animejs.com)
* [Moving letters](http://tobiasahlin.com/moving-letters/) by [@tobiasahlin](https://twitter.com/tobiasahlin)
* [Gradient topography animation](https://tympanus.net/Development/GradientTopographyAnimation/) by [@crnacura](https://twitter.com/crnacura)
* [Organic shape animations](https://tympanus.net/Development/OrganicShapeAnimations/) by [@crnacura](https://twitter.com/crnacura)
* [Pieces slider](https://tympanus.net/Tutorials/PiecesSlider/) by [@lmgonzalves](https://twitter.com/lmgonzalves)
* [Staggering animations](https://codepen.io/juliangarnier/pen/4fe31bbe8579a256e828cd4d48c86182?editors=0100)
* [Easings animations](https://codepen.io/juliangarnier/pen/444ed909fd5de38e3a77cc6e95fc1884)
* [Sphere animation](https://codepen.io/juliangarnier/pen/b3bb8ca599ad0f9d00dd044e56cbdea5?editors=0010)
* [Layered animations](https://codepen.io/juliangarnier/pen/6ca836535cbea42157d1b8d56d00be84?editors=0010)
* [anime.js logo animation](https://codepen.io/juliangarnier/pen/d43e8ec355c30871cbe775193255d6f6?editors=0010)
## Browser support
| Chrome | Safari | IE / Edge | Firefox | Opera |
| --- | --- | --- | --- | --- |
| 24+ | 8+ | 11+ | 32+ | 15+ |
## <a href="https://animejs.com"><img src="/documentation/assets/img/animejs-v3-logo-animation.gif" width="150" alt="anime-js-v3-logo"/></a>
[Website](https://animejs.com/) | [Documentation](https://animejs.com/documentation/) | [Demos and examples](http://codepen.io/collection/b392d3a52d6abf5b8d9fda4e4cab61ab/) | [MIT License](LICENSE.md) | © 2019 [Julian Garnier](http://juliangarnier.com).

View File

@ -0,0 +1,30 @@
{
"name": "animejs",
"description": "JavaScript animation engine",
"main": "anime.js",
"repository": {
"type": "git",
"url": "https://github.com/juliangarnier/anime.git"
},
"keywords": [
"anime",
"animation",
"javascript",
"CSS",
"transforms",
"SVG",
"canvas"
],
"authors": [
"Julian Garnier <hello@julian.gr>"
],
"license": "MIT",
"homepage": "https://animejs.com/",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
]
}

69
js/anime-master/build.js Normal file
View File

@ -0,0 +1,69 @@
const fs = require('fs');
const { rollup } = require('rollup');
const { minify } = require('uglify-js');
const pretty = require('pretty-bytes');
const sizer = require('gzip-size');
const pkg = require('./package');
const umd = pkg['umd:main'];
const date = new Date();
const banner = `/*
* anime.js v${ pkg.version }
* (c) ${ date.getFullYear() } Julian Garnier
* Released under the MIT license
* animejs.com
*/
`;
console.info('Compiling... 😤');
rollup({
input: 'src/index.js',
plugins: [
require('rollup-plugin-buble')({
transforms: {
modules: false,
dangerousForOf: true
},
targets: {
firefox: 32,
chrome: 24,
safari: 6,
opera: 15,
edge: 10,
ie: 10
}
})
]
}).then(bun => {
bun.write({
banner,
format: 'cjs',
file: pkg.main
});
bun.write({
banner,
format: 'es',
file: pkg.module
});
bun.write({
banner,
file: umd,
format: 'umd',
name: pkg['umd:name']
}).then(_ => {
const data = fs.readFileSync(umd, 'utf8');
// produce minified output
const { code } = minify(data);
fs.writeFileSync(umd, `${banner}\n${code}`); // with banner
// output gzip size
const int = sizer.sync(code);
console.info('Compilation was a success! 👍');
console.info(`~> gzip size: ${ pretty(int) }`);
}).catch(console.error);
}).catch(console.error);

View File

@ -0,0 +1,73 @@
.hljs {
display: block;
color: #F6F4F2;
}
.hljs-comment,
.hljs-quote {
color: #A2A09F;
font-style: italic;
}
.hljs-doctag,
.hljs-keyword,
.hljs-formula {
color: #B08CFF;
}
.hljs-section,
.hljs-name,
.hljs-selector-tag,
.hljs-deletion,
.hljs-subst {
color: #FF7C72;
}
.hljs-literal {
color: #1CE2B2;
}
.hljs-string,
.hljs-regexp,
.hljs-addition,
.hljs-attribute,
.hljs-attr,
.hljs-meta-string {
color: #A6FF8F;
}
.hljs-built_in,
.hljs-class .hljs-title {
color: #FBF38C;
}
.hljs-variable,
.hljs-template-variable,
.hljs-type,
.hljs-selector-class,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-number {
color: #FF7C72;
}
.hljs-symbol,
.hljs-bullet,
.hljs-link,
.hljs-meta,
.hljs-selector-id,
.hljs-title {
color: #61C3FF;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}
.hljs-link {
text-decoration: underline;
}

View File

@ -0,0 +1,121 @@
@font-face {
font-family: "Roobert";
font-weight: 400;
font-style: normal;
src: url("../fonts/Roobert-Regular.woff2") format("woff2");
}
@font-face {
font-family: "Roobert";
font-weight: 400;
font-style: italic;
src: url("../fonts/Roobert-Regular.woff2") format("woff2");
}
@font-face {
font-family: "Roobert";
font-weight: 600;
font-style: normal;
src: url("../fonts/Roobert-SemiBold.woff2") format("woff2");
}
@font-face {
font-family: "Roobert";
font-weight: 600;
font-style: italic;
src: url("../fonts/Roobert-SemiBoldItalic.woff2") format("woff2");
}
@font-face {
font-family: "InputMono";
src: url("../fonts/InputMono-Regular.woff2") format("woff2"),
url("../fonts/InputMono-Regular.woff") format("woff");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "InputMono";
src: url("../fonts/InputMono-Bold.woff2") format("woff2"),
url("../fonts/InputMono-Bold.woff") format("woff");
font-weight: bold;
font-style: normal;
}
@font-face {
font-family: "InputMono";
src: url("../fonts/InputMono-BoldItalic.woff2") format("woff2"),
url("../fonts/InputMono-BoldItalic.woff") format("woff");
font-weight: bold;
font-style: italic;
}
@font-face {
font-family: "InputMono";
src: url("../fonts/InputMono-Italic.woff2") format("woff2"),
url("../fonts/InputMono-Italic.woff") format("woff");
font-weight: normal;
font-style: italic;
}
*, *:before, *:after {
box-sizing: border-box;
margin: 0;
padding: 0;
border: 0;
font: inherit;
vertical-align: baseline;
}
html,
body {
background-color: #252423;
color: #F6F4F2;
}
body {
font-family: Roobert, Helvetica Neue, Helvetica, Arial, sans-serif;
font-weight: 400;
font-feature-settings:"tnum" 1, "ss03" 1;
-webkit-font-smoothing: antialiased;
}
h1, h2 {
font-weight: 600;
}
input {
font-family: Roobert, Helvetica Neue, Helvetica, Arial, sans-serif;
font-variant-numeric: tabular-nums;
}
sup {
vertical-align: super;
font-size: .625em;
}
strong {
font-weight: 600;
}
.color-white { color: #F6F4F2; } /* White */
.color-black { color: #2E2C2C; } /* Black */
.color-red, .color-targets { color: #FF4B4B; }/* red: */
.color-orange, .color-properties { color: #FF8F42; }/* orange: */
.color-lightorange, .color-prop-params { color: #FFC730; }/* lightorange: */
.color-yellow, .color-anim-params { color: #F6FF56; }/* yellow: */
.color-citrus, .color-values { color: #A4FF4F; }/* citrus: */
.color-green, .color-keyframes { color: #18FF74; }/* green: */
.color-darkgreen, .color-staggering { color: #00D672; }/* darkgreen: */
.color-turquoise, .color-tl { color: #3CFFEC; }/* turquoise: */
.color-skyblue, .color-controls { color: #61C3FF; }/* skyblue: */
.color-kingblue, .color-callbacks { color: #5A87FF; }/* kingblue: */
.color-lavender, .color-svg { color: #8453E3; }/* lavender: */
.color-purple, .color-easings { color: #C26EFF; }/* purple: */
.color-pink, .color-helpers { color: #FB89FB; }/* pink: */
.anime-mini-logo {
width: 100px;
height: 24px;
transform: scaleY(.5);
}

View File

@ -0,0 +1,748 @@
html,
body,
header {
background-color: #252423;
}
body {
position: absolute;
width: 100%;
height: 100%;
color: white;
font-variant-numeric: tabular-nums;
-webkit-font-smoothing: antialiased;
overflow-x: hidden;
}
.content {
overflow: hidden;
opacity: 0;
display: flex;
flex-direction: row;
width: 100%;
height: 100%;
transition: opacity 1s ease;
}
.ready .content {
opacity: 1;
}
/* Headers */
.header {
position: absolute;
z-index: 1;
top: 0;
width: 100%;
}
.logo {
display: flex;
justify-content: space-between;
opacity: .8;
width: 100%;
height: 20px;
text-decoration: none;
color: currentColor;
}
.logo:visited {
color: currentColor;
}
.logo svg {
width: 100%;
height: 100%;
}
.logo:hover {
opacity: 1;
}
.version-number {
opacity: .6;
color: currentColor;
}
header {
position: sticky;
top: 0;
z-index: 2;
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
height: 60px;
padding-left: 20px;
padding-right: 20px;
border-bottom: 1px solid rgba(0,0,0,.65);
}
h2 {
font-size: 16px;
letter-spacing: 1px;
text-transform: uppercase;
font-weight: 200;
}
/* Panes */
.pane {
position: relative;
height: 100%;
}
/* Sidebar */
.sidebar {
display: flex;
flex-direction: column;
width: 240px;
padding-top: 60px;
border-right: 1px solid rgba(0,0,0,.65);
}
.sidebar-info {
display: flex;
justify-content: space-between;
padding: 20px;
}
.navigation {
overflow-y: auto;
width: 100%;
height: 100%;
padding: 10px 0 20px 20px;
}
.navigation ul {
height: 30px;
overflow-y: hidden;
-webkit-transition:opacity .4s ease;
transition: opacity .4s ease;
}
.navigation ul li {
position: relative;
}
.navigation ul li:before {
content: "";
display: block;
position: absolute;
top: 4px;
left: 2px;
width: 1px;
height: calc(100% - 8px);
background-color: white;
}
.navigation ul li:first-child:before {
display: none;
}
.navigation a {
display: block;
padding-left: 10px;
color: white;
text-decoration: none;
font-size: 14px;
line-height: 20px;
letter-spacing: .5px;
text-transform: uppercase;
}
.navigation ul li:first-child a {
padding-left: 0;
padding-top: 10px;
padding-bottom: 10px;
}
.navigation ul li a,
.navigation ul li:before {
opacity: .4;
}
.navigation ul li a {
transition: opacity .4s ease, color .4s ease;
}
.navigation ul.active a {
opacity: .7;
}
.navigation ul li:hover a,
.navigation ul li:hover:before {
transition: none;
opacity: 1;
}
.navigation ul li.active a,
.navigation ul li.active:before {
opacity: 1;
color: currentColor;
}
.navigation ul li.active:before {
background-color: currentColor;
}
.navigation ul.active li:first-child a,
.navigation ul.active li:first-child a:hover {
opacity: 1;
color: currentColor;
}
/* Info pane */
.demo-info {
flex-direction: column;
font-size: 16px;
line-height: 22px;
}
.info-output {
overflow-x: hidden;
overflow-y: auto;
position: relative;
top: 0;
width: 100%;
height: calc(100% - 60px);
padding: 20px;
}
.demo-info pre {
font-variant-ligatures: none;
-webkit-font-variant-ligatures: none;
}
.demo-info code {
font-family: "Input Mono Reg", monospace;
font-size: 14px;
line-height: 22px;
white-space: pre-wrap;
}
.demo-info p {
margin-bottom: 20px;
}
.demo-info p,
.demo-info td {
color: #F6F4F2;
}
.demo-info i {
font-style: italic;
}
.demo-info a {
text-decoration: none;
border-bottom: 1px dotted currentColor;
word-wrap: break-word;
overflow-wrap: break-word;
}
.demo-info a:hover {
border-bottom: 1px solid currentColor;
}
.demo-info a[href^="http"],
.demo-info a[href^="http"]:visited {
color: #F6F4F2;
}
.demo-info p.bubble {
display: inline-block;
position: relative;
padding: 8px 12px;
}
.demo-info p.bubble.warning {
color: #FBF38C;
}
.demo-info p.bubble.info {
color: #61C3FF;
}
.demo-info p.bubble:after {
content: "";
pointer-events: none;
color: currentColor;
display: inline-block;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: currentColor;
border-radius: 3px;
opacity: .05;
}
.demo-info code.hljs {
display: inline-block;
}
.demo-info pre {
margin-bottom: 20px;
}
.demo-info pre code {
position: relative;
display: inline-block;
width: 100%;
padding: 8px 12px;
background-color: rgba(0,0,0,.2);
border: 1px solid rgba(0,0,0,.2);
border-radius: 3px;
}
.demo-info p code {
position: relative;
padding: 0 2px;
height: 20px;
background-color: rgba(0,0,0,.2);
box-shadow: inset 0 0 1px rgba(0,0,0,.4);
border-radius: 3px;
}
.demo-info table {
margin-bottom: 20px;
border: 1px solid rgba(255,255,255,.15);
border-spacing: 0;
border-radius: 3px;
}
.demo-info td {
vertical-align: middle;
padding: 8px 12px;
border-left: 1px solid rgba(255,255,255,.15);
border-top: 1px solid rgba(255,255,255,.15);
}
.demo-info thead td {
text-transform: uppercase;
font-size: 16px;
line-height: 22px;
letter-spacing: 1px;
color: rgba(255,255,255,.4);
border-top: none;
}
.demo-info td:first-child {
border-left: none;
}
.code-preview {
width: 100%;
padding-top: 40px;
}
.code-preview h2 {
margin-bottom: 20px;
}
/* Demos */
.demos {
overflow-y: scroll;
width: calc(50% - 240px);
min-width: 330px;
}
article {
width: 100%;
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: flex-start;
justify-content: flex-start;
}
.demo {
position: relative;
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
min-height: 200px;
padding-top: 35px;
border-bottom: 1px solid rgba(0,0,0,.65);
cursor: pointer;
}
.demo-description {
display: none;
}
.demo.controls {
padding-top: 50px;
}
.demo.active.controls {
cursor: default;
}
.demo:before {
content: "";
position: absolute;
z-index: 0;
top: 0;
left: 0;
opacity: 0;
display: block;
width: 100%;
height: 100%;
background-color: currentColor;
}
.demo.active:before {
opacity: .05;
}
.demo-content {
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
width: 290px;
height: 100%;
}
.demo-content.vertical {
flex-direction: row;
}
.demo-title {
position: absolute;
top: 0;
left: 20px;
width: calc(100% - 40px);
padding: 23px 0;
font-size: 14px;
letter-spacing: 2px;
text-transform: uppercase;
color: #F6F4F2;
opacity: .9;
}
.active .demo-title {
color: currentColor;
opacity: 1;
}
.line {
width: 100%;
padding: 1px 0px;
}
.line.align-center {
display: flex;
justify-content: center;
}
.grid {
display: flex;
flex-wrap: wrap;
}
.controls {
opacity: .4;
display: flex;
align-items: center;
justify-content: center;
padding-top: 20px;
padding-bottom: 10px;
}
.controls button {
position: relative;
display: block;
margin: 0 0 0 -1px;
padding: 5px 10px;
font-size: 14px;
text-transform: uppercase;
border: 1px solid currentColor;
background-color: transparent;
color: currentColor;
}
.controls button:focus {
outline: none;
}
.active .controls {
opacity: 1;
}
.active .controls button:after {
content: '';
opacity: 0;
position: absolute;
left: 0;
top: 0;
display: block;
width: 100%;
height: 100%;
background-color: currentColor;
}
.active .controls button:hover:after {
opacity: .2;
}
.controls button.is-active:after,
.controls button.is-active:hover:after {
opacity: .4;
}
.controls button:first-child {
margin-left: 0;
}
.controls input {
margin-left: 10px;
}
.text-output {
padding-top: 10px;
padding-bottom: 10px;
font-size: 16px;
color: currentColor;
text-align: center;
background-color: transparent;
border: 1px solid currentColor;
}
.log {
width: 100%;
height: 100%;
background: transparent;
color: currentColor;
border: none;
font-size: 16px;
text-align: center;
}
.bottom.log {
padding-top: 10px;
padding-bottom: 10px;
}
.logs {
pointer-events: none;
display: flex;
flex-direction: column;
align-items: center;
position: absolute;
width: 100%;
height: auto;
}
.log:focus {
outline: none;
}
input.progress {
cursor: ew-resize;
}
input.progress[value] {
position: relative;
width: 100%;
height: 27px;
-webkit-appearance: none;
background-color: transparent;
color: currentColor;
}
input.progress[value]:focus {
outline: none;
}
input.progress[value]:after {
content: "";
position: absolute;
top: 13px;
left: 0;
width: 100%;
height: 1px;
background-color: currentColor;
}
input.progress[value]::-webkit-slider-thumb {
-webkit-appearance: none;
background-color: currentColor;
border-radius: 50%;
width: 16px;
height: 16px;
}
.square,
.circle {
pointer-events: none;
position: relative;
width: 28px;
height: 28px;
margin: 1px;
background-color: currentColor;
font-size: 14px;
}
.circle {
border-radius: 50%;
}
.square.outline,
.circle.outline {
background-color: transparent;
border: 1px solid currentColor;
}
.triangle {
pointer-events: none;
position: relative;
width: 0;
height: 0;
border-style: solid;
border-width: 0 14px 24px 14px;
border-color: transparent transparent currentColor transparent;
}
.small {
width: 18px;
height: 18px;
}
.small.triangle {
border-width: 0 10px 17px 10px;
}
.large {
width: 48px;
height: 48px;
}
.stretched {
height: 2px;
}
.shadow {
position: absolute;
opacity: .2;
}
.label {
position: absolute;
opacity: 0;
display: flex;
flex-direction: column;
justify-content: center;
text-align: left;
width: 100%;
height: auto;
padding-left: 38px;
transition: opacity .5s ease;
white-space: nowrap
}
.demo.active .label {
opacity: .2;
}
.small.label {
height: 18px;
padding-left: 28px;
}
.large.label {
height: 48px;
padding-left: 58px;
}
.motion-path {
position: relative;
width: 256px;
margin: auto;
}
.follow-path {
position: absolute;
top: -9px;
left: -9px;
}
.align-center {
align-items: center;
}
.add-states-demo .el {
border: 1px solid rgba(0,0,0,0);
}
#cssProperties .el {
transform: translate3d(0,0,0);
}
/* Responsive */
.sidebar,
.demo-info {
display: none;
}
.demos {
top: 60px;
width: 100%;
min-width: auto;
height: calc(100% - 60px);
-webkit-overflow-scrolling: touch;
}
@media (min-width: 800px) {
.header {
width: 239px;
}
.demo-info {
display: inherit;
width: calc(100% - 380px);
}
.demos {
top: 0;
width: 380px;
height: 100%;
}
.demos::-webkit-scrollbar {
width: 1px;
background-color: transparent;
}
.demos::-webkit-scrollbar-track {
background-color: rgba(0,0,0,.65);
}
.demos::-webkit-scrollbar-thumb {
background-color: rgba(255,255,255,.3);
}
.demos::-webkit-scrollbar-thumb:hover {
background-color: rgba(255,255,255,.6);
}
}
@media (min-width: 1100px) {
.sidebar {
display: inherit;
}
.demos {
width: calc(50% - 240px);
}
.demo-info {
width: 50%;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 240">
<g id="anime-mini-logo" fill="none" fill-rule="evenodd" stroke-linecap="square">
<path id="Path-18-Copy-66" stroke="#F6F4F2" stroke-width="40" d="M30 20h130c9.996 0 10 40 10 60v140H41c-11.004 0-11-40-11-60s-.004-60 10-60h110"/>
<path id="Path-18-Copy-67" stroke="#F6F4F2" stroke-width="40" d="M850 140h110c10 0 10-40 10-60s0-60-10-60H840c-10 0-10 40-10 60v80c0 20 0 60 10 60h130"/>
<path id="Path-18-Copy-68" stroke="#F6F4F2" stroke-width="40" d="M430 100v120"/>
<path id="Path-18-Copy-69" stroke="#F6F4F2" stroke-width="40" d="M430 20.2v.6"/>
<path id="Path-18-Copy-71" stroke="#F6F4F2" stroke-width="40" d="M370 220V80c0-20 0-60-10-60H240c-10 0-10 40-10 60v140"/>
<path id="Path-18-Copy-74" stroke="#F6F4F2" stroke-width="40" d="M770 220V80c0-20 0-60-10-60H500c-10 0-10 40-10 60v140"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 892 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<g id="icon-codepen" fill="none" fill-rule="evenodd">
<g id="Group-4" fill="#F6F4F2" transform="translate(8 8)">
<path id="Fill-1" d="M16 29.372C8.627 29.372 2.628 23.373 2.628 16S8.627 2.628 16 2.628 29.372 8.627 29.372 16 23.373 29.372 16 29.372M16 0C7.163 0 0 7.163 0 16s7.163 16 16 16 16-7.163 16-16S24.837 0 16 0"/>
<path id="Fill-3" d="M24.112 17.409l-2.106-1.41 2.106-1.408v2.818zm-7.27 5.972v-3.927l3.65-2.441 2.946 1.97-6.596 4.398zM16 17.99L13.022 16 16 14.008 18.978 16 16 17.992zm-.842 5.39l-6.596-4.398 2.946-1.97 3.65 2.441v3.927zm-7.27-8.79L9.994 16l-2.106 1.409V14.59zm7.27-5.972v3.927l-3.65 2.441-2.946-1.97 6.596-4.398zm1.684 0l6.596 4.397-2.946 1.971-3.65-2.441V8.619zm8.946 4.286c-.001-.012-.005-.024-.007-.036a.824.824 0 0 0-.014-.07l-.013-.041-.022-.062a.815.815 0 0 0-.047-.097l-.024-.039a.75.75 0 0 0-.107-.133l-.033-.033a.962.962 0 0 0-.048-.04l-.038-.029-.014-.01-8.954-5.97a.842.842 0 0 0-.934 0l-8.954 5.97-.014.01-.038.029a.763.763 0 0 0-.047.04c-.012.01-.023.022-.034.033a.73.73 0 0 0-.13.172.784.784 0 0 0-.03.056l-.018.041-.022.062-.013.04c-.006.023-.01.047-.015.07l-.006.037a.81.81 0 0 0-.008.11v5.97c0 .037.003.073.008.11l.006.036c.005.024.009.047.015.07l.013.041.022.062.019.04a.997.997 0 0 0 .053.096.77.77 0 0 0 .106.133l.034.032a.72.72 0 0 0 .085.07l.014.01 8.954 5.97a.842.842 0 0 0 .934 0l8.954-5.97.014-.01a.939.939 0 0 0 .086-.07l.033-.032a.807.807 0 0 0 .042-.046l.029-.036a.75.75 0 0 0 .036-.051l.024-.04a.757.757 0 0 0 .028-.055l.019-.041.022-.062c.004-.013.01-.027.013-.04a.83.83 0 0 0 .014-.071c.002-.012.006-.024.007-.036a.871.871 0 0 0 .008-.11v-5.97a.856.856 0 0 0-.008-.11z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<g id="icon-css" fill="none" fill-rule="evenodd" stroke-linecap="square">
<g id="Group" stroke="#F6F4F2" transform="translate(8 12)">
<path id="Oval-Copy-7" stroke-width="3" d="M8 0a4 4 0 0 0-4 4v4a4 4 0 0 1-4 4 4 4 0 0 1 4 4v4a4 4 0 0 0 4 4"/>
<path id="Oval-Copy-4" stroke-width="3" d="M25 0a4 4 0 0 1 4 4v4a4 4 0 0 0 4 4 4 4 0 0 0-4 4v4a4 4 0 0 1-4 4"/>
<rect id="Rectangle-41" width="6" height="6" x="9" y="5" stroke-width="1.5"/>
<circle id="Oval-18" cx="21.5" cy="16.5" r="3.5" stroke-width="1.5"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 619 B

View File

@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<g id="icon-docs" fill="none" fill-rule="evenodd" stroke-linecap="square">
<g id="Group" stroke="#F6F4F2" transform="translate(10 12)">
<path id="Oval" stroke-width="1.5" d="M13.5 0a4 4 0 0 0-4 4v4a4 4 0 0 1-4 4 4 4 0 0 1 4 4v4a4 4 0 0 0 4 4"/>
<path id="Oval-Copy" stroke-width="1.5" d="M16 0a4 4 0 0 1 4 4v4a4 4 0 0 0 4 4 4 4 0 0 0-4 4v4a4 4 0 0 1-4 4"/>
<path id="Path-10" stroke-width="3" d="M5 0a5 5 0 0 0-5 5v14a5 5 0 0 0 5 5"/>
<path id="Path-10-Copy" stroke-width="3" d="M24 0a5 5 0 0 1 5 5v14a5 5 0 0 1-5 5"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 633 B

View File

@ -0,0 +1,12 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 136">
<g id="icon-documentation" fill="none" fill-rule="evenodd">
<polygon stroke="currentColor" stroke-width="2" points="1 1 239 1 239 135 1 135"/>
<polygon stroke="currentColor" points="56 16 128 16 128 40 56 40"/>
<polygon stroke="currentColor" points="56 1 128 1 128 16 56 16"/>
<path stroke="currentColor" d="M0 16h240"/>
<polygon stroke="currentColor" points="56 40 128 40 128 64 56 64"/>
<polygon stroke="currentColor" points="56 64 128 64 128 88 56 88"/>
<polygon stroke="currentColor" points="56 88 128 88 128 112 56 112"/>
<polygon stroke="currentColor" points="56 112 128 112 128 136 56 136"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 710 B

View File

@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 136">
<g id="icon-download" fill="none" fill-rule="evenodd">
<polygon stroke="currentColor" stroke-width="2" points="1 1 239 1 239 135 1 135"/>
<polygon stroke="currentColor" points="48 32 192 32 192 40 48 40"/>
<polygon stroke="currentColor" points="48 56 192 56 192 64 48 64"/>
<path stroke="currentColor" d="M0 16h240"/>
<polygon stroke="currentColor" points="48 40 192 40 192 48 48 48"/>
<polygon stroke="currentColor" points="48 64 192 64 192 72 48 72"/>
<polygon stroke="currentColor" points="48 48 192 48 192 56 48 56"/>
<polygon stroke="currentColor" points="48 72 192 72 192 80 48 80"/>
<polygon stroke="currentColor" points="48 96 192 96 192 135 48 135"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 775 B

View File

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<g id="icon-easing-cubic" fill="none" fill-rule="evenodd">
<g id="Group-11" stroke="#F6F4F2" transform="translate(8 8)">
<polyline id="Rectangle-41-Copy" points="32 0 32 32 0 32" opacity=".4"/>
<polyline id="Shape" fill-rule="nonzero" stroke-width="3" points=".516 31.484 .826 31.484 1.135 31.484 1.445 31.484 1.755 31.484 2.065 31.484 2.374 31.484 2.684 31.484 2.994 31.484 3.303 31.484 3.613 31.484 3.923 31.432 4.232 31.432 4.542 31.432 4.852 31.381 5.161 31.381 5.471 31.329 5.781 31.277 6.09 31.226 6.4 31.174 6.71 31.071 7.019 31.019 7.329 30.916 7.639 30.813 7.948 30.658 8.258 30.503 8.568 30.348 8.877 30.142 9.187 29.935 9.497 29.729 9.806 29.471 10.116 29.213 10.426 28.903 10.735 28.542 11.045 28.181 11.355 27.768 11.665 27.303 11.974 26.839 12.284 26.323 12.594 25.755 12.903 25.135 13.213 24.465 13.523 23.794 13.832 23.019 14.142 22.194 14.452 21.316 14.761 20.387 15.071 19.406 15.381 18.323 15.69 17.187 16 16 16.31 14.813 16.619 13.677 16.929 12.594 17.239 11.613 17.548 10.684 17.858 9.806 18.168 8.981 18.477 8.206 18.787 7.535 19.097 6.865 19.406 6.245 19.716 5.677 20.026 5.161 20.335 4.697 20.645 4.232 20.955 3.819 21.265 3.458 21.574 3.097 21.884 2.787 22.194 2.529 22.503 2.271 22.813 2.065 23.123 1.858 23.432 1.652 23.742 1.497 24.052 1.342 24.361 1.187 24.671 1.084 24.981 .981 25.29 .929 25.6 .826 25.91 .774 26.219 .723 26.529 .671 26.839 .619 27.148 .619 27.458 .568 27.768 .568 28.077 .568 28.387 .516 28.697 .516 29.006 .516 29.316 .516 29.626 .516 29.935 .516 30.245 .516 30.555 .516 30.865 .516 31.174 .516 31.484 .516"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<g id="icon-easing-elastic" fill="none" fill-rule="evenodd">
<g id="Group-13" stroke="#F6F4F2" transform="translate(8 1)">
<polyline id="Rectangle-41-Copy-2" points="32 7 32 39 0 39" opacity=".4"/>
<path id="Shape-Copy-3" fill="#FFFFFF" fill-opacity="0" fill-rule="nonzero" stroke-width="3" d="M1 39C2.825 15.474 4.169 2.62 5.03.44c1.292-3.27 3.554 12.707 4.96 14.15 1.406 1.443 2.028-7.163 4.03-7.92 2.002-.756 3.392 1.64 4.65 1.64 1.258 0 2.422-.422 3.637-.422H32"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 571 B

View File

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<g id="icon-easing-spring" fill="none" fill-rule="evenodd">
<g id="Group-12" stroke="#F6F4F2" transform="translate(8 1)">
<polyline id="Rectangle-41-Copy-3" points="32 7 32 39 0 39" opacity=".4"/>
<path id="Shape-Copy-4" fill="#FFFFFF" fill-opacity="0" fill-rule="nonzero" stroke-width="3" d="M1.028 38.715C.588 13.238 1.078.5 2.5.5c2.132 0 1.963 18.468 4.186 18.468 2.222 0 1.3-16.514 2.864-16.514 1.563 0 .925 11.234 2.633 11.234 1.707 0 1.143-8.883 3.066-8.883 1.923 0 1.077 5.314 2.73 5.314 1.654 0 .955-3.791 2.599-3.791 1.644 0 1.49 1.332 3.913 1.332h7.537"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 668 B

View File

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<g id="icon-easing-steps" fill="none" fill-rule="evenodd">
<g id="Group-12-Copy" stroke="#F6F4F2" transform="translate(8 8)">
<polyline id="Rectangle-41-Copy-3" points="32 0 32 32 0 32" opacity=".4"/>
<polyline id="Rectangle" fill-rule="nonzero" stroke-width="3" points="1 32 1 27 6 27 6 22 11 22 11 17 17 17 17 11 22 11 22 6 27 6 27 1 32 1"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 446 B

View File

@ -0,0 +1,15 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 136">
<g id="icon-examples" fill="none" fill-rule="evenodd">
<polygon stroke="currentColor" stroke-width="2" points="1 1 239 1 239 135 1 135"/>
<polygon stroke="currentColor" points="0 16 80 16 80 56 0 56"/>
<polygon stroke="currentColor" points="80 16 160 16 160 56 80 56"/>
<polygon stroke="currentColor" points="160 16 240 16 240 56 160 56"/>
<polygon stroke="currentColor" points="0 56 80 56 80 96 0 96"/>
<polygon stroke="currentColor" points="80 56 160 56 160 96 80 96"/>
<polygon stroke="currentColor" points="160 56 240 56 240 96 160 96"/>
<polygon stroke="currentColor" points="0 96 80 96 80 136 0 136"/>
<polygon stroke="currentColor" points="80 96 160 96 160 136 80 136"/>
<polygon stroke="currentColor" points="160 96 240 96 240 136 160 136"/>
<path stroke="currentColor" d="M0 16h240"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 917 B

View File

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<g id="icon-github" fill="none" fill-rule="evenodd">
<path id="Fill-51" fill="#F6F4F2" d="M24.288 8C15.294 8 8 15.293 8 24.29c0 7.197 4.667 13.302 11.14 15.456.815.15 1.112-.353 1.112-.785 0-.387-.014-1.411-.022-2.77-4.531.984-5.487-2.184-5.487-2.184-.741-1.882-1.809-2.383-1.809-2.383-1.479-1.01.112-.99.112-.99 1.635.115 2.495 1.679 2.495 1.679 1.453 2.489 3.813 1.77 4.741 1.353.148-1.052.569-1.77 1.034-2.177-3.617-.411-7.42-1.809-7.42-8.051 0-1.778.635-3.233 1.677-4.371-.168-.412-.727-2.069.16-4.311 0 0 1.367-.438 4.479 1.67a15.602 15.602 0 0 1 4.078-.549 15.62 15.62 0 0 1 4.078.549c3.11-2.108 4.475-1.67 4.475-1.67.889 2.242.33 3.899.163 4.311 1.044 1.138 1.674 2.593 1.674 4.371 0 6.258-3.809 7.635-7.437 8.038.584.503 1.105 1.497 1.105 3.016 0 2.178-.02 3.935-.02 4.469 0 .436.294.943 1.12.784 6.468-2.159 11.131-8.26 11.131-15.455C40.579 15.293 33.285 8 24.288 8"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 959 B

View File

@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<g id="icon-html" fill="none" fill-rule="evenodd" stroke-linecap="square">
<g id="Group" stroke="#F6F4F2" transform="translate(8 12)">
<polyline id="Path-8" stroke-width="3" points="12 0 0 12 12 24"/>
<polyline id="Path-8-Copy" stroke-width="3" points="20 0 32 12 20 24"/>
<path id="Path-9" stroke-width="1.5" d="M20 8l-8 8"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 435 B

View File

@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<g id="icon-js" fill="none" fill-rule="evenodd" stroke-linecap="square">
<g id="Group" stroke="#F6F4F2" transform="translate(10 12)">
<path id="Oval" stroke-width="1.5" d="M12.5 0a4 4 0 0 0-4 4v4a4 4 0 0 1-4 4 4 4 0 0 1 4 4v4a4 4 0 0 0 4 4"/>
<path id="Oval-Copy" stroke-width="1.5" d="M16 0a4 4 0 0 1 4 4v4a4 4 0 0 0 4 4 4 4 0 0 0-4 4v4a4 4 0 0 1-4 4"/>
<path id="Path-10" stroke-width="3" d="M5 0a5 5 0 0 0-5 5v14a5 5 0 0 0 5 5"/>
<path id="Path-10-Copy" stroke-width="3" d="M23 0a5 5 0 0 1 5 5v14a5 5 0 0 1-5 5"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 631 B

View File

@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<g id="icon-staggering-center" fill="none" fill-rule="evenodd">
<rect id="Rectangle-40-Copy-9" width="33" height="33" x="7.5" y="7.5" stroke="#242423" opacity=".3"/>
<path id="Path-13-Copy-46" stroke="#242423" stroke-width="2" d="M24 25v-2"/>
<path id="Path-13-Copy-45" stroke="#242423" stroke-width="2" d="M20 27v-6"/>
<path id="Path-13-Copy-47" stroke="#242423" stroke-width="2" d="M28 27v-6"/>
<path id="Path-13-Copy-44" stroke="#242423" stroke-width="2" d="M16 29V19"/>
<path id="Path-13-Copy-48" stroke="#242423" stroke-width="2" d="M32 29V19"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 652 B

View File

@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<g id="icon-staggering-easing" fill="none" fill-rule="evenodd">
<rect id="Rectangle-40-Copy-10" width="33" height="33" x="7.5" y="7.5" stroke="#242423" opacity=".3"/>
<path id="Path-13-Copy-53" stroke="#242423" stroke-width="2" d="M28 33V22"/>
<path id="Path-13-Copy-52" stroke="#242423" stroke-width="2" d="M32 33V15"/>
<path id="Path-13-Copy-51" stroke="#242423" stroke-width="2" d="M24 33v-6"/>
<path id="Path-13-Copy-50" stroke="#242423" stroke-width="2" d="M16 33v-2"/>
<path id="Path-13-Copy-49" stroke="#242423" stroke-width="2" d="M20 33v-3"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 653 B

View File

@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<g id="icon-staggering-forward" fill="none" fill-rule="evenodd">
<rect id="Rectangle-40-Copy-7" width="33" height="33" x="7.5" y="7.5" stroke="#242423" opacity=".3"/>
<path id="Path-13-Copy-41" stroke="#242423" stroke-width="2" d="M32 25v-2"/>
<path id="Path-13-Copy-40" stroke="#242423" stroke-width="2" d="M28 27v-6"/>
<path id="Path-13-Copy-39" stroke="#242423" stroke-width="2" d="M24 29V19"/>
<path id="Path-13-Copy-38" stroke="#242423" stroke-width="2" d="M20 31V17"/>
<path id="Path-13-Copy-37" stroke="#242423" stroke-width="2" d="M16 33V15"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 653 B

View File

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<g id="icon-staggering-grid" fill="none" fill-rule="evenodd">
<rect id="Mask" width="33" height="33" x="7.5" y="7.5" stroke="#242423" opacity=".3"/>
<circle id="Oval" cx="24" cy="24" r="1" fill="#242423"/>
<circle id="Oval-Copy" cx="24" cy="24" r="4" stroke="#242423" stroke-width="2"/>
<circle id="Oval-Copy-2" cx="24" cy="24" r="8" stroke="#242423" stroke-width="2"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 463 B

View File

@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<g id="icon-staggering-index" fill="none" fill-rule="evenodd">
<rect id="Rectangle-40-Copy-10" width="33" height="33" x="7.5" y="7.5" stroke="#242423" opacity=".3"/>
<path id="Path-13-Copy-53" stroke="#242423" stroke-width="2" d="M20 25v-2"/>
<path id="Path-13-Copy-52" stroke="#242423" stroke-width="2" d="M16 27v-6"/>
<path id="Path-13-Copy-51" stroke="#242423" stroke-width="2" d="M24 27v-6"/>
<path id="Path-13-Copy-50" stroke="#242423" stroke-width="2" d="M32 31V17"/>
<path id="Path-13-Copy-49" stroke="#242423" stroke-width="2" d="M28 29V19"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 652 B

View File

@ -0,0 +1,11 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<g id="icon-staggering-reverse" fill="none" fill-rule="evenodd">
<rect id="Rectangle-40-Copy-8" width="33" height="33" x="7.5" y="7.5" stroke="#242423" opacity=".3"/>
<path id="Path-13-Copy-35" stroke="#242423" stroke-width="2" d="M16 25v-2"/>
<path id="Path-13-Copy-34" stroke="#242423" stroke-width="2" d="M20 27v-6"/>
<path id="Path-13-Copy-33" stroke="#242423" stroke-width="2" d="M24 29V19"/>
<path id="Path-13-Copy-32" stroke="#242423" stroke-width="2" d="M28 31V17"/>
<path id="Path-13-Copy-31" stroke="#242423" stroke-width="2" d="M32 33V15"/>
<path id="Path-13-Copy-35" stroke="#242423" stroke-width="2"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 720 B

View File

@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<g id="icon-svg" fill="none" fill-rule="evenodd" stroke-linecap="square">
<g id="Group" stroke="#F6F4F2" transform="translate(12 12)">
<polyline id="Oval-16" stroke-width="3" points="0 20 0 0 14 0"/>
<polyline id="Oval-16-Copy" stroke-width="3" points="10 24 10 4 24 4" transform="rotate(-180 17 14)"/>
<path id="Path-11" stroke-width="1.5" d="M0 24C12.072 24 12.072 0 24 0"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 485 B

View File

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<g id="icon-twitter" fill="none" fill-rule="evenodd">
<path id="Shape" fill="#F6F4F2" fill-rule="nonzero" d="M18.063 37.002c12.076 0 18.68-10.005 18.68-18.68 0-.285 0-.567-.019-.85A13.358 13.358 0 0 0 40 14.076c-1.198.53-2.47.879-3.77 1.032a6.588 6.588 0 0 0 2.886-3.63 13.157 13.157 0 0 1-4.17 1.593 6.572 6.572 0 0 0-11.188 5.988 18.64 18.64 0 0 1-13.53-6.86 6.57 6.57 0 0 0 2.032 8.764 6.516 6.516 0 0 1-2.98-.822v.084a6.568 6.568 0 0 0 5.267 6.435 6.555 6.555 0 0 1-2.964.113 6.573 6.573 0 0 0 6.133 4.56A13.174 13.174 0 0 1 8 34.051a18.587 18.587 0 0 0 10.063 2.945"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 655 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

View File

@ -0,0 +1,124 @@
import anime from '../../../src/index.js';
function animePlayer(instance, containerEl) {
function createEl(type, className, parentEl) {
var el = document.createElement(type);
if (className) el.classList.add(className);
if (parentEl) parentEl.appendChild(el);
return el;
}
function createButton(value, prentEl, action) {
var el = createEl('button', 'ap-button');
if (parentEl) parentEl.appendChild(el);
if (action) el.addEventListener('click', action);
return el;
}
var parentEl = containerEl || document.body;
var timelineEl = createEl('div', 'ap-timeline', parentEl);
var needleEl = createEl('div', 'ap-needle', timelineEl);
var animations = [];
var colors = ['#FF1461','#FF7C72','#FBF38C','#A6FF8F','#18FF92','#1CE2B2','#5EF3FB','#61C3FF','#5A87FF','#8453E3','#C26EFF','#FB89FB'];
var colorIndex = 0;
anime.setValue(timelineEl, {
overflow: 'auto',
display: 'block',
position: 'absolute',
left: 0,
bottom: 0,
width: '100%',
height: '100%',
maxHeight: '50vh',
paddingTop: 4
});
function convertMStoEM(ms) { return ms / 100; }
function convertEMtoMS(em) { return parseFloat(em) * 250; }
function createAnimationLog(animObj, timelineOffset) {
var anim = animObj;
anim.player = {};
anim.player.trackEl = createEl('div', 'ap-track', timelineEl);
anim.player.animationEl = createEl('div', 'ap-animation', anim.player.trackEl);
anim.player.delayEl = createEl('div', 'ap-delay', anim.player.animationEl);
anim.player.endDelayEl = createEl('div', 'ap-delay', anim.player.animationEl);
anime.setValue(anim.player.trackEl, {
position: 'relative',
width: '100%',
height: 4,
marginBottom: 2,
});
anime.setValue(anim.player.animationEl, {
position: 'relative',
display: 'flex',
justifyContent: 'space-between',
width: 'auto',
height: '100%',
backgroundColor: 'currentColor',
borderRadius: '.5rem'
});
anime.setValue([anim.player.delayEl, anim.player.endDelayEl], {
width: '100%',
height: '100%',
backgroundColor: 'rgba(0,0,0,.5)'
});
anim.update = function() {
anime.setValue(anim.player.animationEl, {
left: convertMStoEM(timelineOffset) + 'em',
width: convertMStoEM(anim.duration) + 'em'
});
anime.setValue(anim.player.delayEl, {width: (anim.delay / anim.duration) * 100 + '%'});
anime.setValue(anim.player.endDelayEl, {width: (anim.endDelay / anim.duration) * 100 + '%'});
}
anime.setValue(anim.player.animationEl, {color: colors[colorIndex]});
colorIndex++;
if (!colors[colorIndex]) colorIndex = 0;
anim.update();
animations.push(anim);
return anim;
}
instance.pause();
var playerAnimation = anime({
targets: needleEl,
translateX: convertMStoEM(instance.duration) + 'em',
duration: instance.duration,
direction: instance.direction,
loop: instance.loop,
easing: 'linear',
update: function(a) {
instance.seek(a.currentTime);
}
});
if (instance.children.length) {
instance.children.forEach(function(child) {
console.log(child.timelineOffset);
child.animations.forEach(function(anim) {
createAnimationLog(anim, child.timelineOffset);
});
})
} else {
instance.animations.forEach(function(anim) {
createAnimationLog(anim);
});
}
anime.setValue(needleEl, {
position: 'absolute',
zIndex: 2,
top: 0,
left: 0,
width: 2,
height: timelineEl.scrollHeight,
marginLeft: -1,
backgroundColor: '#FFF'
});
}
export default animePlayer;

View File

@ -0,0 +1,27 @@
/*
* Anime v1.0.0
* https://animejs.com
* JavaScript animation engine
* Copyright (c) 2016 Julian Garnier
* http://juliangarnier.com
* Released under the MIT license
*/
(function(r,n){"function"===typeof define&&define.amd?define([],n):"object"===typeof module&&module.exports?module.exports=n():r.anime=n()})(this,function(){var r={duration:1E3,delay:0,loop:!1,autoplay:!0,direction:"normal",easing:"easeOutElastic",elasticity:400,round:!1,begin:void 0,update:void 0,complete:void 0},n="translateX translateY translateZ rotate rotateX rotateY rotateZ scale scaleX scaleY scaleZ skewX skewY".split(" "),e=function(){return{array:function(a){return Array.isArray(a)},object:function(a){return-1<
Object.prototype.toString.call(a).indexOf("Object")},html:function(a){return a instanceof NodeList||a instanceof HTMLCollection},node:function(a){return a.nodeType},svg:function(a){return a instanceof SVGElement},number:function(a){return!isNaN(parseInt(a))},string:function(a){return"string"===typeof a},func:function(a){return"function"===typeof a},undef:function(a){return"undefined"===typeof a},"null":function(a){return"null"===typeof a},hex:function(a){return/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(a)},
rgb:function(a){return/^rgb/.test(a)},rgba:function(a){return/^rgba/.test(a)},hsl:function(a){return/^hsl/.test(a)},color:function(a){return e.hex(a)||e.rgb(a)||e.rgba(a)||e.hsl(a)}}}(),z=function(){var a={},b={Sine:function(a){return 1-Math.cos(a*Math.PI/2)},Circ:function(a){return 1-Math.sqrt(1-a*a)},Elastic:function(a,b){if(0===a||1===a)return a;var f=1-Math.min(b,998)/1E3,h=a/1-1;return-(Math.pow(2,10*h)*Math.sin(2*(h-f/(2*Math.PI)*Math.asin(1))*Math.PI/f))},Back:function(a){return a*a*(3*a-2)},
Bounce:function(a){for(var b,f=4;a<((b=Math.pow(2,--f))-1)/11;);return 1/Math.pow(4,3-f)-7.5625*Math.pow((3*b-2)/22-a,2)}};["Quad","Cubic","Quart","Quint","Expo"].forEach(function(a,d){b[a]=function(a){return Math.pow(a,d+2)}});Object.keys(b).forEach(function(c){var d=b[c];a["easeIn"+c]=d;a["easeOut"+c]=function(a,b){return 1-d(1-a,b)};a["easeInOut"+c]=function(a,b){return.5>a?d(2*a,b)/2:1-d(-2*a+2,b)/2}});a.linear=function(a){return a};return a}(),u=function(a){return e.string(a)?a:a+""},A=function(a){return a.replace(/([a-z])([A-Z])/g,
"$1-$2").toLowerCase()},B=function(a){if(e.color(a))return!1;try{return document.querySelectorAll(a)}catch(b){return!1}},v=function(a){return a.reduce(function(a,c){return a.concat(e.array(c)?v(c):c)},[])},p=function(a){if(e.array(a))return a;e.string(a)&&(a=B(a)||a);return e.html(a)?[].slice.call(a):[a]},C=function(a,b){return a.some(function(a){return a===b})},N=function(a,b){var c={};a.forEach(function(a){var f=JSON.stringify(b.map(function(b){return a[b]}));c[f]=c[f]||[];c[f].push(a)});return Object.keys(c).map(function(a){return c[a]})},
D=function(a){return a.filter(function(a,c,d){return d.indexOf(a)===c})},w=function(a){var b={},c;for(c in a)b[c]=a[c];return b},t=function(a,b){for(var c in b)a[c]=e.undef(a[c])?b[c]:a[c];return a},O=function(a){a=a.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,function(a,b,c,e){return b+b+c+c+e+e});var b=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(a);a=parseInt(b[1],16);var c=parseInt(b[2],16),b=parseInt(b[3],16);return"rgb("+a+","+c+","+b+")"},P=function(a){a=/hsl\((\d+),\s*([\d.]+)%,\s*([\d.]+)%\)/g.exec(a);
var b=parseInt(a[1])/360,c=parseInt(a[2])/100,d=parseInt(a[3])/100;a=function(a,b,c){0>c&&(c+=1);1<c&&--c;return c<1/6?a+6*(b-a)*c:.5>c?b:c<2/3?a+(b-a)*(2/3-c)*6:a};if(0==c)c=d=b=d;else var f=.5>d?d*(1+c):d+c-d*c,h=2*d-f,c=a(h,f,b+1/3),d=a(h,f,b),b=a(h,f,b-1/3);return"rgb("+255*c+","+255*d+","+255*b+")"},k=function(a){return/([\+\-]?[0-9|auto\.]+)(%|px|pt|em|rem|in|cm|mm|ex|pc|vw|vh|deg)?/.exec(a)[2]},E=function(a,b,c){return k(b)?b:-1<a.indexOf("translate")?k(c)?b+k(c):b+"px":-1<a.indexOf("rotate")||
-1<a.indexOf("skew")?b+"deg":b},F=function(a,b){if((e.node(a)||e.svg(a))&&C(n,b))return"transform";if((e.node(a)||e.svg(a))&&"transform"!==b&&x(a,b))return"css";if((e.node(a)||e.svg(a))&&(a.getAttribute(b)||e.svg(a)&&a[b]))return"attribute";if(!e["null"](a[b])&&!e.undef(a[b]))return"object"},x=function(a,b){if(b in a.style)return getComputedStyle(a).getPropertyValue(A(b))||"0"},Q=function(a,b){var c=-1<b.indexOf("scale")?1:0,d=a.style.transform;if(!d)return c;for(var f=/(\w+)\((.+?)\)/g,h=[],e=[],
q=[];h=f.exec(d);)e.push(h[1]),q.push(h[2]);d=q.filter(function(a,c){return e[c]===b});return d.length?d[0]:c},G=function(a,b){switch(F(a,b)){case "transform":return Q(a,b);case "css":return x(a,b);case "attribute":return a.getAttribute(b)}return a[b]||0},H=function(a,b,c){if(e.color(b))return b=e.rgb(b)||e.rgba(b)?b:e.hex(b)?O(b):e.hsl(b)?P(b):void 0,b;if(k(b))return b;a=k(a.to)?k(a.to):k(a.from);!a&&c&&(a=k(c));return a?b+a:b},I=function(a){var b=/-?\d*\.?\d+/g;return{original:a,numbers:u(a).match(b)?
u(a).match(b).map(Number):[0],strings:u(a).split(b)}},R=function(a,b,c){return b.reduce(function(b,f,e){f=f?f:c[e-1];return b+a[e-1]+f})},S=function(a){a=a?v(e.array(a)?a.map(p):p(a)):[];return a.map(function(a,c){return{target:a,id:c}})},T=function(a,b){var c=[],d;for(d in a)if(!r.hasOwnProperty(d)&&"targets"!==d){var f=e.object(a[d])?w(a[d]):{value:a[d]};f.name=d;c.push(t(f,b))}return c},J=function(a,b,c,d){"transform"===c?(c=a+"("+E(a,b.from,b.to)+")",b=a+"("+E(a,b.to)+")"):(a="css"===c?x(d,a):
void 0,c=H(b,b.from,a),b=H(b,b.to,a));return{from:I(c),to:I(b)}},U=function(a,b){var c=[];a.forEach(function(d,f){var h=d.target;return b.forEach(function(b){var q=F(h,b.name);if(q){var k;k=b.name;var g=b.value,g=p(e.func(g)?g(h,f):g);k={from:1<g.length?g[0]:G(h,k),to:1<g.length?g[1]:g[0]};g=w(b);g.animatables=d;g.type=q;g.from=J(b.name,k,g.type,h).from;g.to=J(b.name,k,g.type,h).to;g.round=e.color(k.from)||g.round?1:0;g.delay=(e.func(g.delay)?g.delay(h,f,a.length):g.delay)/l.speed;g.duration=(e.func(g.duration)?
g.duration(h,f,a.length):g.duration)/l.speed;c.push(g)}})});return c},V=function(a,b){var c=U(a,b);return N(c,["name","from","to","delay","duration"]).map(function(a){var b=w(a[0]);b.animatables=a.map(function(a){return a.animatables});b.totalDuration=b.delay+b.duration;return b})},y=function(a,b){a.tweens.forEach(function(c){var d=c.from,f=a.duration-(c.delay+c.duration);c.from=c.to;c.to=d;b&&(c.delay=f)});a.reversed=a.reversed?!1:!0},K=function(a){var b=[],c=[];a.tweens.forEach(function(a){if("css"===
a.type||"transform"===a.type)b.push("css"===a.type?A(a.name):"transform"),a.animatables.forEach(function(a){c.push(a.target)})});return{properties:D(b).join(", "),elements:D(c)}},W=function(a){var b=K(a);b.elements.forEach(function(a){a.style.willChange=b.properties})},X=function(a){K(a).elements.forEach(function(a){a.style.removeProperty("will-change")})},Y=function(a,b){var c=a.path,d=a.value*b,f=function(f){f=f||0;return c.getPointAtLength(1<b?a.value+f:d+f)},e=f(),k=f(-1),f=f(1);switch(a.name){case "translateX":return e.x;
case "translateY":return e.y;case "rotate":return 180*Math.atan2(f.y-k.y,f.x-k.x)/Math.PI}},Z=function(a,b){var c=Math.min(Math.max(b-a.delay,0),a.duration)/a.duration,d=a.to.numbers.map(function(b,d){var e=a.from.numbers[d],k=z[a.easing](c,a.elasticity),e=a.path?Y(a,k):e+k*(b-e);return e=a.round?Math.round(e*a.round)/a.round:e});return R(d,a.to.strings,a.from.strings)},L=function(a,b){var c=void 0;a.time=Math.min(b,a.duration);a.progress=a.time/a.duration*100;a.tweens.forEach(function(a){a.currentValue=
Z(a,b);var d=a.currentValue;a.animatables.forEach(function(b){var e=b.id;switch(a.type){case "css":b.target.style[a.name]=d;break;case "attribute":b.target.setAttribute(a.name,d);break;case "object":b.target[a.name]=d;break;case "transform":c||(c={}),c[e]||(c[e]=[]),c[e].push(d)}})});if(c)for(var d in c)a.animatables[d].target.style.transform=c[d].join(" ");a.settings.update&&a.settings.update(a)},M=function(a){var b={};b.animatables=S(a.targets);b.settings=t(a,r);b.properties=T(a,b.settings);b.tweens=
V(b.animatables,b.properties);b.duration=b.tweens.length?Math.max.apply(Math,b.tweens.map(function(a){return a.totalDuration})):a.duration/l.speed;b.time=0;b.progress=0;b.running=!1;b.ended=!1;return b},m=[],l=function(a){var b=M(a),c={tick:function(){if(b.running){b.ended=!1;c.now=+new Date;c.current=c.last+c.now-c.start;L(b,c.current);var a=b.settings;a.begin&&c.current>=a.delay&&(a.begin(b),a.begin=void 0);c.current>=b.duration?(a.loop?(c.start=+new Date,"alternate"===a.direction&&y(b,!0),e.number(a.loop)&&
a.loop--,c.raf=requestAnimationFrame(c.tick)):(b.ended=!0,a.complete&&a.complete(b),b.pause()),c.last=0):c.raf=requestAnimationFrame(c.tick)}}};b.seek=function(a){L(b,a/100*b.duration)};b.pause=function(){b.running=!1;cancelAnimationFrame(c.raf);X(b);var a=m.indexOf(b);-1<a&&m.splice(a,1)};b.play=function(a){a&&(b=t(M(t(a,b.settings)),b));b.pause();b.running=!0;c.start=+new Date;c.last=b.ended?0:b.time;a=b.settings;"reverse"===a.direction&&y(b);"alternate"!==a.direction||a.loop||(a.loop=1);W(b);m.push(b);
c.raf=requestAnimationFrame(c.tick)};b.restart=function(){b.reversed&&y(b);b.pause();b.seek(0);b.play()};b.settings.autoplay&&b.play();return b};l.speed=1;l.list=m;l.remove=function(a){a=v(e.array(a)?a.map(p):p(a));for(var b=m.length-1;0<=b;b--)for(var c=m[b],d=c.tweens.length-1;0<=d;d--)for(var f=c.tweens[d],h=f.animatables.length-1;0<=h;h--)C(a,f.animatables[h].target)&&(f.animatables.splice(h,1),f.animatables.length||c.tweens.splice(d,1),c.tweens.length||c.pause())};l.easings=z;l.getValue=G;l.path=
function(a){a=e.string(a)?B(a)[0]:a;return{path:a,value:a.getTotalLength()}};l.random=function(a,b){return Math.floor(Math.random()*(b-a+1))+a};return l});

View File

@ -0,0 +1,27 @@
/*
* Anime v1.1.3
* https://animejs.com
* JavaScript animation engine
* Copyright (c) 2016 Julian Garnier
* http://juliangarnier.com
* Released under the MIT license
*/
(function(t,q){"function"===typeof define&&define.amd?define([],q):"object"===typeof module&&module.exports?module.exports=q():t.anime=q()})(this,function(){var t={duration:1E3,delay:0,loop:!1,autoplay:!0,direction:"normal",easing:"easeOutElastic",elasticity:400,round:!1,begin:void 0,update:void 0,complete:void 0},q="translateX translateY translateZ rotate rotateX rotateY rotateZ scale scaleX scaleY scaleZ skewX skewY".split(" "),x,f={arr:function(a){return Array.isArray(a)},obj:function(a){return-1<
Object.prototype.toString.call(a).indexOf("Object")},svg:function(a){return a instanceof SVGElement},dom:function(a){return a.nodeType||f.svg(a)},num:function(a){return!isNaN(parseInt(a))},str:function(a){return"string"===typeof a},fnc:function(a){return"function"===typeof a},und:function(a){return"undefined"===typeof a},nul:function(a){return"null"===typeof a},hex:function(a){return/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(a)},rgb:function(a){return/^rgb/.test(a)},hsl:function(a){return/^hsl/.test(a)},
col:function(a){return f.hex(a)||f.rgb(a)||f.hsl(a)}},C=function(){var a={},b={Sine:function(a){return 1+Math.sin(Math.PI/2*a-Math.PI/2)},Circ:function(a){return 1-Math.sqrt(1-a*a)},Elastic:function(a,b){if(0===a||1===a)return a;var c=1-Math.min(b,998)/1E3,d=a/1-1;return-(Math.pow(2,10*d)*Math.sin(2*(d-c/(2*Math.PI)*Math.asin(1))*Math.PI/c))},Back:function(a){return a*a*(3*a-2)},Bounce:function(a){for(var b,c=4;a<((b=Math.pow(2,--c))-1)/11;);return 1/Math.pow(4,3-c)-7.5625*Math.pow((3*b-2)/22-a,2)}};
["Quad","Cubic","Quart","Quint","Expo"].forEach(function(a,d){b[a]=function(a){return Math.pow(a,d+2)}});Object.keys(b).forEach(function(c){var d=b[c];a["easeIn"+c]=d;a["easeOut"+c]=function(a,b){return 1-d(1-a,b)};a["easeInOut"+c]=function(a,b){return.5>a?d(2*a,b)/2:1-d(-2*a+2,b)/2};a["easeOutIn"+c]=function(a,b){return.5>a?(1-d(1-2*a,b))/2:(d(2*a-1,b)+1)/2}});a.linear=function(a){return a};return a}(),y=function(a){return f.str(a)?a:a+""},D=function(a){return a.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()},
E=function(a){if(f.col(a))return!1;try{return document.querySelectorAll(a)}catch(b){return!1}},z=function(a){return a.reduce(function(a,c){return a.concat(f.arr(c)?z(c):c)},[])},r=function(a){if(f.arr(a))return a;f.str(a)&&(a=E(a)||a);return a instanceof NodeList||a instanceof HTMLCollection?[].slice.call(a):[a]},F=function(a,b){return a.some(function(a){return a===b})},Q=function(a,b){var c={};a.forEach(function(a){var d=JSON.stringify(b.map(function(b){return a[b]}));c[d]=c[d]||[];c[d].push(a)});
return Object.keys(c).map(function(a){return c[a]})},G=function(a){return a.filter(function(a,c,d){return d.indexOf(a)===c})},A=function(a){var b={},c;for(c in a)b[c]=a[c];return b},u=function(a,b){for(var c in b)a[c]=f.und(a[c])?b[c]:a[c];return a},R=function(a){a=a.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,function(a,b,c,l){return b+b+c+c+l+l});var b=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(a);a=parseInt(b[1],16);var c=parseInt(b[2],16),b=parseInt(b[3],16);return"rgb("+a+","+c+","+b+")"},
S=function(a){a=/hsl\((\d+),\s*([\d.]+)%,\s*([\d.]+)%\)/g.exec(a);var b=parseInt(a[1])/360,c=parseInt(a[2])/100,d=parseInt(a[3])/100;a=function(a,b,c){0>c&&(c+=1);1<c&&--c;return c<1/6?a+6*(b-a)*c:.5>c?b:c<2/3?a+(b-a)*(2/3-c)*6:a};if(0==c)c=d=b=d;else var e=.5>d?d*(1+c):d+c-d*c,h=2*d-e,c=a(h,e,b+1/3),d=a(h,e,b),b=a(h,e,b-1/3);return"rgb("+255*c+","+255*d+","+255*b+")"},p=function(a){return/([\+\-]?[0-9|auto\.]+)(%|px|pt|em|rem|in|cm|mm|ex|pc|vw|vh|deg)?/.exec(a)[2]},H=function(a,b,c){return p(b)?
b:-1<a.indexOf("translate")?p(c)?b+p(c):b+"px":-1<a.indexOf("rotate")||-1<a.indexOf("skew")?b+"deg":b},v=function(a,b){if(b in a.style)return getComputedStyle(a).getPropertyValue(D(b))||"0"},T=function(a,b){var c=-1<b.indexOf("scale")?1:0,d=a.style.transform;if(!d)return c;for(var e=/(\w+)\((.+?)\)/g,h=[],l=[],f=[];h=e.exec(d);)l.push(h[1]),f.push(h[2]);d=f.filter(function(a,c){return l[c]===b});return d.length?d[0]:c},I=function(a,b){if(f.dom(a)&&F(q,b))return"transform";if(f.dom(a)&&(a.getAttribute(b)||
f.svg(a)&&a[b]))return"attribute";if(f.dom(a)&&"transform"!==b&&v(a,b))return"css";if(!f.nul(a[b])&&!f.und(a[b]))return"object"},J=function(a,b){switch(I(a,b)){case "transform":return T(a,b);case "css":return v(a,b);case "attribute":return a.getAttribute(b)}return a[b]||0},K=function(a,b,c){if(f.col(b))return b=f.rgb(b)?b:f.hex(b)?R(b):f.hsl(b)?S(b):void 0,b;if(p(b))return b;a=p(a.to)?p(a.to):p(a.from);!a&&c&&(a=p(c));return a?b+a:b},L=function(a){var b=/-?\d*\.?\d+/g;return{original:a,numbers:y(a).match(b)?
y(a).match(b).map(Number):[0],strings:y(a).split(b)}},U=function(a,b,c){return b.reduce(function(b,e,h){e=e?e:c[h-1];return b+a[h-1]+e})},V=function(a){a=a?z(f.arr(a)?a.map(r):r(a)):[];return a.map(function(a,c){return{target:a,id:c}})},M=function(a,b,c,d){"transform"===c?(c=a+"("+H(a,b.from,b.to)+")",b=a+"("+H(a,b.to)+")"):(a="css"===c?v(d,a):void 0,c=K(b,b.from,a),b=K(b,b.to,a));return{from:L(c),to:L(b)}},W=function(a,b){var c=[];a.forEach(function(d,e){var h=d.target;return b.forEach(function(b){var l=
I(h,b.name);if(l){var m;m=b.name;var g=b.value,g=r(f.fnc(g)?g(h,e):g);m={from:1<g.length?g[0]:J(h,m),to:1<g.length?g[1]:g[0]};g=A(b);g.animatables=d;g.type=l;g.from=M(b.name,m,g.type,h).from;g.to=M(b.name,m,g.type,h).to;g.round=f.col(m.from)||g.round?1:0;g.delay=(f.fnc(g.delay)?g.delay(h,e,a.length):g.delay)/k.speed;g.duration=(f.fnc(g.duration)?g.duration(h,e,a.length):g.duration)/k.speed;c.push(g)}})});return c},X=function(a,b){var c=W(a,b);return Q(c,["name","from","to","delay","duration"]).map(function(a){var b=
A(a[0]);b.animatables=a.map(function(a){return a.animatables});b.totalDuration=b.delay+b.duration;return b})},B=function(a,b){a.tweens.forEach(function(c){var d=c.from,e=a.duration-(c.delay+c.duration);c.from=c.to;c.to=d;b&&(c.delay=e)});a.reversed=a.reversed?!1:!0},Y=function(a){return Math.max.apply(Math,a.map(function(a){return a.totalDuration}))},Z=function(a){return Math.min.apply(Math,a.map(function(a){return a.delay}))},N=function(a){var b=[],c=[];a.tweens.forEach(function(a){if("css"===a.type||
"transform"===a.type)b.push("css"===a.type?D(a.name):"transform"),a.animatables.forEach(function(a){c.push(a.target)})});return{properties:G(b).join(", "),elements:G(c)}},aa=function(a){var b=N(a);b.elements.forEach(function(a){a.style.willChange=b.properties})},ba=function(a){N(a).elements.forEach(function(a){a.style.removeProperty("will-change")})},ca=function(a,b){var c=a.path,d=a.value*b,e=function(e){e=e||0;return c.getPointAtLength(1<b?a.value+e:d+e)},h=e(),f=e(-1),e=e(1);switch(a.name){case "translateX":return h.x;
case "translateY":return h.y;case "rotate":return 180*Math.atan2(e.y-f.y,e.x-f.x)/Math.PI}},da=function(a,b){var c=Math.min(Math.max(b-a.delay,0),a.duration)/a.duration,d=a.to.numbers.map(function(b,d){var e=a.from.numbers[d],f=C[a.easing](c,a.elasticity),e=a.path?ca(a,f):e+f*(b-e);return e=a.round?Math.round(e*a.round)/a.round:e});return U(d,a.to.strings,a.from.strings)},O=function(a,b){var c;a.currentTime=b;a.progress=b/a.duration*100;for(var d=0;d<a.tweens.length;d++){var e=a.tweens[d];e.currentValue=
da(e,b);for(var f=e.currentValue,l=0;l<e.animatables.length;l++){var k=e.animatables[l],m=k.id,k=k.target,g=e.name;switch(e.type){case "css":k.style[g]=f;break;case "attribute":k.setAttribute(g,f);break;case "object":k[g]=f;break;case "transform":c||(c={}),c[m]||(c[m]=[]),c[m].push(f)}}}if(c)for(d in x||(x=(v(document.body,"transform")?"":"-webkit-")+"transform"),c)a.animatables[d].target.style[x]=c[d].join(" ")},P=function(a){var b={};b.animatables=V(a.targets);b.settings=u(a,t);var c=b.settings,
d=[],e;for(e in a)if(!t.hasOwnProperty(e)&&"targets"!==e){var h=f.obj(a[e])?A(a[e]):{value:a[e]};h.name=e;d.push(u(h,c))}b.properties=d;b.tweens=X(b.animatables,b.properties);b.duration=b.tweens.length?Y(b.tweens):a.duration;b.delay=b.tweens.length?Z(b.tweens):a.delay;b.currentTime=0;b.progress=0;b.ended=!1;return b},n=[],w=0,ea=function(){var a=function(){w=requestAnimationFrame(b)},b=function(b){if(n.length){for(var c=0;c<n.length;c++)n[c].tick(b);a()}else cancelAnimationFrame(w),w=0};return a}(),
k=function(a){var b=P(a),c={};b.tick=function(a){b.ended=!1;c.start||(c.start=a);c.current=Math.min(Math.max(c.last+a-c.start,0),b.duration);O(b,c.current);var d=b.settings;c.current>=b.delay&&(d.begin&&d.begin(b),d.begin=void 0,d.update&&d.update(b));c.current>=b.duration&&(d.loop?(c.start=a,"alternate"===d.direction&&B(b,!0),f.num(d.loop)&&d.loop--):(b.ended=!0,b.pause(),d.complete&&d.complete(b)),c.last=0)};b.seek=function(a){O(b,a/100*b.duration)};b.pause=function(){ba(b);var a=n.indexOf(b);-1<
a&&n.splice(a,1)};b.play=function(a){b.pause();a&&(b=u(P(u(a,b.settings)),b));c.start=0;c.last=b.ended?0:b.currentTime;a=b.settings;"reverse"===a.direction&&B(b);"alternate"!==a.direction||a.loop||(a.loop=1);aa(b);n.push(b);w||ea()};b.restart=function(){b.reversed&&B(b);b.pause();b.seek(0);b.play()};b.settings.autoplay&&b.play();return b};k.version="1.1.3";k.speed=1;k.list=n;k.remove=function(a){a=z(f.arr(a)?a.map(r):r(a));for(var b=n.length-1;0<=b;b--)for(var c=n[b],d=c.tweens,e=d.length-1;0<=e;e--)for(var h=
d[e].animatables,k=h.length-1;0<=k;k--)F(a,h[k].target)&&(h.splice(k,1),h.length||d.splice(e,1),d.length||c.pause())};k.easings=C;k.getValue=J;k.path=function(a){a=f.str(a)?E(a)[0]:a;return{path:a,value:a.getTotalLength()}};k.random=function(a,b){return Math.floor(Math.random()*(b-a+1))+a};return k});

View File

@ -0,0 +1,27 @@
/*
2017 Julian Garnier
Released under the MIT license
*/
var $jscomp$this=this;
(function(u,r){"function"===typeof define&&define.amd?define([],r):"object"===typeof module&&module.exports?module.exports=r():u.anime=r()})(this,function(){function u(a){if(!h.col(a))try{return document.querySelectorAll(a)}catch(b){}}function r(a){return a.reduce(function(a,c){return a.concat(h.arr(c)?r(c):c)},[])}function v(a){if(h.arr(a))return a;h.str(a)&&(a=u(a)||a);return a instanceof NodeList||a instanceof HTMLCollection?[].slice.call(a):[a]}function E(a,b){return a.some(function(a){return a===b})}
function z(a){var b={},c;for(c in a)b[c]=a[c];return b}function F(a,b){var c=z(a),d;for(d in a)c[d]=b.hasOwnProperty(d)?b[d]:a[d];return c}function A(a,b){var c=z(a),d;for(d in b)c[d]=h.und(a[d])?b[d]:a[d];return c}function R(a){a=a.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,function(a,b,c,g){return b+b+c+c+g+g});var b=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(a);a=parseInt(b[1],16);var c=parseInt(b[2],16),b=parseInt(b[3],16);return"rgb("+a+","+c+","+b+")"}function S(a){function b(a,b,c){0>
c&&(c+=1);1<c&&--c;return c<1/6?a+6*(b-a)*c:.5>c?b:c<2/3?a+(b-a)*(2/3-c)*6:a}var c=/hsl\((\d+),\s*([\d.]+)%,\s*([\d.]+)%\)/g.exec(a);a=parseInt(c[1])/360;var d=parseInt(c[2])/100,c=parseInt(c[3])/100;if(0==d)d=c=a=c;else{var e=.5>c?c*(1+d):c+d-c*d,k=2*c-e,d=b(k,e,a+1/3),c=b(k,e,a);a=b(k,e,a-1/3)}return"rgb("+255*d+","+255*c+","+255*a+")"}function w(a){if(a=/([\+\-]?[0-9#\.]+)(%|px|pt|em|rem|in|cm|mm|ex|pc|vw|vh|deg|rad|turn)?/.exec(a))return a[2]}function T(a){if(-1<a.indexOf("translate"))return"px";
if(-1<a.indexOf("rotate")||-1<a.indexOf("skew"))return"deg"}function G(a,b){return h.fnc(a)?a(b.target,b.id,b.total):a}function B(a,b){if(b in a.style)return getComputedStyle(a).getPropertyValue(b.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase())||"0"}function H(a,b){if(h.dom(a)&&E(U,b))return"transform";if(h.dom(a)&&a.getAttribute(b))return"attribute";if(h.dom(a)&&"transform"!==b&&B(a,b))return"css";if(null!=a[b])return"object"}function V(a,b){var c=T(b),c=-1<b.indexOf("scale")?1:0+c;a=a.style.transform;
if(!a)return c;for(var d=[],e=[],k=[],g=/(\w+)\((.+?)\)/g;d=g.exec(a);)e.push(d[1]),k.push(d[2]);a=k.filter(function(a,c){return e[c]===b});return a.length?a[0]:c}function I(a,b){switch(H(a,b)){case "transform":return V(a,b);case "css":return B(a,b);case "attribute":return a.getAttribute(b)}return a[b]||0}function J(a,b){var c=/^(\*=|\+=|-=)/.exec(a);if(!c)return a;b=parseFloat(b);a=parseFloat(a.replace(c[0],""));switch(c[0][0]){case "+":return b+a;case "-":return b-a;case "*":return b*a}}function C(a){return h.obj(a)&&
a.hasOwnProperty("totalLength")}function W(a,b){function c(c){c=void 0===c?0:c;return a.el.getPointAtLength(1<=b+c?b+c:0)}var d=c(),e=c(-1),k=c(1);switch(a.property){case "x":return d.x;case "y":return d.y;case "angle":return 180*Math.atan2(k.y-e.y,k.x-e.x)/Math.PI}}function K(a,b){var c=/-?\d*\.?\d+/g;a=C(a)?a.totalLength:a;if(h.col(a))b=h.rgb(a)?a:h.hex(a)?R(a):h.hsl(a)?S(a):void 0;else{var d=w(a);a=d?a.substr(0,a.length-d.length):a;b=b?a+b:a}b+="";return{original:b,numbers:b.match(c)?b.match(c).map(Number):
[0],strings:b.split(c)}}function X(a,b){return b.reduce(function(b,d,e){return b+a[e-1]+d})}function L(a){return(a?r(h.arr(a)?a.map(v):v(a)):[]).filter(function(a,c,d){return d.indexOf(a)===c})}function Y(a){var b=L(a);return b.map(function(a,d){return{target:a,id:d,total:b.length}})}function Z(a,b){var c=z(b);if(h.arr(a)){var d=a.length;2!==d||h.obj(a[0])?h.fnc(b.duration)||(c.duration=b.duration/d):a={value:a}}return v(a).map(function(a,c){c=c?0:b.delay;a=h.obj(a)&&!C(a)?a:{value:a};h.und(a.delay)&&
(a.delay=c);return a}).map(function(a){return A(a,c)})}function aa(a,b){var c={},d;for(d in a){var e=G(a[d],b);h.arr(e)&&(e=e.map(function(a){return G(a,b)}),1===e.length&&(e=e[0]));c[d]=e}c.duration=parseFloat(c.duration);c.delay=parseFloat(c.delay);return c}function ba(a){return h.arr(a)?x.apply(this,a):M[a]}function ca(a,b){var c;return a.tweens.map(function(d){d=aa(d,b);var e=d.value,k=I(b.target,a.name),g=c?c.to.original:k,g=h.arr(e)?e[0]:g,n=J(h.arr(e)?e[1]:e,g),k=w(n)||w(g)||w(k);d.isPath=
C(e);d.from=K(g,k);d.to=K(n,k);d.start=c?c.end:a.offset;d.end=d.start+d.delay+d.duration;d.easing=ba(d.easing);d.elasticity=(1E3-Math.min(Math.max(d.elasticity,1),999))/1E3;h.col(d.from.original)&&(d.round=1);return c=d})}function da(a,b){return r(a.map(function(a){return b.map(function(b){var c=H(a.target,b.name);if(c){var d=ca(b,a);b={type:c,property:b.name,animatable:a,tweens:d,duration:d[d.length-1].end,delay:d[0].delay}}else b=void 0;return b})})).filter(function(a){return!h.und(a)})}function N(a,
b,c){var d="delay"===a?Math.min:Math.max;return b.length?d.apply(Math,b.map(function(b){return b[a]})):c[a]}function ea(a){var b=F(fa,a),c=F(ga,a),d=Y(a.targets),e=[],k=A(b,c),g;for(g in a)k.hasOwnProperty(g)||"targets"===g||e.push({name:g,offset:k.offset,tweens:Z(a[g],c)});a=da(d,e);return A(b,{animatables:d,animations:a,duration:N("duration",a,c),delay:N("delay",a,c)})}function m(a){function b(){return window.Promise&&new Promise(function(a){return P=a})}function c(a){return f.reversed?f.duration-
a:a}function d(a){for(var b=0,c={},d=f.animations,e={};b<d.length;){var g=d[b],h=g.animatable,k=g.tweens;e.tween=k.filter(function(b){return a<b.end})[0]||k[k.length-1];e.isPath$0=e.tween.isPath;e.round=e.tween.round;e.eased=e.tween.easing(Math.min(Math.max(a-e.tween.start-e.tween.delay,0),e.tween.duration)/e.tween.duration,e.tween.elasticity);k=X(e.tween.to.numbers.map(function(a){return function(b,c){c=a.isPath$0?0:a.tween.from.numbers[c];b=c+a.eased*(b-c);a.isPath$0&&(b=W(a.tween.value,b));a.round&&
(b=Math.round(b*a.round)/a.round);return b}}(e)),e.tween.to.strings);ha[g.type](h.target,g.property,k,c,h.id);g.currentValue=k;b++;e={isPath$0:e.isPath$0,tween:e.tween,eased:e.eased,round:e.round}}if(c)for(var l in c)D||(D=B(document.body,"transform")?"transform":"-webkit-transform"),f.animatables[l].target.style[D]=c[l].join(" ");f.currentTime=a;f.progress=a/f.duration*100}function e(a){if(f[a])f[a](f)}function k(){f.remaining&&!0!==f.remaining&&f.remaining--}function g(a){var g=f.duration,n=f.offset,
m=f.delay,O=f.currentTime,p=f.reversed,q=c(a),q=Math.min(Math.max(q,0),g);q>n&&q<g?(d(q),!f.began&&q>=m&&(f.began=!0,e("begin")),e("run")):(q<=n&&0!==O&&(d(0),p&&k()),q>=g&&O!==g&&(d(g),p||k()));a>=g&&(f.remaining?(t=h,"alternate"===f.direction&&(f.reversed=!f.reversed)):(f.pause(),P(),Q=b(),f.completed||(f.completed=!0,e("complete"))),l=0);if(f.children)for(a=f.children,g=0;g<a.length;g++)a[g].seek(q);e("update")}a=void 0===a?{}:a;var h,t,l=0,P=null,Q=b(),f=ea(a);f.reset=function(){var a=f.direction,
b=f.loop;f.currentTime=0;f.progress=0;f.paused=!0;f.began=!1;f.completed=!1;f.reversed="reverse"===a;f.remaining="alternate"===a&&1===b?2:b};f.tick=function(a){h=a;t||(t=h);g((l+h-t)*m.speed)};f.seek=function(a){g(c(a))};f.pause=function(){var a=p.indexOf(f);-1<a&&p.splice(a,1);f.paused=!0};f.play=function(){f.paused&&(f.paused=!1,t=0,l=f.completed?0:c(f.currentTime),p.push(f),y||ia())};f.reverse=function(){f.reversed=!f.reversed;t=0;l=c(f.currentTime)};f.restart=function(){f.pause();f.reset();f.play()};
f.finished=Q;f.reset();f.autoplay&&f.play();return f}var fa={update:void 0,begin:void 0,run:void 0,complete:void 0,loop:1,direction:"normal",autoplay:!0,offset:0},ga={duration:1E3,delay:0,easing:"easeOutElastic",elasticity:500,round:0},U="translateX translateY translateZ rotate rotateX rotateY rotateZ scale scaleX scaleY scaleZ skewX skewY".split(" "),D,h={arr:function(a){return Array.isArray(a)},obj:function(a){return-1<Object.prototype.toString.call(a).indexOf("Object")},dom:function(a){return a.nodeType||
a instanceof SVGElement},str:function(a){return"string"===typeof a},fnc:function(a){return"function"===typeof a},und:function(a){return"undefined"===typeof a},hex:function(a){return/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(a)},rgb:function(a){return/^rgb/.test(a)},hsl:function(a){return/^hsl/.test(a)},col:function(a){return h.hex(a)||h.rgb(a)||h.hsl(a)}},x=function(){function a(a,c,d){return(((1-3*d+3*c)*a+(3*d-6*c))*a+3*c)*a}return function(b,c,d,e){if(0<=b&&1>=b&&0<=d&&1>=d){var k=new Float32Array(11);
if(b!==c||d!==e)for(var g=0;11>g;++g)k[g]=a(.1*g,b,d);return function(g){if(b===c&&d===e)return g;if(0===g)return 0;if(1===g)return 1;for(var h=0,l=1;10!==l&&k[l]<=g;++l)h+=.1;--l;var l=h+(g-k[l])/(k[l+1]-k[l])*.1,n=3*(1-3*d+3*b)*l*l+2*(3*d-6*b)*l+3*b;if(.001<=n){for(h=0;4>h;++h){n=3*(1-3*d+3*b)*l*l+2*(3*d-6*b)*l+3*b;if(0===n)break;var m=a(l,b,d)-g,l=l-m/n}g=l}else if(0===n)g=l;else{var l=h,h=h+.1,f=0;do m=l+(h-l)/2,n=a(m,b,d)-g,0<n?h=m:l=m;while(1e-7<Math.abs(n)&&10>++f);g=m}return a(g,c,e)}}}}(),
M=function(){function a(a,b){return 0===a||1===a?a:-Math.pow(2,10*(a-1))*Math.sin(2*(a-1-b/(2*Math.PI)*Math.asin(1))*Math.PI/b)}var b="Quad Cubic Quart Quint Sine Expo Circ Back Elastic".split(" "),c={In:[[.55,.085,.68,.53],[.55,.055,.675,.19],[.895,.03,.685,.22],[.755,.05,.855,.06],[.47,0,.745,.715],[.95,.05,.795,.035],[.6,.04,.98,.335],[.6,-.28,.735,.045],a],Out:[[.25,.46,.45,.94],[.215,.61,.355,1],[.165,.84,.44,1],[.23,1,.32,1],[.39,.575,.565,1],[.19,1,.22,1],[.075,.82,.165,1],[.175,.885,.32,1.275],
function(b,c){return 1-a(1-b,c)}],InOut:[[.455,.03,.515,.955],[.645,.045,.355,1],[.77,0,.175,1],[.86,0,.07,1],[.445,.05,.55,.95],[1,0,0,1],[.785,.135,.15,.86],[.68,-.55,.265,1.55],function(b,c){return.5>b?a(2*b,c)/2:1-a(-2*b+2,c)/2}]},d={linear:x(.25,.25,.75,.75)},e={},k;for(k in c)e.type=k,c[e.type].forEach(function(a){return function(c,e){d["ease"+a.type+b[e]]=h.fnc(c)?c:x.apply($jscomp$this,c)}}(e)),e={type:e.type};return d}(),ha={css:function(a,b,c){return a.style[b]=c},attribute:function(a,b,
c){return a.setAttribute(b,c)},object:function(a,b,c){return a[b]=c},transform:function(a,b,c,d,e){d[e]||(d[e]=[]);d[e].push(b+"("+c+")")}},p=[],y=0,ia=function(){function a(){y=requestAnimationFrame(b)}function b(b){var c=p.length;if(c){for(var e=0;e<c;)p[e]&&p[e].tick(b),e++;a()}else cancelAnimationFrame(y),y=0}return a}();m.version="2.0.0";m.speed=1;m.running=p;m.remove=function(a){a=L(a);for(var b=p.length-1;0<=b;b--)for(var c=p[b],d=c.animations,e=d.length-1;0<=e;e--)E(a,d[e].animatable.target)&&
(d.splice(e,1),d.length||c.pause())};m.getValue=I;m.path=function(a,b){var c=h.str(a)?u(a)[0]:a,d=b||100;return function(a){return{el:c,property:a,totalLength:c.getTotalLength()*(d/100)}}};m.setDashoffset=function(a){var b=a.getTotalLength();a.setAttribute("stroke-dasharray",b);return b};m.bezier=x;m.easings=M;m.timeline=function(a){var b=m(a);b.duration=0;b.children=[];b.add=function(a){v(a).forEach(function(a){var c=a.offset,d=b.duration;a.autoplay=!1;a.offset=h.und(c)?d:J(c,d);a=m(a);a.duration>
d&&(b.duration=a.duration);b.children.push(a)});return b};return b};m.random=function(a,b){return Math.floor(Math.random()*(b-a+1))+a};return m});

View File

@ -0,0 +1,871 @@
/**
* https://animejs.com
* JavaScript animation engine
* @version v2.0.1
* @author Julian Garnier
* @copyright ©2017 Julian Garnier
* Released under the MIT license
**/
(function(root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define([], factory);
} else if (typeof module === 'object' && module.exports) {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like environments that support module.exports,
// like Node.
module.exports = factory();
} else {
// Browser globals (root is window)
root.anime = factory();
}
}(this, () => {
// Defaults
const defaultInstanceSettings = {
update: undefined,
begin: undefined,
run: undefined,
complete: undefined,
loop: 1,
direction: 'normal',
autoplay: true,
offset: 0
}
const defaultTweenSettings = {
duration: 1000,
delay: 0,
easing: 'easeOutElastic',
elasticity: 500,
round: 0
}
const validTransforms = ['translateX', 'translateY', 'translateZ', 'rotate', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scaleX', 'scaleY', 'scaleZ', 'skewX', 'skewY'];
let transformString;
// Utils
function stringContains(str, text) {
return str.indexOf(text) > -1;
}
const is = {
arr: a => Array.isArray(a),
obj: a => stringContains(Object.prototype.toString.call(a), 'Object'),
svg: a => a instanceof SVGElement,
dom: a => a.nodeType || is.svg(a),
str: a => typeof a === 'string',
fnc: a => typeof a === 'function',
und: a => typeof a === 'undefined',
hex: a => /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(a),
rgb: a => /^rgb/.test(a),
hsl: a => /^hsl/.test(a),
col: a => (is.hex(a) || is.rgb(a) || is.hsl(a))
}
// BezierEasing https://github.com/gre/bezier-easing
const bezier = (() => {
const kSplineTableSize = 11;
const kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
function A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1 };
function B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1 };
function C (aA1) { return 3.0 * aA1 };
function calcBezier (aT, aA1, aA2) { return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT };
function getSlope (aT, aA1, aA2) { return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1) };
function binarySubdivide (aX, aA, aB, mX1, mX2) {
let currentX, currentT, i = 0;
do {
currentT = aA + (aB - aA) / 2.0;
currentX = calcBezier(currentT, mX1, mX2) - aX;
if (currentX > 0.0) { aB = currentT } else { aA = currentT };
} while (Math.abs(currentX) > 0.0000001 && ++i < 10);
return currentT;
}
function newtonRaphsonIterate (aX, aGuessT, mX1, mX2) {
for (let i = 0; i < 4; ++i) {
const currentSlope = getSlope(aGuessT, mX1, mX2);
if (currentSlope === 0.0) return aGuessT;
const currentX = calcBezier(aGuessT, mX1, mX2) - aX;
aGuessT -= currentX / currentSlope;
}
return aGuessT;
}
function bezier(mX1, mY1, mX2, mY2) {
if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) return;
let sampleValues = new Float32Array(kSplineTableSize);
if (mX1 !== mY1 || mX2 !== mY2) {
for (let i = 0; i < kSplineTableSize; ++i) {
sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
}
}
function getTForX(aX) {
let intervalStart = 0.0;
let currentSample = 1;
const lastSample = kSplineTableSize - 1;
for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) {
intervalStart += kSampleStepSize;
}
--currentSample;
const dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]);
const guessForT = intervalStart + dist * kSampleStepSize;
const initialSlope = getSlope(guessForT, mX1, mX2);
if (initialSlope >= 0.001) {
return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
} else if (initialSlope === 0.0) {
return guessForT;
} else {
return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
}
}
return x => {
if (mX1 === mY1 && mX2 === mY2) return x;
if (x === 0) return 0;
if (x === 1) return 1;
return calcBezier(getTForX(x), mY1, mY2);
}
}
return bezier;
})();
const easings = (() => {
const names = ['Quad', 'Cubic', 'Quart', 'Quint', 'Sine', 'Expo', 'Circ', 'Back', 'Elastic'];
// Elastic easing adapted from jQueryUI http://api.jqueryui.com/easings/
function elastic(t, p) {
return t === 0 || t === 1 ? t :
-Math.pow(2, 10 * (t - 1)) * Math.sin((((t - 1) - (p / (Math.PI * 2.0) * Math.asin(1))) * (Math.PI * 2)) / p );
}
// Approximated Penner equations http://matthewlein.com/ceaser/
const equations = {
In: [
[0.550, 0.085, 0.680, 0.530], /* InQuad */
[0.550, 0.055, 0.675, 0.190], /* InCubic */
[0.895, 0.030, 0.685, 0.220], /* InQuart */
[0.755, 0.050, 0.855, 0.060], /* InQuint */
[0.470, 0.000, 0.745, 0.715], /* InSine */
[0.950, 0.050, 0.795, 0.035], /* InExpo */
[0.600, 0.040, 0.980, 0.335], /* InCirc */
[0.600, -0.280, 0.735, 0.045], /* InBack */
elastic /* InElastic */
], Out: [
[0.250, 0.460, 0.450, 0.940], /* OutQuad */
[0.215, 0.610, 0.355, 1.000], /* OutCubic */
[0.165, 0.840, 0.440, 1.000], /* OutQuart */
[0.230, 1.000, 0.320, 1.000], /* OutQuint */
[0.390, 0.575, 0.565, 1.000], /* OutSine */
[0.190, 1.000, 0.220, 1.000], /* OutExpo */
[0.075, 0.820, 0.165, 1.000], /* OutCirc */
[0.175, 0.885, 0.320, 1.275], /* OutBack */
(t, f) => 1 - elastic(1 - t, f) /* OutElastic */
], InOut: [
[0.455, 0.030, 0.515, 0.955], /* InOutQuad */
[0.645, 0.045, 0.355, 1.000], /* InOutCubic */
[0.770, 0.000, 0.175, 1.000], /* InOutQuart */
[0.860, 0.000, 0.070, 1.000], /* InOutQuint */
[0.445, 0.050, 0.550, 0.950], /* InOutSine */
[1.000, 0.000, 0.000, 1.000], /* InOutExpo */
[0.785, 0.135, 0.150, 0.860], /* InOutCirc */
[0.680, -0.550, 0.265, 1.550], /* InOutBack */
(t, f) => t < .5 ? elastic(t * 2, f) / 2 : 1 - elastic(t * -2 + 2, f) / 2 /* InOutElastic */
]
}
let functions = {
linear: bezier(0.250, 0.250, 0.750, 0.750)
}
for (let type in equations) {
equations[type].forEach((f, i) => {
functions['ease'+type+names[i]] = is.fnc(f) ? f : bezier.apply(this, f);
});
}
return functions;
})();
// Strings
function stringToHyphens(str) {
return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
}
function selectString(str) {
if (is.col(str)) return;
try {
let nodes = document.querySelectorAll(str);
return nodes;
} catch(e) {
return;
}
}
// Arrays
function arrayLength(arr) {
return arr.length;
}
function flattenArray(arr) {
return arr.reduce((a, b) => a.concat(is.arr(b) ? flattenArray(b) : b), []);
}
function toArray(o) {
if (is.arr(o)) return o;
if (is.str(o)) o = selectString(o) || o;
if (o instanceof NodeList || o instanceof HTMLCollection) return [].slice.call(o);
return [o];
}
function arrayContains(arr, val) {
return arr.some(a => a === val);
}
// Objects
function objectHas(obj, prop) {
return obj.hasOwnProperty(prop);
}
function cloneObject(o) {
let clone = {};
for (let p in o) clone[p] = o[p];
return clone;
}
function replaceObjectProps(o1, o2) {
let o = cloneObject(o1);
for (let p in o1) o[p] = objectHas(o2, p) ? o2[p] : o1[p];
return o;
}
function mergeObjects(o1, o2) {
let o = cloneObject(o1);
for (let p in o2) o[p] = is.und(o1[p]) ? o2[p] : o1[p];
return o;
}
// Colors
function hexToRgb(hexValue) {
const rgx = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
const hex = hexValue.replace(rgx, (m, r, g, b) => r + r + g + g + b + b );
const rgb = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
const r = parseInt(rgb[1], 16);
const g = parseInt(rgb[2], 16);
const b = parseInt(rgb[3], 16);
return `rgb(${r},${g},${b})`;
}
function hslToRgb(hslValue) {
const hsl = /hsl\((\d+),\s*([\d.]+)%,\s*([\d.]+)%\)/g.exec(hslValue);
const h = parseInt(hsl[1]) / 360;
const s = parseInt(hsl[2]) / 100;
const l = parseInt(hsl[3]) / 100;
function hue2rgb(p, q, t) {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1/6) return p + (q - p) * 6 * t;
if (t < 1/2) return q;
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
}
let r, g, b;
if (s == 0) {
r = g = b = l;
} else {
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
r = hue2rgb(p, q, h + 1/3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3);
}
return `rgb(${r * 255},${g * 255},${b * 255})`;
}
function colorToRgb(val) {
if (is.rgb(val)) return val;
if (is.hex(val)) return hexToRgb(val);
if (is.hsl(val)) return hslToRgb(val);
}
// Units
function getUnit(val) {
const split = /([\+\-]?[0-9#\.]+)(%|px|pt|em|rem|in|cm|mm|ex|pc|vw|vh|deg|rad|turn)?/.exec(val);
if (split) return split[2];
}
function getTransformUnit(propName) {
if (stringContains(propName, 'translate')) return 'px';
if (stringContains(propName, 'rotate') || stringContains(propName, 'skew')) return 'deg';
}
// Values
function parseFloatValue(val) {
return parseFloat(val);
}
function minMaxValue(val, min, max) {
return Math.min(Math.max(val, min), max);
}
function getFunctionValue(val, animatable) {
if (!is.fnc(val)) return val;
return val(animatable.target, animatable.id, animatable.total);
}
function getCSSValue(el, prop) {
if (prop in el.style) {
return getComputedStyle(el).getPropertyValue(stringToHyphens(prop)) || '0';
}
}
function getAnimationType(el, prop) {
if (is.dom(el) && arrayContains(validTransforms, prop)) return 'transform';
if (is.dom(el) && (el.getAttribute(prop) || (is.svg(el) && el[prop]))) return 'attribute';
if (is.dom(el) && (prop !== 'transform' && getCSSValue(el, prop))) return 'css';
if (el[prop] != null) return 'object';
}
function getTransformValue(el, propName) {
const defaultUnit = getTransformUnit(propName);
const defaultVal = stringContains(propName, 'scale') ? 1 : 0 + defaultUnit;
const str = el.style.transform;
if (!str) return defaultVal;
let match = [];
let props = [];
let values = [];
const rgx = /(\w+)\((.+?)\)/g;
while (match = rgx.exec(str)) {
props.push(match[1]);
values.push(match[2]);
}
const value = values.filter((val, i) => props[i] === propName );
return arrayLength(value) ? value[0] : defaultVal;
}
function getOriginalTargetValue(target, propName) {
switch (getAnimationType(target, propName)) {
case 'transform': return getTransformValue(target, propName);
case 'css': return getCSSValue(target, propName);
case 'attribute': return target.getAttribute(propName);
}
return target[propName] || 0;
}
function getRelativeValue(to, from) {
const operator = /^(\*=|\+=|-=)/.exec(to);
if (!operator) return to;
const x = parseFloatValue(from);
const y = parseFloatValue(to.replace(operator[0], ''));
switch (operator[0][0]) {
case '+': return x + y;
case '-': return x - y;
case '*': return x * y;
}
}
function validateValue(val, unit) {
if (is.col(val)) return colorToRgb(val);
const originalUnit = getUnit(val);
const unitLess = originalUnit ? val.substr(0, arrayLength(val) - arrayLength(originalUnit)) : val;
return unit ? unitLess + unit : unitLess;
}
// Motion path
function isPath(val) {
return is.obj(val) && objectHas(val, 'totalLength');
}
function setDashoffset(el) {
const pathLength = el.getTotalLength();
el.setAttribute('stroke-dasharray', pathLength);
return pathLength;
}
function getPath(path, percent) {
const el = is.str(path) ? selectString(path)[0] : path;
const p = percent || 100;
return function(prop) {
return {
el: el,
property: prop,
totalLength: el.getTotalLength() * (p / 100)
}
}
}
function getPathProgress(path, progress) {
function point(offset = 0) {
const l = progress + offset >= 1 ? progress + offset : 0;
return path.el.getPointAtLength(l);
}
const p = point();
const p0 = point(-1);
const p1 = point(+1);
switch (path.property) {
case 'x': return p.x;
case 'y': return p.y;
case 'angle': return Math.atan2(p1.y - p0.y, p1.x - p0.x) * 180 / Math.PI;
}
}
// Decompose / recompose functions adapted from Animate Plus https://github.com/bendc/animateplus
function decomposeValue(val, unit) {
const rgx = /-?\d*\.?\d+/g;
const value = validateValue((isPath(val) ? val.totalLength : val), unit) + '';
return {
original: value,
numbers: value.match(rgx) ? value.match(rgx).map(Number) : [0],
strings: value.split(rgx)
}
}
function recomposeValue(numbers, strings) {
return strings.reduce((a, b, i) => a + numbers[i - 1] + b);
}
// Animatables
function parseTargets(targets) {
const targetsArray = targets ? (flattenArray(is.arr(targets) ? targets.map(toArray) : toArray(targets))) : [];
return targetsArray.filter((item, pos, self) => self.indexOf(item) === pos);
}
function getAnimatables(targets) {
const parsed = parseTargets(targets);
return parsed.map((t, i) => {
return {target: t, id: i, total: arrayLength(parsed)};
});
}
// Properties
function normalizePropertyTweens(prop, tweenSettings) {
let settings = cloneObject(tweenSettings);
if (is.arr(prop)) {
const l = arrayLength(prop);
const isFromTo = (l === 2 && !is.obj(prop[0]));
if (!isFromTo) {
// Duration divided by the number of tweens
if (!is.fnc(tweenSettings.duration)) settings.duration = tweenSettings.duration / l;
} else {
// Transform [from, to] values shorthand to a valid tween value
prop = {value: prop};
}
}
return toArray(prop).map((v, i) => {
// Default delay value should be applied only on the first tween
const delay = !i ? tweenSettings.delay : 0;
// Use path object as a tween value
let obj = is.obj(v) && !isPath(v) ? v : {value: v};
// Set default delay value
if (is.und(obj.delay)) obj.delay = delay;
return obj;
}).map(k => mergeObjects(k, settings));
}
function getProperties(instanceSettings, tweenSettings, params) {
let properties = [];
const settings = mergeObjects(instanceSettings, tweenSettings);
for (let p in params) {
if (!objectHas(settings, p) && p !== 'targets') {
properties.push({
name: p,
offset: settings['offset'],
tweens: normalizePropertyTweens(params[p], tweenSettings)
});
}
}
return properties;
}
// Tweens
function normalizeTweenValues(tween, animatable) {
let t = {};
for (let p in tween) {
let value = getFunctionValue(tween[p], animatable);
if (is.arr(value)) {
value = value.map(v => getFunctionValue(v, animatable));
if (arrayLength(value) === 1) value = value[0];
}
t[p] = value;
}
t.duration = parseFloatValue(t.duration);
t.delay = parseFloatValue(t.delay);
return t;
}
function normalizeEasing(val) {
return is.arr(val) ? bezier.apply(this, val) : easings[val];
}
function normalizeTweens(prop, animatable) {
let previousTween;
return prop.tweens.map(t => {
let tween = normalizeTweenValues(t, animatable);
const tweenValue = tween.value;
const originalValue = getOriginalTargetValue(animatable.target, prop.name);
const previousValue = previousTween ? previousTween.to.original : originalValue;
const from = is.arr(tweenValue) ? tweenValue[0] : previousValue;
const to = getRelativeValue(is.arr(tweenValue) ? tweenValue[1] : tweenValue, from);
const unit = getUnit(to) || getUnit(from) || getUnit(originalValue);
tween.isPath = isPath(tweenValue);
tween.from = decomposeValue(from, unit);
tween.to = decomposeValue(to, unit);
tween.start = previousTween ? previousTween.end : prop.offset;
tween.end = tween.start + tween.delay + tween.duration;
tween.easing = normalizeEasing(tween.easing);
tween.elasticity = (1000 - minMaxValue(tween.elasticity, 1, 999)) / 1000;
if (is.col(tween.from.original)) tween.round = 1;
previousTween = tween;
return tween;
});
}
// Tween progress
const setTweenProgress = {
css: (t, p, v) => t.style[p] = v,
attribute: (t, p, v) => t.setAttribute(p, v),
object: (t, p, v) => t[p] = v,
transform: (t, p, v, transforms, id) => {
if (!transforms[id]) transforms[id] = [];
transforms[id].push(`${p}(${v})`);
}
}
// Animations
function createAnimation(animatable, prop) {
const animType = getAnimationType(animatable.target, prop.name);
if (animType) {
const tweens = normalizeTweens(prop, animatable);
return {
type: animType,
property: prop.name,
animatable: animatable,
tweens: tweens,
duration: tweens[arrayLength(tweens) - 1].end,
delay: tweens[0].delay
}
}
}
function getAnimations(animatables, properties) {
return flattenArray(animatables.map(animatable => {
return properties.map(prop => {
return createAnimation(animatable, prop);
});
})).filter(a => !is.und(a));
}
// Create Instance
function getInstanceTimings(type, animations, tweenSettings) {
const math = (type === 'delay') ? Math.min : Math.max;
return arrayLength(animations) ? math.apply(Math, animations.map(anim => anim[type])) : tweenSettings[type];
}
function createNewInstance(params) {
const instanceSettings = replaceObjectProps(defaultInstanceSettings, params);
const tweenSettings = replaceObjectProps(defaultTweenSettings, params);
const animatables = getAnimatables(params.targets);
const properties = getProperties(instanceSettings, tweenSettings, params);
const animations = getAnimations(animatables, properties);
return mergeObjects(instanceSettings, {
animatables: animatables,
animations: animations,
duration: getInstanceTimings('duration', animations, tweenSettings),
delay: getInstanceTimings('delay', animations, tweenSettings)
});
}
// Core
let activeInstances = [];
let raf = 0;
const engine = (() => {
function play() { raf = requestAnimationFrame(step); };
function step(t) {
const activeLength = arrayLength(activeInstances);
if (activeLength) {
let i = 0;
while (i < activeLength) {
if (activeInstances[i]) activeInstances[i].tick(t);
i++;
}
play();
} else {
cancelAnimationFrame(raf);
raf = 0;
}
}
return play;
})();
// Public Instance
function anime(params = {}) {
let now, startTime, lastTime = 0;
let resolve = null;
function makePromise() {
return window.Promise && new Promise(_resolve => resolve = _resolve);
}
let promise = makePromise();
let instance = createNewInstance(params);
instance.reset = function() {
const direction = instance.direction;
const loops = instance.loop;
instance.currentTime = 0;
instance.progress = 0;
instance.paused = true;
instance.began = false;
instance.completed = false;
instance.reversed = direction === 'reverse';
instance.remaining = direction === 'alternate' && loops === 1 ? 2 : loops;
}
function toggleInstanceDirection() {
instance.reversed = !instance.reversed;
}
function adjustTime(time) {
return instance.reversed ? instance.duration - time : time;
}
function syncInstanceChildren(insTime) {
const children = instance.children;
for (let i = 0; i < arrayLength(children); i++) children[i].seek(insTime);
}
function setAnimationsProgress(insTime) {
let i = 0;
let transforms = {};
const animations = instance.animations;
while (i < arrayLength(animations)) {
const anim = animations[i];
const animatable = anim.animatable;
const tweens = anim.tweens;
const tween = tweens.filter(t => (insTime < t.end))[0] || tweens[arrayLength(tweens) - 1];
const isPath = tween.isPath;
const round = tween.round;
const elapsed = minMaxValue(insTime - tween.start - tween.delay, 0, tween.duration) / tween.duration;
const eased = tween.easing(elapsed, tween.elasticity);
const progress = recomposeValue(tween.to.numbers.map((number, p) => {
const start = isPath ? 0 : tween.from.numbers[p];
let value = start + eased * (number - start);
if (isPath) value = getPathProgress(tween.value, value);
if (round) value = Math.round(value * round) / round;
return value;
}), tween.to.strings);
setTweenProgress[anim.type](animatable.target, anim.property, progress, transforms, animatable.id);
anim.currentValue = progress;
i++;
}
if (transforms) {
let id; for (id in transforms) {
if (!transformString) {
const t = 'transform';
transformString = (getCSSValue(document.body, t) ? t : `-webkit-${t}`);
}
instance.animatables[id].target.style[transformString] = transforms[id].join(' ');
}
}
instance.currentTime = insTime;
instance.progress = (insTime / instance.duration) * 100;
}
function setCallback(cb) {
if (instance[cb]) instance[cb](instance);
}
function countIteration() {
if (instance.remaining && instance.remaining !== true) {
instance.remaining--;
}
}
function setInstanceProgress(engineTime) {
const insDuration = instance.duration;
const insOffset = instance.offset;
const insDelay = instance.delay;
const insCurrentTime = instance.currentTime;
const insReversed = instance.reversed;
const insTime = minMaxValue(adjustTime(engineTime), 0, insDuration);
if (insTime > insOffset && insTime < insDuration) {
setAnimationsProgress(insTime);
if (!instance.began && insTime >= insDelay) {
instance.began = true;
setCallback('begin');
}
setCallback('run');
} else {
if (insTime <= insOffset && insCurrentTime !== 0) {
setAnimationsProgress(0);
if (insReversed) countIteration();
}
if (insTime >= insDuration && insCurrentTime !== insDuration) {
setAnimationsProgress(insDuration);
if (!insReversed) countIteration();
}
}
if (engineTime >= insDuration) {
if (instance.remaining) {
startTime = now;
if (instance.direction === 'alternate') toggleInstanceDirection();
} else {
instance.pause();
resolve();
promise = makePromise();
if (!instance.completed) {
instance.completed = true;
setCallback('complete');
}
}
lastTime = 0;
}
if (instance.children) syncInstanceChildren(insTime);
setCallback('update');
}
instance.tick = function(t) {
now = t;
if (!startTime) startTime = now;
const engineTime = (lastTime + now - startTime) * anime.speed;
setInstanceProgress(engineTime);
}
instance.seek = function(time) {
setInstanceProgress(adjustTime(time));
}
instance.pause = function() {
const i = activeInstances.indexOf(instance);
if (i > -1) activeInstances.splice(i, 1);
instance.paused = true;
}
instance.play = function() {
if (!instance.paused) return;
instance.paused = false;
startTime = 0;
lastTime = instance.completed ? 0 : adjustTime(instance.currentTime);
activeInstances.push(instance);
if (!raf) engine();
}
instance.reverse = function() {
toggleInstanceDirection();
startTime = 0;
lastTime = adjustTime(instance.currentTime);
}
instance.restart = function() {
instance.pause();
instance.reset();
instance.play();
}
instance.finished = promise;
instance.reset();
if (instance.autoplay) instance.play();
return instance;
}
// Remove targets from animation
function removeTargets(targets) {
const targetsArray = parseTargets(targets);
for (let i = arrayLength(activeInstances)-1; i >= 0; i--) {
const instance = activeInstances[i];
const animations = instance.animations;
for (let a = arrayLength(animations)-1; a >= 0; a--) {
if (arrayContains(targetsArray, animations[a].animatable.target)) {
animations.splice(a, 1);
if (!arrayLength(animations)) instance.pause();
}
}
}
}
// Timeline
function timeline(params) {
let tl = anime(params);
tl.duration = 0;
tl.children = [];
tl.add = function(instancesParams) {
toArray(instancesParams).forEach(insParams => {
const offset = insParams.offset;
const tlDuration = tl.duration;
insParams.autoplay = false;
insParams.offset = is.und(offset) ? tlDuration : getRelativeValue(offset, tlDuration);
const ins = anime(insParams);
if (ins.duration > tlDuration) tl.duration = ins.duration;
tl.children.push(ins);
});
return tl;
}
return tl;
}
anime.version = '2.0.1';
anime.speed = 1;
anime.running = activeInstances;
anime.remove = removeTargets;
anime.getValue = getOriginalTargetValue;
anime.path = getPath;
anime.setDashoffset = setDashoffset;
anime.bezier = bezier;
anime.easings = easings;
anime.timeline = timeline;
anime.random = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
return anime;
}));

View File

@ -0,0 +1,875 @@
/**
* http://anime-js.com
* JavaScript animation engine
* @version v2.0.2
* @author Julian Garnier
* @copyright ©2017 Julian Garnier
* Released under the MIT license
**/
(function(root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define([], factory);
} else if (typeof module === 'object' && module.exports) {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like environments that support module.exports,
// like Node.
module.exports = factory();
} else {
// Browser globals (root is window)
root.anime = factory();
}
}(this, () => {
// Defaults
const defaultInstanceSettings = {
update: undefined,
begin: undefined,
run: undefined,
complete: undefined,
loop: 1,
direction: 'normal',
autoplay: true,
offset: 0
}
const defaultTweenSettings = {
duration: 1000,
delay: 0,
easing: 'easeOutElastic',
elasticity: 500,
round: 0
}
const validTransforms = ['translateX', 'translateY', 'translateZ', 'rotate', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scaleX', 'scaleY', 'scaleZ', 'skewX', 'skewY'];
let transformString;
// Utils
function stringContains(str, text) {
return str.indexOf(text) > -1;
}
const is = {
arr: a => Array.isArray(a),
obj: a => stringContains(Object.prototype.toString.call(a), 'Object'),
svg: a => a instanceof SVGElement,
dom: a => a.nodeType || is.svg(a),
str: a => typeof a === 'string',
fnc: a => typeof a === 'function',
und: a => typeof a === 'undefined',
hex: a => /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(a),
rgb: a => /^rgb/.test(a),
hsl: a => /^hsl/.test(a),
col: a => (is.hex(a) || is.rgb(a) || is.hsl(a))
}
// BezierEasing https://github.com/gre/bezier-easing
const bezier = (() => {
const kSplineTableSize = 11;
const kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
function A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1 };
function B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1 };
function C (aA1) { return 3.0 * aA1 };
function calcBezier (aT, aA1, aA2) { return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT };
function getSlope (aT, aA1, aA2) { return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1) };
function binarySubdivide (aX, aA, aB, mX1, mX2) {
let currentX, currentT, i = 0;
do {
currentT = aA + (aB - aA) / 2.0;
currentX = calcBezier(currentT, mX1, mX2) - aX;
if (currentX > 0.0) { aB = currentT } else { aA = currentT };
} while (Math.abs(currentX) > 0.0000001 && ++i < 10);
return currentT;
}
function newtonRaphsonIterate (aX, aGuessT, mX1, mX2) {
for (let i = 0; i < 4; ++i) {
const currentSlope = getSlope(aGuessT, mX1, mX2);
if (currentSlope === 0.0) return aGuessT;
const currentX = calcBezier(aGuessT, mX1, mX2) - aX;
aGuessT -= currentX / currentSlope;
}
return aGuessT;
}
function bezier(mX1, mY1, mX2, mY2) {
if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) return;
let sampleValues = new Float32Array(kSplineTableSize);
if (mX1 !== mY1 || mX2 !== mY2) {
for (let i = 0; i < kSplineTableSize; ++i) {
sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
}
}
function getTForX(aX) {
let intervalStart = 0.0;
let currentSample = 1;
const lastSample = kSplineTableSize - 1;
for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) {
intervalStart += kSampleStepSize;
}
--currentSample;
const dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]);
const guessForT = intervalStart + dist * kSampleStepSize;
const initialSlope = getSlope(guessForT, mX1, mX2);
if (initialSlope >= 0.001) {
return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
} else if (initialSlope === 0.0) {
return guessForT;
} else {
return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
}
}
return x => {
if (mX1 === mY1 && mX2 === mY2) return x;
if (x === 0) return 0;
if (x === 1) return 1;
return calcBezier(getTForX(x), mY1, mY2);
}
}
return bezier;
})();
const easings = (() => {
const names = ['Quad', 'Cubic', 'Quart', 'Quint', 'Sine', 'Expo', 'Circ', 'Back', 'Elastic'];
// Elastic easing adapted from jQueryUI http://api.jqueryui.com/easings/
function elastic(t, p) {
return t === 0 || t === 1 ? t :
-Math.pow(2, 10 * (t - 1)) * Math.sin((((t - 1) - (p / (Math.PI * 2.0) * Math.asin(1))) * (Math.PI * 2)) / p );
}
// Approximated Penner equations http://matthewlein.com/ceaser/
const equations = {
In: [
[0.550, 0.085, 0.680, 0.530], /* InQuad */
[0.550, 0.055, 0.675, 0.190], /* InCubic */
[0.895, 0.030, 0.685, 0.220], /* InQuart */
[0.755, 0.050, 0.855, 0.060], /* InQuint */
[0.470, 0.000, 0.745, 0.715], /* InSine */
[0.950, 0.050, 0.795, 0.035], /* InExpo */
[0.600, 0.040, 0.980, 0.335], /* InCirc */
[0.600, -0.280, 0.735, 0.045], /* InBack */
elastic /* InElastic */
], Out: [
[0.250, 0.460, 0.450, 0.940], /* OutQuad */
[0.215, 0.610, 0.355, 1.000], /* OutCubic */
[0.165, 0.840, 0.440, 1.000], /* OutQuart */
[0.230, 1.000, 0.320, 1.000], /* OutQuint */
[0.390, 0.575, 0.565, 1.000], /* OutSine */
[0.190, 1.000, 0.220, 1.000], /* OutExpo */
[0.075, 0.820, 0.165, 1.000], /* OutCirc */
[0.175, 0.885, 0.320, 1.275], /* OutBack */
(t, f) => 1 - elastic(1 - t, f) /* OutElastic */
], InOut: [
[0.455, 0.030, 0.515, 0.955], /* InOutQuad */
[0.645, 0.045, 0.355, 1.000], /* InOutCubic */
[0.770, 0.000, 0.175, 1.000], /* InOutQuart */
[0.860, 0.000, 0.070, 1.000], /* InOutQuint */
[0.445, 0.050, 0.550, 0.950], /* InOutSine */
[1.000, 0.000, 0.000, 1.000], /* InOutExpo */
[0.785, 0.135, 0.150, 0.860], /* InOutCirc */
[0.680, -0.550, 0.265, 1.550], /* InOutBack */
(t, f) => t < .5 ? elastic(t * 2, f) / 2 : 1 - elastic(t * -2 + 2, f) / 2 /* InOutElastic */
]
}
let functions = {
linear: bezier(0.250, 0.250, 0.750, 0.750)
}
for (let type in equations) {
equations[type].forEach((f, i) => {
functions['ease'+type+names[i]] = is.fnc(f) ? f : bezier.apply(this, f);
});
}
return functions;
})();
// Strings
function stringToHyphens(str) {
return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
}
function selectString(str) {
if (is.col(str)) return;
try {
let nodes = document.querySelectorAll(str);
return nodes;
} catch(e) {
return;
}
}
// Arrays
function arrayLength(arr) {
return arr.length;
}
function flattenArray(arr) {
return arr.reduce((a, b) => a.concat(is.arr(b) ? flattenArray(b) : b), []);
}
function toArray(o) {
if (is.arr(o)) return o;
if (is.str(o)) o = selectString(o) || o;
if (o instanceof NodeList || o instanceof HTMLCollection) return [].slice.call(o);
return [o];
}
// Objects
function objectHas(obj, prop) {
return obj.hasOwnProperty(prop);
}
function cloneObject(o) {
let clone = {};
for (let p in o) clone[p] = o[p];
return clone;
}
function replaceObjectProps(o1, o2) {
let o = cloneObject(o1);
for (let p in o1) o[p] = objectHas(o2, p) ? o2[p] : o1[p];
return o;
}
function mergeObjects(o1, o2) {
let o = cloneObject(o1);
for (let p in o2) o[p] = is.und(o1[p]) ? o2[p] : o1[p];
return o;
}
// Colors
function hexToRgb(hexValue) {
const rgx = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
const hex = hexValue.replace(rgx, (m, r, g, b) => r + r + g + g + b + b );
const rgb = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
const r = parseInt(rgb[1], 16);
const g = parseInt(rgb[2], 16);
const b = parseInt(rgb[3], 16);
return `rgb(${r},${g},${b})`;
}
function hslToRgb(hslValue) {
const hsl = /hsl\((\d+),\s*([\d.]+)%,\s*([\d.]+)%\)/g.exec(hslValue);
const h = parseInt(hsl[1]) / 360;
const s = parseInt(hsl[2]) / 100;
const l = parseInt(hsl[3]) / 100;
function hue2rgb(p, q, t) {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1/6) return p + (q - p) * 6 * t;
if (t < 1/2) return q;
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
}
let r, g, b;
if (s == 0) {
r = g = b = l;
} else {
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
r = hue2rgb(p, q, h + 1/3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3);
}
return `rgb(${r * 255},${g * 255},${b * 255})`;
}
function colorToRgb(val) {
if (is.rgb(val)) return val;
if (is.hex(val)) return hexToRgb(val);
if (is.hsl(val)) return hslToRgb(val);
}
// Units
function getUnit(val) {
const split = /([\+\-]?[0-9#\.]+)(%|px|pt|em|rem|in|cm|mm|ex|pc|vw|vh|deg|rad|turn)?/.exec(val);
if (split) return split[2];
// if (split && split[2] && val.indexOf(split[2], arrayLength(val) - arrayLength(split[2])) !== -1) return split[2];
}
function getTransformUnit(propName) {
if (stringContains(propName, 'translate')) return 'px';
if (stringContains(propName, 'rotate') || stringContains(propName, 'skew')) return 'deg';
}
// Values
function parseFloatValue(val) {
return parseFloat(val);
}
function minMaxValue(val, min, max) {
return Math.min(Math.max(val, min), max);
}
function getFunctionValue(val, animatable) {
if (!is.fnc(val)) return val;
return val(animatable.target, animatable.id, animatable.total);
}
function getCSSValue(el, prop) {
if (prop in el.style) {
return getComputedStyle(el).getPropertyValue(stringToHyphens(prop)) || '0';
}
}
function getAnimationType(el, prop) {
const isDom = is.dom(el);
if (isDom && validTransforms.some(a => a === prop)) return 'transform';
if (isDom && (el.getAttribute(prop) || (is.svg(el) && el[prop]))) return 'attribute';
if (isDom && (prop !== 'transform' && (prop in el.style))) return 'css';
if (el[prop] != null) return 'object';
}
function getTransformValue(el, propName) {
const defaultUnit = getTransformUnit(propName);
const defaultVal = stringContains(propName, 'scale') ? 1 : 0 + defaultUnit;
const str = el.style.transform;
if (!str) return defaultVal;
let match = [];
let props = [];
let values = [];
const rgx = /(\w+)\((.+?)\)/g;
while (match = rgx.exec(str)) {
props.push(match[1]);
values.push(match[2]);
}
const value = values.filter((val, i) => props[i] === propName );
return arrayLength(value) ? value[0] : defaultVal;
}
function getOriginalTargetValue(target, propName) {
switch (getAnimationType(target, propName)) {
case 'transform': return getTransformValue(target, propName);
case 'css': return getCSSValue(target, propName);
case 'attribute': return target.getAttribute(propName);
}
return target[propName] || 0;
}
function getRelativeValue(to, from) {
const operator = /^(\*=|\+=|-=)/.exec(to);
if (!operator) return to;
const x = parseFloatValue(from);
const y = parseFloatValue(to.replace(operator[0], ''));
switch (operator[0][0]) {
case '+': return x + y;
case '-': return x - y;
case '*': return x * y;
}
}
function validateValue(val, unit) {
if (is.col(val)) return colorToRgb(val);
return unit && !isNaN(val) ? val + unit : val;
}
// Motion path
function isPath(val) {
return is.obj(val) && objectHas(val, 'totalLength');
}
function setDashoffset(el) {
const pathLength = el.getTotalLength();
el.setAttribute('stroke-dasharray', pathLength);
return pathLength;
}
function getPath(path, percent) {
const el = is.str(path) ? selectString(path)[0] : path;
const p = percent || 100;
return function(prop) {
return {
el: el,
property: prop,
totalLength: el.getTotalLength() * (p / 100)
}
}
}
function getPathProgress(path, progress) {
function point(offset = 0) {
const l = progress + offset >= 1 ? progress + offset : 0;
return path.el.getPointAtLength(l);
}
const p = point();
const p0 = point(-1);
const p1 = point(+1);
switch (path.property) {
case 'x': return p.x;
case 'y': return p.y;
case 'angle': return Math.atan2(p1.y - p0.y, p1.x - p0.x) * 180 / Math.PI;
}
}
// Decompose / recompose functions adapted from Animate Plus https://github.com/bendc/animateplus
function decomposeValue(val, unit) {
const rgx = /-?\d*\.?\d+/g;
const value = validateValue((isPath(val) ? val.totalLength : val), unit);
return {
original: value,
numbers: !is.str(value) ? [value] : value.match(rgx) ? value.match(rgx).map(Number) : [0],
strings: is.str(value) ? value.split(rgx) : [0, 0]
}
}
function recomposeValue(numbers, strings) {
return strings.reduce((a, b, i) => a + numbers[i - 1] + b);
}
// Animatables
function parseTargets(targets) {
const targetsArray = targets ? (flattenArray(is.arr(targets) ? targets.map(toArray) : toArray(targets))) : [];
return targetsArray.filter((item, pos, self) => self.indexOf(item) === pos);
}
function getAnimatables(targets) {
const parsed = parseTargets(targets);
return parsed.map((t, i) => {
return {target: t, id: i, total: arrayLength(parsed)};
});
}
// Properties
function normalizePropertyTweens(prop, tweenSettings) {
let settings = cloneObject(tweenSettings);
if (is.arr(prop)) {
const l = arrayLength(prop);
const isFromTo = (l === 2 && !is.obj(prop[0]));
if (!isFromTo) {
// Duration divided by the number of tweens
if (!is.fnc(tweenSettings.duration)) settings.duration = tweenSettings.duration / l;
} else {
// Transform [from, to] values shorthand to a valid tween value
prop = {value: prop};
}
}
return toArray(prop).map((v, i) => {
// Default delay value should be applied only on the first tween
const delay = !i ? tweenSettings.delay : 0;
// Use path object as a tween value
let obj = is.obj(v) && !isPath(v) ? v : {value: v};
// Set default delay value
if (is.und(obj.delay)) obj.delay = delay;
return obj;
}).map(k => mergeObjects(k, settings));
}
function getProperties(instanceSettings, tweenSettings, params) {
let properties = [];
const settings = mergeObjects(instanceSettings, tweenSettings);
for (let p in params) {
if (!objectHas(settings, p) && p !== 'targets') {
properties.push({
name: p,
offset: settings['offset'],
tweens: normalizePropertyTweens(params[p], tweenSettings)
});
}
}
return properties;
}
// Tweens
function normalizeTweenValues(tween, animatable) {
let t = {};
for (let p in tween) {
let value = getFunctionValue(tween[p], animatable);
if (is.arr(value)) {
value = value.map(v => getFunctionValue(v, animatable));
if (arrayLength(value) === 1) value = value[0];
}
t[p] = value;
}
t.duration = parseFloatValue(t.duration);
t.delay = parseFloatValue(t.delay);
return t;
}
function normalizeEasing(val) {
return is.arr(val) ? bezier.apply(this, val) : easings[val];
}
function normalizeTweens(prop, animatable) {
let previousTween;
return prop.tweens.map(t => {
let tween = normalizeTweenValues(t, animatable);
const tweenValue = tween.value;
const originalValue = getOriginalTargetValue(animatable.target, prop.name);
const previousValue = previousTween ? previousTween.to.original : originalValue;
const from = is.arr(tweenValue) ? tweenValue[0] : previousValue;
const to = getRelativeValue(is.arr(tweenValue) ? tweenValue[1] : tweenValue, from);
const unit = getUnit(to) || getUnit(from) || getUnit(originalValue);
tween.isPath = isPath(tweenValue);
tween.from = decomposeValue(from, unit);
tween.to = decomposeValue(to, unit);
tween.start = previousTween ? previousTween.end : prop.offset;
tween.end = tween.start + tween.delay + tween.duration;
tween.easing = normalizeEasing(tween.easing);
tween.elasticity = (1000 - minMaxValue(tween.elasticity, 1, 999)) / 1000;
if (is.col(tween.from.original)) tween.round = 1;
previousTween = tween;
return tween;
});
}
// Tween progress
const setTweenProgress = {
css: (t, p, v) => t.style[p] = v,
attribute: (t, p, v) => t.setAttribute(p, v),
object: (t, p, v) => t[p] = v,
transform: (t, p, v, transforms, id) => {
if (!transforms[id]) transforms[id] = [];
transforms[id].push(`${p}(${v})`);
}
}
// Animations
function createAnimation(animatable, prop) {
const animType = getAnimationType(animatable.target, prop.name);
if (animType) {
const tweens = normalizeTweens(prop, animatable);
return {
type: animType,
property: prop.name,
animatable: animatable,
tweens: tweens,
duration: tweens[arrayLength(tweens) - 1].end,
delay: tweens[0].delay
}
}
}
function getAnimations(animatables, properties) {
return flattenArray(animatables.map(animatable => {
return properties.map(prop => {
return createAnimation(animatable, prop);
});
})).filter(a => !is.und(a));
}
// Create Instance
function getInstanceTimings(type, animations, tweenSettings) {
const math = (type === 'delay') ? Math.min : Math.max;
return arrayLength(animations) ? math.apply(Math, animations.map(anim => anim[type])) : tweenSettings[type];
}
function createNewInstance(params) {
const instanceSettings = replaceObjectProps(defaultInstanceSettings, params);
const tweenSettings = replaceObjectProps(defaultTweenSettings, params);
const animatables = getAnimatables(params.targets);
const properties = getProperties(instanceSettings, tweenSettings, params);
const animations = getAnimations(animatables, properties);
return mergeObjects(instanceSettings, {
animatables: animatables,
animations: animations,
duration: getInstanceTimings('duration', animations, tweenSettings),
delay: getInstanceTimings('delay', animations, tweenSettings)
});
}
// Core
let activeInstances = [];
let raf = 0;
const engine = (() => {
function play() { raf = requestAnimationFrame(step); };
function step(t) {
const activeLength = arrayLength(activeInstances);
if (activeLength) {
let i = 0;
while (i < activeLength) {
if (activeInstances[i]) activeInstances[i].tick(t);
i++;
}
play();
} else {
cancelAnimationFrame(raf);
raf = 0;
}
}
return play;
})();
// Public Instance
function anime(params = {}) {
let now, startTime, lastTime = 0;
let resolve = null;
function makePromise() {
return window.Promise && new Promise(_resolve => resolve = _resolve);
}
let promise = makePromise();
let instance = createNewInstance(params);
instance.reset = function() {
const direction = instance.direction;
const loops = instance.loop;
instance.currentTime = 0;
instance.progress = 0;
instance.paused = true;
instance.began = false;
instance.completed = false;
instance.reversed = direction === 'reverse';
instance.remaining = direction === 'alternate' && loops === 1 ? 2 : loops;
}
function toggleInstanceDirection() {
instance.reversed = !instance.reversed;
}
function adjustTime(time) {
return instance.reversed ? instance.duration - time : time;
}
function syncInstanceChildren(insTime) {
let i = 0;
const children = instance.children;
while (i < arrayLength(children)) {
children[i].seek(insTime);
i++;
}
}
function setAnimationsProgress(insTime) {
let i = 0;
let transforms = {};
const animations = instance.animations;
while (i < arrayLength(animations)) {
const anim = animations[i];
const animatable = anim.animatable;
const tweens = anim.tweens;
const tween = tweens.filter(t => (insTime < t.end))[0] || tweens[arrayLength(tweens) - 1];
const isPath = tween.isPath;
const round = tween.round;
const elapsed = minMaxValue(insTime - tween.start - tween.delay, 0, tween.duration) / tween.duration;
const eased = tween.easing(elapsed, tween.elasticity);
const progress = recomposeValue(tween.to.numbers.map((number, p) => {
const start = isPath ? 0 : tween.from.numbers[p];
let value = start + eased * (number - start);
if (isPath) value = getPathProgress(tween.value, value);
if (round) value = Math.round(value * round) / round;
return value;
}), tween.to.strings);
setTweenProgress[anim.type](animatable.target, anim.property, progress, transforms, animatable.id);
anim.currentValue = progress;
i++;
}
if (transforms) {
let id; for (id in transforms) {
if (!transformString) {
const t = 'transform';
transformString = (getCSSValue(document.body, t) ? t : `-webkit-${t}`);
}
instance.animatables[id].target.style[transformString] = transforms[id].join(' ');
}
}
instance.currentTime = insTime;
instance.progress = (insTime / instance.duration) * 100;
}
function setCallback(cb) {
if (instance[cb]) instance[cb](instance);
}
function setInstanceProgress(engineTime) {
const insDuration = instance.duration;
const insOffset = instance.offset;
const insDelay = instance.delay;
const insCurrentTime = instance.currentTime;
const insRemaining = instance.remaining;
const insReversed = instance.reversed;
const insTime = minMaxValue(adjustTime(engineTime), 0, insDuration);
if (insTime >= insOffset && insTime <= insDuration) {
setAnimationsProgress(insTime);
if (!instance.began && insTime >= insDelay) {
instance.began = true;
setCallback('begin');
}
setCallback('run');
}
if (insRemaining && insRemaining !== true) {
if (
(insReversed && insTime === insOffset && insCurrentTime !== 0) ||
(!insReversed && insTime === insDuration && insCurrentTime !== insDuration)) {
instance.remaining--;
}
}
if (engineTime >= insDuration) {
if (instance.remaining) {
startTime = now;
if (instance.direction === 'alternate') toggleInstanceDirection();
} else {
instance.pause();
resolve();
promise = makePromise();
if (!instance.completed) {
instance.completed = true;
setCallback('complete');
}
}
lastTime = 0;
}
if (instance.children) syncInstanceChildren(insTime);
setCallback('update');
}
instance.tick = function(t) {
now = t;
if (!startTime) startTime = now;
const engineTime = (lastTime + now - startTime) * anime.speed;
setInstanceProgress(engineTime);
}
instance.seek = function(time) {
setInstanceProgress(adjustTime(time));
}
instance.pause = function() {
const i = activeInstances.indexOf(instance);
if (i > -1) activeInstances.splice(i, 1);
instance.paused = true;
}
instance.play = function() {
if (!instance.paused) return;
instance.paused = false;
startTime = 0;
lastTime = instance.completed ? 0 : adjustTime(instance.currentTime);
activeInstances.push(instance);
if (!raf) engine();
}
instance.reverse = function() {
toggleInstanceDirection();
startTime = 0;
lastTime = adjustTime(instance.currentTime);
}
instance.restart = function() {
instance.pause();
instance.reset();
instance.play();
}
instance.finished = promise;
instance.reset();
if (instance.autoplay) instance.play();
return instance;
}
// Remove targets from animation
function removeTargets(targets) {
const targetsArray = parseTargets(targets);
for (let i = arrayLength(activeInstances)-1; i >= 0; i--) {
const instance = activeInstances[i];
const animations = instance.animations;
for (let a = arrayLength(animations)-1; a >= 0; a--) {
if (targetsArray.some(t => t === animations[a].animatable.target)) {
animations.splice(a, 1);
if (!arrayLength(animations)) instance.pause();
}
}
}
}
// Timeline
function timeline(params) {
let tl = anime(params);
tl.duration = 0;
tl.children = [];
tl.add = function(instancesParams) {
tl.children.forEach( i => { i.began = true; i.completed = true; });
toArray(instancesParams).forEach(insParams => {
const tlDuration = tl.duration;
const insOffset = insParams.offset;
insParams.autoplay = false;
insParams.offset = is.und(insOffset) ? tlDuration : getRelativeValue(insOffset, tlDuration);
tl.seek(insParams.offset);
const ins = anime(insParams);
if (ins.duration > tlDuration) tl.duration = ins.duration;
ins.began = true;
tl.children.push(ins);
});
tl.seek(0);
tl.reset();
for (let i = tl.children.length; i--; ){
const child = tl.children[i];
child.seek(child.offset);
child.reset();
}
if (tl.autoplay) tl.play();
return tl;
}
return tl;
}
anime.version = '2.0.2';
anime.speed = 1;
anime.running = activeInstances;
anime.remove = removeTargets;
anime.getValue = getOriginalTargetValue;
anime.path = getPath;
anime.setDashoffset = setDashoffset;
anime.bezier = bezier;
anime.easings = easings;
anime.timeline = timeline;
anime.random = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
return anime;
}));

View File

@ -0,0 +1,939 @@
/**
* https://animejs.com
* JavaScript animation engine
* @version v2.1.0
* @author Julian Garnier
* @copyright ©2017 Julian Garnier
* Released under the MIT license
**/
(function(root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define([], factory);
} else if (typeof module === 'object' && module.exports) {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like environments that support module.exports,
// like Node.
module.exports = factory();
} else {
// Browser globals (root is window)
root.anime = factory();
}
}(this, () => {
// Defaults
const defaultInstanceSettings = {
update: undefined,
begin: undefined,
run: undefined,
complete: undefined,
loop: 1,
direction: 'normal',
autoplay: true,
offset: 0
}
const defaultTweenSettings = {
duration: 1000,
delay: 0,
easing: 'easeOutElastic',
elasticity: 500,
round: 0
}
const validTransforms = ['translateX', 'translateY', 'translateZ', 'rotate', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scaleX', 'scaleY', 'scaleZ', 'skewX', 'skewY', 'perspective'];
let transformString;
// Utils
function stringContains(str, text) {
return str.indexOf(text) > -1;
}
const is = {
arr: a => Array.isArray(a),
obj: a => stringContains(Object.prototype.toString.call(a), 'Object'),
svg: a => a instanceof SVGElement,
dom: a => a.nodeType || is.svg(a),
str: a => typeof a === 'string',
fnc: a => typeof a === 'function',
und: a => typeof a === 'undefined',
hex: a => /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(a),
rgb: a => /^rgb/.test(a),
hsl: a => /^hsl/.test(a),
col: a => (is.hex(a) || is.rgb(a) || is.hsl(a))
}
// BezierEasing https://github.com/gre/bezier-easing
const bezier = (() => {
const kSplineTableSize = 11;
const kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
function A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1 };
function B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1 };
function C (aA1) { return 3.0 * aA1 };
function calcBezier (aT, aA1, aA2) { return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT };
function getSlope (aT, aA1, aA2) { return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1) };
function binarySubdivide (aX, aA, aB, mX1, mX2) {
let currentX, currentT, i = 0;
do {
currentT = aA + (aB - aA) / 2.0;
currentX = calcBezier(currentT, mX1, mX2) - aX;
if (currentX > 0.0) { aB = currentT } else { aA = currentT };
} while (Math.abs(currentX) > 0.0000001 && ++i < 10);
return currentT;
}
function newtonRaphsonIterate (aX, aGuessT, mX1, mX2) {
for (let i = 0; i < 4; ++i) {
const currentSlope = getSlope(aGuessT, mX1, mX2);
if (currentSlope === 0.0) return aGuessT;
const currentX = calcBezier(aGuessT, mX1, mX2) - aX;
aGuessT -= currentX / currentSlope;
}
return aGuessT;
}
function bezier(mX1, mY1, mX2, mY2) {
if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) return;
let sampleValues = new Float32Array(kSplineTableSize);
if (mX1 !== mY1 || mX2 !== mY2) {
for (let i = 0; i < kSplineTableSize; ++i) {
sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
}
}
function getTForX(aX) {
let intervalStart = 0.0;
let currentSample = 1;
const lastSample = kSplineTableSize - 1;
for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) {
intervalStart += kSampleStepSize;
}
--currentSample;
const dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]);
const guessForT = intervalStart + dist * kSampleStepSize;
const initialSlope = getSlope(guessForT, mX1, mX2);
if (initialSlope >= 0.001) {
return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
} else if (initialSlope === 0.0) {
return guessForT;
} else {
return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
}
}
return x => {
if (mX1 === mY1 && mX2 === mY2) return x;
if (x === 0) return 0;
if (x === 1) return 1;
return calcBezier(getTForX(x), mY1, mY2);
}
}
return bezier;
})();
const easings = (() => {
const names = ['Quad', 'Cubic', 'Quart', 'Quint', 'Sine', 'Expo', 'Circ', 'Back', 'Elastic'];
// Elastic easing adapted from jQueryUI http://api.jqueryui.com/easings/
function elastic(t, p) {
return t === 0 || t === 1 ? t :
-Math.pow(2, 10 * (t - 1)) * Math.sin((((t - 1) - (p / (Math.PI * 2.0) * Math.asin(1))) * (Math.PI * 2)) / p );
}
// Approximated Penner equations http://matthewlein.com/ceaser/
const equations = {
In: [
[0.550, 0.085, 0.680, 0.530], /* InQuad */
[0.550, 0.055, 0.675, 0.190], /* InCubic */
[0.895, 0.030, 0.685, 0.220], /* InQuart */
[0.755, 0.050, 0.855, 0.060], /* InQuint */
[0.470, 0.000, 0.745, 0.715], /* InSine */
[0.950, 0.050, 0.795, 0.035], /* InExpo */
[0.600, 0.040, 0.980, 0.335], /* InCirc */
[0.600, -0.280, 0.735, 0.045], /* InBack */
elastic /* InElastic */
], Out: [
[0.250, 0.460, 0.450, 0.940], /* OutQuad */
[0.215, 0.610, 0.355, 1.000], /* OutCubic */
[0.165, 0.840, 0.440, 1.000], /* OutQuart */
[0.230, 1.000, 0.320, 1.000], /* OutQuint */
[0.390, 0.575, 0.565, 1.000], /* OutSine */
[0.190, 1.000, 0.220, 1.000], /* OutExpo */
[0.075, 0.820, 0.165, 1.000], /* OutCirc */
[0.175, 0.885, 0.320, 1.275], /* OutBack */
(t, f) => 1 - elastic(1 - t, f) /* OutElastic */
], InOut: [
[0.455, 0.030, 0.515, 0.955], /* InOutQuad */
[0.645, 0.045, 0.355, 1.000], /* InOutCubic */
[0.770, 0.000, 0.175, 1.000], /* InOutQuart */
[0.860, 0.000, 0.070, 1.000], /* InOutQuint */
[0.445, 0.050, 0.550, 0.950], /* InOutSine */
[1.000, 0.000, 0.000, 1.000], /* InOutExpo */
[0.785, 0.135, 0.150, 0.860], /* InOutCirc */
[0.680, -0.550, 0.265, 1.550], /* InOutBack */
(t, f) => t < .5 ? elastic(t * 2, f) / 2 : 1 - elastic(t * -2 + 2, f) / 2 /* InOutElastic */
]
}
let functions = {
linear: bezier(0.250, 0.250, 0.750, 0.750)
}
for (let type in equations) {
equations[type].forEach((f, i) => {
functions['ease'+type+names[i]] = is.fnc(f) ? f : bezier.apply(this, f);
});
}
return functions;
})();
// Strings
function stringToHyphens(str) {
return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
}
function selectString(str) {
if (is.col(str)) return;
try {
let nodes = document.querySelectorAll(str);
return nodes;
} catch(e) {
return;
}
}
// Arrays
function flattenArray(arr) {
return arr.reduce((a, b) => a.concat(is.arr(b) ? flattenArray(b) : b), []);
}
function toArray(o) {
if (is.arr(o)) return o;
if (is.str(o)) o = selectString(o) || o;
if (o instanceof NodeList || o instanceof HTMLCollection) return [].slice.call(o);
return [o];
}
function arrayContains(arr, val) {
return arr.some(a => a === val);
}
// Objects
function objectHas(obj, prop) {
return obj.hasOwnProperty(prop);
}
function cloneObject(o) {
let clone = {};
for (let p in o) clone[p] = o[p];
return clone;
}
function replaceObjectProps(o1, o2) {
let o = cloneObject(o1);
for (let p in o1) o[p] = objectHas(o2, p) ? o2[p] : o1[p];
return o;
}
function mergeObjects(o1, o2) {
let o = cloneObject(o1);
for (let p in o2) o[p] = is.und(o1[p]) ? o2[p] : o1[p];
return o;
}
// Colors
function hexToRgb(hexValue) {
const rgx = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
const hex = hexValue.replace(rgx, (m, r, g, b) => r + r + g + g + b + b );
const rgb = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
const r = parseInt(rgb[1], 16);
const g = parseInt(rgb[2], 16);
const b = parseInt(rgb[3], 16);
return `rgb(${r},${g},${b})`;
}
function hslToRgb(hslValue) {
const hsl = /hsl\((\d+),\s*([\d.]+)%,\s*([\d.]+)%\)/g.exec(hslValue);
const h = parseInt(hsl[1]) / 360;
const s = parseInt(hsl[2]) / 100;
const l = parseInt(hsl[3]) / 100;
function hue2rgb(p, q, t) {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1/6) return p + (q - p) * 6 * t;
if (t < 1/2) return q;
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
}
let r, g, b;
if (s == 0) {
r = g = b = l;
} else {
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
r = hue2rgb(p, q, h + 1/3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3);
}
return `rgb(${r * 255},${g * 255},${b * 255})`;
}
function colorToRgb(val) {
if (is.rgb(val)) return val;
if (is.hex(val)) return hexToRgb(val);
if (is.hsl(val)) return hslToRgb(val);
}
// Units
function getUnit(val) {
const split = /([\+\-]?[0-9#\.]+)(%|px|pt|em|rem|in|cm|mm|ex|ch|pc|vw|vh|vmin|vmax|deg|rad|turn)?$/.exec(val);
if (split) return split[2];
}
function getTransformUnit(propName) {
if (stringContains(propName, 'translate') || propName === 'perspective') return 'px';
if (stringContains(propName, 'rotate') || stringContains(propName, 'skew')) return 'deg';
}
// Values
function minMaxValue(val, min, max) {
return Math.min(Math.max(val, min), max);
}
function getFunctionValue(val, animatable) {
if (!is.fnc(val)) return val;
return val(animatable.target, animatable.id, animatable.total);
}
function getCSSValue(el, prop) {
if (prop in el.style) {
return getComputedStyle(el).getPropertyValue(stringToHyphens(prop)) || '0';
}
}
function getAnimationType(el, prop) {
if (is.dom(el) && arrayContains(validTransforms, prop)) return 'transform';
if (is.dom(el) && (el.getAttribute(prop) || (is.svg(el) && el[prop]))) return 'attribute';
if (is.dom(el) && (prop !== 'transform' && getCSSValue(el, prop))) return 'css';
if (el[prop] != null) return 'object';
}
function getTransformValue(el, propName) {
const defaultUnit = getTransformUnit(propName);
const defaultVal = stringContains(propName, 'scale') ? 1 : 0 + defaultUnit;
const str = el.style.transform;
if (!str) return defaultVal;
let match = [];
let props = [];
let values = [];
const rgx = /(\w+)\((.+?)\)/g;
while (match = rgx.exec(str)) {
props.push(match[1]);
values.push(match[2]);
}
const value = values.filter((val, i) => props[i] === propName );
return value.length ? value[0] : defaultVal;
}
function getOriginalTargetValue(target, propName) {
switch (getAnimationType(target, propName)) {
case 'transform': return getTransformValue(target, propName);
case 'css': return getCSSValue(target, propName);
case 'attribute': return target.getAttribute(propName);
}
return target[propName] || 0;
}
function getRelativeValue(to, from) {
const operator = /^(\*=|\+=|-=)/.exec(to);
if (!operator) return to;
const u = getUnit(to) || 0;
const x = parseFloat(from);
const y = parseFloat(to.replace(operator[0], ''));
switch (operator[0][0]) {
case '+': return x + y + u;
case '-': return x - y + u;
case '*': return x * y + u;
}
}
function validateValue(val, unit) {
if (is.col(val)) return colorToRgb(val);
const originalUnit = getUnit(val);
const unitLess = originalUnit ? val.substr(0, val.length - originalUnit.length) : val;
return unit && !/\s/g.test(val) ? unitLess + unit : unitLess;
}
// getTotalLength() equivalent for circle, rect, polyline, polygon and line shapes.
// adapted from https://gist.github.com/SebLambla/3e0550c496c236709744
function getDistance(p1, p2) {
return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));
}
function getCircleLength(el) {
return 2 * Math.PI * el.getAttribute('r');
}
function getRectLength(el) {
return (el.getAttribute('width') * 2) + (el.getAttribute('height') * 2);
}
function getLineLength(el) {
return getDistance(
{x: el.getAttribute('x1'), y: el.getAttribute('y1')},
{x: el.getAttribute('x2'), y: el.getAttribute('y2')}
);
}
function getPolylineLength(el) {
const points = el.points;
let totalLength = 0;
let previousPos;
for (let i = 0 ; i < points.numberOfItems; i++) {
const currentPos = points.getItem(i);
if (i > 0) totalLength += getDistance(previousPos, currentPos);
previousPos = currentPos;
}
return totalLength;
}
function getPolygonLength(el) {
const points = el.points;
return getPolylineLength(el) + getDistance(points.getItem(points.numberOfItems - 1), points.getItem(0));
}
// Path animation
function getTotalLength(el) {
if (el.getTotalLength) return el.getTotalLength();
switch(el.tagName.toLowerCase()) {
case 'circle': return getCircleLength(el);
case 'rect': return getRectLength(el);
case 'line': return getLineLength(el);
case 'polyline': return getPolylineLength(el);
case 'polygon': return getPolygonLength(el);
}
}
function setDashoffset(el) {
const pathLength = getTotalLength(el);
el.setAttribute('stroke-dasharray', pathLength);
return pathLength;
}
// Motion path
function isPath(val) {
return is.obj(val) && objectHas(val, 'totalLength');
}
function getPath(path, percent) {
const el = is.str(path) ? selectString(path)[0] : path;
const p = percent || 100;
return function(prop) {
return {
el: el,
property: prop,
totalLength: getTotalLength(el) * (p / 100)
}
}
}
function getPathProgress(path, progress) {
function point(offset = 0) {
const l = progress + offset >= 1 ? progress + offset : 0;
return path.el.getPointAtLength(l);
}
const p = point();
const p0 = point(-1);
const p1 = point(+1);
switch (path.property) {
case 'x': return p.x;
case 'y': return p.y;
case 'angle': return Math.atan2(p1.y - p0.y, p1.x - p0.x) * 180 / Math.PI;
}
}
// Decompose / recompose functions adapted from Animate Plus https://github.com/bendc/animateplus
function decomposeValue(val, unit) {
const rgx = /-?\d*\.?\d+/g;
const value = validateValue((isPath(val) ? val.totalLength : val), unit) + '';
return {
original: value,
numbers: value.match(rgx) ? value.match(rgx).map(Number) : [0],
strings: (is.str(val) || unit) ? value.split(rgx) : []
}
}
function recomposeValue(numbers, strings) {
return (strings.length === 0) ? numbers[0] : strings.reduce((a, b, i) => a + numbers[i - 1] + (b ? b : ' '));
}
// Animatables
function parseTargets(targets) {
const targetsArray = targets ? (flattenArray(is.arr(targets) ? targets.map(toArray) : toArray(targets))) : [];
return targetsArray.filter((item, pos, self) => self.indexOf(item) === pos);
}
function getAnimatables(targets) {
const parsed = parseTargets(targets);
return parsed.map((t, i) => {
return {target: t, id: i, total: parsed.length};
});
}
// Properties
function normalizePropertyTweens(prop, tweenSettings) {
let settings = cloneObject(tweenSettings);
if (is.arr(prop)) {
const l = prop.length;
const isFromTo = (l === 2 && !is.obj(prop[0]));
if (!isFromTo) {
// Duration divided by the number of tweens
if (!is.fnc(tweenSettings.duration)) settings.duration = tweenSettings.duration / l;
} else {
// Transform [from, to] values shorthand to a valid tween value
prop = {value: prop};
}
}
return toArray(prop).map((v, i) => {
// Default delay value should be applied only on the first tween
const delay = !i ? tweenSettings.delay : 0;
// Use path object as a tween value
let obj = is.obj(v) && !isPath(v) ? v : {value: v};
// Set default delay value
if (is.und(obj.delay)) obj.delay = delay;
return obj;
}).map(k => mergeObjects(k, settings));
}
function getProperties(instanceSettings, tweenSettings, params) {
let properties = [];
const settings = mergeObjects(instanceSettings, tweenSettings);
for (let p in params) {
if (!objectHas(settings, p) && p !== 'targets') {
properties.push({
name: p,
offset: settings['offset'],
tweens: normalizePropertyTweens(params[p], tweenSettings)
});
}
}
return properties;
}
// Tweens
function normalizeTweenValues(tween, animatable) {
let t = {};
for (let p in tween) {
let value = getFunctionValue(tween[p], animatable);
if (is.arr(value)) {
value = value.map(v => getFunctionValue(v, animatable));
if (value.length === 1) value = value[0];
}
t[p] = value;
}
t.duration = parseFloat(t.duration);
t.delay = parseFloat(t.delay);
return t;
}
function normalizeEasing(val) {
return is.arr(val) ? bezier.apply(this, val) : easings[val];
}
function normalizeTweens(prop, animatable) {
let previousTween;
return prop.tweens.map(t => {
let tween = normalizeTweenValues(t, animatable);
const tweenValue = tween.value;
const originalValue = getOriginalTargetValue(animatable.target, prop.name);
const previousValue = previousTween ? previousTween.to.original : originalValue;
const from = is.arr(tweenValue) ? tweenValue[0] : previousValue;
const to = getRelativeValue(is.arr(tweenValue) ? tweenValue[1] : tweenValue, from);
const unit = getUnit(to) || getUnit(from) || getUnit(originalValue);
tween.isPath = isPath(tweenValue);
tween.from = decomposeValue(from, unit);
tween.to = decomposeValue(to, unit);
tween.start = previousTween ? previousTween.end : prop.offset;
tween.end = tween.start + tween.delay + tween.duration;
tween.easing = normalizeEasing(tween.easing);
tween.elasticity = (1000 - minMaxValue(tween.elasticity, 1, 999)) / 1000;
if (is.col(tween.from.original)) tween.round = 1;
previousTween = tween;
return tween;
});
}
// Tween progress
const setTweenProgress = {
css: (t, p, v) => t.style[p] = v,
attribute: (t, p, v) => t.setAttribute(p, v),
object: (t, p, v) => t[p] = v,
transform: (t, p, v, transforms, id) => {
if (!transforms[id]) transforms[id] = [];
transforms[id].push(`${p}(${v})`);
}
}
// Animations
function createAnimation(animatable, prop) {
const animType = getAnimationType(animatable.target, prop.name);
if (animType) {
const tweens = normalizeTweens(prop, animatable);
return {
type: animType,
property: prop.name,
animatable: animatable,
tweens: tweens,
duration: tweens[tweens.length - 1].end,
delay: tweens[0].delay
}
}
}
function getAnimations(animatables, properties) {
return flattenArray(animatables.map(animatable => {
return properties.map(prop => {
return createAnimation(animatable, prop);
});
})).filter(a => !is.und(a));
}
// Create Instance
function getInstanceTimings(type, animations, tweenSettings) {
const math = (type === 'delay') ? Math.min : Math.max;
return animations.length ? math.apply(Math, animations.map(anim => anim[type])) : tweenSettings[type];
}
function createNewInstance(params) {
const instanceSettings = replaceObjectProps(defaultInstanceSettings, params);
const tweenSettings = replaceObjectProps(defaultTweenSettings, params);
const animatables = getAnimatables(params.targets);
const properties = getProperties(instanceSettings, tweenSettings, params);
const animations = getAnimations(animatables, properties);
return mergeObjects(instanceSettings, {
children: [],
animatables: animatables,
animations: animations,
duration: getInstanceTimings('duration', animations, tweenSettings),
delay: getInstanceTimings('delay', animations, tweenSettings)
});
}
// Core
let activeInstances = [];
let raf = 0;
const engine = (() => {
function play() { raf = requestAnimationFrame(step); };
function step(t) {
const activeLength = activeInstances.length;
if (activeLength) {
let i = 0;
while (i < activeLength) {
if (activeInstances[i]) activeInstances[i].tick(t);
i++;
}
play();
} else {
cancelAnimationFrame(raf);
raf = 0;
}
}
return play;
})();
// Public Instance
function anime(params = {}) {
let now, startTime, lastTime = 0;
let resolve = null;
function makePromise() {
return window.Promise && new Promise(_resolve => resolve = _resolve);
}
let promise = makePromise();
let instance = createNewInstance(params);
function toggleInstanceDirection() {
instance.reversed = !instance.reversed;
}
function adjustTime(time) {
return instance.reversed ? instance.duration - time : time;
}
function syncInstanceChildren(time) {
const children = instance.children;
if (time >= instance.currentTime) {
for (let i = 0; i < children.length; i++) children[i].seek(time);
} else {
for (let i = children.length; i--;) children[i].seek(time);
}
}
function setAnimationsProgress(insTime) {
let i = 0;
let transforms = {};
const animations = instance.animations;
while (i < animations.length) {
const anim = animations[i];
const animatable = anim.animatable;
const tweens = anim.tweens;
const tween = tweens.filter(t => (insTime < t.end))[0] || tweens[tweens.length - 1];
const elapsed = minMaxValue(insTime - tween.start - tween.delay, 0, tween.duration) / tween.duration;
const eased = isNaN(elapsed) ? 1 : tween.easing(elapsed, tween.elasticity);
const round = tween.round;
const progress = recomposeValue(tween.to.numbers.map((number, p) => {
const start = tween.from.numbers[p];
let value = start + eased * (number - start);
if (tween.isPath) value = getPathProgress(tween.value, value);
if (round) value = Math.round(value * round) / round;
return value;
}), tween.to.strings);
setTweenProgress[anim.type](animatable.target, anim.property, progress, transforms, animatable.id);
anim.currentValue = progress;
i++;
}
if (transforms) {
let id; for (id in transforms) {
if (!transformString) {
const t = 'transform';
transformString = (getCSSValue(document.body, t) ? t : `-webkit-${t}`);
}
instance.animatables[id].target.style[transformString] = transforms[id].join(' ');
}
}
instance.currentTime = insTime;
instance.progress = (insTime / instance.duration) * 100;
}
function setCallback(cb) {
if (instance[cb]) instance[cb](instance);
}
function countIteration() {
if (instance.remaining && instance.remaining !== true) {
instance.remaining--;
}
}
function setInstanceProgress(engineTime) {
const insDuration = instance.duration;
const insOffset = instance.offset;
const insDelay = instance.delay;
const insCurrentTime = instance.currentTime;
const insReversed = instance.reversed;
const insTime = adjustTime(engineTime);
if (instance.children.length) syncInstanceChildren(insTime);
if (insTime >= insDelay) {
setCallback('run');
if (!instance.began) {
instance.began = true;
setCallback('begin');
}
}
if (insTime > insOffset && insTime < insDuration) {
setAnimationsProgress(insTime);
} else {
if (insTime <= insOffset && insCurrentTime !== 0) {
setAnimationsProgress(0);
if (insReversed) countIteration();
}
if (insTime >= insDuration && insCurrentTime !== insDuration) {
setAnimationsProgress(insDuration);
if (!insReversed) countIteration();
}
}
setCallback('update');
if (engineTime >= insDuration) {
if (instance.remaining) {
startTime = now;
if (instance.direction === 'alternate') toggleInstanceDirection();
} else {
instance.pause();
if (!instance.completed) {
instance.completed = true;
setCallback('complete');
if ('Promise' in window) {
resolve();
promise = makePromise();
}
}
}
lastTime = 0;
}
}
instance.reset = function() {
const direction = instance.direction;
const loops = instance.loop;
instance.currentTime = 0;
instance.progress = 0;
instance.paused = true;
instance.began = false;
instance.completed = false;
instance.reversed = direction === 'reverse';
instance.remaining = direction === 'alternate' && loops === 1 ? 2 : loops;
setAnimationsProgress(0);
for (let i = instance.children.length; i--; ){
instance.children[i].reset();
}
}
instance.tick = function(t) {
now = t;
if (!startTime) startTime = now;
const engineTime = (lastTime + now - startTime) * anime.speed;
setInstanceProgress(engineTime);
}
instance.seek = function(time) {
setInstanceProgress(adjustTime(time));
}
instance.pause = function() {
const i = activeInstances.indexOf(instance);
if (i > -1) activeInstances.splice(i, 1);
instance.paused = true;
}
instance.play = function() {
if (!instance.paused) return;
instance.paused = false;
startTime = 0;
lastTime = adjustTime(instance.currentTime);
activeInstances.push(instance);
if (!raf) engine();
}
instance.reverse = function() {
toggleInstanceDirection();
startTime = 0;
lastTime = adjustTime(instance.currentTime);
}
instance.restart = function() {
instance.pause();
instance.reset();
instance.play();
}
instance.finished = promise;
instance.reset();
if (instance.autoplay) instance.play();
return instance;
}
// Remove targets from animation
function removeTargets(targets) {
const targetsArray = parseTargets(targets);
for (let i = activeInstances.length; i--;) {
const instance = activeInstances[i];
const animations = instance.animations;
for (let a = animations.length; a--;) {
if (arrayContains(targetsArray, animations[a].animatable.target)) {
animations.splice(a, 1);
if (!animations.length) instance.pause();
}
}
}
}
// Timeline
function timeline(params) {
let tl = anime(params);
tl.pause();
tl.duration = 0;
tl.add = function(instancesParams) {
tl.children.forEach(i => { i.began = true; i.completed = true; });
toArray(instancesParams).forEach(instanceParams => {
let insParams = mergeObjects(instanceParams, replaceObjectProps(defaultTweenSettings, params || {}));
insParams.targets = insParams.targets || params.targets;
const tlDuration = tl.duration;
const insOffset = insParams.offset;
insParams.autoplay = false;
insParams.offset = is.und(insOffset) ? tlDuration : getRelativeValue(insOffset, tlDuration);
tl.began = true;
tl.completed = true;
tl.seek(insParams.offset);
const ins = anime(insParams);
ins.began = true;
ins.completed = true;
if (ins.duration > tlDuration) tl.duration = ins.duration;
tl.children.push(ins);
});
tl.seek(0);
tl.reset();
if (tl.autoplay) tl.restart();
return tl;
}
return tl;
}
anime.version = '2.1.0';
anime.speed = 1;
anime.running = activeInstances;
anime.remove = removeTargets;
anime.getValue = getOriginalTargetValue;
anime.path = getPath;
anime.setDashoffset = setDashoffset;
anime.bezier = bezier;
anime.easings = easings;
anime.timeline = timeline;
anime.random = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
return anime;
}));

View File

@ -0,0 +1,994 @@
/**
* https://animejs.com
* JavaScript animation engine
* @version v2.2.0
* @author Julian Garnier
* @copyright ©2017 Julian Garnier
* Released under the MIT license
**/
(function(root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define([], factory);
} else if (typeof module === 'object' && module.exports) {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like environments that support module.exports,
// like Node.
module.exports = factory();
} else {
// Browser globals (root is window)
root.anime = factory();
}
}(this, () => {
// Defaults
const defaultInstanceSettings = {
update: undefined,
begin: undefined,
run: undefined,
complete: undefined,
loop: 1,
direction: 'normal',
autoplay: true,
offset: 0
}
const defaultTweenSettings = {
duration: 1000,
delay: 0,
easing: 'easeOutElastic',
elasticity: 500,
round: 0
}
const validTransforms = ['translateX', 'translateY', 'translateZ', 'rotate', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scaleX', 'scaleY', 'scaleZ', 'skewX', 'skewY', 'perspective'];
let transformString;
// Utils
function stringContains(str, text) {
return str.indexOf(text) > -1;
}
const is = {
arr: a => Array.isArray(a),
obj: a => stringContains(Object.prototype.toString.call(a), 'Object'),
pth: a => is.obj(a) && a.hasOwnProperty('totalLength'),
svg: a => a instanceof SVGElement,
dom: a => a.nodeType || is.svg(a),
str: a => typeof a === 'string',
fnc: a => typeof a === 'function',
und: a => typeof a === 'undefined',
hex: a => /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(a),
rgb: a => /^rgb/.test(a),
hsl: a => /^hsl/.test(a),
col: a => (is.hex(a) || is.rgb(a) || is.hsl(a))
}
// BezierEasing https://github.com/gre/bezier-easing
const bezier = (() => {
const kSplineTableSize = 11;
const kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
function A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1 };
function B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1 };
function C (aA1) { return 3.0 * aA1 };
function calcBezier (aT, aA1, aA2) { return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT };
function getSlope (aT, aA1, aA2) { return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1) };
function binarySubdivide (aX, aA, aB, mX1, mX2) {
let currentX, currentT, i = 0;
do {
currentT = aA + (aB - aA) / 2.0;
currentX = calcBezier(currentT, mX1, mX2) - aX;
if (currentX > 0.0) { aB = currentT } else { aA = currentT };
} while (Math.abs(currentX) > 0.0000001 && ++i < 10);
return currentT;
}
function newtonRaphsonIterate (aX, aGuessT, mX1, mX2) {
for (let i = 0; i < 4; ++i) {
const currentSlope = getSlope(aGuessT, mX1, mX2);
if (currentSlope === 0.0) return aGuessT;
const currentX = calcBezier(aGuessT, mX1, mX2) - aX;
aGuessT -= currentX / currentSlope;
}
return aGuessT;
}
function bezier(mX1, mY1, mX2, mY2) {
if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) return;
let sampleValues = new Float32Array(kSplineTableSize);
if (mX1 !== mY1 || mX2 !== mY2) {
for (let i = 0; i < kSplineTableSize; ++i) {
sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
}
}
function getTForX(aX) {
let intervalStart = 0.0;
let currentSample = 1;
const lastSample = kSplineTableSize - 1;
for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) {
intervalStart += kSampleStepSize;
}
--currentSample;
const dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]);
const guessForT = intervalStart + dist * kSampleStepSize;
const initialSlope = getSlope(guessForT, mX1, mX2);
if (initialSlope >= 0.001) {
return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
} else if (initialSlope === 0.0) {
return guessForT;
} else {
return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
}
}
return x => {
if (mX1 === mY1 && mX2 === mY2) return x;
if (x === 0) return 0;
if (x === 1) return 1;
return calcBezier(getTForX(x), mY1, mY2);
}
}
return bezier;
})();
const easings = (() => {
const names = ['Quad', 'Cubic', 'Quart', 'Quint', 'Sine', 'Expo', 'Circ', 'Back', 'Elastic'];
// Elastic easing adapted from jQueryUI http://api.jqueryui.com/easings/
function elastic(t, p) {
return t === 0 || t === 1 ? t :
-Math.pow(2, 10 * (t - 1)) * Math.sin((((t - 1) - (p / (Math.PI * 2.0) * Math.asin(1))) * (Math.PI * 2)) / p );
}
// Approximated Penner equations http://matthewlein.com/ceaser/
const equations = {
In: [
[0.550, 0.085, 0.680, 0.530], /* InQuad */
[0.550, 0.055, 0.675, 0.190], /* InCubic */
[0.895, 0.030, 0.685, 0.220], /* InQuart */
[0.755, 0.050, 0.855, 0.060], /* InQuint */
[0.470, 0.000, 0.745, 0.715], /* InSine */
[0.950, 0.050, 0.795, 0.035], /* InExpo */
[0.600, 0.040, 0.980, 0.335], /* InCirc */
[0.600, -0.280, 0.735, 0.045], /* InBack */
elastic /* InElastic */
], Out: [
[0.250, 0.460, 0.450, 0.940], /* OutQuad */
[0.215, 0.610, 0.355, 1.000], /* OutCubic */
[0.165, 0.840, 0.440, 1.000], /* OutQuart */
[0.230, 1.000, 0.320, 1.000], /* OutQuint */
[0.390, 0.575, 0.565, 1.000], /* OutSine */
[0.190, 1.000, 0.220, 1.000], /* OutExpo */
[0.075, 0.820, 0.165, 1.000], /* OutCirc */
[0.175, 0.885, 0.320, 1.275], /* OutBack */
(t, f) => 1 - elastic(1 - t, f) /* OutElastic */
], InOut: [
[0.455, 0.030, 0.515, 0.955], /* InOutQuad */
[0.645, 0.045, 0.355, 1.000], /* InOutCubic */
[0.770, 0.000, 0.175, 1.000], /* InOutQuart */
[0.860, 0.000, 0.070, 1.000], /* InOutQuint */
[0.445, 0.050, 0.550, 0.950], /* InOutSine */
[1.000, 0.000, 0.000, 1.000], /* InOutExpo */
[0.785, 0.135, 0.150, 0.860], /* InOutCirc */
[0.680, -0.550, 0.265, 1.550], /* InOutBack */
(t, f) => t < .5 ? elastic(t * 2, f) / 2 : 1 - elastic(t * -2 + 2, f) / 2 /* InOutElastic */
]
}
let functions = {
linear: bezier(0.250, 0.250, 0.750, 0.750)
}
for (let type in equations) {
equations[type].forEach((f, i) => {
functions['ease'+type+names[i]] = is.fnc(f) ? f : bezier.apply(this, f);
});
}
return functions;
})();
// Strings
function stringToHyphens(str) {
return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
}
function selectString(str) {
if (is.col(str)) return;
try {
let nodes = document.querySelectorAll(str);
return nodes;
} catch(e) {
return;
}
}
// Arrays
function filterArray(arr, callback) {
const len = arr.length;
const thisArg = arguments.length >= 2 ? arguments[1] : void 0;
let result = [];
for (let i = 0; i < len; i++) {
if (i in arr) {
const val = arr[i];
if (callback.call(thisArg, val, i, arr)) {
result.push(val);
}
}
}
return result;
}
function flattenArray(arr) {
return arr.reduce((a, b) => a.concat(is.arr(b) ? flattenArray(b) : b), []);
}
function toArray(o) {
if (is.arr(o)) return o;
if (is.str(o)) o = selectString(o) || o;
if (o instanceof NodeList || o instanceof HTMLCollection) return [].slice.call(o);
return [o];
}
function arrayContains(arr, val) {
return arr.some(a => a === val);
}
// Objects
function cloneObject(o) {
let clone = {};
for (let p in o) clone[p] = o[p];
return clone;
}
function replaceObjectProps(o1, o2) {
let o = cloneObject(o1);
for (let p in o1) o[p] = o2.hasOwnProperty(p) ? o2[p] : o1[p];
return o;
}
function mergeObjects(o1, o2) {
let o = cloneObject(o1);
for (let p in o2) o[p] = is.und(o1[p]) ? o2[p] : o1[p];
return o;
}
// Colors
function rgbToRgba(rgbValue) {
const rgb = /rgb\((\d+,\s*[\d]+,\s*[\d]+)\)/g.exec(rgbValue);
return rgb ? `rgba(${rgb[1]},1)` : rgbValue;
}
function hexToRgba(hexValue) {
const rgx = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
const hex = hexValue.replace(rgx, (m, r, g, b) => r + r + g + g + b + b );
const rgb = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
const r = parseInt(rgb[1], 16);
const g = parseInt(rgb[2], 16);
const b = parseInt(rgb[3], 16);
return `rgba(${r},${g},${b},1)`;
}
function hslToRgba(hslValue) {
const hsl = /hsl\((\d+),\s*([\d.]+)%,\s*([\d.]+)%\)/g.exec(hslValue) || /hsla\((\d+),\s*([\d.]+)%,\s*([\d.]+)%,\s*([\d.]+)\)/g.exec(hslValue);
const h = parseInt(hsl[1]) / 360;
const s = parseInt(hsl[2]) / 100;
const l = parseInt(hsl[3]) / 100;
const a = hsl[4] || 1;
function hue2rgb(p, q, t) {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1/6) return p + (q - p) * 6 * t;
if (t < 1/2) return q;
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
}
let r, g, b;
if (s == 0) {
r = g = b = l;
} else {
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
r = hue2rgb(p, q, h + 1/3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3);
}
return `rgba(${r * 255},${g * 255},${b * 255},${a})`;
}
function colorToRgb(val) {
if (is.rgb(val)) return rgbToRgba(val);
if (is.hex(val)) return hexToRgba(val);
if (is.hsl(val)) return hslToRgba(val);
}
// Units
function getUnit(val) {
const split = /([\+\-]?[0-9#\.]+)(%|px|pt|em|rem|in|cm|mm|ex|ch|pc|vw|vh|vmin|vmax|deg|rad|turn)?$/.exec(val);
if (split) return split[2];
}
function getTransformUnit(propName) {
if (stringContains(propName, 'translate') || propName === 'perspective') return 'px';
if (stringContains(propName, 'rotate') || stringContains(propName, 'skew')) return 'deg';
}
// Values
function minMaxValue(val, min, max) {
return Math.min(Math.max(val, min), max);
}
function getFunctionValue(val, animatable) {
if (!is.fnc(val)) return val;
return val(animatable.target, animatable.id, animatable.total);
}
function getCSSValue(el, prop) {
if (prop in el.style) {
return getComputedStyle(el).getPropertyValue(stringToHyphens(prop)) || '0';
}
}
function getAnimationType(el, prop) {
if (is.dom(el) && arrayContains(validTransforms, prop)) return 'transform';
if (is.dom(el) && (el.getAttribute(prop) || (is.svg(el) && el[prop]))) return 'attribute';
if (is.dom(el) && (prop !== 'transform' && getCSSValue(el, prop))) return 'css';
if (el[prop] != null) return 'object';
}
function getTransformValue(el, propName) {
const defaultUnit = getTransformUnit(propName);
const defaultVal = stringContains(propName, 'scale') ? 1 : 0 + defaultUnit;
const str = el.style.transform;
if (!str) return defaultVal;
let match = [];
let props = [];
let values = [];
const rgx = /(\w+)\((.+?)\)/g;
while (match = rgx.exec(str)) {
props.push(match[1]);
values.push(match[2]);
}
const value = filterArray(values, (val, i) => props[i] === propName);
return value.length ? value[0] : defaultVal;
}
function getOriginalTargetValue(target, propName) {
switch (getAnimationType(target, propName)) {
case 'transform': return getTransformValue(target, propName);
case 'css': return getCSSValue(target, propName);
case 'attribute': return target.getAttribute(propName);
}
return target[propName] || 0;
}
function getRelativeValue(to, from) {
const operator = /^(\*=|\+=|-=)/.exec(to);
if (!operator) return to;
const u = getUnit(to) || 0;
const x = parseFloat(from);
const y = parseFloat(to.replace(operator[0], ''));
switch (operator[0][0]) {
case '+': return x + y + u;
case '-': return x - y + u;
case '*': return x * y + u;
}
}
function validateValue(val, unit) {
if (is.col(val)) return colorToRgb(val);
const originalUnit = getUnit(val);
const unitLess = originalUnit ? val.substr(0, val.length - originalUnit.length) : val;
return unit && !/\s/g.test(val) ? unitLess + unit : unitLess;
}
// getTotalLength() equivalent for circle, rect, polyline, polygon and line shapes.
// adapted from https://gist.github.com/SebLambla/3e0550c496c236709744
function getDistance(p1, p2) {
return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));
}
function getCircleLength(el) {
return 2 * Math.PI * el.getAttribute('r');
}
function getRectLength(el) {
return (el.getAttribute('width') * 2) + (el.getAttribute('height') * 2);
}
function getLineLength(el) {
return getDistance(
{x: el.getAttribute('x1'), y: el.getAttribute('y1')},
{x: el.getAttribute('x2'), y: el.getAttribute('y2')}
);
}
function getPolylineLength(el) {
const points = el.points;
let totalLength = 0;
let previousPos;
for (let i = 0 ; i < points.numberOfItems; i++) {
const currentPos = points.getItem(i);
if (i > 0) totalLength += getDistance(previousPos, currentPos);
previousPos = currentPos;
}
return totalLength;
}
function getPolygonLength(el) {
const points = el.points;
return getPolylineLength(el) + getDistance(points.getItem(points.numberOfItems - 1), points.getItem(0));
}
// Path animation
function getTotalLength(el) {
if (el.getTotalLength) return el.getTotalLength();
switch(el.tagName.toLowerCase()) {
case 'circle': return getCircleLength(el);
case 'rect': return getRectLength(el);
case 'line': return getLineLength(el);
case 'polyline': return getPolylineLength(el);
case 'polygon': return getPolygonLength(el);
}
}
function setDashoffset(el) {
const pathLength = getTotalLength(el);
el.setAttribute('stroke-dasharray', pathLength);
return pathLength;
}
// Motion path
function getPath(path, percent) {
const el = is.str(path) ? selectString(path)[0] : path;
const p = percent || 100;
return function(prop) {
return {
el: el,
property: prop,
totalLength: getTotalLength(el) * (p / 100)
}
}
}
function getPathProgress(path, progress) {
function point(offset = 0) {
const l = progress + offset >= 1 ? progress + offset : 0;
return path.el.getPointAtLength(l);
}
const p = point();
const p0 = point(-1);
const p1 = point(+1);
switch (path.property) {
case 'x': return p.x;
case 'y': return p.y;
case 'angle': return Math.atan2(p1.y - p0.y, p1.x - p0.x) * 180 / Math.PI;
}
}
// Decompose value
function decomposeValue(val, unit) {
const rgx = /-?\d*\.?\d+/g;
const value = validateValue((is.pth(val) ? val.totalLength : val), unit) + '';
return {
original: value,
numbers: value.match(rgx) ? value.match(rgx).map(Number) : [0],
strings: (is.str(val) || unit) ? value.split(rgx) : []
}
}
// Animatables
function parseTargets(targets) {
const targetsArray = targets ? (flattenArray(is.arr(targets) ? targets.map(toArray) : toArray(targets))) : [];
return filterArray(targetsArray, (item, pos, self) => self.indexOf(item) === pos);
}
function getAnimatables(targets) {
const parsed = parseTargets(targets);
return parsed.map((t, i) => {
return {target: t, id: i, total: parsed.length};
});
}
// Properties
function normalizePropertyTweens(prop, tweenSettings) {
let settings = cloneObject(tweenSettings);
if (is.arr(prop)) {
const l = prop.length;
const isFromTo = (l === 2 && !is.obj(prop[0]));
if (!isFromTo) {
// Duration divided by the number of tweens
if (!is.fnc(tweenSettings.duration)) settings.duration = tweenSettings.duration / l;
} else {
// Transform [from, to] values shorthand to a valid tween value
prop = {value: prop};
}
}
return toArray(prop).map((v, i) => {
// Default delay value should be applied only on the first tween
const delay = !i ? tweenSettings.delay : 0;
// Use path object as a tween value
let obj = is.obj(v) && !is.pth(v) ? v : {value: v};
// Set default delay value
if (is.und(obj.delay)) obj.delay = delay;
return obj;
}).map(k => mergeObjects(k, settings));
}
function getProperties(instanceSettings, tweenSettings, params) {
let properties = [];
const settings = mergeObjects(instanceSettings, tweenSettings);
for (let p in params) {
if (!settings.hasOwnProperty(p) && p !== 'targets') {
properties.push({
name: p,
offset: settings['offset'],
tweens: normalizePropertyTweens(params[p], tweenSettings)
});
}
}
return properties;
}
// Tweens
function normalizeTweenValues(tween, animatable) {
let t = {};
for (let p in tween) {
let value = getFunctionValue(tween[p], animatable);
if (is.arr(value)) {
value = value.map(v => getFunctionValue(v, animatable));
if (value.length === 1) value = value[0];
}
t[p] = value;
}
t.duration = parseFloat(t.duration);
t.delay = parseFloat(t.delay);
return t;
}
function normalizeEasing(val) {
return is.arr(val) ? bezier.apply(this, val) : easings[val];
}
function normalizeTweens(prop, animatable) {
let previousTween;
return prop.tweens.map(t => {
let tween = normalizeTweenValues(t, animatable);
const tweenValue = tween.value;
const originalValue = getOriginalTargetValue(animatable.target, prop.name);
const previousValue = previousTween ? previousTween.to.original : originalValue;
const from = is.arr(tweenValue) ? tweenValue[0] : previousValue;
const to = getRelativeValue(is.arr(tweenValue) ? tweenValue[1] : tweenValue, from);
const unit = getUnit(to) || getUnit(from) || getUnit(originalValue);
tween.from = decomposeValue(from, unit);
tween.to = decomposeValue(to, unit);
tween.start = previousTween ? previousTween.end : prop.offset;
tween.end = tween.start + tween.delay + tween.duration;
tween.easing = normalizeEasing(tween.easing);
tween.elasticity = (1000 - minMaxValue(tween.elasticity, 1, 999)) / 1000;
tween.isPath = is.pth(tweenValue);
tween.isColor = is.col(tween.from.original);
if (tween.isColor) tween.round = 1;
previousTween = tween;
return tween;
});
}
// Tween progress
const setTweenProgress = {
css: (t, p, v) => t.style[p] = v,
attribute: (t, p, v) => t.setAttribute(p, v),
object: (t, p, v) => t[p] = v,
transform: (t, p, v, transforms, id) => {
if (!transforms[id]) transforms[id] = [];
transforms[id].push(`${p}(${v})`);
}
}
// Animations
function createAnimation(animatable, prop) {
const animType = getAnimationType(animatable.target, prop.name);
if (animType) {
const tweens = normalizeTweens(prop, animatable);
return {
type: animType,
property: prop.name,
animatable: animatable,
tweens: tweens,
duration: tweens[tweens.length - 1].end,
delay: tweens[0].delay
}
}
}
function getAnimations(animatables, properties) {
return filterArray(flattenArray(animatables.map(animatable => {
return properties.map(prop => {
return createAnimation(animatable, prop);
});
})), a => !is.und(a));
}
// Create Instance
function getInstanceTimings(type, animations, instanceSettings, tweenSettings) {
const isDelay = (type === 'delay');
if (animations.length) {
return (isDelay ? Math.min : Math.max).apply(Math, animations.map(anim => anim[type]));
} else {
return isDelay ? tweenSettings.delay : instanceSettings.offset + tweenSettings.delay + tweenSettings.duration;
}
}
function createNewInstance(params) {
const instanceSettings = replaceObjectProps(defaultInstanceSettings, params);
const tweenSettings = replaceObjectProps(defaultTweenSettings, params);
const animatables = getAnimatables(params.targets);
const properties = getProperties(instanceSettings, tweenSettings, params);
const animations = getAnimations(animatables, properties);
return mergeObjects(instanceSettings, {
children: [],
animatables: animatables,
animations: animations,
duration: getInstanceTimings('duration', animations, instanceSettings, tweenSettings),
delay: getInstanceTimings('delay', animations, instanceSettings, tweenSettings)
});
}
// Core
let activeInstances = [];
let raf = 0;
const engine = (() => {
function play() { raf = requestAnimationFrame(step); };
function step(t) {
const activeLength = activeInstances.length;
if (activeLength) {
let i = 0;
while (i < activeLength) {
if (activeInstances[i]) activeInstances[i].tick(t);
i++;
}
play();
} else {
cancelAnimationFrame(raf);
raf = 0;
}
}
return play;
})();
// Public Instance
function anime(params = {}) {
let now, startTime, lastTime = 0;
let resolve = null;
function makePromise(instance) {
const promise = window.Promise && new Promise(_resolve => resolve = _resolve);
instance.finished = promise;
return promise;
}
let instance = createNewInstance(params);
let promise = makePromise(instance);
function toggleInstanceDirection() {
instance.reversed = !instance.reversed;
}
function adjustTime(time) {
return instance.reversed ? instance.duration - time : time;
}
function syncInstanceChildren(time) {
const children = instance.children;
const childrenLength = children.length;
if (time >= instance.currentTime) {
for (let i = 0; i < childrenLength; i++) children[i].seek(time);
} else {
for (let i = childrenLength; i--;) children[i].seek(time);
}
}
function setAnimationsProgress(insTime) {
let i = 0;
let transforms = {};
const animations = instance.animations;
const animationsLength = animations.length;
while (i < animationsLength) {
const anim = animations[i];
const animatable = anim.animatable;
const tweens = anim.tweens;
const tweenLength = tweens.length - 1;
let tween = tweens[tweenLength];
// Only check for keyframes if there is more than one tween
if (tweenLength) tween = filterArray(tweens, t => (insTime < t.end))[0] || tween;
const elapsed = minMaxValue(insTime - tween.start - tween.delay, 0, tween.duration) / tween.duration;
const eased = isNaN(elapsed) ? 1 : tween.easing(elapsed, tween.elasticity);
const strings = tween.to.strings;
const round = tween.round;
let numbers = [];
let progress;
const toNumbersLength = tween.to.numbers.length;
for (let n = 0; n < toNumbersLength; n++) {
let value;
const toNumber = tween.to.numbers[n];
const fromNumber = tween.from.numbers[n];
if (!tween.isPath) {
value = fromNumber + (eased * (toNumber - fromNumber));
} else {
value = getPathProgress(tween.value, eased * toNumber);
}
if (round) {
if (!(tween.isColor && n > 2)) {
value = Math.round(value * round) / round;
}
}
numbers.push(value);
}
// Manual Array.reduce for better performances
const stringsLength = strings.length;
if (!stringsLength) {
progress = numbers[0];
} else {
progress = strings[0];
for (let s = 0; s < stringsLength; s++) {
const a = strings[s];
const b = strings[s + 1];
const n = numbers[s];
if (!isNaN(n)) {
if (!b) {
progress += n + ' ';
} else {
progress += n + b;
}
}
}
}
setTweenProgress[anim.type](animatable.target, anim.property, progress, transforms, animatable.id);
anim.currentValue = progress;
i++;
}
const transformsLength = Object.keys(transforms).length;
if (transformsLength) {
for (let id = 0; id < transformsLength; id++) {
if (!transformString) {
const t = 'transform';
transformString = (getCSSValue(document.body, t) ? t : `-webkit-${t}`);
}
instance.animatables[id].target.style[transformString] = transforms[id].join(' ');
}
}
instance.currentTime = insTime;
instance.progress = (insTime / instance.duration) * 100;
}
function setCallback(cb) {
if (instance[cb]) instance[cb](instance);
}
function countIteration() {
if (instance.remaining && instance.remaining !== true) {
instance.remaining--;
}
}
function setInstanceProgress(engineTime) {
const insDuration = instance.duration;
const insOffset = instance.offset;
const insStart = insOffset + instance.delay;
const insCurrentTime = instance.currentTime;
const insReversed = instance.reversed;
const insTime = adjustTime(engineTime);
if (instance.children.length) syncInstanceChildren(insTime);
if (insTime >= insStart || !insDuration) {
if (!instance.began) {
instance.began = true;
setCallback('begin');
}
setCallback('run');
}
if (insTime > insOffset && insTime < insDuration) {
setAnimationsProgress(insTime);
} else {
if (insTime <= insOffset && insCurrentTime !== 0) {
setAnimationsProgress(0);
if (insReversed) countIteration();
}
if ((insTime >= insDuration && insCurrentTime !== insDuration) || !insDuration) {
setAnimationsProgress(insDuration);
if (!insReversed) countIteration();
}
}
setCallback('update');
if (engineTime >= insDuration) {
if (instance.remaining) {
startTime = now;
if (instance.direction === 'alternate') toggleInstanceDirection();
} else {
instance.pause();
if (!instance.completed) {
instance.completed = true;
setCallback('complete');
if ('Promise' in window) {
resolve();
promise = makePromise(instance);
}
}
}
lastTime = 0;
}
}
instance.reset = function() {
const direction = instance.direction;
const loops = instance.loop;
instance.currentTime = 0;
instance.progress = 0;
instance.paused = true;
instance.began = false;
instance.completed = false;
instance.reversed = direction === 'reverse';
instance.remaining = direction === 'alternate' && loops === 1 ? 2 : loops;
setAnimationsProgress(0);
for (let i = instance.children.length; i--; ){
instance.children[i].reset();
}
}
instance.tick = function(t) {
now = t;
if (!startTime) startTime = now;
const engineTime = (lastTime + now - startTime) * anime.speed;
setInstanceProgress(engineTime);
}
instance.seek = function(time) {
setInstanceProgress(adjustTime(time));
}
instance.pause = function() {
const i = activeInstances.indexOf(instance);
if (i > -1) activeInstances.splice(i, 1);
instance.paused = true;
}
instance.play = function() {
if (!instance.paused) return;
instance.paused = false;
instance.completed = false;
startTime = 0;
lastTime = adjustTime(instance.currentTime);
activeInstances.push(instance);
if (!raf) engine();
}
instance.reverse = function() {
toggleInstanceDirection();
startTime = 0;
lastTime = adjustTime(instance.currentTime);
}
instance.restart = function() {
instance.pause();
instance.reset();
instance.play();
}
instance.reset();
if (instance.autoplay) instance.play();
return instance;
}
// Remove targets from animation
function removeTargets(targets) {
const targetsArray = parseTargets(targets);
for (let i = activeInstances.length; i--;) {
const instance = activeInstances[i];
const animations = instance.animations;
for (let a = animations.length; a--;) {
if (arrayContains(targetsArray, animations[a].animatable.target)) {
animations.splice(a, 1);
if (!animations.length) instance.pause();
}
}
}
}
// Timeline
function timeline(params) {
let tl = anime(params);
tl.pause();
tl.duration = 0;
tl.add = function(instancesParams) {
tl.children.forEach(i => { i.began = true; i.completed = true; });
toArray(instancesParams).forEach(instanceParams => {
let insParams = mergeObjects(instanceParams, replaceObjectProps(defaultTweenSettings, params || {}));
insParams.targets = insParams.targets || params.targets;
const tlDuration = tl.duration;
const insOffset = insParams.offset;
insParams.autoplay = false;
insParams.direction = tl.direction;
insParams.offset = is.und(insOffset) ? tlDuration : getRelativeValue(insOffset, tlDuration);
tl.began = true;
tl.completed = true;
tl.seek(insParams.offset);
const ins = anime(insParams);
ins.began = true;
ins.completed = true;
if (ins.duration > tlDuration) tl.duration = ins.duration;
tl.children.push(ins);
});
tl.seek(0);
tl.reset();
if (tl.autoplay) tl.restart();
return tl;
}
return tl;
}
anime.version = '2.2.0';
anime.speed = 1;
anime.running = activeInstances;
anime.remove = removeTargets;
anime.getValue = getOriginalTargetValue;
anime.path = getPath;
anime.setDashoffset = setDashoffset;
anime.bezier = bezier;
anime.easings = easings;
anime.timeline = timeline;
anime.random = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
return anime;
}));

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,268 @@
var navigationEl = document.querySelector('.navigation');
var demosEl = document.querySelector('.demos');
var articleEls = document.querySelectorAll('article');
var demoInfoEl = document.querySelector('.demo-info');
var descriptionEl = document.querySelector('.info-output');
var descriptionTitleEl = document.querySelector('.demo-info h2');
var demos = [];
function getScrollTop() {
return document.body.scrollTop || document.documentElement.scrollTop;
}
function scrollTo(selector, offset, cb) {
var offset = offset || 0;
var el = document.querySelector(selector);
var scrollAnim = anime({
targets: {scroll: demosEl.scrollTop},
scroll: el.offsetTop - offset,
duration: 500,
easing: 'easeInOutQuart',
update: function(a) { demosEl.scrollTop = a.animations[0].currentValue; },
complete: function() { if (cb) cb(); }
});
}
function parseJS(demoCode) {
var split = demoCode.split('/*DEMO*/\n');
return split[1] || '';
}
function createCodePreview(code) {
var previewEl = document.createElement('div');
var preEl = document.createElement('pre');
var codeEl = document.createElement('code');
previewEl.classList.add('code-preview');
previewEl.innerHTML = '<h2>Code example</h2>';
codeEl.appendChild(code);
preEl.appendChild(codeEl);
previewEl.appendChild(preEl);
return previewEl;
}
function outputCode(demoCode, demoTitle, demoDecription, demoColorClass) {
var js = document.createTextNode(parseJS(demoCode));
demoInfoEl.classList.remove(demoInfoEl.classList[2]);
demoInfoEl.classList.add(demoColorClass);
descriptionEl.innerHTML = demoDecription;
descriptionEl.appendChild(createCodePreview(js));
descriptionTitleEl.innerHTML = demoTitle;
codeEls = descriptionEl.querySelectorAll('code');
for (var i = 0; i < codeEls.length; i++) {
hljs.highlightBlock(codeEls[i]);
}
}
function toggleSectionLink(ulEl) {
var ulEls = document.querySelectorAll('.navigation ul');
var ulLiEls = ulEl.querySelectorAll('.li');
for (var i = 0; i < ulEls.length; i++) ulEls[i].classList.remove('active');
ulEl.classList.add('active');
anime.remove(ulEls);
anime({
targets: '.navigation ul:not(.active)',
height: 30,
duration: 400,
easing: 'easeOutQuart'
});
anime({
targets: ulEl,
height: function(el) {
var height = 0;
var childNodes = el.childNodes;
for (var i = 0; i < childNodes.length; i++) height += childNodes[i].offsetHeight;
return height;
},
duration: 600,
delay: 400,
easing: 'easeInOutQuart'
});
}
function resetDemo() {
var els = document.querySelectorAll('.el');
for (var i = 0; i < els.length; i++) {
anime.remove(els[i]);
els[i].style = '';
}
}
function resetDemos() {
for (var i = 0; i < anime.running.length; i++) {
var anim = anime.running[i];
anim.pause();
anim.seek(0);
}
document.body.classList.add('ready');
}
function createDemo(el) {
var demo = {};
var demoColorClass = el.parentNode.classList[0];
var scriptEl = el.querySelector('script');
var demoContentEl = el.querySelector('.demo-content');
var descriptionContentEl = el.querySelector('.demo-description');
var demoTitle = el.querySelector('h3').innerHTML;
var id = el.id;
var demoAnim = window[id];
var demoCode = scriptEl ? scriptEl.innerHTML : '';
var demoDescription = descriptionContentEl ? descriptionContentEl.innerHTML : '';
function restart() {
resetDemo();
demoAnim();
}
function highlightDemo(e, push) {
var canRestart = !el.classList.contains('controls');
if (e) {
e.preventDefault();
if (e.target.tagName === 'BUTTON' || e.target.tagName === 'INPUT') {
canRestart = false;
}
}
if (!el.classList.contains('active')) {
resetDemos();
var linkEls = document.querySelectorAll('.demo-link');
for (var i = 0; i < demos.length; i++) {
var d = demos[i];
d.el.classList.remove('active');
linkEls[i].parentNode.classList.remove('active');
//d.anim.pause();
}
outputCode(demoCode, demoTitle, demoDescription, demoColorClass);
var linkEl = document.querySelector('a[href="#'+id+'"]');
var ulEl = linkEl.parentNode.parentNode;
linkEl.parentNode.classList.add('active');
el.classList.add('active');
scrollTo('#'+id, 60, function() {
toggleSectionLink(ulEl);
if (canRestart) restart();
});
if (push) history.pushState(null, null, '#'+id);
} else {
if (canRestart) restart();
}
}
function enterDemo() {
if (!el.classList.contains('active')) {
restart();
}
}
function leaveDemo() {
if (!el.classList.contains('active')) {
resetDemo();
}
}
el.addEventListener('click', function(e) {
highlightDemo(e, true);
});
resetDemos();
return {
el: el,
title: demoTitle,
id: id,
anim: demoAnim,
highlight: highlightDemo
}
}
function getDemoById(id) {
return demos.filter(function(a) { return a.id === id})[0];
}
function createLinksSection(articleEl) {
var articleId = articleEl.id;
var articleTitle = articleEl.querySelector('h2').innerHTML;
var colorClass = articleEl.classList[0];
var ulEl = document.createElement('ul');
var liEl = document.createElement('li');
var sectionLinkEl = document.createElement('a');
sectionLinkEl.setAttribute('href', '#'+articleId);
sectionLinkEl.innerHTML = articleTitle;
sectionLinkEl.addEventListener('click', function(e) {
e.preventDefault();
var firstDemoId = articleEl.querySelector('.demo').id;
var firstDemo = getDemoById(firstDemoId);
firstDemo.highlight(e, true);
});
liEl.appendChild(sectionLinkEl);
ulEl.appendChild(liEl);
ulEl.classList.add(colorClass);
return ulEl;
}
function createDemoLink(demo) {
var liEl = document.createElement('li');
var demoLinkEl = document.createElement('a');
demoLinkEl.setAttribute('href', '#'+demo.id);
demoLinkEl.innerHTML = demo.title;
demoLinkEl.classList.add('demo-link');
demoLinkEl.addEventListener('click', function(e) {
demo.highlight(e, true);
});
liEl.appendChild(demoLinkEl);
return liEl;
}
var fragment = document.createDocumentFragment();
for (var i = 0; i < articleEls.length; i++) {
var articleEl = articleEls[i];
var linksSectionEl = createLinksSection(articleEl);
var demoEls = articleEl.querySelectorAll('.demo');
for (var d = 0; d < demoEls.length; d++) {
var demo = createDemo(demoEls[d]);
var demoLinkEl = createDemoLink(demo);
linksSectionEl.appendChild(demoLinkEl);
demos.push(demo);
}
fragment.appendChild(linksSectionEl);
}
navigationEl.appendChild(fragment);
function updateDemos() {
var hash = window.location.hash;
if (hash) {
var id = hash.replace('#','');
var demo = getDemoById(id);
if (demo) demo.highlight();
} else {
demos[0].highlight();
}
}
function keyboardNavigation(e) {
var activeDemoEl = document.querySelector('.demo.active');
switch (e.keyCode) {
case 38:
var prevEl = activeDemoEl.previousElementSibling;
while (prevEl && !prevEl.classList.contains('demo') && prevEl.parentNode.previousElementSibling) {
prevEl = prevEl.parentNode.previousElementSibling.lastElementChild;
}
if (prevEl && prevEl.classList.contains('demo')) getDemoById(prevEl.id).highlight(e, true);
break;
case 40:
var nextEl = activeDemoEl.nextElementSibling;
if (!nextEl && activeDemoEl.parentNode.nextElementSibling) {
nextEl = activeDemoEl.parentNode.nextElementSibling.querySelector('.demo');
}
if (nextEl && nextEl.classList.contains('demo')) getDemoById(nextEl.id).highlight(e, true);
break;
}
}
// Update date and version number
var versionNumerEls = document.querySelectorAll('.version-number');
var dateEl = document.querySelector('.date');
var date = new Date();
for (var i = 0; i < versionNumerEls.length; i++) {
versionNumerEls[i].innerHTML = anime.version;
}
// Init
updateDemos();
window.onhashchange = updateDemos;
document.onkeydown = keyboardNavigation;

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,17 @@
// stats.js - http://github.com/mrdoob/stats.js
(function(f,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"===typeof define&&define.amd?define(e):f.Stats=e()})(this,function(){var f=function(){function e(a){c.appendChild(a.dom);return a}function u(a){for(var d=0;d<c.children.length;d++)c.children[d].style.display=d===a?"block":"none";l=a}var l=0,c=document.createElement("div");c.style.cssText="position:fixed;top:0;left:0;cursor:pointer;opacity:0.9;z-index:10000";c.addEventListener("click",function(a){a.preventDefault();
u(++l%c.children.length)},!1);var k=(performance||Date).now(),g=k,a=0,r=e(new f.Panel("FPS","#0ff","#002")),h=e(new f.Panel("MS","#0f0","#020"));if(self.performance&&self.performance.memory)var t=e(new f.Panel("MB","#f08","#201"));u(0);return{REVISION:16,dom:c,addPanel:e,showPanel:u,begin:function(){k=(performance||Date).now()},end:function(){a++;var c=(performance||Date).now();h.update(c-k,200);if(c>g+1E3&&(r.update(1E3*a/(c-g),100),g=c,a=0,t)){var d=performance.memory;t.update(d.usedJSHeapSize/
1048576,d.jsHeapSizeLimit/1048576)}return c},update:function(){k=this.end()},domElement:c,setMode:u}};f.Panel=function(e,f,l){var c=Infinity,k=0,g=Math.round,a=g(window.devicePixelRatio||1),r=80*a,h=48*a,t=3*a,v=2*a,d=3*a,m=15*a,n=74*a,p=30*a,q=document.createElement("canvas");q.width=r;q.height=h;q.style.cssText="width:80px;height:48px";var b=q.getContext("2d");b.font="bold "+9*a+"px Helvetica,Arial,sans-serif";b.textBaseline="top";b.fillStyle=l;b.fillRect(0,0,r,h);b.fillStyle=f;b.fillText(e,t,v);
b.fillRect(d,m,n,p);b.fillStyle=l;b.globalAlpha=.9;b.fillRect(d,m,n,p);return{dom:q,update:function(h,w){c=Math.min(c,h);k=Math.max(k,h);b.fillStyle=l;b.globalAlpha=1;b.fillRect(0,0,r,m);b.fillStyle=f;b.fillText(g(h)+" "+e+" ("+g(c)+"-"+g(k)+")",t,v);b.drawImage(q,d+a,m,n-a,p,d,m,n-a,p);b.fillRect(d+n-a,m,a,p);b.fillStyle=l;b.globalAlpha=.9;b.fillRect(d+n-a,m,a,g((1-h/w)*p))}}};return f});
var stats = new Stats();
stats.showPanel(0);
document.body.appendChild(stats.dom);
anime({
update: function() {
stats.begin();
stats.end();
},
duration: Infinity
});

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,72 @@
<!DOCTYPE html>
<html>
<head>
<title>DOM stress test | anime.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:title" content="anime.js">
<meta property="og:url" content="https://animejs.com">
<meta property="og:description" content="Javascript Animation Engine">
<meta property="og:image" content="https://animejs.com/documentation/assets/img/icons/og.png">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="anime.js">
<meta name="twitter:site" content="@juliangarnier">
<meta name="twitter:description" content="Javascript Animation Engine">
<meta name="twitter:image" content="https://animejs.com/documentation/assets/img/icons/twitter.png">
<link rel="apple-touch-icon-precomposed" href="../assets/img/social-media-image.png">
<link rel="icon" type="image/png" href="../assets/img/favicon.png" >
<link href="../assets/css/animejs.css" rel="stylesheet">
<link href="../assets/css/documentation.css" rel="stylesheet">
<script src="../../lib/anime.min.js"></script>
<!-- <script src="../assets/js/anime/anime.2.0.2.js"></script> -->
<!-- <script src="../assets/js/anime/anime.1.0.js"></script> -->
<style>
.el {
position: absolute;
top: 50%;
left: 50%;
width: 1em;
height: 1em;
margin: -.5em 0 0 -.5em;
font-size: 20px;
}
</style>
</head>
<body></body>
<script>
var wrapperEl = document.body;
var numberOfEls = 500;
var duration = numberOfEls * 10;
var radius = window.innerWidth < window.innerHeight ? window.innerWidth : window.innerHeight;
var distance = (radius / 4 <= 150 ? 150 : radius / 2.5) / 16;
function createEl(i) {
var el = document.createElement('div');
var hue = Math.round(360 / numberOfEls * i);
el.classList.add('el');
//el.style.border = '5px solid hsl(' + hue + ', 50%, 50%)';
el.style.backgroundColor = 'hsl(' + hue + ', 50%, 50%)';
wrapperEl.appendChild(el);
anime({
targets: el,
translateX: Math.sin(i) * distance + 'rem',
translateY: Math.cos(i) * distance + 'rem',
scale: [
{value: [.1, 2]},
{value: .1}
],
easing: 'easeInOutSine',
loop: true,
duration: duration,
delay: i * (duration / numberOfEls)
});
};
for (var i = 0; i < numberOfEls; i++) createEl(i);
</script>
<script src="../assets/js/vendors/stats.min.js"></script>
</html>

View File

@ -0,0 +1,158 @@
<!DOCTYPE html>
<html>
<head>
<title>advanced staggering • anime.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:title" content="anime.js">
<meta property="og:url" content="https://animejs.com">
<meta property="og:description" content="Javascript Animation Engine">
<meta property="og:image" content="https://animejs.com/documentation/assets/img/icons/og.png">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="anime.js">
<meta name="twitter:site" content="@juliangarnier">
<meta name="twitter:description" content="Javascript Animation Engine">
<meta name="twitter:image" content="https://animejs.com/documentation/assets/img/icons/twitter.png">
<link rel="apple-touch-icon-precomposed" href="../assets/img/social-media-image.png">
<link rel="icon" type="image/png" href="../assets/img/favicon.png" >
<link href="../assets/css/animejs.css" rel="stylesheet">
<link href="../assets/css/documentation.css" rel="stylesheet">
<style>
:root {
font-size: 20px;
}
body {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #000;
}
.stagger-visualizer {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
position: relative;
width: 32rem;
height: 16rem;
}
.dots-wrapper {
position: absolute;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
}
.stagger-visualizer .dot {
position: relative;
width: calc(1rem - 8px);
height: calc(1rem - 8px);
margin: 4px;
border-radius: 50%;
background-color: currentColor;
}
</style>
</head>
<body>
<div class="stagger-visualizer">
<div class="dots-wrapper"></div>
</div>
</body>
<script type="module">
import anime from '../../src/index.js';
var advancedStaggeringAnimation = (function() {
var staggerVisualizerEl = document.querySelector('.stagger-visualizer');
var dotsWrapperEl = staggerVisualizerEl.querySelector('.dots-wrapper');
var dotsFragment = document.createDocumentFragment();
var grid = [32, 16];
var cellSize = 1;
var numberOfElements = grid[0] * grid[1];
var animation;
var paused = true;
for (var i = 0; i < numberOfElements; i++) {
var dotEl = document.createElement('div');
dotEl.classList.add('dot');
dotsFragment.appendChild(dotEl);
}
dotsWrapperEl.appendChild(dotsFragment);
var index = anime.random(0, numberOfElements-1);
var nextIndex = 0;
function play() {
paused = false;
if (animation) animation.pause();
nextIndex = anime.random(0, numberOfElements-1);
var saturation = 75;
var colorStart = anime.random(0, 256);
var colorEnd = anime.random(0, 256);
var colorRangeValue = [colorStart, colorEnd];
var luminosityStart = anime.random(60, 80);
var luminosityEnd = anime.random(20, 40);
var luminosityRangeValue = [luminosityStart, luminosityEnd];
function staggeredGridColors(el, i, total) {
var hue = Math.round(anime.stagger(colorRangeValue, {grid: grid, from: index})(el, i, total));
var luminosity = Math.round(anime.stagger(luminosityRangeValue, {grid: grid, from: index})(el, i, total));
return 'hsl(' + hue + ', ' + saturation + '%, ' + luminosity + '%)';
}
animation = anime({
targets: '.stagger-visualizer .dot',
keyframes: [
{
zIndex: function(el, i, total) {
return Math.round(anime.stagger([numberOfElements, 0], {grid: grid, from: index})(el, i, total));
},
translateX: anime.stagger('-.001rem', {grid: grid, from: index, axis: 'x'}),
translateY: anime.stagger('-.001rem', {grid: grid, from: index, axis: 'y'}),
duration: 200
}, {
translateX: anime.stagger('.075rem', {grid: grid, from: index, axis: 'x'}),
translateY: anime.stagger('.075rem', {grid: grid, from: index, axis: 'y'}),
scale: anime.stagger([2, .2], {grid: grid, from: index}),
backgroundColor: staggeredGridColors,
duration: 450
}, {
translateX: 0,
translateY: 0,
scale: 1,
duration: 500,
}
],
delay: anime.stagger(60, {grid: grid, from: index}),
easing: 'easeInOutQuad',
complete: play
}, 30)
index = nextIndex;
}
play();
})();
</script>
</html>

View File

@ -0,0 +1,152 @@
<!DOCTYPE html>
<html>
<head>
<title>advanced staggering • anime.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:title" content="anime.js">
<meta property="og:url" content="https://animejs.com">
<meta property="og:description" content="Javascript Animation Engine">
<meta property="og:image" content="https://animejs.com/documentation/assets/img/icons/og.png">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="anime.js">
<meta name="twitter:site" content="@juliangarnier">
<meta name="twitter:description" content="Javascript Animation Engine">
<meta name="twitter:image" content="https://animejs.com/documentation/assets/img/icons/twitter.png">
<link rel="apple-touch-icon-precomposed" href="../assets/img/social-media-image.png">
<link rel="icon" type="image/png" href="../assets/img/favicon.png" >
<link href="../assets/css/animejs.css" rel="stylesheet">
<link href="../assets/css/documentation.css" rel="stylesheet">
<style>
:root {
font-size: 24px;
}
body {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
height: 100vh;
}
.stagger-visualizer {
position: relative;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
width: 16rem;
height: 16rem;
}
.stagger-visualizer .dot {
position: relative;
width: .25rem;
height: .25rem;
margin: .375rem;
background-color: currentColor;
border-radius: 50%;
}
.stagger-visualizer .cursor {
position: absolute;
z-index: 1;
top: 0;
left: 0;
width: 1rem;
height: 1rem;
background-color: currentColor;
border-radius: 50%;
}
</style>
</head>
<body>
<div class="stagger-visualizer">
<div class="cursor color-red"></div>
</div>
</body>
<script type="module">
import anime from '../../src/index.js';
const staggerVisualizerEl = document.querySelector('.stagger-visualizer');
const fragment = document.createDocumentFragment();
const numberOfElements = 16*16;
var animation;
for (let i = 0; i < numberOfElements; i++) {
const dotEl = document.createElement('div');
dotEl.classList.add('dot');
fragment.appendChild(dotEl);
}
staggerVisualizerEl.appendChild(fragment);
let index = anime.random(0, numberOfElements);
let nextIndex = 0;
function animateGrid() {
if (animation) animation.pause();
nextIndex = anime.random(0, numberOfElements);
anime.set('.cursor', {
translateX: anime.stagger('-1rem', {grid: [16, 16], from: index, axis: 'x'}),
translateY: anime.stagger('-1rem', {grid: [16, 16], from: index, axis: 'y'})
});
animation = anime.timeline({
easing: 'easeInOutQuad',
complete: animateGrid
})
.add({
targets: '.cursor',
keyframes: [
{ scale: .625 },
{ scale: 1.125 },
{ scale: 1 }
],
duration: 600
})
.add({
targets: '.dot',
keyframes: [
{
translateX: anime.stagger('-.175rem', {grid: [16, 16], from: index, axis: 'x'}),
translateY: anime.stagger('-.175rem', {grid: [16, 16], from: index, axis: 'y'}),
duration: 200
}, {
translateX: anime.stagger('.125rem', {grid: [16, 16], from: index, axis: 'x'}),
translateY: anime.stagger('.125rem', {grid: [16, 16], from: index, axis: 'y'}),
scale: 2,
duration: 500
}, {
translateX: 0,
translateY: 0,
scale: 1,
duration: 600,
}
],
delay: anime.stagger(50, {grid: [16, 16], from: index})
}, '-=600')
.add({
targets: '.cursor',
translateX: { value: anime.stagger('-1rem', {grid: [16, 16], from: nextIndex, axis: 'x'}), duration: anime.random(400, 1200) },
translateY: { value: anime.stagger('-1rem', {grid: [16, 16], from: nextIndex, axis: 'y'}), duration: anime.random(400, 1200) },
easing: 'easeOutSine'
}, '-=1100')
index = nextIndex;
}
animateGrid();
</script>
</html>

View File

@ -0,0 +1,243 @@
<!DOCTYPE html>
<html>
<head>
<title>Anime MGS logo animation | anime.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:title" content="anime.js">
<meta property="og:url" content="https://animejs.com">
<meta property="og:description" content="Javascript Animation Engine">
<meta property="og:image" content="https://animejs.com/documentation/assets/img/icons/og.png">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="anime.js">
<meta name="twitter:site" content="@juliangarnier">
<meta name="twitter:description" content="Javascript Animation Engine">
<meta name="twitter:image" content="https://animejs.com/documentation/assets/img/icons/twitter.png">
<link rel="apple-touch-icon-precomposed" href="../assets/img/social-media-image.png">
<link rel="icon" type="image/png" href="../assets/img/favicon.png">
<link href="../assets/css/animejs.css" rel="stylesheet">
<link href="../assets/css/documentation.css" rel="stylesheet">
<script src="../../lib/anime.min.js"></script>
<!-- <script src="../assets/js/anime/anime.2.2.0.js"></script> -->
<style>
html,
body {
background-color: black;
}
section {
position: absolute;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
}
.mgs-logo { margin: auto; }
.vert { transform-origin: center bottom; }
.hori { transform-origin: 0% 50%; }
.diag-left { transform-origin: 100% 100%; }
.diag-right { transform-origin: 100% 0%; }
.stripes path,
.text-fills path,
.katakana path,
.line {
opacity: 0
}
</style>
</head>
<body>
<section>
<svg class="mgs-logo" width="100%" height="448" viewBox="0 0 1024 448">
<g class="stripes" transform="translate(321.000000, 160.000000)" fill="#FFF">
<path d="M8,20 L12,16 L92,16 L88,20 L8,20 L8,20 L8,20 L8,20 Z" class="stripe stripe-left"></path>
<path d="M4,24 L0,28 L80,28 L84,24 L4,24 L4,24 L4,24 L4,24 Z" class="stripe stripe-left"></path>
<path d="M16,12 L20,8 L100,8 L96,12 L16,12 L16,12 L16,12 L16,12 Z" class="stripe stripe-left"></path>
<path d="M24,4 L28,0 L108,7.10542736e-15 L104,4 L24,4 L24,4 L24,4 L24,4 Z" class="stripe stripe-left"></path>
</g>
<g class="stripes" transform="translate(592.000000, 160.000000)" fill="#FFF">
<path d="M8,20 L12,16 L92,16 L88,20 L8,20 L8,20 L8,20 L8,20 Z" class="stripe stripe-right"></path>
<path d="M4,24 L0,28 L80,28 L84,24 L4,24 L4,24 L4,24 L4,24 Z" class="stripe stripe-right"></path>
<path d="M16,12 L20,8 L100,8 L96,12 L16,12 L16,12 L16,12 L16,12 Z" class="stripe stripe-right"></path>
<path d="M24,4 L28,0 L108,7.10542736e-15 L104,4 L24,4 L24,4 L24,4 L24,4 Z" class="stripe stripe-right"></path>
</g>
<g class="katakana" transform="translate(202.000000, 128.000000)" fill="#FFF">
<path d="M55,33 L56,32 L136,32 L135,33 L55,33 Z" data-d="M0,92 L60,32 L140,32 L80,92 L0,92 Z"></path>
<path d="M28,28 L29,28 L1,0 L0,0 L28,28 Z" data-d="M32,28 L230,28 L202,0 L4,0 L32,28 Z"></path>
<path d="M232,28 L204,0 L205,0 L233,28 L232,28 Z" data-d="M236,28 L208,0 L388,0 L416,28 L236,28 Z"></path>
<path d="M169,92 L197,64 L199,64 L171,92 L169,92 Z" data-d="M173,92 L201,64 L381,64 L353,92 L173,92 Z"></path>
<path d="M435,92 L355,92 L356,91 L436,91 L435,92 Z" data-d="M439,92 L359,92 L387,64 L467,64 L439,92 Z"></path>
<path d="M497,28 L498,28 L470,0 L469,0 L497,28 Z" data-d="M422,28 L502,28 L474,0 L394,0 L422,28 Z"></path>
<path d="M476,65 L556,65 L555,64 L475,64 L476,65 Z" data-d="M507,92 L587,92 L559,64 L479,64 L507,92 Z"></path>
<path d="M554,59 L553,60 L473,60 L474,59 L554,59 Z" data-d="M617,0 L557,60 L477,60 L537,0 L617,0 Z"></path>
</g>
<g class="text-fills" transform="translate(128.000000, 240.000000)" fill="#FFF">
<path d="M0,48 L0,68 L16,84 L96,84 L112,68 L112,16 L96,0 L20,0 L0,20 L92,20 L92,64 L20,64 L20,52 L60,52 L80,32 L16,32 L0,48 Z" id="a"></path>
<path d="M216,84 L236,84 L236,16 L220,0 L140,0 L124,16 L124,84 L144,84 L144,20 L216,20 L216,84 L216,84 Z" id="n"></path>
<path d="M248,0 L268,0 L268,84 L248,84 L248,0 Z" id="i"></path>
<path d="M300,20 L300,84 L280,84 L280,16 L296,0 L408,0 L424,16 L424,84 L404,84 L404,20 L362,20 L362,84 L342,84 L342,20 L300,20 Z" id="m"></path>
<path d="M548,36 L548,16 L532,2.55795385e-13 L452,2.4158453e-13 L436,16 L436,68 L452,84 L528,84 L548,64 L456,64 L456,20 L528,20 L528,32 L488,32 L468,52 L532,52 L548,36 L548,36 Z" id="e"></path>
<path d="M562,64 L582,84 L626,84 L642,68 L642,0 L622,0 L622,64 L562,64 Z" id="j"></path>
<path d="M674,20 L766,20 L746,0 L670,0 L654,16 L654,36 L670,52 L746,52 L746,64 L654,64 L674,84 L750,84 L766,68 L766,48 L750,32 L674,32 L674,20 Z" id="s"></path>
</g>
<g stroke="#FFF" stroke-width="2" fill="none" fill-rule="evenodd">
<path d="M148,292 L148,304" class="line vert" stroke-linecap="square"></path>
<path d="M128,288 L128,308" class="line vert" stroke-linecap="square"></path>
<path d="M148,240 L128,260" class="line diag-right"></path>
<path d="M128,308 L144,324" class="line diag-left"></path>
<path d="M144,272 L128,288" class="line diag-right"></path>
<path d="M148,240 L224,240" class="line hori" stroke-linecap="square"></path>
<path d="M144,272 L208,272" class="line hori" stroke-linecap="square"></path>
<path d="M148,292 L188,292" class="line hori" stroke-linecap="square"></path>
<path d="M148,304 L220,304" class="line hori" stroke-linecap="square"></path>
<path d="M144,324 L224,324" class="line hori" stroke-linecap="square"></path>
<path d="M129,260 L220,260" class="line hori" stroke-linecap="square"></path>
<path d="M208,272 L188,292" class="line diag-right"></path>
<path d="M220,260 L220,304" class="line vert" stroke-linecap="square"></path>
<path d="M224,240 L240,256" class="line diag-left"></path>
<path d="M240,308 L224,324" class="line diag-right"></path>
<path d="M240,256 L240,308" class="line vert" stroke-linecap="square"></path>
<path d="M252,256 L252,324" class="line vert" stroke-linecap="square"></path>
<path d="M268,240 L252,256" class="line diag-right"></path>
<path d="M252,324 L272,324" class="line hori" stroke-linecap="square"></path>
<path d="M272,260 L272,324" class="line vert" stroke-linecap="square"></path>
<path d="M268,240 L348,240" class="line hori" stroke-linecap="square"></path>
<path d="M272,260 L344,260" class="line hori" stroke-linecap="square"></path>
<path d="M344,260 L344,324" class="line vert" stroke-linecap="square"></path>
<path d="M348,240 L364,256" class="line diag-left"></path>
<path d="M344,324 L364,324" class="line hori" stroke-linecap="square"></path>
<path d="M364,256 L364,324" class="line vert" stroke-linecap="square"></path>
<path d="M376,240 L376,324" class="line vert" stroke-linecap="square"></path>
<path d="M376,324 L396,324" class="line hori" stroke-linecap="square"></path>
<path d="M376,240 L396,240" class="line hori" stroke-linecap="square"></path>
<path d="M396,240 L396,324" class="line vert" stroke-linecap="square"></path>
<path d="M408,256 L408,324" class="line vert" stroke-linecap="square"></path>
<path d="M424,240 L408,256" class="line diag-right"></path>
<path d="M408,324 L428,324" class="line hori" stroke-linecap="square"></path>
<path d="M428,261 L428,323" class="line vert" stroke-linecap="square"></path>
<path d="M424,240 L536,240" class="line hori" stroke-linecap="square"></path>
<path d="M428,260 L470,260" class="line hori" stroke-linecap="square"></path>
<path d="M470,261 L470,323" class="line vert" stroke-linecap="square"></path>
<path d="M470,324 L490,324" class="line hori" stroke-linecap="square"></path>
<path d="M490,261 L490,323" class="line vert" stroke-linecap="square"></path>
<path d="M490,260 L532,260" class="line hori" stroke-linecap="square"></path>
<path d="M532,261 L532,323" class="line vert" stroke-linecap="square"></path>
<path d="M536,240 L552,256" class="line diag-left"></path>
<path d="M532,324 L552,324" class="line hori" stroke-linecap="square"></path>
<path d="M552,256 L552,324" class="line vert" stroke-linecap="square"></path>
<path d="M564,256 L564,308" class="line vert" stroke-linecap="square"></path>
<path d="M564,308 L580,324" class="line diag-left"></path>
<path d="M580,240 L564,256" class="line diag-right"></path>
<path d="M584,260 L584,304" class="line vert" stroke-linecap="square"></path>
<path d="M616,272 L596,292" class="line diag-right"></path>
<path d="M580,240 L660,240" class="line hori" stroke-linecap="square"></path>
<path d="M584,260 L656,260" class="line hori" stroke-linecap="square"></path>
<path d="M580,324 L656,324" class="line hori" stroke-linecap="square"></path>
<path d="M596,292 L660,292" class="line hori" stroke-linecap="square"></path>
<path d="M616,272 L656,272" class="line hori" stroke-linecap="square"></path>
<path d="M656,260 L656,272" class="line vert" stroke-linecap="square"></path>
<path d="M660,240 L676,256" class="line diag-left"></path>
<path d="M676,304 L656,324" class="line diag-right"></path>
<path d="M676,276 L660,292" class="line diag-right"></path>
<path d="M584,304 L676,304" class="line hori" stroke-linecap="square"></path>
<path d="M676,256 L676,276" class="line vert" stroke-linecap="square"></path>
<path d="M690,304 L710,324" class="line diag-left"></path>
<path d="M690,304 L750,304" class="line hori" stroke-linecap="square"></path>
<path d="M710,324 L754,324" class="line hori" stroke-linecap="square"></path>
<path d="M750,240 L750,304" class="line vert" stroke-linecap="square"></path>
<path d="M770,308 L754,324" class="line diag-right"></path>
<path d="M750,240 L770,240" class="line hori" stroke-linecap="square"></path>
<path d="M770,240 L770,308" class="line vert" stroke-linecap="square"></path>
<path d="M782,256 L782,276" class="line vert" stroke-linecap="square"></path>
<path d="M782,276 L798,292" class="line diag-left"></path>
<path d="M782,304 L802,324" class="line diag-left"></path>
<path d="M798,240 L782,256" class="line diag-right"></path>
<path d="M802,260 L802,272" class="line vert" stroke-linecap="square"></path>
<path d="M798,240 L874,240" class="line hori" stroke-linecap="square"></path>
<path d="M802,272 L878,272" class="line hori" stroke-linecap="square"></path>
<path d="M802,324 L878,324" class="line hori" stroke-linecap="square"></path>
<path d="M798,292 L874,292" class="line hori" stroke-linecap="square"></path>
<path d="M782,304 L874,304" class="line hori" stroke-linecap="square"></path>
<path d="M874,292 L874,304" class="line vert" stroke-linecap="square"></path>
<path d="M878,272 L894,288" class="line diag-left"></path>
<path d="M874,240 L894,260" class="line diag-left"></path>
<path d="M894,308 L878,324" class="line diag-right"></path>
<path d="M802,260 L894,260" class="line hori" stroke-linecap="square"></path>
<path d="M894,288 L894,308" class="line vert" stroke-linecap="square"></path>
</g>
</svg>
</section>
<script>
var logoAnimation = anime.timeline({
direction: 'alternate',
loop: true
});
logoAnimation
.add({
targets: '.stripes path',
translateX: [-1000, 0],
opacity: {
value: 1,
duration: 100
},
fill: '#F9C100',
delay: (el, i) => 2200 + (i * 75),
duration: 400,
easing: 'easeOutExpo',
}, 0)
.add({
targets: '.katakana path',
d: (el) => el.getAttribute('data-d'),
opacity: {
value: [0, 1],
duration: 100
},
fill: '#F9C100',
delay: (el, i) => 2400 + (i * 120),
duration: 1200,
easing: 'easeOutCirc',
}, 0)
.add({
targets: '.text-fills path',
opacity: [0, 1],
fill: '#F9C100',
easing: 'easeOutExpo',
duration: 200,
delay: (t, i) => 3300 + (anime.random(0, 450)),
}, 0)
.add({
targets: '.line',
translateX: (target) => {
let x = 1200;
let translate;
if (target.classList.contains('hori')) translate = anime.random(0, 1) ? x : -x;
if (target.classList.contains('diag-right') || target.classList.contains('diag-left')) translate = x / 3;
return [translate, 0];
},
translateY: (target) => {
let y = 1200;
let translate;
if (target.classList.contains('vert')) translate = anime.random(0, 1) ? y : -y;
if (target.classList.contains('diag-right')) translate = -y / 3;
if (target.classList.contains('diag-left')) translate = y / 3;
return [translate, 0];
},
stroke: '#F9C100',
opacity: {
value: [0, 1],
duration: 100,
},
delay: (t, i) => (i * 25),
duration: 500,
easing: 'easeOutSine',
}, 0);
</script>
<script src="../assets/js/vendors/stats.min.js"></script>
</body>
</html>

View File

@ -0,0 +1,337 @@
<!DOCTYPE html>
<html>
<head>
<title>Anime logo animation | anime.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:title" content="anime.js">
<meta property="og:url" content="https://animejs.com">
<meta property="og:description" content="Javascript Animation Engine">
<meta property="og:image" content="https://animejs.com/documentation/assets/img/icons/og.png">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="anime.js">
<meta name="twitter:site" content="@juliangarnier">
<meta name="twitter:description" content="Javascript Animation Engine">
<meta name="twitter:image" content="https://animejs.com/documentation/assets/img/icons/twitter.png">
<link rel="apple-touch-icon-precomposed" href="../assets/img/social-media-image.png">
<link rel="icon" type="image/png" href="../assets/img/favicon.png">
<link href="../assets/css/animejs.css" rel="stylesheet">
<link href="../assets/css/documentation.css" rel="stylesheet">
<script src="../../lib/anime.min.js"></script>
<!-- <script src="../assets/js/anime/anime.2.2.0.js"></script> -->
<style>
body {
opacity: 0;
display: flex;
flex-direction: column;
justify-content: center;
}
body.ready {
opacity: 1;
}
.logo-animation {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
margin-top: -40px;
}
.letters {
position: relative;
display: flex;
width: 682px;
height: 162px;
}
.letter {
position: relative;
width: 162px;
height: 162px;
}
.letter:not(:first-child) {
margin-left: -42px;
}
.letter-i {
z-index: 1;
width: 82px;
transform-origin: 100% 50%;
}
.dot {
position: absolute;
width: 42px;
height: 42px;
transform: scale(0);
}
.dot-i {
top: 0;
left: 240px;
}
.dot-e {
bottom: 0;
right: 0;
}
.logo-icon {
display: flex;
position: absolute;
left: 230px;
top: -10px;
width: 222px;
height: 62px;
}
.icon {
width: 62px;
height: 62px;
opacity: 0;
}
.icon-text {
position: absolute;
top: 60px;
left: 60px;
width: 160px;
height: 62px;
}
.icon-text path,
.icon-text polygon {
opacity: 0;
}
</style>
</head>
<body>
<div class="logo-animation">
<div class="letters">
<div class="letter letter-a">
<svg viewBox="0 0 162 162">
<g fill="none" fill-rule="evenodd" stroke="#5E89FB">
<path class="fill in" stroke-width="40" d="M101 141H81a60 60 0 1 1 0-120c33.14 0 59 26.86 60 60v80"/>
<path class="fill out" stroke-width="40" d="M141 161V81c-1-33.14-26.86-60-60-60a60 60 0 1 0 0 120h20"/>
<path class="line out" stroke-width="2" d="M121 161V81.33C120.18 58.59 102.7 41 81 41a40 40 0 1 0 0 80h20v40H81A80 80 0 1 1 81 1c43.8 0 78.66 35.27 80 79.7V161h-40z"/>
</g>
</svg>
</div>
<div class="letter letter-n">
<svg viewBox="0 0 162 162">
<g fill="none" fill-rule="evenodd" stroke="#FB155A">
<path class="fill in" stroke-width="40" d="M21 161V1"/>
<path class="fill out" stroke-width="40" d="M21 1v160"/>
<path class="fill in" stroke-width="40" d="M21 161V81c1-33.14 26.86-60 60-60a60 60 0 0 1 60 60v80"/>
<path class="fill out" stroke-width="40" d="M141 161V81a60 60 0 0 0-60-60c-33.14 0-59 26.86-60 60v80"/>
<path class="line out" stroke-width="2" d="M41 161V1H1v160h40z"/>
<path class="line out" stroke-width="2" d="M1 161V80.4C2.35 36.27 37.2 1 81 1a80 80 0 0 1 80 80v80h-40V81a40 40 0 0 0-40-40c-21.7 0-39.18 17.59-40 40.33V161H1z"/>
</g>
</svg>
</div>
<div class="letter letter-i">
<svg viewBox="0 0 82 162">
<g fill="none" fill-rule="evenodd" stroke="#18FF92">
<path class="fill in" stroke-width="40" d="M21 61v20a60 60 0 0 0 60 60"/>
<path class="fill out" stroke-width="40" d="M81 141a60 60 0 0 1-60-60V61"/>
<path class="line out" stroke-width="2" d="M81 121a40 40 0 0 1-40-40V61H1v20a80 80 0 0 0 80 80v-40z"/>
</g>
</svg>
</div>
<div class="letter letter-m-1">
<svg viewBox="0 0 162 162">
<g fill="none" fill-rule="evenodd" stroke="#5E89FB">
<path class="fill in" stroke-width="40" d="M21 161V1"/>
<path class="fill out" stroke-width="40" d="M21 1v160"/>
<path class="fill in" stroke-width="40" d="M21 161V81c1-33.14 26.86-60 60-60a60 60 0 0 1 60 60v80"/>
<path class="fill out" stroke-width="40" d="M141 161V81a60 60 0 0 0-60-60c-33.14 0-59 26.86-60 60v80"/>
<path class="line out" stroke-width="2" d="M41 161V1H1v160h40z"/>
<path class="line out" stroke-width="2" d="M1 161V80.4C2.35 36.27 37.2 1 81 1a80 80 0 0 1 80 80v80h-40V81a40 40 0 0 0-40-40c-21.7 0-39.18 17.59-40 40.33V161H1z"/>
</g>
</svg>
</div>
<div class="letter letter-m-2">
<svg viewBox="0 0 162 162">
<g fill="none" fill-rule="evenodd" stroke="#FB155A">
<path class="fill in" stroke-width="40" d="M21 161V81c1-33.14 26.86-60 60-60a60 60 0 0 1 60 60v80"/>
<path class="fill out" stroke-width="40" d="M141 161V81a60 60 0 0 0-60-60c-33.14 0-59 26.86-60 60v80"/>
<path class="line out" stroke-width="2" d="M1 161V80.4C2.35 36.27 37.2 1 81 1a80 80 0 0 1 80 80v80h-40V81a40 40 0 0 0-40-40c-21.7 0-39.18 17.59-40 40.33V161H1z"/>
</g>
</svg>
</div>
<div class="letter letter-e">
<svg viewBox="0 0 162 162">
<g fill="none" fill-rule="evenodd" stroke="#18FF92">
<path class="fill in" stroke-width="40" d="M81 101h60V81c-1-33.14-26.86-60-60-60a60 60 0 1 0 0 120"/>
<path class="fill out" stroke-width="40" d="M81 141a60 60 0 1 1 0-120c33.14 0 59 26.86 60 60v20H81"/>
<path class="line out" stroke-width="2" d="M81 81v40h80V80.7C159.66 36.27 124.8 1 81 1a80 80 0 1 0 0 160v-40a40 40 0 1 1 0-80c21.6 0 39.01 17.42 39.99 40H81z"/>
</g>
</svg>
</div>
<div class="logo-icon">
<div class="icon">
<svg viewBox="0 0 62 62">
<g fill="none" fill-rule="evenodd" stroke-width="2" transform="translate(1 1)">
<path class="icon-curve" stroke="#FF1554" d="M0 16a80.88 80.88 0 0 1 44 44"/>
<path class="icon-line" stroke="#5E89FB" d="M4 0h54a2 2 0 0 1 2 2.01V58A2 2 0 0 1 58 60H2a2 2 0 0 1-2-2.01V2A2 2 0 0 1 2 0h2z"/>
<rect width="40" height="40" x="10" y="10" stroke="#18FF92" rx="20"/>
</g>
</svg>
</div>
<div class="icon-text">
<svg viewBox="0 0 160 62">
<g fill="#FBF3FB" fill-rule="evenodd">
<path d="M27.33 18h1.73l10.15 25.7h-1.69l-3.24-8.24H21.97l-3.28 8.24H17L27.33 18zm6.45 16.1l-5.51-14.55h-.07l-5.73 14.54h11.3z"/>
<polygon points="51.334 18 53.314 18 69.55 41.58 69.622 41.58 69.622 18 71.206 18 71.206 43.704 69.334 43.704 52.99 19.944 52.918 19.944 52.918 43.704 51.334 43.704"/>
<polygon points="86.027 18 87.611 18 87.611 43.704 86.027 43.704"/>
<polygon points="102.433 18 104.701 18 114.745 41.94 114.817 41.94 124.753 18 127.021 18 127.021 43.704 125.437 43.704 125.437 19.944 125.365 19.944 115.573 43.704 113.989 43.704 104.089 19.944 104.017 19.944 104.017 43.704 102.433 43.704"/>
<polygon points="141.843 18 159.123 18 159.123 19.368 143.427 19.368 143.427 29.664 158.187 29.664 158.187 31.032 143.427 31.032 143.427 42.336 159.303 42.336 159.303 43.704 141.843 43.704"/>
</g>
</svg>
</div>
</div>
<div class="dot dot-i">
<svg viewBox="0 0 42 42">
<g fill="none" fill-rule="evenodd">
<rect width="40" height="40" x="1" y="1" fill="#17F28C" rx="20"/>
</g>
</svg>
</div>
<div class="dot dot-e">
<svg viewBox="0 0 42 42">
<g fill="none" fill-rule="evenodd">
<rect width="40" height="40" x="1" y="1" fill="#FFFFFF" rx="20"/>
</g>
</svg>
</div>
</div>
</div>
<script>
var logoAnimation = (function() {
var logoEl = document.querySelector('.logo-animation');
var pathEls = document.querySelectorAll('.logo-animation path:not(.icon-curve)');
var innerWidth = window.innerWidth;
var maxWidth = 740;
var logoScale = innerWidth <= maxWidth ? innerWidth / maxWidth : 1;
var logoTimeline = anime.timeline({ autoplay: false, direction: 'alternate', loop: true });
logoEl.style.transform = 'translateY(50px) scale('+logoScale+')';
for (var i = 0; i < pathEls.length; i++) {
var el = pathEls[i];
el.setAttribute('stroke-dashoffset', anime.setDashoffset(el));
}
logoTimeline
.add({
targets: '.dot-e',
translateX: [
{ value: -600, duration: 520, delay: 200, easing: 'easeInQuart' },
{ value: [-100, 0], duration: 500, delay: 1000, easing: 'easeOutQuart' }
],
scale: [
{ value: [0, 1], duration: 200, easing: 'easeOutBack' },
{ value: 0, duration: 20, delay: 500, easing: 'easeInQuart' },
{ value: 1, duration: 200, delay: 1000, easing: 'easeOutQuart' },
{ value: 0, duration: 400, delay: 500, easing: 'easeInBack' }
]
}, 0)
.add({
targets: '.dot-i',
translateY: { value: [-200, 0], duration: 500, elasticity: 400 },
scale: [
{ value: [0, 1], duration: 100, easing: 'easeOutQuart' },
{ value: 0, duration: 400, delay: 1400, easing: 'easeInBack' }
],
delay: 1200
}, 0)
.add({
targets: '.fill.in',
strokeDashoffset: {
value: [anime.setDashoffset, 0],
duration: 600,
delay: function(el, i, t) { return 700 + ( i * 100 ); },
easing: 'easeOutQuart'
},
stroke: {
value: ['#FFF', function(el) { return anime.get(el.parentNode, 'stroke') } ],
duration: 500,
delay: 500,
easing: 'easeInQuad'
},
opacity: {
value: 0,
duration: 1,
delay: function(el, i, t) { return 1900 + ( i * 80 ); },
}
}, 0)
.add({
targets: '.fill.out',
strokeDashoffset: [
{ value: [anime.setDashoffset, anime.setDashoffset], duration: 1890 },
{
value: [0, anime.setDashoffset],
duration: 800,
delay: function(el, i) { return (i * 80); },
easing: 'easeInQuart'
}
]
}, 0)
.add({
targets: '.line.out',
strokeDashoffset: {
value: [0, anime.setDashoffset],
duration: 1200,
delay: function(el, i, t) { return 2500 + ( i * 100 ); },
easing: 'easeInQuart'
},
strokeWidth: {
value: [0, 2],
delay: function(el, i, t) { return 2000 + ( i * 100 ); },
duration: 200,
easing: 'linear'
}
}, 0)
.add({
targets: '.icon',
opacity: { value: 1, duration: 10, delay: 2800, easing: 'linear' },
translateY: { value: 60, duration: 800 },
delay: 4200
}, 0)
.add({
targets: '.icon-line',
strokeDashoffset: [
{ value: [anime.setDashoffset, anime.setDashoffset], duration: 3000 },
{ value: 0, duration: 1200, easing: 'easeInOutQuart' }
],
strokeWidth: {
value: [8, 2],
delay: 3000,
duration: 800,
easing: 'easeInQuad'
},
stroke: {
value: ['#FFF', function(el) { return anime.get(el, 'stroke') } ],
duration: 800,
delay: 3400,
easing: 'easeInQuad'
}
}, 0)
.add({
targets: ['.icon-text path', '.icon-text polygon'],
translateY: [50, 0],
opacity: { value: [0, 1], duration: 100, easing: 'linear' },
delay: function(el, i, t) { return 4200 + ( i * 20 ); }
}, 0)
function init() {
document.body.classList.add('ready');
logoTimeline.play();
}
return {
init: init
}
})();
window.onload = function() {
logoAnimation.init();
}
</script>
<script src="../assets/js/vendors/stats.min.js"></script>
</body>
</html>

View File

@ -0,0 +1,391 @@
<!DOCTYPE html>
<html>
<head>
<title>Anime logo animation | anime.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:title" content="anime.js">
<meta property="og:url" content="https://animejs.com">
<meta property="og:description" content="Javascript Animation Engine">
<meta property="og:image" content="https://animejs.com/documentation/assets/img/icons/og.png">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="anime.js">
<meta name="twitter:site" content="@juliangarnier">
<meta name="twitter:description" content="Javascript Animation Engine">
<meta name="twitter:image" content="https://animejs.com/documentation/assets/img/icons/twitter.png">
<link rel="apple-touch-icon-precomposed" href="../assets/img/social-media-image.png">
<link rel="icon" type="image/png" href="../assets/img/favicon.png">
<link href="../assets/css/animejs.css" rel="stylesheet">
<link href="../assets/css/documentation.css" rel="stylesheet">
<!-- <script src="../../lib/anime.min.js"></script> -->
<!-- <script src="../assets/js/anime/anime.2.2.0.js"></script> -->
<style>
body {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
width: 100%;
height: 100vh;
}
/* Logo */
.main-logo {
position: relative;
display: flex;
flex-direction: column;
width: 100%;
max-width: 600px;
}
.logo-animation-wrapper {
position: relative;
width: 100%;
padding-bottom: 12%;
}
.logo-animation {
pointer-events: none;
overflow: visible;
display: flex;
flex-shrink: 0;
flex-direction: column;
justify-content: center;
align-items: center;
position: absolute;
top: 50%;
left: 50%;
width: 1000px;
height: 240px;
margin: -120px 0 0 -500px;
/*transform: scale(.633333);*/
}
.anime-logo {
overflow: visible;
position: relative;
display: flex;
flex-direction: column;
width: 1000px;
height: 120px;
}
.anime-logo-signs {
overflow: visible;
display: flex;
align-items: flex-end;
position: relative;
width: 100%;
height: 512px;
margin-top: -352px;
}
.logo-letter {
display: flex;
align-items: flex-end;
overflow: hidden;
height: 100%;
}
.bounced {
transform-origin: 50% 100% 0px;
transform: translateY(200px) scaleX(.55) scaleY(.8);
}
.logo-animation .bounce {
overflow: visible;
position: absolute;
left: 0;
bottom: 70px;
/* stroke: red;*/
}
.logo-animation .dot {
opacity: 0.001;
position: absolute;
z-index: 10;
top: 0;
left: 0;
width: 40px;
height: 40px;
margin: -20px 0 0 -20px;
background-color: currentColor;
transform: translate3d(0,0,0);
}
.logo-animation .logo-letter svg {
overflow: visible;
fill: none;
fill-rule: evenodd;
}
.logo-animation .line {
fill: none;
fill-rule: evenodd;
stroke-linecap: square;
stroke-width: 40;
stroke: currentColor;
}
.logo-animation .fill {
opacity: .001;
stroke: currentColor;
stroke-width: 40px;
}
.logo-text {
opacity: .001;
margin-top: .25em;
font-weight: 400;
font-size: 11px;
line-height: 1;
letter-spacing: .125em;
text-align: justify;
word-break: keep-all;
}
.logo-text:after {
content: "";
display: inline-block;
width: 100%;
height: 0;
font-size: 0;
line-height: 0;
}
</style>
</head>
<body>
<div class="main-logo">
<div class="logo-animation-wrapper">
<div class="logo-animation">
<div class="anime-logo">
<div class="anime-logo-signs">
<div class="logo-letter letter-a">
<svg class="bounced" viewBox="0 0 200 240" width="200" height="240">
<path class="line" d="M30 20h130c9.996 0 10 40 10 60v140H41c-11.004 0-11-40-11-60s-.004-60 10-60h110"/>
</svg>
</div>
<div class="logo-letter letter-n">
<svg class="bounced" viewBox="0 0 200 240" width="200" height="240">
<path class="line" d="M170 220V60c0-31.046-8.656-40-19.333-40H49.333C38.656 20 30 28.954 30 60v160"/>
</svg>
</div>
<div class="logo-letter letter-i">
<svg class="bounced" viewBox="0 0 60 240" width="60" height="240">
<path class="line"
d="M30 20v200"
data-d2="M30 100v120"
/>
</svg>
</div>
<div class="logo-letter letter-m">
<svg class="bounced" viewBox="0 0 340 240" width="340" height="240" fill="none" fill-rule="evenodd">
<path class="line"
d="M240,220 L240,60 C240,28.954305 231.344172,20 220.666667,20 C171.555556,20 254.832031,20 170,20 C85.1679688,20 168.444444,20 119.333333,20 C108.655828,20 100,28.954305 100,60 L100,220"
data-d2="M310,220 L310,60 C310,28.954305 301.344172,20 290.666667,20 C241.555556,20 254.832031,110 170,110 C85.1679688,110 98.4444444,20 49.3333333,20 C38.6558282,20 30,28.954305 30,60 L30,220"
data-d3="M310,220 L310,60 C310,28.954305 301.344172,20 290.666667,20 C241.555556,20 254.832031,20 170,20 C85.1679688,20 98.4444444,20 49.3333333,20 C38.6558282,20 30,28.954305 30,60 L30,220"
/>
</svg>
</div>
<div class="logo-letter letter-e">
<svg class="bounced" viewBox="0 0 200 240" width="200" height="240">
<path class="line" d="M50 140h110c10 0 10-40 10-60s0-60-10-60H40c-10 0-10 40-10 60v80c0 20 0 60 10 60h130"/>
</svg>
</div>
<div class="bounce">
<svg viewBox="0 0 1000 260" width="1000" height="260" fill="none">
<path d="M630,240 C630,111.154418 608.971354,40 530.160048,40 C451.348741,40 430,127.460266 430,210"/>
</svg>
<div class="dot"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<script type="module">
import anime from '../../src/index.js';
function fitElementToParent(el, padding, exception) {
var timeout = null;
function resize() {
if (timeout) clearTimeout(timeout);
anime.set(el, {scale: 1});
if (exception) anime.set(exception, {scale: 1});
var pad = padding || 0;
var parentEl = el.parentNode;
var elOffsetWidth = el.offsetWidth - pad;
var parentOffsetWidth = parentEl.offsetWidth;
var ratio = parentOffsetWidth / elOffsetWidth;
var invertedRatio = elOffsetWidth / parentOffsetWidth;
timeout = setTimeout(function() {
anime.set(el, {scale: ratio});
if (exception) anime.set(exception, {scale: invertedRatio});
}, 10);
}
resize();
window.addEventListener('resize', resize);
}
// main logo animation
var logoAnimation = (function() {
var logoAnimationEl = document.querySelector('.logo-animation');
var bouncePath = anime.path('.bounce path');
fitElementToParent(logoAnimationEl, 0, '.bounce svg');
anime.set(['.letter-a', '.letter-n', '.letter-i'], {translateX: 70});
anime.set('.letter-e', {translateX: -70});
anime.set('.dot', { translateX: 630, translateY: -200 });
var logoAnimationTL = anime.timeline({
autoplay: false,
easing: 'easeOutSine'
})
.add({
targets: '.letter-i .line',
duration: 0,
begin: function(a) { a.animatables[0].target.removeAttribute('stroke-dasharray'); }
}, 0)
.add({
targets: '.bounced',
transformOrigin: ['50% 100% 0px', '50% 100% 0px'],
translateY: [
{value: [150, -160], duration: 190, endDelay: 20, easing: 'cubicBezier(0.225, 1, 0.915, 0.980)'},
{value: 4, duration: 120, easing: 'easeInQuad'},
{value: 0, duration: 120, easing: 'easeOutQuad'}
],
scaleX: [
{value: [.25, .85], duration: 190, easing: 'easeOutQuad'},
{value: 1.08, duration: 120, delay: 85, easing: 'easeInOutSine'},
{value: 1, duration: 260, delay: 25, easing: 'easeOutQuad'}
],
scaleY: [
{value: [.3, .8], duration: 120, easing: 'easeOutSine'},
{value: .35, duration: 120, delay: 180, easing: 'easeInOutSine'},
{value: .57, duration: 180, delay: 25, easing: 'easeOutQuad'},
{value: .5, duration: 190, delay: 15, easing: 'easeOutQuad'}
],
delay: anime.stagger(80)
}, 1000)
.add({
targets: '.dot',
opacity: { value: 1, duration: 100 },
translateY: 250,
scaleY: [4, .7],
scaleX: { value: 1.3, delay: 100, duration: 200},
duration: 280,
easing: 'cubicBezier(0.350, 0.560, 0.305, 1)'
}, '-=290')
.add({
targets: '.letter-m .line',
easing: 'easeOutElastic(1, .8)',
duration: 600,
d: function(el) { return el.dataset.d2 },
begin: function(a) { a.animatables[0].target.removeAttribute('stroke-dasharray'); }
}, '-=140')
.add({
targets: ['.letter-a', '.letter-n', '.letter-i', '.letter-e'],
translateX: 0,
easing: 'easeOutElastic(1, .6)',
duration: 800,
delay: anime.stagger(40, {from: 2.5}),
change: function(a) { a.animatables[2].target.removeAttribute('stroke-dasharray'); }
}, '-=600')
.add({
targets: '.letter-m .line',
d: function(el) { return el.dataset.d3 },
easing: 'spring(.2, 200, 3, 60)',
}, '-=680')
.add({
targets: '.dot',
translateX: bouncePath('x'),
translateY: bouncePath('y'),
rotate: {value: '1turn', duration: 790},
scaleX: { value: 1, duration: 50, easing: 'easeOutSine' },
scaleY: [
{ value: [1, 1.5], duration: 50, easing: 'easeInSine' },
{ value: 1, duration: 50, easing: 'easeOutExpo' }
],
easing: 'cubicBezier(0, .74, 1, .255)',
duration: 800
}, '-=1273')
.add({
targets: '.dot',
scale: 1,
rotate: '1turn',
scaleY: {value: .5, delay: 0, duration: 150, delay: 230},
translateX: 430,
translateY: [
{value: 244, duration: 100},
{value: 204, duration: 200, delay: 130},
{value: 224, duration: 225, easing: 'easeOutQuad', delay: 25}
],
duration: 200,
easing: 'easeOutSine'
}, '-=474')
.add({
targets: '.letter-i .line',
transformOrigin: ['50% 100% 0', '50% 100% 0'],
d: function(el) { return el.dataset.d2 },
easing: 'cubicBezier(0.400, 0.530, 0.070, 1)',
duration: 80
}, '-=670')
.add({
targets: '.logo-letter',
translateY: [
{value: 40, duration: 150, easing: 'easeOutQuart'},
{value: 0, duration: 800, easing: 'easeOutElastic(1, .5)'}
],
strokeDashoffset: [anime.setDashoffset, 0],
delay: anime.stagger(60, {from: 'center'})
}, '-=670')
.add({
targets: '.bounced',
scaleY: [
{value: .4, duration: 150, easing: 'easeOutQuart'},
{value: .5, duration: 800, easing: 'easeOutElastic(1, .5)'}
],
delay: anime.stagger(60, {from: 'center'})
}, '-=1090')
.add({
targets: '.logo-text',
translateY: [
{value: 20, easing: 'easeOutQuad', duration: 100},
{value: 0, easing: 'easeOutElastic(1, .9)', duration: 450}
],
opacity: {value: [0.001, 1], duration: 50},
duration: 500
}, '-=970')
.add({
targets: '.main-logo-circle',
opacity: {value: [0.001, 1], duration: 1500},
backgroundImage: ['linear-gradient(-135deg, #FFFFFF 50%, #F6F4F2 75%, #F6F4F2 100%, #DDDAD7 100%)', 'linear-gradient(-135deg, #FFFFFF 5%, #F6F4F2 40%, #F6F4F2 70%, #DDDAD7 100%)'],
translateY: {value: ['60px', 0], easing: 'cubicBezier(0.175, 0.865, 0.245, 0.840)'},
duration: 2000,
easing: 'easeInOutQuad'
}, '-=970')
.add({
targets: ['.description-title','.description-paragraph'],
opacity: {value: [0.001, 1], easing: 'cubicBezier(0.175, 0.865, 0.245, 0.840)'},
translateY: {value: ['80px', 0], easing: 'cubicBezier(0.175, 0.865, 0.245, 0.840)'},
duration: 3500,
delay: anime.stagger(75)
}, '-=1300')
return logoAnimationTL;
})();
logoAnimation.play();
</script>
</body>
</html>

View File

@ -0,0 +1,136 @@
<!DOCTYPE html>
<html>
<head>
<title>built-in easings • anime.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:title" content="anime.js">
<meta property="og:url" content="https://animejs.com">
<meta property="og:description" content="Javascript Animation Engine">
<meta property="og:image" content="https://animejs.com/documentation/assets/img/icons/og.png">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="anime.js">
<meta name="twitter:site" content="@juliangarnier">
<meta name="twitter:description" content="Javascript Animation Engine">
<meta name="twitter:image" content="https://animejs.com/documentation/assets/img/icons/twitter.png">
<link rel="apple-touch-icon-precomposed" href="../assets/img/social-media-image.png">
<link rel="icon" type="image/png" href="../assets/img/favicon.png" >
<link href="../assets/css/animejs.css" rel="stylesheet">
<link href="../assets/css/documentation.css" rel="stylesheet">
<style>
:root {
font-size: 24px;
}
body {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
height: 100vh;
}
.easing-visualizer {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
max-width: 908px;
padding-bottom: 50%;
}
.easing-visualizer .wrapper {
position: absolute;
bottom: 0;
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
height: 100%;
}
.easing-visualizer .bar {
width: 2px;
height: 4px;
margin: 0 3px;
background-color: currentColor;
transform-origin: 50% 50%;
}
.easing-visualizer .dot {
position: relative;
width: 8px;
height: 8px;
background-color: currentColor;
border-radius: 50%;
}
</style>
</head>
<body>
<div class="easing-visualizer">
<div class="wrapper bars-wrapper"></div>
<div class="wrapper dots-wrapper"></div>
</div>
</body>
<script type="module">
import anime from '../../src/index.js';
const easingVisualizerEl = document.querySelector('.easing-visualizer');
const barsWrapperEl = easingVisualizerEl.querySelector('.bars-wrapper');
const dotsWrapperEl = easingVisualizerEl.querySelector('.dots-wrapper');
const barsFragment = document.createDocumentFragment();
const dotsFragment = document.createDocumentFragment();
const numberOfBars = 101;
for (let i = 0; i < numberOfBars; i++) {
const barEl = document.createElement('div');
const dotEl = document.createElement('div');
barEl.classList.add('bar');
dotEl.classList.add('dot');
dotEl.classList.add('color-red');
barsFragment.appendChild(barEl);
dotsFragment.appendChild(dotEl);
}
barsWrapperEl.appendChild(barsFragment);
dotsWrapperEl.appendChild(dotsFragment);
// anime.setValue('.easing-visualizer .dot', { translateX: anime.stagger(6) });
function animateEasing() {
const easings = [];
for (let ease in anime.penner) easings.push(ease);
easings.push('steps('+anime.random(5, 20)+')');
easings.push('cubicBezier(0.545, 0.475, 0.145, 1)');
const ease = easings[anime.random(0, easings.length - 1)];
const duration = 450;
anime.timeline({
complete: animateEasing,
easing: ease,
duration: duration
})
.add({
targets: '.easing-visualizer .bar',
scaleY: anime.stagger([1, 100], {easing: ease, from: 'center', direction: 'reverse'}),
delay: anime.stagger(14, {from: 'center'})
})
.add({
targets: '.easing-visualizer .dot',
translateY: anime.stagger(['-6rem', '6rem'], {easing: ease, from: 'last'}),
delay: anime.stagger(10, {from: 'center'})
}, 0);
}
animateEasing();
</script>
</html>

View File

@ -0,0 +1,354 @@
<!DOCTYPE html>
<html>
<head>
<title>Anime states system | anime.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:title" content="anime.js">
<meta property="og:url" content="https://animejs.com">
<meta property="og:description" content="Javascript Animation Engine">
<meta property="og:image" content="https://animejs.com/documentation/assets/img/icons/og.png">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="anime.js">
<meta name="twitter:site" content="@juliangarnier">
<meta name="twitter:description" content="Javascript Animation Engine">
<meta name="twitter:image" content="https://animejs.com/documentation/assets/img/icons/twitter.png">
<link rel="apple-touch-icon-precomposed" href="../assets/img/social-media-image.png">
<link rel="icon" type="image/png" href="../assets/img/favicon.png" >
<link href="../assets/css/animejs.css" rel="stylesheet">
<link href="../assets/css/documentation.css" rel="stylesheet">
<style>
body {
display: flex;
flex-wrap: no-wrap;
justify-content: space-around;
align-items: center;
position: absolute;
width: 100%;
height: 100vh;
padding-bottom: 128px;
}
.el {
width: 50px;
height: 50px;
background-color: currentColor;
}
.log {
overflow-y: scroll;
position: absolute;
top: 0;
height: 100%;
padding: 20px;
padding-top: 80px;
font-size: 16px;
line-height: 20px;
text-align: left;
font-family: monospace;
}
.log-animation {
left: 0;
width: 50%;
}
.log-timeline {
left: 50%;
width: 50%;
}
.counter {
display: inline-block;
margin-right: 10px;
padding: 3px;
background-color: rgba(255,255,255,.2);
}
.currentTime, .progress { opacity: .5 }
.time {
position: absolute;
top: 0;
height: 80px;
padding: 20px;
font-size: 16px;
line-height: 20px;
text-align: left;
font-family: monospace;
}
.time-animation {
left: 0;
width: 50%;
}
.time-timeline {
left: 50%;
width: 50%;
}
/* Player animation */
.timeline {
position: fixed;
bottom: 0;
height: 128px;
padding-top: 4px;
background-color: #000;
}
.timeline.player-animation {
width: 50%;
left: 0;
}
.timeline.player-timeline {
width: 50%;
left: 50%;
}
.tl-needle {
position: absolute;
z-index: 2;
top: 0;
left: 0;
bottom: 0;
width: 2px;
margin-left: -1px;
background-color: #FFF;
}
.tl-animation {
position: relative;
display: flex;
justify-content: space-between;
width: auto;
height: 8px;
margin-bottom: 4px;
background-color: currentColor;
border-radius: .5rem;
}
.tl-delay,
.tl-end-delay {
width: auto;
height: 100%;
background-color: rgba(0,0,0,.5);
}
</style>
</head>
<body>
<div class="el color-04"></div>
<div class="el color-08"></div>
<div class="log log-animation"></div>
<div class="time time-animation"></div>
<div class="log log-timeline"></div>
<div class="time time-timeline"></div>
</body>
<script type="module">
import anime from '../../src/index.js';
var animationTimeLogEl = document.querySelector('.time-animation');
var timelineTimeLogEl = document.querySelector('.time-timeline');
var animation = anime({
targets: '.el.color-04',
translateX: [
{value: 200},
{value: -200},
{value: 200}
],
rotate: {
value: 720,
easing: 'easeInOutCirc',
duration: 500,
delay: 500
},
opacity: {
value: .5,
easing: 'linear',
duration: 1000,
delay: 1000,
endDelay: 0
},
delay: 1000,
endDelay: 500,
duration: 1000,
easing: 'easeOutQuad',
direction: 'reverse',
loop: 2,
autoplay: false,
update: function(a) {
animationTimeLogEl.innerHTML = 'progress : ' + a.progress + '<br>currentTime : ' + a.currentTime;
},
});
var tl = anime.timeline({
targets: '.el.color-08',
easing: 'easeInOutQuad',
autoplay: false,
direction: 'alternate',
loop: 3,
update: function(a) {
timelineTimeLogEl.innerHTML = 'progress : ' + a.progress + '<br>currentTime : ' + a.currentTime;
}
})
.add({
translateX: 100,
delay: 1000
})
.add({
translateY: 100
}, '-=500')
.add({
rotate: 360,
endDelay: 1000
}, '-=500');
function animePlayer(instance, playerClass) {
function createEl(type, className, parentEl) {
var el = document.createElement(type);
if (className) el.classList.add(className);
if (parentEl) parentEl.appendChild(el);
return el;
}
var timelineEl = createEl('div', 'timeline', document.body);
if (playerClass) timelineEl.classList.add(playerClass);
var needleEl = createEl('div', 'tl-needle', timelineEl);
var animations = [];
var colors = ['#FF1461','#FF7C72','#FBF38C','#A6FF8F','#18FF92','#1CE2B2','#5EF3FB','#61C3FF','#5A87FF','#8453E3','#C26EFF','#FB89FB'];
var colorIndex = 0;
function convertMStoEM(ms) { return ms / 100; }
function convertEMtoMS(em) { return parseFloat(em) * 250; }
function createAnimationLog(animObj, timelineOffset) {
var anim = animObj;
anim.player = {};
anim.player.animationEl = createEl('div', 'tl-animation', timelineEl);
anim.player.delayEl = createEl('div', 'tl-delay', anim.player.animationEl);
anim.player.endDelayEl = createEl('div', 'tl-end-delay', anim.player.animationEl);
anim.update = function() {
anime.set(anim.player.animationEl, {
left: convertMStoEM(timelineOffset) + 'em',
width: convertMStoEM(anim.duration) + 'em'
});
anime.set(anim.player.delayEl, {width: (anim.delay / anim.duration) * 100 + '%'});
anime.set(anim.player.endDelayEl, {width: (anim.endDelay / anim.duration) * 100 + '%'});
}
anime.set(anim.player.animationEl, {color: colors[colorIndex]});
colorIndex++;
if (!colors[colorIndex]) colorIndex = 0;
anim.update();
animations.push(anim);
return anim;
}
instance.pause();
var playerAnimation = anime({
targets: needleEl,
translateX: convertMStoEM(instance.duration) + 'em',
duration: instance.duration,
direction: instance.direction,
loop: instance.loop,
easing: 'linear',
update: function(a) {
instance.seek(a.currentTime);
},
complete: function(a) {
instance.seek(a.currentTime);
}
});
if (instance.children.length) {
instance.children.forEach(function(child) {
child.animations.forEach(function(anim) {
createAnimationLog(anim, child.timelineOffset);
});
})
} else {
instance.animations.forEach(function(anim) {
createAnimationLog(anim);
});
}
}
animePlayer(animation, 'player-animation');
animePlayer(tl, 'player-timeline');
function logCallbacks(animation, logEl, callbacks) {
function appendLog(cbName) {
animation[cbName] = function() {
var pEl = document.createElement('p');
var counterSpanEl = document.createElement('span');
var currentTimeSpanEl = document.createElement('span');
var progressSpanEl = document.createElement('span');
var textSpanEl = document.createElement('span');
var lastPEl = logEl.querySelector('p:last-child');
currentTimeSpanEl.innerHTML = ' ' + animation.currentTime + 'ms';
progressSpanEl.innerHTML = ' ' + animation.progress + '%';
if (lastPEl && lastPEl.querySelector('.text').innerHTML === cbName) {
var lastCountEl = lastPEl.querySelector('.counter');
var lastCountValue = parseFloat(lastCountEl.innerHTML);
lastCountValue++;
lastCountEl.innerHTML = lastCountValue;
} else {
counterSpanEl.innerHTML = 1;
textSpanEl.innerHTML = cbName;
counterSpanEl.classList.add('counter');
textSpanEl.classList.add('text');
currentTimeSpanEl.classList.add('currentTime');
progressSpanEl.classList.add('progress');
pEl.appendChild(counterSpanEl);
pEl.appendChild(textSpanEl);
pEl.appendChild(currentTimeSpanEl);
pEl.appendChild(progressSpanEl);
logEl.appendChild(pEl);
logEl.scrollTop = logEl.scrollHeight;
}
}
}
callbacks.forEach(appendLog);
}
logCallbacks(animation, document.querySelector('.log-animation'), [
'begin',
'loopBegin',
'changeBegin',
'change',
'changeComplete',
'loopComplete',
'complete'
]);
logCallbacks(tl, document.querySelector('.log-timeline'), ['begin',
'loopBegin',
'changeBegin',
'change',
'changeComplete',
'loopComplete',
'complete'
]);
</script>
</html>

View File

@ -0,0 +1,119 @@
<!DOCTYPE html>
<html>
<head>
<title>Colors test | anime.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:title" content="anime.js">
<meta property="og:url" content="https://animejs.com">
<meta property="og:description" content="Javascript Animation Engine">
<meta property="og:image" content="https://animejs.com/documentation/assets/img/icons/og.png">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="anime.js">
<meta name="twitter:site" content="@juliangarnier">
<meta name="twitter:description" content="Javascript Animation Engine">
<meta name="twitter:image" content="https://animejs.com/documentation/assets/img/icons/twitter.png">
<link rel="apple-touch-icon-precomposed" href="../assets/img/social-media-image.png">
<link rel="icon" type="image/png" href="../assets/img/favicon.png">
<link href="../assets/css/documentation.css" rel="stylesheet">
<script src="../../lib/anime.min.js"></script>
<!-- <script src="../assets/js/anime/anime.2.0.2.js"></script> -->
<!-- <script src="../assets/js/anime/anime.1.3.js"></script> -->
<style>
body {
width: 100%;
height: 100vh;
}
.color-tests {
display: flex;
flex-wrap: wrap;
}
.section-title {
display: block;
width: 100%;
margin-bottom: 10px;
padding: 10px;
border-bottom: 1px solid #FFF;
}
.color-test {
flex-shrink: 2;
text-align: center;
font-size: 10px;
line-height: 1em;
font-family: monospace;
}
.color-el {
display: flex;
align-items: center;
justify-content: center;
position: relative;
width: 12vw;
height: 12vw;
margin-top: 10px;
}
</style>
</head>
<body>
<section class="color-section">
<h1 class="section-title">HEX</h1>
<div class="color-tests">
<div class="color-test hex-to-hex-shorthand">#F47<br><br>#6AF</div>
<div class="color-test hex-to-hex">#FF4477<br><br>#66AAFF</div>
<div class="color-test hex-to-rgb">#FF4477<br><br>rgb(102,170,255)</div>
<div class="color-test hex-to-hsl">#FF4477<br><br>hsl(213,100%,70%)</div>
<div class="color-test hex-to-rgba">#FF4477<br><br>rgba(102,170,255,.15)</div>
<div class="color-test hex-to-hsla">#FF4477<br><br>hsla(213,100%,70%,.15)</div>
</div>
</section>
<section class="color-section">
<h1 class="section-title">RGB</h1>
<div class="color-tests">
<div class="color-test rgb-to-hex-shorthand">rgb(255,68,119)<br><br>#6AF</div>
<div class="color-test rgb-to-hex">rgb(255,68,119)<br><br>#66AAFF</div>
<div class="color-test rgb-to-rgb">rgb(255,68,119)<br><br>rgb(102,170,255)</div>
<div class="color-test rgb-to-hsl">rgb(255,68,119)<br><br>hsl(213,100%,70%)</div>
<div class="color-test rgb-to-rgba">rgb(255,68,119)<br><br>rgba(102,170,255,.15)</div>
<div class="color-test rgb-to-hsla">rgb(255,68,119)<br><br>hsla(213,100%,70%,.15)</div>
<div class="color-test rgba-to-rgba">rgba(255,68,119,.5)<br><br>rgba(102,170,255,.15)</div>
<div class="color-test rgba-to-hsla">rgba(255,68,119,.5)<br><br>hsla(213,100%,70%,.15)</div>
</div>
</section>
<section class="color-section">
<h1 class="section-title">HSL</h1>
<div class="color-tests">
<div class="color-test hsl-to-hex-shorthand">hsl(344,100%,63%)<br><br>#6AF</div>
<div class="color-test hsl-to-hex">hsl(344,100%,63%)<br><br>#66AAFF</div>
<div class="color-test hsl-to-rgb">hsl(344,100%,63%)<br><br>rgb(102,170,255)</div>
<div class="color-test hsl-to-hsl">hsl(344,100%,63%)<br><br>hsl(213,100%,70%)</div>
<div class="color-test hsl-to-rgba">hsl(344,100%,63%)<br><br>rgba(102,170,255,.15)</div>
<div class="color-test hsl-to-hsla">hsl(344,100%,63%)<br><br>hsla(213,100%,70%,.15)</div>
<div class="color-test hsla-to-rgba">hsla(344,100%,63%,.5)<br><br>rgba(102,170,255,.15)</div>
<div class="color-test hsla-to-hsla">hsla(344,100%,63%,.5)<br><br>hsla(213,100%,70%,.15)</div>
</div>
</section>
<script>
var colorTestEls = document.querySelectorAll('.color-test');
function createTest(el) {
var testHtml = el.innerHTML;
var testValues = testHtml.split('<br><br>');
var colorEl = document.createElement('div');
colorEl.classList.add('color-el');
el.appendChild(colorEl);
anime({
targets: colorEl,
backgroundColor: [testValues[0], testValues[1]],
scale: [.97, .75],
direction: 'alternate',
easing: 'easeInOutSine',
duration: 4000,
loop: true
});
}
for (var i = 0; i < colorTestEls.length; i++) createTest(colorTestEls[i]);
</script>
</body>
</html>

View File

@ -0,0 +1,187 @@
<!DOCTYPE html>
<html>
<head>
<title>Complex properties | anime.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:title" content="anime.js">
<meta property="og:url" content="https://animejs.com">
<meta property="og:description" content="Javascript Animation Engine">
<meta property="og:image" content="https://animejs.com/documentation/assets/img/icons/og.png">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="anime.js">
<meta name="twitter:site" content="@juliangarnier">
<meta name="twitter:description" content="Javascript Animation Engine">
<meta name="twitter:image" content="https://animejs.com/documentation/assets/img/icons/twitter.png">
<link rel="apple-touch-icon-precomposed" href="../assets/img/social-media-image.png">
<link href="../assets/css/animejs.css" rel="stylesheet">
<link href="../assets/css/documentation.css" rel="stylesheet">
<!-- <script src="../../lib/anime.min.js"></script> -->
<!-- <script src="../assets/js/anime/anime.1.3.js"></script> -->
<!-- <script src="../assets/js/anime/anime.2.0.1.js"></script> -->
<style>
body {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.item {
width: 100px;
height: 100px;
margin-top: 20px;
border-radius: 50%;
background-color: currentColor;
margin: 10px;
}
.box-shadow {
background-color: transparent;
}
.clip-path {
border-radius: 0;
}
.auto-property {
background-image: radial-gradient(50% 100%, #FFF7A0 50%, #FF7A6D 100%);
background-size: auto 100px;
}
.exponent-values {
width: 300px;
background-color: transparent;
text-align: center;
}
</style>
</head>
<body>
<div class="box-shadow item color-red"></div>
<div class="unit-less item color-orange"></div>
<div class="specified-unit item color-lightorange"></div>
<div class="filter item color-yellow"></div>
<div class="rgba item color-citrus"></div>
<div class="calc item color-green"></div>
<div class="zero-value item color-darkgreen"></div>
<div class="round-value item color-turquoise"></div>
<div class="clip-path item color-skyblue"></div>
<svg class="item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<g id="Page-1" fill="none" fill-rule="evenodd">
<g id="svg" fill="#A7FF87">
<rect id="Rectangle" width="50" height="50" x="25" y="25"/>
</g>
</g>
</svg>
<input class="item" type="range" value="0" min="0" max="100">
<div class="basic-css color-lavender item"></div>
<div class="auto-property color-purple item"></div>
<input class="exponent-values color-pink item" value="-1.1234567890123456789e+30px"></input>
<script type="module">
import anime from "../../src/index.js";
var boxShadow = anime({
targets: '.box-shadow',
boxShadow: [
{value: ['10px -10px 10px 0 currentColor', '10px 10px 20px 0 currentColor']},
{value: '-10px 10px 30px 0 currentColor'},
{value: '-10px -10px 20px 0 currentColor'},
{value: '10px -10px 10px 0 currentColor'}
],
loop: true,
easing: 'linear'
});
var unitLess = anime({
targets: '.unit-less',
borderRadius: 16,
loop: true,
direction: 'alternate',
easing: 'linear'
});
var specifiedUnit = anime({
targets: '.specified-unit',
borderRadius: '1em',
loop: true,
direction: 'alternate',
easing: 'linear'
});
var filter = anime({
targets: '.filter',
filter: ["blur(20px)", "blur(0px)"],
loop: true,
direction: 'alternate',
easing: 'linear'
});
var rgba = anime({
targets: '.rgba',
backgroundColor: ['rgba(255,100,50,1)', 'rgba(255,100,50,.0)'],
loop: true,
direction: 'alternate',
easing: 'linear'
});
var calc = anime({
targets: '.calc',
height: ['calc(25% - 100px)', 'calc(25% - 0px)'],
loop: true,
direction: 'alternate',
easing: 'linear'
});
var zeroValue = anime({
targets: '.zero-value',
scale: 0,
loop: true,
direction: 'alternate',
easing: 'linear'
});
var roundValue = anime({
targets: '.round-value',
translateY: 100,
round: .1,
loop: true,
direction: 'alternate',
easing: 'linear'
});
var clipPath = anime({
targets: '.clip-path',
clipPath: ['circle(0px at center)', 'circle(100px at center)'],
loop: true,
direction: 'alternate',
easing: 'linear'
});
var svgTransform = anime({
targets: 'rect',
transform: 'translate(10 10) scale(2)',
loop: true,
direction: 'alternate',
easing: 'linear'
});
var rangeValue = anime({
targets: 'input[type="range"]',
value: 100,
loop: true,
direction: 'alternate',
easing: 'linear'
});
var basicCSS = anime({
targets: '.basic-css',
width: 50,
height: 50,
loop: true,
direction: 'alternate',
easing: 'linear'
});
var autoProperty = anime({
targets: '.auto-property',
backgroundSize: ['auto 10px', 'auto 400px'],
margin: '20% 40px 10px 30px',
loop: true,
direction: 'alternate',
easing: 'linear'
});
var exponentValues = anime({
targets: '.exponent-values',
value: '+1.0123456789012346e+21px',
loop: true,
direction: 'alternate',
easing: 'linear'
});
</script>
</body>
</html>

View File

@ -0,0 +1,186 @@
<!DOCTYPE html>
<html>
<head>
<title>Diretions Testing | anime.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:title" content="anime.js">
<meta property="og:url" content="https://animejs.com">
<meta property="og:description" content="Javascript Animation Engine">
<meta property="og:image" content="https://animejs.com/documentation/assets/img/icons/og.png">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="anime.js">
<meta name="twitter:site" content="@juliangarnier">
<meta name="twitter:description" content="Javascript Animation Engine">
<meta name="twitter:image" content="https://animejs.com/documentation/assets/img/icons/twitter.png">
<link rel="apple-touch-icon-precomposed" href="../assets/img/social-media-image.png">
<link rel="icon" type="image/png" href="../assets/img/favicon.png">
<link href="../assets/css/animejs.css" rel="stylesheet">
<link href="../assets/css/documentation.css" rel="stylesheet">
<script src="../../lib/anime.min.js"></script>
<style>
body {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: flex-start;
height: auto;
}
article {
padding: 1vw;
position: relative;
width: 33.33%;
height: 20vh;
background: currentColor;
border: 1px solid #111116;
}
h2 {
color: #111116;
}
.el {
position: relative;
top: 5vh;
width: 2vw;
height: 2vw;
background: #111116;
}
.logs {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: center;
justify-content: center;
position: absolute;
top: 1vh;
left: 0;
bottom: 0;
height: 19vh;
width: 100%;
}
input {
text-align: center;
background: none;
border: none;
}
</style>
</head>
<body>
<script>
function createTest(title, numberOfTargets, params) {
var testEl = document.createElement('article');
var testZoneEl = document.createElement('div');
var logsEl = document.createElement('div');
var progressEl = document.createElement('input');
var promiseEl = document.createElement('input');
var h2El = document.createElement('h2');
for (var i = 0; i < numberOfTargets; i++) {
var el = document.createElement('div');
el.classList.add('el');
testZoneEl.appendChild(el);
}
h2El.innerHTML = title;
testEl.appendChild(h2El);
logsEl.classList.add('logs');
logsEl.appendChild(progressEl);
logsEl.appendChild(promiseEl);
testEl.appendChild(logsEl);
testEl.appendChild(testZoneEl);
document.body.appendChild(testEl);
params.targets = testZoneEl.querySelectorAll('div');
params.translateX = '29vw';
params.delay = 1000;
params.endDelay = 1000;
params.easing = 'easeInOutQuad';
params.begin = function() { testEl.classList.add('color-lightorange') };
params.update = function(a) {
testEl.classList.add('color-red');
progressEl.value = 'Progress ' + Math.round(a.progress) + '%';
};
params.complete = function() { testEl.classList.add('color-darkgreen') };
var animation = anime(params);
animation.finished.then(function() {
promiseEl.value = 'Promise resolved'
console.log('Promise resolved');
});
testEl.onclick = function() {
testEl.classList.add('color-red');
testEl.classList.remove('color-lightorange');
testEl.classList.remove('color-darkgreen');
animation.restart();
}
}
createTest('Normal', 1, {});
createTest('Reverse', 1, {
direction: 'reverse'
});
createTest('Alternate', 1, {
direction: 'alternate'
});
createTest('Normal 1 time', 1, {
loop: 1
});
createTest('Reverse 1 time', 1, {
direction: 'reverse',
loop: 1
});
createTest('Alternate 1 time (equals 2)', 1, {
direction: 'alternate',
loop: 1
});
createTest('Normal 2 times', 1, {
loop: 2
});
createTest('Reverse 2 times', 1, {
direction: 'reverse',
loop: 2
});
createTest('Alternate 2 times', 1, {
direction: 'alternate',
loop: 2
});
createTest('Normal 3 times', 1, {
loop: 3
});
createTest('Reverse 3 times', 1, {
direction: 'reverse',
loop: 3
});
createTest('Alternate 3 times', 1, {
direction: 'alternate',
loop: 3
});
createTest('Normal true', 1, {
loop: true
});
createTest('Reverse true', 1, {
direction: 'reverse',
loop: true
});
createTest('Alternate true', 1, {
direction: 'alternate',
loop: true
});
</script>
</body>
</html>

View File

@ -0,0 +1,419 @@
<!DOCTYPE html>
<html>
<head>
<title>Ease visualizer | anime.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:title" content="anime.js">
<meta property="og:url" content="https://animejs.com">
<meta property="og:description" content="Javascript Animation Engine">
<meta property="og:image" content="https://animejs.com/documentation/assets/img/icons/og.png">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="anime.js">
<meta name="twitter:site" content="@juliangarnier">
<meta name="twitter:description" content="Javascript Animation Engine">
<meta name="twitter:image" content="https://animejs.com/documentation/assets/img/icons/twitter.png">
<link rel="apple-touch-icon-precomposed" href="../assets/img/social-media-image.png">
<link rel="icon" type="image/png" href="../assets/img/favicon.png">
<link href="../assets/css/animejs.css" rel="stylesheet">
<link href="../assets/css/documentation.css" rel="stylesheet">
<!-- <script src="../../lib/anime.min.js"></script> -->
<style>
.easings {
display: flex;
justify-content: space-between;
align-items: center;
flex-direction: column;
position: absolute;
width: 100%;
height: 100%;
}
.output {
display: flex;
justify-content: center;
align-items: center;
position: relative;
width: 100%;
height: 400px;
}
.options {
display: flex;
flex-wrap: wrap;
flex-direction: row;
width: 100%;
min-height: 300px;
border-top: 1px solid #09090B;
}
.grid {
border-top: 1px solid rgba(255,255,255,0.2);
border-right: 1px solid rgba(255,255,255,0.2);
background: linear-gradient(0deg, rgba(255,255,255,0.2) 1px, rgba(0,0,0,0) 1px),
linear-gradient(90deg, rgba(255,255,255,0.2) 1px, rgba(0,0,0,0) 1px),
linear-gradient(0deg, rgba(255,255,255,0.1) 1px, rgba(0,0,0,0) 1px),
linear-gradient(90deg, rgba(255,255,255,0.1) 1px, rgba(0,0,0,0) 1px);
background-position: 0px -1px;
background-size: 100px 100px, 100px 100px, 20px 20px, 20px 20px;
}
.visualizer-wrapper {
position: relative;
width: 100%;
height: 100%;
}
.visualizer {
position: relative;
width: 100%;
}
.value {
position: relative;
width: 20px;
height: 100%;
margin-left: 20px;
}
@media screen and (min-width: 980px) {
.easings {
flex-direction: row;
}
.output {
width: 50%;
height: 100%;
}
.options {
width: 50%;
height: 100%;
}
.visualizer-wrapper {
width: 400px;
height: 400px;
}
.value {
width: 40px;
height: 400px;
margin-left: 40px;
}
}
.axis {
position: absolute;
background: #5A87FF;
}
.axis.x {
width: 1px;
height: 100%;
transform-origin: 0 0;
}
.axis.y {
bottom: 0;
width: 100%;
height: 1px;
transform-origin: 100% 0;
}
.graph {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.cursor {
position: absolute;
z-index: 2;
width: 40px;
height: 40px;
margin-top: -20px;
background: #FF1461;
border-radius: 50%;
transform: translateY(100px);
}
.curve {
display: flex;
justify-content: space-between;
align-items: flex-end;
overflow: visible;
position: relative;
z-index: 1;
width: 100%;
height: 100%;
}
.curve-dot {
position: relative;
width: 6px;
height: 6px;
margin-bottom: -3px;
margin-left: -3px;
border-radius: 50%;
flex-shrink: 0;
background-color: #18FF92;
}
.curve-dot:first-child {
margin-left: -3px;
}
.curve-dot:last-child {
margin-right: -4px;
}
button {
opacity: 1;
position: relative;
color: currentColor;
font-size: 16px;
width: calc(50% + 1px);
border: 1px solid #09090B;
background: transparent;
margin: -1px 0 0 -1px;
letter-spacing: 1px;
}
label {
display: flex;
align-items: center;
justify-content: center;
width: calc(100% + 1px);
margin: -1px 0 0 -1px;
border-top: 0px;
border-left: 1px solid #09090B;
border-right: 1px solid #09090B;
color: rgba(255,255,255,.3);
}
button.active {
color: #18FF92;
z-index: 1;
opacity: 1;
border: 1px solid currentColor;
background: #222027;
}
button:focus {
outline: none;
}
button:hover {
background: #222027;
}
</style>
</head>
<body>
<div class="easings">
<div class="output">
<div class="visualizer-wrapper grid">
<div class="axis x"></div>
<div class="axis y"></div>
<div class="visualizer">
<div class="curve">
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
<div class="curve-dot"></div>
</div>
</div>
</div>
<div class="value grid">
<div class="graph">
<div class="cursor"></div>
<div class="cursor"></div>
<div class="cursor"></div>
<div class="cursor"></div>
<div class="cursor"></div>
<div class="cursor"></div>
<div class="cursor"></div>
<div class="cursor"></div>
<div class="cursor"></div>
<div class="cursor"></div>
<div class="cursor"></div>
<div class="cursor"></div>
<div class="cursor"></div>
<div class="cursor"></div>
<div class="cursor"></div>
<div class="cursor"></div>
<div class="cursor"></div>
<div class="cursor"></div>
</div>
</div>
</div>
<div class="options">
<label>Ease In</label>
<button class="active" value="easeInQuad" >Quad</button>
<button value="easeInCubic" >Cubic</button>
<button value="easeInQuart" >Quart</button>
<button value="easeInQuint" >Quint</button>
<button value="easeInSine" >Sine</button>
<button value="easeInExpo" >Expo</button>
<button value="easeInCirc" >Circ</button>
<button value="easeInBack" >Back</button>
<button value="easeInBounce" >Bounce</button>
<button value="easeInElastic" >Elastic</button>
<label>Ease Out</label>
<button value="easeOutQuad" >Quad</button>
<button value="easeOutCubic" >Cubic</button>
<button value="easeOutQuart" >Quart</button>
<button value="easeOutQuint" >Quint</button>
<button value="easeOutSine" >Sine</button>
<button value="easeOutExpo" >Expo</button>
<button value="easeOutCirc" >Circ</button>
<button value="easeOutBack" >Back</button>
<button value="easeOutBounce" >Bounce</button>
<button value="easeOutElastic" >Elastic</button>
<label>Ease In Out</label>
<button value="easeInOutQuad" >Quad</button>
<button value="easeInOutCubic" >Cubic</button>
<button value="easeInOutQuart" >Quart</button>
<button value="easeInOutQuint" >Quint</button>
<button value="easeInOutSine" >Sine</button>
<button value="easeInOutExpo" >Expo</button>
<button value="easeInOutCirc" >Circ</button>
<button value="easeInOutBack" >Back</button>
<button value="easeInOutBounce" >Bounce</button>
<button value="easeInOutElastic" >Elastic</button>
<label>Steps</label>
<button value="steps(2)" >steps(2)</button>
<button value="steps(5)" >steps(5)</button>
<button value="steps(10)" >steps(10)</button>
<button value="steps(20)" >steps(20)</button>
</div>
</div>
<script type="module">
import anime from '../../src/index.js';
var pathEl = document.querySelector('.curve');
var presetsEls = document.querySelectorAll('.options button');
var duration = 1000;
function animateProgress(easingName) {
anime.remove(['.axis.x', '.axis.y', '.cursor']);
var tl = anime.timeline({
duration: duration,
easing: 'linear',
complete: function() {
animateProgress(easingName);
}
})
.add({
targets: '.axis.x',
translateX: [0, 399],
translateZ: [0, 0]
}, 0)
.add({
targets: '.axis.y',
translateY: [0, -399],
translateZ: [0, 0],
easing: easingName,
endDelay: 1000
}, 0)
.add({
targets: '.cursor',
translateY: [400, 0],
translateZ: [0, 0],
easing: easingName,
update: function(anim) {
var timeSegment = (100 / (anim.animatables.length - 2));
var index = Math.round((anim.progress +.5) / timeSegment);
var animatable = anim.animatables[index];
if (animatable) {
var target = animatable.target;
anime.remove(target);
target.style.opacity = .20;
}
}
}, 0);
}
function changeEase(event) {
for (var i = 0; i < presetsEls.length; i++) {
presetsEls[i].classList.remove('active');
}
var buttonEl = event.target;
var easingName = buttonEl.value;
buttonEl.classList.add('active');
animateProgress(easingName);
anime({
targets: '.curve-dot',
translateY: anime.stagger([0, -400], {easing: easingName}),
easing: 'easeInOutQuad',
duration: 400
});
}
for (var i = 0; i < presetsEls.length; i++) {
presetsEls[i].onclick = changeEase;
}
presetsEls[0].click();
</script>
</body>
</html>

View File

@ -0,0 +1,238 @@
<!DOCTYPE html>
<html>
<head>
<title>Follow scroll | anime.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:title" content="anime.js">
<meta property="og:url" content="https://animejs.com">
<meta property="og:description" content="Javascript Animation Engine">
<meta property="og:image" content="https://animejs.com/documentation/assets/img/icons/og.png">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="anime.js">
<meta name="twitter:site" content="@juliangarnier">
<meta name="twitter:description" content="Javascript Animation Engine">
<meta name="twitter:image" content="https://animejs.com/documentation/assets/img/icons/twitter.png">
<link rel="apple-touch-icon-precomposed" href="../assets/img/social-media-image.png">
<link rel="icon" type="image/png" href="../assets/img/favicon.png" >
<link href="../assets/css/animejs.css" rel="stylesheet">
<link href="../assets/css/documentation.css" rel="stylesheet">
<!-- <script src="../../lib/anime.min.js"></script> -->
<!-- <script src="../assets/js/anime/anime.2.2.0.js"></script> -->
<style>
.scroll-area {
width: 100%;
height: 700vh;
}
.animation-wrapper {
position: fixed;
top: 0;
left: 0;
width: 100%;
}
.pane {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 100vh;
left: 0;
width: 100%;
height: 100vh;
background-color: #000;
font-size: 40vw;
}
</style>
</head>
<body>
<div class="scroll-area"></div>
<div class="animation-wrapper">
<div class="pane pane-01">01</div>
<div class="pane pane-02">02</div>
<div class="pane pane-03">03</div>
<div class="pane pane-04">04</div>
<div class="pane pane-05">05</div>
<div class="pane pane-06">06</div>
<div class="pane pane-07">07</div>
<div class="pane pane-08">08</div>
<div class="pane pane-09">09</div>
<div class="pane pane-10">10</div>
<div class="pane pane-11">11</div>
<div class="pane pane-12">12</div>
<div class="pane pane-13">13</div>
<div class="pane pane-14">14</div>
</div>
</body>
<script type="module">
import anime from '../../src/index.js';
import animePlayer from '../assets/js/anime.player.js'
// Scrolling helper
function onScroll(cb) {
var isTicking = false;
var scrollY = 0;
var body = document.body;
var html = document.documentElement;
var scrollHeight = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);
function scroll() {
scrollY = window.scrollY;
if (cb) cb(scrollY, scrollHeight);
requestTick();
}
function requestTick() {
if (!isTicking) requestAnimationFrame(updateScroll);
isTicking = true;
}
function updateScroll() {
isTicking = false;
var currentScrollY = scrollY;
}
scroll();
window.onscroll = scroll;
}
var began = 0;
var completed = 0;
function logChangeBegan(instance) {
began++;
// console.log(instance.id, 'CHANGE BEGAN', instance.changeBegan);
}
function logChangeComplete(instance) {
completed++;
// console.log(instance.id, 'CHANGE COMPLETE', instance.changeCompleted);
}
window.tl = anime.timeline({
easing: 'easeInOutSine',
autoplay: false,
duration: 1000,
// delay: 500,
// endDelay: 500,
update: function(instane) {
console.log(instane.reversePlayback);
}
})
.add({
targets: '.pane-01',
translateY: '-100vh',
background: '#FF1461',
changeBegin: logChangeBegan,
changeComplete: logChangeComplete
})
.set('.pane-02', {'translateY': '-100vh'})
.add({
targets: '.pane-02',
translateX: ['100%', 0],
background: '#FF1461',
changeBegin: logChangeBegan,
changeComplete: logChangeComplete
}, '-=500')
.set('.pane-03', {'translateY': '-200vh'})
.add({
targets: '.pane-03',
translateY: '-100vh',
background: '#FF1461',
changeBegin: logChangeBegan,
changeComplete: logChangeComplete
}, '-=500')
.set('.pane-04', {'translateY': '-100vh'})
.add({
targets: '.pane-04',
scale: [0, 1],
background: '#FF1461',
changeBegin: logChangeBegan,
changeComplete: logChangeComplete,
}, '-=500')
.add({
targets: '.pane-05',
translateY: '-100vh',
rotate: [-180, 0],
background: '#FF1461',
changeBegin: logChangeBegan,
changeComplete: logChangeComplete,
}, '-=500')
.add({
targets: '.pane-06',
translateY: '-100vh',
background: '#FF1461',
changeBegin: logChangeBegan,
changeComplete: logChangeComplete,
}, '-=500')
.add({
targets: '.pane-07',
translateY: '-100vh',
background: '#FF1461',
changeBegin: logChangeBegan,
changeComplete: logChangeComplete,
}, '-=500')
.add({
targets: '.pane-08',
translateY: '-100vh',
background: '#FF1461',
changeBegin: logChangeBegan,
changeComplete: logChangeComplete,
}, '-=500')
.add({
targets: '.pane-09',
translateY: '-100vh',
background: '#FF1461',
changeBegin: logChangeBegan,
changeComplete: logChangeComplete,
}, '-=500')
.add({
targets: '.pane-10',
translateY: '-100vh',
background: '#FF1461',
changeBegin: logChangeBegan,
changeComplete: logChangeComplete,
}, '-=500')
.add({
targets: '.pane-11',
translateY: '-100vh',
background: '#FF1461',
changeBegin: logChangeBegan,
changeComplete: logChangeComplete,
}, '-=500')
.add({
targets: '.pane-12',
translateY: '-100vh',
background: '#FF1461',
changeBegin: logChangeBegan,
changeComplete: logChangeComplete,
}, '-=500')
.add({
targets: '.pane-13',
translateY: '-100vh',
background: '#FF1461',
changeBegin: logChangeBegan,
changeComplete: logChangeComplete,
}, '-=500')
.add({
targets: '.pane-14',
translateY: '-100vh',
background: '#FF1461',
changeBegin: logChangeBegan,
changeComplete: logChangeComplete,
}, '-=500')
onScroll(function(top, scrollHeight) {
var currentTime = tl.duration * (top / (scrollHeight - window.innerHeight));
tl.seek(currentTime);
});
</script>
<!-- <script src="../assets/js/vendors/stats.min.js"></script> -->
</html>

View File

@ -0,0 +1,104 @@
<!DOCTYPE html>
<html>
<head>
<title>stagger | anime.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:title" content="anime.js">
<meta property="og:url" content="https://animejs.com">
<meta property="og:description" content="Javascript Animation Engine">
<meta property="og:image" content="https://animejs.com/documentation/assets/img/icons/og.png">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="anime.js">
<meta name="twitter:site" content="@juliangarnier">
<meta name="twitter:description" content="Javascript Animation Engine">
<meta name="twitter:image" content="https://animejs.com/documentation/assets/img/icons/twitter.png">
<link rel="apple-touch-icon-precomposed" href="../assets/img/social-media-image.png">
<link rel="icon" type="image/png" href="../assets/img/favicon.png" >
<link href="../assets/css/animejs.css" rel="stylesheet">
<link href="../assets/css/documentation.css" rel="stylesheet">
<style>
:root {
font-size: 20px;
}
body {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
background-color: #F6F4F2;
}
.keyframes-visualizer {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
width: 16rem;
height: 16rem;
}
.keyframes-visualizer div {
position: relative;
width: .8rem;
height: .8rem;
margin: .1rem;
border: 2px solid currentColor;
background-color: #F6F4F2;
color: #373535;
border-radius: 50%;
}
</style>
</head>
<body>
<div class="keyframes-visualizer"></div>
</body>
<script src="../../lib/anime.min.js"></script>
<script>
//import anime from '../../src/index.js';
const keyframesVisualizerEl = document.querySelector('.keyframes-visualizer');
const fragment = document.createDocumentFragment();
const numberOfElements = 256;
for (let i = 0; i < numberOfElements; i++) {
fragment.appendChild(document.createElement('div'));
}
keyframesVisualizerEl.appendChild(fragment);
const animation = anime({
targets: '.keyframes-visualizer div',
keyframes: [
{
color: '#FF4B4B',
translateX: anime.stagger('-.15rem', {grid: [16, 16], from: 'center', axis: 'x'}),
translateY: anime.stagger('-.15rem', {grid: [16, 16], from: 'center', axis: 'y'}),
duration: 300
},
{
translateX: anime.stagger('.125rem', {grid: [16, 16], from: 'center', axis: 'x'}),
translateY: anime.stagger('.125rem', {grid: [16, 16], from: 'center', axis: 'y'}),
duration: 500
}, {
color: '#373535',
translateX: 0,
translateY: 0,
duration: 600,
}
],
delay: anime.stagger(2),
easing: 'easeInOutQuad',
loop: true
});
console.log(animation);
</script>
</html>

View File

@ -0,0 +1,155 @@
<!DOCTYPE html>
<html>
<head>
<title>layered animations • anime.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:title" content="anime.js">
<meta property="og:url" content="https://animejs.com">
<meta property="og:description" content="Javascript Animation Engine">
<meta property="og:image" content="https://animejs.com/documentation/assets/img/icons/og.png">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="anime.js">
<meta name="twitter:site" content="@juliangarnier">
<meta name="twitter:description" content="Javascript Animation Engine">
<meta name="twitter:image" content="https://animejs.com/documentation/assets/img/icons/twitter.png">
<link rel="apple-touch-icon-precomposed" href="../assets/img/social-media-image.png">
<link rel="icon" type="image/png" href="../assets/img/favicon.png" >
<link href="../assets/css/animejs.css" rel="stylesheet">
<style>
:root {
font-size: 24px;
}
body {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
height: 100vh;
}
.layered-animations {
position: relative;
display: flex;
justify-content: center;
align-items: center;
width: 16rem;
height: 16rem;
/*border: 1px solid red;*/
}
.layered-animations .shape {
position: absolute;
overflow: visible;
width: 8rem;
height: 8rem;
stroke: currentColor;
fill: transparent;
}
.layered-animations .small.shape {
width: 1.5rem;
height: 1.5rem;
stroke: currentColor;
stroke-width: 2px;
fill: currentColor;
}
</style>
</head>
<body>
<div class="layered-animations">
<svg class="small shape color-red" viewBox="0 0 96 96">
<rect width="48" height="48" x="24" y="24" fill-rule="evenodd" stroke-linecap="square"/>
</svg>
<svg class="small shape color-red" viewBox="0 0 96 96">
<polygon fill-rule="evenodd" points="48 17.28 86.4 80.11584 9.6 80.11584" stroke-linecap="square"/>
</svg>
<svg class="small shape color-red" viewBox="0 0 96 96">
<circle cx="48" cy="48" r="32" fill-rule="evenodd" stroke-linecap="square"/>
</svg>
<svg class="shape" viewBox="0 0 96 96">
<circle cx="48" cy="48" r="28" fill-rule="evenodd" stroke-linecap="square"/>
</svg>
<svg class="shape" viewBox="0 0 96 96">
<rect width="48" height="48" x="24" y="24" fill-rule="evenodd" stroke-linecap="square"/>
</svg>
<svg class="shape" viewBox="0 0 96 96">
<polygon fill-rule="evenodd" points="48 17.28 86.4 80.11584 9.6 80.11584" stroke-linecap="square"/>
</svg>
</div>
</body>
<script type="module">
import anime from '../../src/index.js';
var shapeEls = document.querySelectorAll('.shape');
var triangleEl = document.querySelector('.layered-animations polygon');
var trianglePoints = triangleEl.getAttribute('points').split(' ');
var easings = ['easeInOutQuad', 'easeInOutCirc', 'easeInOutSine', 'spring'];
function animateShape(el) {
var circleEl = el.querySelector('circle');
var rectEl = el.querySelector('rect');
var polyEl = el.querySelector('polygon');
function createKeyframes(total, min, max, unit) {
var keyframes = [];
var unit = unit || 0;
for (var i = 0; i < total; i++) keyframes.push({ value: function() { return anime.random(min, max) + unit; } });
return keyframes;
}
function createKeyframes(value) {
var keyframes = [];
for (var i = 0; i < 30; i++) keyframes.push({ value: value });
return keyframes;
}
var animation = anime.timeline({
targets: el,
duration: function() { return anime.random(800, 2000); },
easing: function() { return easings[anime.random(0, easings.length - 1)]; },
complete: function(anim) { animateShape(anim.animatables[0].target); },
})
.add({
translateX: createKeyframes(function() { return anime.random(-4, 4) + 'rem'; }),
translateY: createKeyframes(function() { return anime.random(-4, 4) + 'rem'; }),
rotate: createKeyframes(function() { return anime.random(-180, 180); }),
}, 0);
if (circleEl) {
animation.add({
targets: circleEl,
r: createKeyframes(function() { return anime.random(24, 56); }),
}, 0);
}
if (rectEl) {
animation.add({
targets: rectEl,
width: createKeyframes(function() { return anime.random(56, 96); }),
height: createKeyframes(function() { return anime.random(56, 96); }),
}, 0);
}
if (polyEl) {
animation.add({
targets: polyEl,
points: createKeyframes(function() {
var scale = anime.random(64, 148) / 100;
return trianglePoints.map(function(p) { return p * scale; }).join(' ');
}),
}, 0);
}
}
for (var i = 0; i < shapeEls.length; i++) {
animateShape(shapeEls[i]);
}
</script>
</html>

View File

@ -0,0 +1,83 @@
<!DOCTYPE html>
<html>
<head>
<title>domaku | anime.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:title" content="anime.js">
<meta property="og:url" content="https://animejs.com">
<meta property="og:description" content="Javascript Animation Engine">
<meta property="og:image" content="https://animejs.com/documentation/assets/img/icons/og.png">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="anime.js">
<meta name="twitter:site" content="@juliangarnier">
<meta name="twitter:description" content="Javascript Animation Engine">
<meta name="twitter:image" content="https://animejs.com/documentation/assets/img/icons/twitter.png">
<link rel="apple-touch-icon-precomposed" href="../assets/img/social-media-image.png">
<link rel="icon" type="image/png" href="../assets/img/favicon.png">
<link href="../assets/css/documentation.css" rel="stylesheet">
<script src="../../lib/anime.min.js"></script>
<!-- <script src="../assets/js/anime/anime.3.0.0-alpha.js"></script> -->
<!-- <script src="../assets/js/anime/anime.2.2.0.js"></script> -->
<!-- <script src="../assets/js/anime/anime.2.0.1.js"></script> -->
<!-- <script src="../assets/js/anime/anime.1.3.js"></script> -->
<style>
body {
overflow: hidden;
position: absolute;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
padding: 8em;
font-size: 24px;
}
.wrapper {
display: flex;
flex-direction: column;
flex-wrap: wrap;
}
.particule {
width: 1px;
height: 10em;
margin-left: 1px;
transform-origin: 50 50%;
}
</style>
</head>
<body>
<script>
var numberOfEls = 500;
var duration = 5000;
var midScreenX = window.innerWidth / 2;
var midScreenY = window.innerHeight / 2;
var radius = Math.sqrt(midScreenX * midScreenX + midScreenY * midScreenY);
var fragment = document.createDocumentFragment();
for (var i = 0; i < numberOfEls; i++) {
var hue = 10 + Math.round(40 / numberOfEls * i);
var el = document.createElement('div');
el.classList.add('particule');
el.style.backgroundColor = 'hsl(' + hue + ', 100%, 50%)';
el.style.transform = 'rotate(' + i * 1 + 'deg) translateX(100px)';
document.body.appendChild(el);
anime({
targets: el,
rotate: '+=360',
//delay: i * (duration / numberOfEls),
//endDelay: i * (duration / numberOfEls),
easing: 'linear',
duration: duration,
loop: true
});
}
</script>
<script src="../assets/js/vendors/stats.min.js"></script>
</body>
</html>

View File

@ -0,0 +1,153 @@
<!DOCTYPE html>
<html>
<head>
<title>stagger | anime.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:title" content="anime.js">
<meta property="og:url" content="https://animejs.com">
<meta property="og:description" content="Javascript Animation Engine">
<meta property="og:image" content="https://animejs.com/documentation/assets/img/icons/og.png">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="anime.js">
<meta name="twitter:site" content="@juliangarnier">
<meta name="twitter:description" content="Javascript Animation Engine">
<meta name="twitter:image" content="https://animejs.com/documentation/assets/img/icons/twitter.png">
<link rel="apple-touch-icon-precomposed" href="../assets/img/social-media-image.png">
<link rel="icon" type="image/png" href="../assets/img/favicon.png" >
<link href="../assets/css/animejs.css" rel="stylesheet">
<link href="../assets/css/documentation.css" rel="stylesheet">
<style>
body {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
background-color: #F6F4F2;
}
.stagger-visualizer {
display: flex;
/*flex-wrap: wrap;*/
justify-content: center;
align-items: center;
width: 450px;
height: 450px;
}
.stagger-visualizer div {
/*position: absolute;*/
width: 64px;
height: 128px;
border: 1px solid #373535;
background-color: #F6F4F2;
}
</style>
</head>
<body>
<div class="stagger-visualizer"></div>
</body>
<script type="module">
import anime from '../../src/index.js';
const staggerVisualizerEl = document.querySelector('.stagger-visualizer');
const fragment = document.createDocumentFragment();
const numberOfElements = 81;
for (let i = 0; i < numberOfElements; i++) {
fragment.appendChild(document.createElement('div'));
}
staggerVisualizerEl.appendChild(fragment);
const staggersAnimation = anime.timeline({
targets: '.stagger-visualizer div',
easing: 'easeInOutSine',
delay: anime.stagger(50),
loop: true,
autoplay: false,
duration: 600,
loopComplete: (a) => console.log('end'),
//update: () => console.log(staggersAnimation.progress)
})
.add({
scale: anime.stagger([2.5, 1], {from: 'center', grid: [9, 9]}),
translateX: anime.stagger([-100, 100]),
rotate: anime.stagger([-45, 45]),
easing: 'easeInOutCirc',
delay: anime.stagger(10, {from: 'center'})
})
.add({
scale: anime.stagger([2.5, 1], {from: 'center', easing: 'easeInOutCirc'}),
translateX: anime.stagger([-200, 200]),
translateY: anime.stagger([-200, 200]),
rotate: 0,
delay: anime.stagger(1, {from: 'last'})
})
.add({
rotate: anime.stagger(2, {from: 'center', direction: 'reverse', easing: 'easeInSine'}),
translateX: 0,
translateY: 0,
delay: anime.stagger(10, {from: 'center'})
})
.add({
scale: anime.stagger([2, 1], {grid: [9, 9], axis: 'y'}),
translateY: anime.stagger([-100, 200], {grid: [9, 9], axis: 'y'}),
rotate: 0,
delay: anime.stagger(1, {from: 'last'})
})
.add({
translateX: () => anime.random(-100, 100),
translateY: () => anime.random(-100, 100),
scale: anime.stagger([1.5, .5], {from: 'center'}),
rotate: anime.stagger([10, -10], {from: 'last'}),
delay: anime.stagger(50, {from: 'center', grid: [9, 9]}),
})
.add({
translateX: () => anime.random(-100, 100),
translateY: () => anime.random(-100, 100),
rotate: anime.stagger([-10, 10], {from: 'last'}),
scale: 1,
delay: anime.stagger(50, {from: 'center', grid: [9, 9]}),
})
.add({
translateX: 0,
translateY: anime.stagger(6, {from: 'center', direction: 'reverse'}),
rotate: 0,
delay: anime.stagger(50, {from: 'center', grid: [9, 9]}),
})
.add({
translateX: anime.stagger('1rem', {grid: [9, 9], from: 'center', axis: 'x'}),
//translateY: anime.stagger('1rem', {grid: [9, 9], from: 'center', axis: 'y'}),
delay: anime.stagger(200, {grid: [9, 9], from: 'center', direction: 'reverse'})
})
.add({
translateX: anime.stagger([25, -25], {from: 'first'}),
translateY: 0,
rotate: anime.stagger([40, -40], {from: 'first'}),
delay: anime.stagger(10, {from: 'first'}),
})
.add({
translateY: anime.stagger([-240, 240]),
rotate: () => anime.random(-100, 100),
scale: anime.stagger([1, 3], {from: 'center'}),
delay: anime.stagger(10, {from: 0}),
})
.add({
translateX: 0,
translateY: 0,
scale: 1,
rotate: 360,
duration: 2000,
delay: 0,
});
staggersAnimation.play();
</script>
</html>

View File

@ -0,0 +1,130 @@
<!DOCTYPE html>
<html>
<head>
<title>stagger | anime.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:title" content="anime.js">
<meta property="og:url" content="https://animejs.com">
<meta property="og:description" content="Javascript Animation Engine">
<meta property="og:image" content="https://animejs.com/documentation/assets/img/icons/og.png">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="anime.js">
<meta name="twitter:site" content="@juliangarnier">
<meta name="twitter:description" content="Javascript Animation Engine">
<meta name="twitter:image" content="https://animejs.com/documentation/assets/img/icons/twitter.png">
<link rel="apple-touch-icon-precomposed" href="../assets/img/social-media-image.png">
<link rel="icon" type="image/png" href="../assets/img/favicon.png" >
<link href="../assets/css/animejs.css" rel="stylesheet">
<link href="../assets/css/documentation.css" rel="stylesheet">
<style>
:root {
font-size: 20px;
}
body {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
background-color: #FF4B4B;
}
.stagger-visualizer {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
width: 17rem;
height: 17rem;
}
.stagger-visualizer div {
/*position: absolute;*/
width: 1rem;
height: 1rem;
border: 1px solid #FFF;
background-color: #FFF;
}
</style>
</head>
<body>
<div class="stagger-visualizer"></div>
</body>
<script type="module">
import anime from '../../src/index.js';
const staggerVisualizerEl = document.querySelector('.stagger-visualizer');
const fragment = document.createDocumentFragment();
const grid = [17, 17];
const col = grid[0];
const row = grid[1];
const numberOfElements = col * row;
for (let i = 0; i < numberOfElements; i++) {
fragment.appendChild(document.createElement('div'));
}
staggerVisualizerEl.appendChild(fragment);
const staggersAnimation = anime.timeline({
targets: '.stagger-visualizer div',
easing: 'easeInOutSine',
delay: anime.stagger(50),
loop: true,
autoplay: false
})
.add({
translateX: [
{value: anime.stagger('-.1rem', {grid: grid, from: 'center', axis: 'x'}) },
{value: anime.stagger('.1rem', {grid: grid, from: 'center', axis: 'x'}) }
],
translateY: [
{value: anime.stagger('-.1rem', {grid: grid, from: 'center', axis: 'y'}) },
{value: anime.stagger('.1rem', {grid: grid, from: 'center', axis: 'y'}) }
],
duration: 1000,
scale: .5,
delay: anime.stagger(100, {grid: grid, from: 'center'})
})
.add({
translateX: () => anime.random(-10, 10),
translateY: () => anime.random(-10, 10),
delay: anime.stagger(8, {from: 'last'})
})
.add({
translateX: anime.stagger('.25rem', {grid: grid, from: 'center', axis: 'x'}),
translateY: anime.stagger('.25rem', {grid: grid, from: 'center', axis: 'y'}),
rotate: 0,
scaleX: 4,
scaleY: .25,
delay: anime.stagger(4, {from: 'center'})
})
.add({
rotate: anime.stagger([90, 0], {grid: grid, from: 'center'}),
delay: anime.stagger(50, {grid: grid, from: 'center'})
})
.add({
translateX: 0,
translateY: 0,
scale: .5,
scaleX: 1,
rotate: 0,
duration: 1000,
delay: anime.stagger(100, {grid: grid, from: 'center'})
})
.add({
scaleY: 1,
scale: 1,
delay: anime.stagger(20, {grid: grid, from: 'center'})
})
staggersAnimation.play();
</script>
</html>

View File

@ -0,0 +1,440 @@
<!DOCTYPE html>
<html>
<head>
<title>stagger | anime.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:title" content="anime.js">
<meta property="og:url" content="https://animejs.com">
<meta property="og:description" content="Javascript Animation Engine">
<meta property="og:image" content="https://animejs.com/documentation/assets/img/icons/og.png">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="anime.js">
<meta name="twitter:site" content="@juliangarnier">
<meta name="twitter:description" content="Javascript Animation Engine">
<meta name="twitter:image" content="https://animejs.com/documentation/assets/img/icons/twitter.png">
<link rel="apple-touch-icon-precomposed" href="../assets/img/social-media-image.png">
<link rel="icon" type="image/png" href="../assets/img/favicon.png" >
<link href="../assets/css/animejs.css" rel="stylesheet">
<link href="../assets/css/documentation.css" rel="stylesheet">
<style>
body {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
}
.testarea {
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
flex-shrink: 0;
width: 100%;
height: 100%;
}
.demo {
position: relative;
flex-wrap: wrap;
align-items: center;
flex-grow: 1;
width: 14rem;
height: 4rem;
padding: 2rem;
border-bottom: none;
}
.demo h1 {
position: absolute;
top: 0;
left: 0;
right: 0;
text-align: center;
}
.demo div {
width: 1rem;
height: 1rem;
/*background-color: currentColor;*/
border: 2px solid currentColor;
}
.demo .grid-wrapper {
position: relative;
display: flex;
flex-wrap: wrap;
align-items: center;
width: 10rem;
height: 5rem;
margin: auto;
border: none;
}
/* Player animation */
.timeline {
opacity: .2;
position: fixed;
flex-shrink: 0;
width: 100%;
height: 100%;
padding-top: 4px;
}
.timeline.player-animation {
width: 100%;
left: 0;
}
.tl-needle {
position: fixed;
z-index: 2;
top: 0;
left: 0;
width: 2px;
height: 100%;
margin-left: -1px;
background-color: #FFF;
}
.tl-animation {
position: relative;
display: flex;
justify-content: space-between;
width: auto;
height: 2px;
margin-bottom: 2px;
background-color: currentColor;
border-radius: .5rem;
}
.tl-delay,
.tl-end-delay {
width: auto;
height: 100%;
background-color: rgba(0,0,0,.5);
}
</style>
</head>
<body>
<div class="player-animation"></div>
<div class="testarea">
<section class="demo normal">
<h1>Normal</h1>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</section>
<section class="demo normal-reversed">
<h1>Normal reversed</h1>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</section>
<section class="demo from-last">
<h1>From last</h1>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</section>
<section class="demo from-last-reversed">
<h1>From last reversed</h1>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</section>
<section class="demo from-center">
<h1>From center</h1>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</section>
<section class="demo from-center-reversed">
<h1>From center reversed</h1>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</section>
<section class="demo from-index">
<h1>From index</h1>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</section>
<section class="demo from-index-reversed">
<h1>From index reversed</h1>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</section>
<section class="demo range">
<h1>Range</h1>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</section>
<section class="demo range-reversed">
<h1>Range reversed</h1>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</section>
<section class="demo range-from-last">
<h1>Range from last</h1>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</section>
<section class="demo range-from-last-reversed">
<h1>Range from last reversed</h1>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</section>
<section class="demo range-from-center">
<h1>Range from center</h1>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</section>
<section class="demo range-from-center-reversed">
<h1>Range from center reversed</h1>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</section>
<section class="demo easing">
<h1>Easing</h1>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</section>
<section class="demo easing-reversed">
<h1>Easing reversed</h1>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</section>
<section class="demo">
<h1>Coordinates</h1>
<div class="grid-wrapper grid">
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</div>
</section>
<section class="demo">
<h1>Coordinates reversed</h1>
<div class="grid-wrapper grid-reversed">
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</div>
</section>
<section class="demo">
<h1>Coordinates reversed</h1>
<div class="grid-wrapper grid-axis">
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</div>
</section>
<section class="demo">
<h1>Coordinates reversed</h1>
<div class="grid-wrapper grid-axis-reversed">
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</div>
</section>
</div>
</body>
<script type="module">
import anime from '../../src/index.js';
var animations = anime.timeline({
easing: 'easeInOutQuad',
// direction: 'alternate',
loop: true
})
.add({
targets: '.normal div',
translateY: anime.stagger('-.5em'),
delay: anime.stagger(200)
}, 0)
.add({
targets: '.normal-reversed div',
translateY: anime.stagger('-.5em', { direction: 'reverse' }),
delay: anime.stagger(200, { direction: 'reverse' }),
}, 0)
.add({
targets: '.from-last div',
translateY: anime.stagger('-.5em', {from: 'last'}),
delay: anime.stagger(200, {from: 'last'})
}, 0)
.add({
targets: '.from-last-reversed div',
translateY: anime.stagger('-.5em', { from: 'last', direction: 'reverse' }),
delay: anime.stagger(200, { from: 'last', direction: 'reverse' }),
}, 0)
.add({
targets: '.from-center div',
translateY: anime.stagger('-.5em', {from: 'center'}),
delay: anime.stagger(200, {from: 'center'})
}, 0)
.add({
targets: '.from-center-reversed div',
translateY: anime.stagger('-.5em', { from: 'center', direction: 'reverse' }),
delay: anime.stagger(200, { from: 'center', direction: 'reverse' }),
}, 0)
.add({
targets: '.from-index div',
translateY: anime.stagger('-.5em', {from: 3}),
delay: anime.stagger(200, {from: 3})
}, 0)
.add({
targets: '.from-index-reversed div',
translateY: anime.stagger('-.5em', { from: 3, direction: 'reverse' }),
delay: anime.stagger(200, { from: 3, direction: 'reverse' }),
}, 0)
.add({
targets: '.range div',
translateY: anime.stagger(['-2em', '2em']),
delay: anime.stagger([0, 600])
}, 0)
.add({
targets: '.range-reversed div',
translateY: anime.stagger(['-2em', '2em'], { direction: 'reverse'}),
delay: anime.stagger([0, 600], { direction: 'reverse'}),
}, 0)
.add({
targets: '.range-from-last div',
translateY: anime.stagger(['-2em', '2em'], {from: 'last'}),
delay: anime.stagger([0, 600], {from: 'last'})
}, 0)
.add({
targets: '.range-from-last-reversed div',
translateY: anime.stagger(['-2em', '2em'], { from: 'last', direction: 'reverse'}),
delay: anime.stagger([0, 600], { from: 'last', direction: 'reverse'}),
}, 0)
.add({
targets: '.range-from-center div',
translateY: anime.stagger(['-2em', '2em'], {from: 'center'}),
delay: anime.stagger([0, 600], {from: 'center'})
}, 0)
.add({
targets: '.range-from-center-reversed div',
translateY: anime.stagger(['-2em', '2em'], { from: 'center', direction: 'reverse'}),
delay: anime.stagger([0, 600], { from: 'center', direction: 'reverse'}),
}, 0)
.add({
targets: '.easing div',
translateY: anime.stagger(['2rem', '-2rem'], {from: 'center', easing: 'easeOutExpo'}),
delay: anime.stagger([0, 600], {from: 'center', easing: 'easeOutExpo'})
}, 0)
.add({
targets: '.easing-reversed div',
translateY: anime.stagger(['2rem', '-2rem'], {from: 'center', direction: 'reverse', easing: 'easeOutExpo'}),
delay: anime.stagger([0, 600], {from: 'center', direction: 'reverse', easing: 'easeOutExpo'}),
}, 0)
.add({
targets: '.grid div',
scale: anime.stagger([1, 0], {grid: [10, 5], from: 38}),
delay: anime.stagger(100, {grid: [10, 5], from: 38})
}, 0)
.add({
targets: '.grid-reversed div',
scale: anime.stagger([1, 0], {grid: [10, 5], from: 38, direction: 'reverse'}),
delay: anime.stagger(100, {grid: [10, 5], from: 38, direction: 'reverse'})
}, 0)
.add({
targets: '.grid-axis div',
translateX: anime.stagger('.5rem', {grid: [10, 5], from: 38, axis: 'x'}),
translateY: anime.stagger('.5rem', {grid: [10, 5], from: 38, axis: 'y'}),
delay: anime.stagger(100, {grid: [10, 5], from: 38})
}, 0)
.add({
targets: '.grid-axis-reversed div',
translateX: anime.stagger('.5rem', {grid: [10, 5], from: 38, axis: 'x', direction: 'reverse'}),
translateY: anime.stagger('.5rem', {grid: [10, 5], from: 38, axis: 'y', direction: 'reverse'}),
delay: anime.stagger(100, {grid: [10, 5], from: 38, direction: 'reverse'})
}, 0);
function animePlayer(instance, playerClass) {
function createEl(type, className, parentEl) {
var el = document.createElement(type);
if (className) el.classList.add(className);
if (parentEl) parentEl.appendChild(el);
return el;
}
var timelineEl = createEl('div', 'timeline', document.body);
if (playerClass) timelineEl.classList.add(playerClass);
var needleEl = createEl('div', 'tl-needle', timelineEl);
var animations = [];
var colors = ['#FF1461','#FF7C72','#FBF38C','#A6FF8F','#18FF92','#1CE2B2','#5EF3FB','#61C3FF','#5A87FF','#8453E3','#C26EFF','#FB89FB'];
var colorIndex = 0;
function convertMStoEM(ms) { return ms / 100; }
function convertEMtoMS(em) { return parseFloat(em) * 250; }
function createAnimationLog(animObj, timelineOffset) {
var anim = animObj;
anim.player = {};
anim.player.animationEl = createEl('div', 'tl-animation', timelineEl);
anim.player.delayEl = createEl('div', 'tl-delay', anim.player.animationEl);
anim.player.endDelayEl = createEl('div', 'tl-end-delay', anim.player.animationEl);
anim.update = function() {
anime.set(anim.player.animationEl, {
left: convertMStoEM(timelineOffset) + 'em',
width: convertMStoEM(anim.duration * 3) + 'em'
});
anime.set(anim.player.delayEl, {width: (anim.delay / anim.duration) * 100 + '%'});
anime.set(anim.player.endDelayEl, {width: (anim.endDelay / anim.duration) * 100 + '%'});
}
anime.set(anim.player.animationEl, {color: colors[colorIndex]});
colorIndex++;
if (!colors[colorIndex]) colorIndex = 0;
anim.update();
animations.push(anim);
return anim;
}
instance.pause();
var playerAnimation = anime({
targets: needleEl,
translateX: convertMStoEM(instance.duration * 3) + 'em',
duration: instance.duration,
direction: instance.direction,
loop: instance.loop,
easing: 'linear',
update: function(a) {
instance.seek(a.currentTime);
}
});
if (instance.children.length) {
instance.children.forEach(function(child) {
child.animations.forEach(function(anim) {
createAnimationLog(anim, child.timelineOffset);
});
})
} else {
instance.animations.forEach(function(anim) {
createAnimationLog(anim);
});
}
}
animePlayer(animations, 'player-animation');
</script>
</html>

View File

@ -0,0 +1,95 @@
<!DOCTYPE html>
<html>
<head>
<title>Staggered loops | anime.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:title" content="anime.js">
<meta property="og:url" content="https://animejs.com">
<meta property="og:description" content="Javascript Animation Engine">
<meta property="og:image" content="https://animejs.com/documentation/assets/img/icons/og.png">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="anime.js">
<meta name="twitter:site" content="@juliangarnier">
<meta name="twitter:description" content="Javascript Animation Engine">
<meta name="twitter:image" content="https://animejs.com/documentation/assets/img/icons/twitter.png">
<link rel="apple-touch-icon-precomposed" href="../assets/img/social-media-image.png">
<link rel="icon" type="image/png" href="../assets/img/favicon.png">
<link href="../assets/css/documentation.css" rel="stylesheet">
<script src="../../lib/anime.min.js"></script>
<!-- <script src="../assets/js/anime/anime.2.2.0.js"></script> -->
<!-- <script src="../assets/js/anime/anime.1.3.js"></script> -->
<style>
body {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100vh;
}
.wrapper {
position: relative;
display: flex;
align-items: center;
flex-wrap: wrap;
width: 1px;
height: 100vh;
}
.el {
position: absolute;
opacity: 1;
width: 2px;
height: 24vh;
margin-top: -12vh;
transform-origin: 50% 100%;
background: white;
}
</style>
</head>
<body>
<div class="wrapper"></div>
<script>
const wrapperEl = document.querySelector('.wrapper');
const numberOfEls = 180;
const duration = 6000;
const delay = duration / numberOfEls;
let tl = anime.timeline({
duration: delay,
complete: function() { tl.restart(); }
});
function createEl(i) {
let el = document.createElement('div');
const rotate = (360 / numberOfEls) * i;
const translateY = -50;
const hue = Math.round(360 / numberOfEls * i);
el.classList.add('el');
el.style.backgroundColor = 'hsl(' + hue + ', 40%, 60%)';
el.style.transform = 'rotate(' + rotate + 'deg) translateY(' + translateY + '%)';
tl.add({
begin: function() {
anime({
targets: el,
backgroundColor: ['hsl(' + hue + ', 40%, 60%)', 'hsl(' + hue + ', 60%, 80%)'],
rotate: [rotate + 'deg', rotate + 10 +'deg'],
translateY: [translateY + '%', translateY + 10 + '%'],
scale: [1, 1.25],
easing: 'easeInOutSine',
direction: 'alternate',
duration: duration * .1
});
}
});
wrapperEl.appendChild(el);
};
for (let i = 0; i < numberOfEls; i++) createEl(i);
</script>
<script src="../assets/js/vendors/stats.min.js"></script>
</body>
</html>

View File

@ -0,0 +1,126 @@
<!DOCTYPE html>
<html>
<head>
<title>stagger | anime.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:title" content="anime.js">
<meta property="og:url" content="https://animejs.com">
<meta property="og:description" content="Javascript Animation Engine">
<meta property="og:image" content="https://animejs.com/documentation/assets/img/icons/og.png">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="anime.js">
<meta name="twitter:site" content="@juliangarnier">
<meta name="twitter:description" content="Javascript Animation Engine">
<meta name="twitter:image" content="https://animejs.com/documentation/assets/img/icons/twitter.png">
<link rel="apple-touch-icon-precomposed" href="../assets/img/social-media-image.png">
<link rel="icon" type="image/png" href="../assets/img/favicon.png" >
<link href="../assets/css/animejs.css" rel="stylesheet">
<link href="../assets/css/documentation.css" rel="stylesheet">
<style>
body {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
}
.easing-visualizer {
display: flex;
justify-content: space-between;
align-items: flex-end;
width: 400px;
height: 400px;
}
.easing-visualizer div {
width: 4px;
height: 4px;
margin: 0 0 0 0;
background-color: #FFF;
transform-origin: 50% 100%;
border-radius: 50%;
}
</style>
</head>
<body>
<div class="easing-visualizer"></div>
</body>
<script type="module">
import anime from '../../src/index.js';
const easingVisualizerEl = document.querySelector('.easing-visualizer');
const fragment = document.createDocumentFragment();
const numberOfElements = 101;
for (let i = 0; i < numberOfElements; i++) {
fragment.appendChild(document.createElement('div'));
}
easingVisualizerEl.appendChild(fragment);
var easings = [
"easeInSine",
"easeOutSine",
"easeInOutSine",
"easeInCirc",
"easeOutCirc",
"easeInOutCirc",
"easeInBack",
"easeOutBack",
"easeInOutBack",
"easeInBounce",
"easeOutBounce",
"easeInOutBounce",
"easeInElastic",
"easeOutElastic",
"easeInOutElastic",
"easeInQuad",
"easeOutQuad",
"easeInOutQuad",
"easeInCubic",
"easeOutCubic",
"easeInOutCubic",
"easeInQuart",
"easeOutQuart",
"easeInOutQuart",
"easeInQuint",
"easeOutQuint",
"easeInOutQuint",
"easeInExpo",
"easeOutExpo",
"easeInOutExpo",
"linear"
]
anime.set('.easing-visualizer div', {
translateY: anime.stagger([0, -400], {easing: 'linear'})
})
anime({
targets: '.easing-visualizer div',
translateY: (() => {
const keyframes = [];
easings.forEach(function(ease) {
keyframes.push({
value: anime.stagger([0, -400], {easing: ease}),
delay: anime.stagger(.125)
});
})
return keyframes;
})(),
translateZ: 0,
easing: 'easeInOutSine',
duration: 9000,
loop: true
});
console.log(anime.penner);
</script>
</html>

View File

@ -0,0 +1,93 @@
<!DOCTYPE html>
<html>
<head>
<title>SVG line drawing | anime.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:title" content="anime.js">
<meta property="og:url" content="https://animejs.com">
<meta property="og:description" content="Javascript Animation Engine">
<meta property="og:image" content="https://animejs.com/documentation/assets/img/icons/og.png">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="anime.js">
<meta name="twitter:site" content="@juliangarnier">
<meta name="twitter:description" content="Javascript Animation Engine">
<meta name="twitter:image" content="https://animejs.com/documentation/assets/img/icons/twitter.png">
<link rel="apple-touch-icon-precomposed" href="../assets/img/social-media-image.png">
<link rel="icon" type="image/png" href="../assets/img/favicon.png">
<link href="../assets/css/documentation.css" rel="stylesheet">
<style>
body {
display: flex;
align-items: center;
justify-content: center;
position: absolute;
overflow: hidden;
width: 100%;
height: 100%;
}
.anim {
position: relative;
width: 50%;
}
.anim svg {
position: relative;
width: 100%;
border: 1px solid red;
}
.anim path {
stroke-width: 2;
}
.item {
position: absolute;
left: 0;
top: 0;
width: 30px;
height: 30px;
margin-left: -15px;
margin-top: -15px;
background-color: white;
}
</style>
</head>
<body>
<div class="anim">
<div class="item"></div>
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid slice" viewBox="0 0 600 400">
<g fill="none" fill-rule="evenodd" stroke-width="2">
<line class="line-1" stroke="#F96F82" x1="51.5" x2="149.5" y1="51.5" y2="149.5" stroke-linecap="square"/>
<line class="line-2s" stroke="#F96F82" x1="149.5" x2="51.5" y1="51.5" y2="149.5" stroke-linecap="square"/>
<circle cx="300" cy="100" r="50" stroke="#FED28B"/>
<polygon stroke="#D1FA9E" points="500 130.381 464.772 149 471.5 109.563 443 81.634 482.386 75.881 500 40 517.614 75.881 557 81.634 528.5 109.563 535.228 149"/>
<polyline stroke="#7BE6D6" points="63.053 343 43 281.815 95.5 244 95.5 244 148 281.815 127.947 343"/>
<path class="path" stroke="#4E7EFC" d="M250 300a50 50 0 0 1 100 0v25h-25v-25a25 25 0 1 0-25 25v25a50 50 0 0 1-50-50z"/>
<rect width="98" height="98" x="451" y="251" stroke="#C987FE" rx="25"/>
</g>
</svg>
</div>
<!-- <script type="module" src="../../src/index.js"></script> -->
<script type="module">
import anime from "../../src/index.js";
anime({
targets: ['line', 'circle', 'polygon', 'polyline', 'path', 'rect'],
strokeDashoffset: [anime.setDashoffset, 0],
easing: 'easeInOutSine',
duration: 1500,
direction: 'alternate',
loop: true
});
var pathEl = anime.path('.path');
anime({
targets: '.item',
translateX: pathEl('x'),
translateY: pathEl('y'),
rotate: pathEl('angle'),
easing: 'easeInOutSine',
duration: 1500,
direction: 'alternate',
loop: true
});
</script>
<!-- <script src="../assets/js/vendors/stats.min.js"></script> -->
</body>
</html>

View File

@ -0,0 +1,118 @@
<!DOCTYPE html>
<html>
<head>
<title>SVG responsive path animation | anime.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:title" content="anime.js">
<meta property="og:url" content="https://animejs.com">
<meta property="og:description" content="Javascript Animation Engine">
<meta property="og:image" content="https://animejs.com/documentation/assets/img/icons/og.png">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="anime.js">
<meta name="twitter:site" content="@juliangarnier">
<meta name="twitter:description" content="Javascript Animation Engine">
<meta name="twitter:image" content="https://animejs.com/documentation/assets/img/icons/twitter.png">
<link rel="apple-touch-icon-precomposed" href="../assets/img/social-media-image.png">
<link rel="icon" type="image/png" href="../assets/img/favicon.png">
<link href="../assets/css/animejs.css" rel="stylesheet">
<link href="../assets/css/documentation.css" rel="stylesheet">
<style>
body {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
position: absolute;
overflow: hidden;
width: 100%;
height: 100%;
}
h2 {
margin-bottom: 20px;
}
.container {
position: relative;
margin-bottom: 20px;
}
.container > svg {
width: 100%;
box-shadow: 0px 0px 1px 1px red;
overflow: visible;
}
.dom-el {
position: absolute;
top: -1rem;
left: -1rem;
width: 2rem;
height: 2rem;
border: 2px solid currentColor;
}
</style>
</head>
<body>
<h2>No specified width</h2>
<div class="container no-specified-width">
<svg viewBox="0 0 256 112">
<path id="noSpecifiedWidth" fill="none" stroke="#FFF" d="M8,56 C8,33.90861 25.90861,16 48,16 C70.09139,16 88,33.90861 88,56 C88,78.09139 105.90861,92 128,92 C150.09139,92 160,72 160,56 C160,40 148,24 128,24 C108,24 96,40 96,56 C96,72 105.90861,92 128,92 C154,93 168,78 168,56 C168,33.90861 185.90861,16 208,16 C230.09139,16 248,33.90861 248,56 C248,78.09139 230.09139,96 208,96 L48,96 C25.90861,96 8,78.09139 8,56 Z"/>
<rect class="rect-el" fill="none" stroke="yellow" stroke-width="2" x="-10" y="-10" width="20" height="20"/>
</svg>
<div class="dom-el color-green"></div>
</div>
<h2>Specified width</h2>
<div class="container specified-width">
<svg viewBox="0 0 256 112" width="200" height="200">
<path id="specifiedWidth" fill="none" stroke="#FFF" d="M8,56 C8,33.90861 25.90861,16 48,16 C70.09139,16 88,33.90861 88,56 C88,78.09139 105.90861,92 128,92 C150.09139,92 160,72 160,56 C160,40 148,24 128,24 C108,24 96,40 96,56 C96,72 105.90861,92 128,92 C154,93 168,78 168,56 C168,33.90861 185.90861,16 208,16 C230.09139,16 248,33.90861 248,56 C248,78.09139 230.09139,96 208,96 L48,96 C25.90861,96 8,78.09139 8,56 Z"/>
<rect class="rect-el" fill="none" stroke="yellow" stroke-width="2" x="-10" y="-10" width="20" height="20"/>
</svg>
<div class="dom-el color-green"></div>
</div>
<h2>preserveAspectRatio with specified width</h2>
<div class="container preserveAspectRatio">
<svg viewBox="0 0 256 112" width="200" height="200" preserveAspectRatio="xMidYMid slice">
<path id="preserveAspectRatio" fill="none" stroke="#FFF" d="M8,56 C8,33.90861 25.90861,16 48,16 C70.09139,16 88,33.90861 88,56 C88,78.09139 105.90861,92 128,92 C150.09139,92 160,72 160,56 C160,40 148,24 128,24 C108,24 96,40 96,56 C96,72 105.90861,92 128,92 C154,93 168,78 168,56 C168,33.90861 185.90861,16 208,16 C230.09139,16 248,33.90861 248,56 C248,78.09139 230.09139,96 208,96 L48,96 C25.90861,96 8,78.09139 8,56 Z"/>
<rect class="rect-el" fill="none" stroke="yellow" stroke-width="2" x="-10" y="-10" width="20" height="20"/>
</svg>
<div class="dom-el color-green"></div>
</div>
</div>
<script type="module">
import anime from '../../src/index.js';
const path = anime.path('#noSpecifiedWidth');
anime({
targets: ['.no-specified-width .dom-el', '.no-specified-width .rect-el'],
translateX: path('x'),
translateY: path('y'),
rotate: path('angle'),
duration: 3000,
loop: true,
easing: 'linear'
});
const specifiedWidthPath = anime.path('#specifiedWidth');
anime({
targets: ['.specified-width .dom-el', '.specified-width .rect-el'],
translateX: specifiedWidthPath('x'),
translateY: specifiedWidthPath('y'),
rotate: specifiedWidthPath('angle'),
duration: 3000,
loop: true,
easing: 'linear'
});
const preserveAspectRatioPath = anime.path('#preserveAspectRatio');
anime({
targets: ['.preserveAspectRatio .dom-el', '.preserveAspectRatio .rect-el'],
translateX: preserveAspectRatioPath('x'),
translateY: preserveAspectRatioPath('y'),
rotate: preserveAspectRatioPath('angle'),
duration: 3000,
loop: true,
easing: 'linear'
});
</script>
</body>
</html>

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