Showing preview only (566K chars total). Download the full file or copy to clipboard to get everything.
Repository: tweenjs/es6-tween
Branch: master
Commit: 5b64a82535cb
Files: 41
Total size: 546.3 KB
Directory structure:
gitextract_2t0s81jl/
├── .babelrc
├── .editorconfig
├── .eslintignore
├── .eslintrc.json
├── .github/
│ ├── FUNDING.yml
│ └── ISSUE_TEMPLATE/
│ ├── bug_report.md
│ ├── feature_request.md
│ └── regular-issue.md
├── .gitignore
├── .npmignore
├── .prettierrc
├── .travis.yml
├── API.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── examples/
│ ├── basic.html
│ └── test.html
├── jsdoc.json
├── package.json
├── performance/
│ ├── TweenMax.js
│ ├── es6-tween.html
│ ├── gsap.html
│ ├── kute.html
│ └── kute.js
├── rollup.config.js
├── src/
│ ├── Easing.js
│ ├── Interpolation.js
│ ├── Interpolator.js
│ ├── NodeCache.js
│ ├── PlaybackPosition.js
│ ├── Timeline.js
│ ├── Tween.js
│ ├── constants.js
│ ├── core.js
│ ├── index.js
│ ├── selector.js
│ └── shim.js
├── test.js
└── withPage.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .babelrc
================================================
{
"exclude": ["node_modules/**", "bundled/**", "performance/**", "logo/**", "examples/**"],
"presets": [
[
"@babel/preset-env",
{
"modules": false,
"shippedProposals": true
}
]
],
"plugins": ["@babel/plugin-proposal-class-properties"]
}
================================================
FILE: .editorconfig
================================================
================================================
FILE: .eslintignore
================================================
# /node_modules/* and /bower_components/* in the project root are ignored by default
# Ignore
.github/*
bundled/*
examples/*
performance/*
logo/*
================================================
FILE: .eslintrc.json
================================================
{
"env": {
"browser": true,
"es6": true,
"node": true
},
"extends": "standard",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module"
},
"rules": {}
}
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
# github: dalisoft
patreon: dalisoft # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # dalisoft # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # ['https://www.buymeacoffee.com/dalisoft', 'https://paypal.me/dalisoft']
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
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.
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
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.
================================================
FILE: .github/ISSUE_TEMPLATE/regular-issue.md
================================================
---
name: Regular issue
about: For regular issue
title: ''
labels: ''
assignees: ''
---
|Issue name|Issue description|Issue Demo URL
|---|---|---|
| | | |
### Related
This issue is related to
- [ ] README
- [ ] package.json
- [ ] Demos
- [ ] Core features/functionality
- [ ] Tween class
- [ ] Easing
- [ ] Interpolation
- [ ] Timeline class
- [ ] LICENSE
- [ ] ABOUT COPYRIGHT VIOLATION (be careful before checking this...!)
- or provide something else (from es6-tween files...)
### What you excepted?
- Describe your result of research or idea...
### NOTE
- Please add read code, docs, files, issues, PR list for avoid duplicating existing question, bug or something else...
================================================
FILE: .gitignore
================================================
dist/
docs/
full/
bundled/
lite/
guide_notes/
node_modules/
npm-debug.log
yarn-error.log
.vscode
.idea
================================================
FILE: .npmignore
================================================
.gitignore
.git
.github
bower.json
tsconfig.json
tslint.json
assets
docs
examples
logo
performance
guide_notes
CONTRIBUTING.md
ISSUE_TEMPLATE.md
API.md
.travis.yml
yarn-error.log
.vscode
.idea
================================================
FILE: .prettierrc
================================================
{
"singleQuote": true,
"printWidth": 120,
"trailingComma": "es5",
"arrowParens": "always",
"bracketSpacing": true
}
================================================
FILE: .travis.yml
================================================
language: node_js
cache:
directories:
- node_modules
notifications:
email: false
node_js:
- '12'
before_script:
- npm prune
script:
- npm test
================================================
FILE: API.md
================================================
<a name="TWEEN"></a>
## TWEEN : <code>object</code>
Lightweight, effecient and modular ES6 version of tween.js
**Kind**: global namespace
**License**: MIT
**Copyright**: 2019 @dalisoft and es6-tween contributors
**Example**
```js
// ES6
const {add, remove, isRunning, autoPlay} = TWEEN
```
* [TWEEN](#TWEEN) : <code>object</code>
* [.Easing](#TWEEN.Easing) : <code>object</code>
* [.Interpolation](#TWEEN.Interpolation) : <code>object</code>
* [.Interpolator](#TWEEN.Interpolator) ⇒ <code>function</code>
* [.Timeline](#TWEEN.Timeline) : <code>object</code>
* [.Tween](#TWEEN.Tween) : <code>object</code>
* [.Tween#setMaxListener(count)](#TWEEN.Tween.Tween+setMaxListener)
* [.Tween#on(event, callback)](#TWEEN.Tween.Tween+on)
* [.Tween#once(event, callback)](#TWEEN.Tween.Tween+once)
* [.Tween#off(event, callback)](#TWEEN.Tween.Tween+off)
* [.Tween#emit(event)](#TWEEN.Tween.Tween+emit)
* [.Tween#isPlaying()](#TWEEN.Tween.Tween+isPlaying) ⇒ <code>boolean</code>
* [.Tween#isStarted()](#TWEEN.Tween.Tween+isStarted) ⇒ <code>boolean</code>
* [.Tween#reverse([state])](#TWEEN.Tween.Tween+reverse)
* [.Tween#reversed()](#TWEEN.Tween.Tween+reversed) ⇒ <code>boolean</code>
* [.Tween#pause()](#TWEEN.Tween.Tween+pause)
* [.Tween#play()](#TWEEN.Tween.Tween+play)
* [.Tween#restart([noDelay])](#TWEEN.Tween.Tween+restart)
* ~~[.Tween#seek(time, [keepPlaying])](#TWEEN.Tween.Tween+seek)~~
* ~~[.Tween#duration(amount)](#TWEEN.Tween.Tween+duration)~~
* [.Tween#to(properties, [duration])](#TWEEN.Tween.Tween+to)
* [.Tween#start(time)](#TWEEN.Tween.Tween+start)
* [.Tween#stop()](#TWEEN.Tween.Tween+stop)
* [.Tween#delay(amount)](#TWEEN.Tween.Tween+delay)
* [.Tween#chainedTweens(arguments)](#TWEEN.Tween.Tween+chainedTweens)
* [.Tween#repeat(amount)](#TWEEN.Tween.Tween+repeat)
* [.Tween#reverseDelay(amount)](#TWEEN.Tween.Tween+reverseDelay)
* [.Tween#yoyo(state, [_easingReverse])](#TWEEN.Tween.Tween+yoyo)
* [.Tween#easing(_easingFunction)](#TWEEN.Tween.Tween+easing)
* [.Tween#interpolation(_interpolationFunction)](#TWEEN.Tween.Tween+interpolation)
* [.Tween#update(time, [preserve], [forceTime])](#TWEEN.Tween.Tween+update)
* [.Plugins](#TWEEN.Plugins) : <code>object</code>
* [.now](#TWEEN.now) ⇒
* [.add(tween)](#TWEEN.add)
* [.onTick(fn)](#TWEEN.onTick)
* [.FrameThrottle(frameCount)](#TWEEN.FrameThrottle)
* [.ToggleLagSmoothing(state)](#TWEEN.ToggleLagSmoothing)
* [.autoPlay(state)](#TWEEN.autoPlay)
* [.removeAll()](#TWEEN.removeAll)
* [.get(tween)](#TWEEN.get) ⇒ <code>Tween</code>
* [.has(tween)](#TWEEN.has) ⇒ <code>Boolean</code>
* [.remove(tween)](#TWEEN.remove)
* [.update([time], [preserve])](#TWEEN.update)
* [.isRunning()](#TWEEN.isRunning) ⇒ <code>Boolean</code>
* [.isLagSmoothing()](#TWEEN.isLagSmoothing) ⇒ <code>Boolean</code>
<a name="TWEEN.Easing"></a>
### TWEEN.Easing : <code>object</code>
List of full easings
**Kind**: static namespace of [<code>TWEEN</code>](#TWEEN)
**Example**
```js
import {Tween, Easing} from 'es6-tween'
// then set via new Tween({x:0}).to({x:100}, 1000).easing(Easing.Quadratic.InOut).start()
```
<a name="TWEEN.Interpolation"></a>
### TWEEN.Interpolation : <code>object</code>
List of full Interpolation
**Kind**: static namespace of [<code>TWEEN</code>](#TWEEN)
**Example**
```js
import {Interpolation, Tween} from 'es6-tween'
let bezier = Interpolation.Bezier
new Tween({x:0}).to({x:[0, 4, 8, 12, 15, 20, 30, 40, 20, 40, 10, 50]}, 1000).interpolation(bezier).start()
```
<a name="TWEEN.Interpolator"></a>
### TWEEN.Interpolator ⇒ <code>function</code>
Tween helper for plugins
**Kind**: static namespace of [<code>TWEEN</code>](#TWEEN)
**Returns**: <code>function</code> - Returns function that accepts number between `0-1`
| Param | Type | Description |
| --- | --- | --- |
| a | <code>any</code> | Initial position |
| b | <code>any</code> | End position |
<a name="TWEEN.Timeline"></a>
### TWEEN.Timeline : <code>object</code>
Timeline main constructor.
It works same as `Tween` instance, using `.repeat`, `.restart` or `etc` works like a `Tween`, so please see `Tween` class for methods
**Kind**: static namespace of [<code>TWEEN</code>](#TWEEN)
**Extends**: <code>Tween</code>
| Param | Type | Description |
| --- | --- | --- |
| [params] | <code>Object</code> | Default params for new tweens |
**Example**
```js
let tl = new Timeline({delay:200})
```
<a name="TWEEN.Tween"></a>
### TWEEN.Tween : <code>object</code>
Tween main constructor
**Kind**: static namespace of [<code>TWEEN</code>](#TWEEN)
| Param | Type | Description |
| --- | --- | --- |
| node | <code>Object</code> \| <code>Element</code> | Node Element or Tween initial object |
| [object] | <code>Object</code> | If Node Element is using, second argument is used for Tween initial object |
**Example**
```js
let tween = new Tween(myNode, {width:'100px'}).to({width:'300px'}, 2000).start()
```
* [.Tween](#TWEEN.Tween) : <code>object</code>
* [.Tween#setMaxListener(count)](#TWEEN.Tween.Tween+setMaxListener)
* [.Tween#on(event, callback)](#TWEEN.Tween.Tween+on)
* [.Tween#once(event, callback)](#TWEEN.Tween.Tween+once)
* [.Tween#off(event, callback)](#TWEEN.Tween.Tween+off)
* [.Tween#emit(event)](#TWEEN.Tween.Tween+emit)
* [.Tween#isPlaying()](#TWEEN.Tween.Tween+isPlaying) ⇒ <code>boolean</code>
* [.Tween#isStarted()](#TWEEN.Tween.Tween+isStarted) ⇒ <code>boolean</code>
* [.Tween#reverse([state])](#TWEEN.Tween.Tween+reverse)
* [.Tween#reversed()](#TWEEN.Tween.Tween+reversed) ⇒ <code>boolean</code>
* [.Tween#pause()](#TWEEN.Tween.Tween+pause)
* [.Tween#play()](#TWEEN.Tween.Tween+play)
* [.Tween#restart([noDelay])](#TWEEN.Tween.Tween+restart)
* ~~[.Tween#seek(time, [keepPlaying])](#TWEEN.Tween.Tween+seek)~~
* ~~[.Tween#duration(amount)](#TWEEN.Tween.Tween+duration)~~
* [.Tween#to(properties, [duration])](#TWEEN.Tween.Tween+to)
* [.Tween#start(time)](#TWEEN.Tween.Tween+start)
* [.Tween#stop()](#TWEEN.Tween.Tween+stop)
* [.Tween#delay(amount)](#TWEEN.Tween.Tween+delay)
* [.Tween#chainedTweens(arguments)](#TWEEN.Tween.Tween+chainedTweens)
* [.Tween#repeat(amount)](#TWEEN.Tween.Tween+repeat)
* [.Tween#reverseDelay(amount)](#TWEEN.Tween.Tween+reverseDelay)
* [.Tween#yoyo(state, [_easingReverse])](#TWEEN.Tween.Tween+yoyo)
* [.Tween#easing(_easingFunction)](#TWEEN.Tween.Tween+easing)
* [.Tween#interpolation(_interpolationFunction)](#TWEEN.Tween.Tween+interpolation)
* [.Tween#update(time, [preserve], [forceTime])](#TWEEN.Tween.Tween+update)
<a name="TWEEN.Tween.Tween+setMaxListener"></a>
#### Tween.Tween#setMaxListener(count)
Sets max `event` listener's count to Events system
**Kind**: static method of [<code>Tween</code>](#TWEEN.Tween)
| Param | Type | Default | Description |
| --- | --- | --- | --- |
| count | <code>number</code> | <code>15</code> | Event listener's count |
<a name="TWEEN.Tween.Tween+on"></a>
#### Tween.Tween#on(event, callback)
Adds `event` to Events system
**Kind**: static method of [<code>Tween</code>](#TWEEN.Tween)
| Param | Type | Description |
| --- | --- | --- |
| event | <code>string</code> | Event listener name |
| callback | <code>function</code> | Event listener callback |
<a name="TWEEN.Tween.Tween+once"></a>
#### Tween.Tween#once(event, callback)
Adds `event` to Events system.
Removes itself after fired once
**Kind**: static method of [<code>Tween</code>](#TWEEN.Tween)
| Param | Type | Description |
| --- | --- | --- |
| event | <code>string</code> | Event listener name |
| callback | <code>function</code> | Event listener callback |
<a name="TWEEN.Tween.Tween+off"></a>
#### Tween.Tween#off(event, callback)
Removes `event` from Events system
**Kind**: static method of [<code>Tween</code>](#TWEEN.Tween)
| Param | Type | Description |
| --- | --- | --- |
| event | <code>string</code> | Event listener name |
| callback | <code>function</code> | Event listener callback |
<a name="TWEEN.Tween.Tween+emit"></a>
#### Tween.Tween#emit(event)
Emits/Fired/Trigger `event` from Events system listeners
**Kind**: static method of [<code>Tween</code>](#TWEEN.Tween)
| Param | Type | Description |
| --- | --- | --- |
| event | <code>string</code> | Event listener name |
<a name="TWEEN.Tween.Tween+isPlaying"></a>
#### Tween.Tween#isPlaying() ⇒ <code>boolean</code>
**Kind**: static method of [<code>Tween</code>](#TWEEN.Tween)
**Returns**: <code>boolean</code> - State of playing of tween
**Example**
```js
tween.isPlaying() // returns `true` if tween in progress
```
<a name="TWEEN.Tween.Tween+isStarted"></a>
#### Tween.Tween#isStarted() ⇒ <code>boolean</code>
**Kind**: static method of [<code>Tween</code>](#TWEEN.Tween)
**Returns**: <code>boolean</code> - State of started of tween
**Example**
```js
tween.isStarted() // returns `true` if tween in started
```
<a name="TWEEN.Tween.Tween+reverse"></a>
#### Tween.Tween#reverse([state])
Reverses the tween state/direction
**Kind**: static method of [<code>Tween</code>](#TWEEN.Tween)
| Param | Type | Description |
| --- | --- | --- |
| [state] | <code>boolean</code> | Set state of current reverse |
**Example**
```js
tween.reverse()
```
<a name="TWEEN.Tween.Tween+reversed"></a>
#### Tween.Tween#reversed() ⇒ <code>boolean</code>
**Kind**: static method of [<code>Tween</code>](#TWEEN.Tween)
**Returns**: <code>boolean</code> - State of reversed
**Example**
```js
tween.reversed() // returns `true` if tween in reversed state
```
<a name="TWEEN.Tween.Tween+pause"></a>
#### Tween.Tween#pause()
Pauses tween
**Kind**: static method of [<code>Tween</code>](#TWEEN.Tween)
**Example**
```js
tween.pause()
```
<a name="TWEEN.Tween.Tween+play"></a>
#### Tween.Tween#play()
Play/Resume the tween
**Kind**: static method of [<code>Tween</code>](#TWEEN.Tween)
**Example**
```js
tween.play()
```
<a name="TWEEN.Tween.Tween+restart"></a>
#### Tween.Tween#restart([noDelay])
Restarts tween from initial value
**Kind**: static method of [<code>Tween</code>](#TWEEN.Tween)
| Param | Type | Description |
| --- | --- | --- |
| [noDelay] | <code>boolean</code> | If this param is set to `true`, restarts tween without `delay` |
**Example**
```js
tween.restart()
```
<a name="TWEEN.Tween.Tween+seek"></a>
#### ~~Tween.Tween#seek(time, [keepPlaying])~~
***Deprecated***
Seek tween value by `time`. Note: Not works as excepted. PR are welcome
**Kind**: static method of [<code>Tween</code>](#TWEEN.Tween)
| Param | Type | Description |
| --- | --- | --- |
| time | <code>Time</code> | Tween update time |
| [keepPlaying] | <code>boolean</code> | When this param is set to `false`, tween pausing after seek |
**Example**
```js
tween.seek(500)
```
<a name="TWEEN.Tween.Tween+duration"></a>
#### ~~Tween.Tween#duration(amount)~~
***Deprecated***
Sets tween duration
**Kind**: static method of [<code>Tween</code>](#TWEEN.Tween)
| Param | Type | Description |
| --- | --- | --- |
| amount | <code>number</code> | Duration is milliseconds |
**Example**
```js
tween.duration(2000)
```
<a name="TWEEN.Tween.Tween+to"></a>
#### Tween.Tween#to(properties, [duration])
Sets target value and duration
**Kind**: static method of [<code>Tween</code>](#TWEEN.Tween)
| Param | Type | Default | Description |
| --- | --- | --- | --- |
| properties | <code>object</code> | | Target value (to value) |
| [duration] | <code>number</code> \| <code>Object</code> | <code>1000</code> | Duration of tween |
**Example**
```js
let tween = new Tween({x:0}).to({x:100}, 2000)
```
<a name="TWEEN.Tween.Tween+start"></a>
#### Tween.Tween#start(time)
Start the tweening
**Kind**: static method of [<code>Tween</code>](#TWEEN.Tween)
| Param | Type | Description |
| --- | --- | --- |
| time | <code>number</code> \| <code>string</code> | setting manual time instead of Current browser timestamp or like `+1000` relative to current timestamp |
**Example**
```js
tween.start()
```
<a name="TWEEN.Tween.Tween+stop"></a>
#### Tween.Tween#stop()
Stops the tween
**Kind**: static method of [<code>Tween</code>](#TWEEN.Tween)
**Example**
```js
tween.stop()
```
<a name="TWEEN.Tween.Tween+delay"></a>
#### Tween.Tween#delay(amount)
Set delay of tween
**Kind**: static method of [<code>Tween</code>](#TWEEN.Tween)
| Param | Type | Description |
| --- | --- | --- |
| amount | <code>number</code> | Sets tween delay / wait duration |
**Example**
```js
tween.delay(500)
```
<a name="TWEEN.Tween.Tween+chainedTweens"></a>
#### Tween.Tween#chainedTweens(arguments)
Chained tweens
**Kind**: static method of [<code>Tween</code>](#TWEEN.Tween)
| Param | Type | Description |
| --- | --- | --- |
| arguments | <code>any</code> | Arguments list |
**Example**
```js
tween.chainedTweens(tween1, tween2)
```
<a name="TWEEN.Tween.Tween+repeat"></a>
#### Tween.Tween#repeat(amount)
Sets how times tween is repeating
**Kind**: static method of [<code>Tween</code>](#TWEEN.Tween)
| Param | Type | Description |
| --- | --- | --- |
| amount | <code>amount</code> | the times of repeat |
**Example**
```js
tween.repeat(5)
```
<a name="TWEEN.Tween.Tween+reverseDelay"></a>
#### Tween.Tween#reverseDelay(amount)
Set delay of each repeat alternate of tween
**Kind**: static method of [<code>Tween</code>](#TWEEN.Tween)
| Param | Type | Description |
| --- | --- | --- |
| amount | <code>number</code> | Sets tween repeat alternate delay / repeat alternate wait duration |
**Example**
```js
tween.reverseDelay(500)
```
<a name="TWEEN.Tween.Tween+yoyo"></a>
#### Tween.Tween#yoyo(state, [_easingReverse])
Set `yoyo` state (enables reverse in repeat)
**Kind**: static method of [<code>Tween</code>](#TWEEN.Tween)
| Param | Type | Description |
| --- | --- | --- |
| state | <code>boolean</code> | Enables alternate direction for repeat |
| [_easingReverse] | <code>function</code> | Easing function in reverse direction |
**Example**
```js
tween.yoyo(true)
```
<a name="TWEEN.Tween.Tween+easing"></a>
#### Tween.Tween#easing(_easingFunction)
Set easing
**Kind**: static method of [<code>Tween</code>](#TWEEN.Tween)
| Param | Type | Description |
| --- | --- | --- |
| _easingFunction | <code>function</code> | Easing function, applies in non-reverse direction if Tween#yoyo second argument is applied |
**Example**
```js
tween.easing(Easing.Elastic.InOut)
```
<a name="TWEEN.Tween.Tween+interpolation"></a>
#### Tween.Tween#interpolation(_interpolationFunction)
Set interpolation
**Kind**: static method of [<code>Tween</code>](#TWEEN.Tween)
| Param | Type | Description |
| --- | --- | --- |
| _interpolationFunction | <code>function</code> | Interpolation function |
**Example**
```js
tween.interpolation(Interpolation.Bezier)
```
<a name="TWEEN.Tween.Tween+update"></a>
#### Tween.Tween#update(time, [preserve], [forceTime])
Updates initial object to target value by given `time`
**Kind**: static method of [<code>Tween</code>](#TWEEN.Tween)
| Param | Type | Description |
| --- | --- | --- |
| time | <code>Time</code> | Current time |
| [preserve] | <code>boolean</code> | Prevents from removing tween from store |
| [forceTime] | <code>boolean</code> | Forces to be frame rendered, even mismatching time |
**Example**
```js
tween.update(100)
```
<a name="TWEEN.Plugins"></a>
### TWEEN.Plugins : <code>object</code>
The plugins store object
**Kind**: static namespace of [<code>TWEEN</code>](#TWEEN)
**Example**
```js
let num = Plugins.num = function (node, start, end) {
return t => start + (end - start) * t
}
```
<a name="TWEEN.now"></a>
### TWEEN.now ⇒
Get browser/Node.js current time-stamp
**Kind**: static constant of [<code>TWEEN</code>](#TWEEN)
**Returns**: Normalised current time-stamp in milliseconds
**Example**
```js
TWEEN.now
```
<a name="TWEEN.add"></a>
### TWEEN.add(tween)
Adds tween to list
**Kind**: static method of [<code>TWEEN</code>](#TWEEN)
| Param | Type | Description |
| --- | --- | --- |
| tween | <code>Tween</code> | Tween instance |
**Example**
```js
let tween = new Tween({x:0})
tween.to({x:200}, 1000)
TWEEN.add(tween)
```
<a name="TWEEN.onTick"></a>
### TWEEN.onTick(fn)
Adds ticker like event
**Kind**: static method of [<code>TWEEN</code>](#TWEEN)
| Param | Type | Description |
| --- | --- | --- |
| fn | <code>function</code> | callback |
**Example**
```js
TWEEN.onTick(time => console.log(time))
```
<a name="TWEEN.FrameThrottle"></a>
### TWEEN.FrameThrottle(frameCount)
Sets after how much frames empty updating should stop
**Kind**: static method of [<code>TWEEN</code>](#TWEEN)
| Param | Type | Default | Description |
| --- | --- | --- | --- |
| frameCount | <code>number</code> | <code>120</code> | count of frames that should stop after all tweens removed |
**Example**
```js
TWEEN.FrameThrottle(60)
```
<a name="TWEEN.ToggleLagSmoothing"></a>
### TWEEN.ToggleLagSmoothing(state)
Handle lag, useful if you have rendering Canvas or DOM objects or using es6-tween plugins
**Kind**: static method of [<code>TWEEN</code>](#TWEEN)
| Param | Type | Default | Description |
| --- | --- | --- | --- |
| state | <code>number</code> | <code>true</code> | handle lag state |
**Example**
```js
TWEEN.ToggleLagSmoothing(false)
```
<a name="TWEEN.autoPlay"></a>
### TWEEN.autoPlay(state)
Runs update loop automaticlly
**Kind**: static method of [<code>TWEEN</code>](#TWEEN)
| Param | Type | Description |
| --- | --- | --- |
| state | <code>Boolean</code> | State of auto-run of update loop |
**Example**
```js
TWEEN.autoPlay(true)
```
<a name="TWEEN.removeAll"></a>
### TWEEN.removeAll()
Removes all tweens from list
**Kind**: static method of [<code>TWEEN</code>](#TWEEN)
**Example**
```js
TWEEN.removeAll() // removes all tweens, stored in global tweens list
```
<a name="TWEEN.get"></a>
### TWEEN.get(tween) ⇒ <code>Tween</code>
**Kind**: static method of [<code>TWEEN</code>](#TWEEN)
**Returns**: <code>Tween</code> - Matched tween
| Param | Type | Description |
| --- | --- | --- |
| tween | <code>Tween</code> | Tween Instance to be matched |
**Example**
```js
TWEEN.get(tween)
```
<a name="TWEEN.has"></a>
### TWEEN.has(tween) ⇒ <code>Boolean</code>
**Kind**: static method of [<code>TWEEN</code>](#TWEEN)
**Returns**: <code>Boolean</code> - Status of Exists tween or not
| Param | Type | Description |
| --- | --- | --- |
| tween | <code>Tween</code> | Tween Instance to be matched |
**Example**
```js
TWEEN.has(tween)
```
<a name="TWEEN.remove"></a>
### TWEEN.remove(tween)
Removes tween from list
**Kind**: static method of [<code>TWEEN</code>](#TWEEN)
| Param | Type | Description |
| --- | --- | --- |
| tween | <code>Tween</code> | Tween instance |
**Example**
```js
TWEEN.remove(tween)
```
<a name="TWEEN.update"></a>
### TWEEN.update([time], [preserve])
Updates global tweens by given time
**Kind**: static method of [<code>TWEEN</code>](#TWEEN)
| Param | Type | Description |
| --- | --- | --- |
| [time] | <code>number</code> | Timestamp |
| [preserve] | <code>Boolean</code> | Prevents tween to be removed after finish |
**Example**
```js
TWEEN.update(500)
```
<a name="TWEEN.isRunning"></a>
### TWEEN.isRunning() ⇒ <code>Boolean</code>
The state of ticker running
**Kind**: static method of [<code>TWEEN</code>](#TWEEN)
**Returns**: <code>Boolean</code> - Status of running updates on all tweens
**Example**
```js
TWEEN.isRunning()
```
<a name="TWEEN.isLagSmoothing"></a>
### TWEEN.isLagSmoothing() ⇒ <code>Boolean</code>
Returns state of lag smoothing handling
**Kind**: static method of [<code>TWEEN</code>](#TWEEN)
**Returns**: <code>Boolean</code> - Status of lag smoothing state
**Example**
```js
TWEEN.isRunning()
```
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
- The use of sexualized language or imagery and unwelcome sexual attention or advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or electronic address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at dalisoft@mail.ru. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/
================================================
FILE: CONTRIBUTING.md
================================================
# CONTRIBUTING
## Before reporting a bug
---
If you find something that you believe to be a bug, please
1. search the [issue tracker](https://github.com/tweenjs/es6-tween/issues) for similar issues
2. check out the [master](https://github.com/tweenjs/es6-tween/tree/master) branch and see if the bug still exists there.
## How to report a bug
---
1. Specify the revision number of the tween.js library where the bug occurred
2. Specify your browser version and operating system (i.e. Chrome 23.0.1271.95, Windows 7)
3. Describe the problem in detail. What happened? What did you expect to happen?
4. Provide a small test case (e.g. using [jsfiddle](http://jsfiddle.net)). Or if not possible, provide a link to a live version of your application.
## Contributing
---
1. Get a GitHub account (if you don't have one yet).
2. Fork the project in GitHub.
3. Check the [contribution guidelines](https://github.com/tweenjs/es6-tween/wiki/Contributing-to-tween.js).
4. Make changes to your clone of the repository
5. Submit a pull request.
_If you tried all of the above and still can't fix the bug, or you're not sure you're doing things right, [let us know](https://github.com/tween.js/es6-tween/issues)._
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2018 tween.js and es6-tween contributors
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.
================================================
FILE: README.md
================================================
# es6-tween
## This project development suspended due of no support from community and no financial support to author
- High-performant animations without headaches
- Simple, modular and functional animation library for web and node
- Tweening library that needs to use where performance matter
- Flexible, extendable, modular and resource-efficient tweening library
[![NPM Min Size][npm-min-size]][unpkg-url]
[![NPM Gzip Size][npm-gzip-size]][unpkg-url]
[![CDNJS][cdnjs-image]][cdnjs-url]
[![NPM Version][npm-image]][npm-url]
[![NPM Downloads][downloads-image]][npm-url]
[]()
[![Travis tests][travis-image]][travis-url]
<br/>
[](https://nodei.co/npm/es6-tween/)
## Frameworks
- [react-es6-tween](https://github.com/dalisoft/react-es6-tween)
## Docs
- [API documentation](./API.md)
- [Wiki page](https://github.com/tweenjs/es6-tween/wiki)
```javascript
TWEEN.autoPlay(true); // simplify the your code
let coords = { x: 0, y: 0 };
let tween = new TWEEN.Tween(coords)
.to({ x: 100, y: 100 }, 1000)
.on('update', ({ x, y }) => {
console.log(`The values is x: ${x} and y: ${y}`);
})
.start();
```
## Plugins
Starting at `v3`, we provide excluded plugins from core, so our core becomes lighter and faster. [Here our plugins list](https://www.npmjs.com/browse/keyword/es6-tween)
## Demos
- Demo #1 [Morphing SVG Shape + Cross-browser SVG Transform](https://codepen.io/dalisoft/pen/mMJmxX)
- Demo #2 [Morphing SVG Shape](https://codepen.io/dalisoft/pen/BdLydv)
- Collection on the [Codepen](https://codepen.io/collection/DapBmv/)
## Installation
Download the [library](https://unpkg.com/es6-tween/bundled/Tween.js) and include it in your code:
```html
<script src="bundled/Tween.js"></script>
```
### CDN-Hosted version
- See [cdnjs-hosted version](https://cdnjs.com/libraries/es6-tween) for get which result you want
- NOTE: `@latest` suffix sometimes saves life by loading latest, because sometimes CDN services will not load the latest
- Now you can load from CDN
```html
<!-- jsDelivr -->
<script src="https://cdn.jsdelivr.net/npm/es6-tween"></script>
<!-- unpkg -->
<script src="https://unpkg.com/es6-tween"></script>
<!-- npmcdn -->
<script src="https://npmcdn.com/es6-tween"></script>
```
### More advanced users might want to
#### Using `import`
```javascript
import { Easing, Tween, autoPlay } from 'es6-tween';
```
#### Using [getlibs](https://github.com/activewidgets/getlibs)
```html
<script src="https://unpkg.com/getlibs"></script>
<script type="x-module">
// ES6
import { Easing, Tween, autoPlay } from 'es6-tween'
// CommonJS
const { Tween, Easing, autoPlay } = require('es6-tween')
</script>
```
#### Using `npm` or `yarn`
```bash
$ yarn add es6-tween
# or
$ npm install es6-tween
```
Then include the Tween.js module with the standard node.js `require`:
```javascript
const { Tween, Easing, autoPlay } = require('es6-tween');
```
And you can use Tween.js as in all other examples--for example:
```javascript
const t = new Tween(/* etc */);
t.start();
```
You can run script commands to build modules into single `UMD` compatible file:
#### Using commands
```bash
$ yarn build # builds production files
# or
$ yarn dev # builds and watchs development files
```
Then reference the library source:
```html
<script src="bundled/Tween.min.js"></script>
```
## Features
- Tweens everything you give them, string, number, number of arrays, number of object, all-to, interpolators and much more. Endless possibilites
- Can use CSS units (e.g. appending `px`)
- Can interpolate colours
- Easing functions are reusable outside of Tween
- Can also use custom easing functions
- Much of easings
## Compatiblity Testing
Thanks to BrowserStack for providing us testing in a real devices to make it cross-browser, bug-free and better.
BrowserStack saved my countless hours, before i spent on testing much of time, now it's very easy. I recommend to others use this service.
I sure, BrowserStack helps us to make it, so i am linking to BrowserStack as our sponsor.
[<img src="https://cloud.githubusercontent.com/assets/7864462/12837037/452a17c6-cb73-11e5-9f39-fc96893bc9bf.png" alt="Browser Stack Logo" width="400">](https://www.browserstack.com/)
## Tests
```bash
yarn test
```
or you can go [here](https://travis-ci.org/tweenjs/es6-tween) for more information, tests and etc...
every time you want to run the tests.
If you want to add any feature or change existing features, you _must_ run the tests to make sure you didn't break anything else. If you send a PR to add something new and it doesn't have tests, or the tests don't pass, the PR won't be accepted. See [contributing](CONTRIBUTING.md) for more information.
## People
- [All contributors](https://github.com/tweenjs/es6-tween/contributors).
- [es6-tween contributors](https://github.com/tweenjs/es6-tween/graphs/contributors)/
## Thanks to
these tools developers and to their community and without these tools maybe this library wouldn't be possible
- [GitHub](https://github.com/)
- [Travis CI](http://travis-ci.org)
- [BrowserStack](https://www.browserstack.com/)
- [Node.js](https://nodejs.org/en/)
- [ESLint](http://eslint.org)
- [jsDoc](http://usejsdoc.org) ([docdash theme](https://github.com/clenemt/docdash))
- [Rollup](https://rollupjs.org/guide/en)
- [Babel](https://babeljs.io)
- [Ava](https://github.com/avajs/ava)
- [Puppeteer](https://pptr.dev)
- [UglifyJS v3](https://github.com/mishoo/UglifyJS2)
- [Husky](https://github.com/typicode/husky)
## Projects using es6-tween
- [ft](https://github.com/2players/ft)
- [react-heartwood-components](https://www.npmjs.com/package/@sprucelabs/react-heartwood-components)
- [el-controls](https://github.com/eljs/el-controls)
- [lightweight-pixijs-engine](https://github.com/dgzornoza/lightweight-pixijs-engine#readme)
- [vue-sliderx](https://www.npmjs.com/package/vue-sliderx)
- [vue-mapbox-feature](https://cityseer.github.io/vue-mapbox-feature)
- [vuxtras](https://github.com/homerjam/vuxtras#readme)
- [Slye](https://github.com/Slye3D/slye#readme)
- [react-3d-globe](https://chrisrzhou.github.io/react-3d-globe/)
It's great to see this library to be used in production and/or library, thank you!
If you have projects using es6-tween, please make issue or PR, i will add here your project too :)
[npm-min-size]: https://img.shields.io/bundlephobia/min/es6-tween.svg
[npm-gzip-size]: https://img.badgesize.io/https://unpkg.com/es6-tween?compression=gzip
[npm-image]: https://img.shields.io/npm/v/es6-tween.svg
[npm-url]: https://npmjs.org/package/es6-tween
[downloads-image]: https://img.shields.io/npm/dm/es6-tween.svg
[travis-image]: https://travis-ci.org/tweenjs/es6-tween.svg?branch=master
[travis-url]: https://travis-ci.org/tweenjs/es6-tween
[cdnjs-image]: https://img.shields.io/cdnjs/v/es6-tween.svg
[cdnjs-url]: https://cdnjs.com/libraries/es6-tween
[unpkg-url]: https://unpkg.com/es6-tween
================================================
FILE: examples/basic.html
================================================
<!DOCTYPE html>
<html>
<head>
<title>Tween.js - Basic Demo</title>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<style type="text/css">
html, body {
font-family: Helvetica Neue, Segoe UI Light, Arial;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
text-align: center;
line-height: 5em;
}
</style>
</head>
<body>
<div class="container">
</div>
<script src="../bundled/Tween.js"></script>
<script>
var body = document.body;
TWEEN.autoPlay(true);
var round = function round(o) {
for ( var p in o ) {
if ( typeof o[p] === "number" ) {
o[p] = o[p] | 0;
} else if (typeof o[p] === "object") {
round(o[p]);
}
}
}
var tween = new TWEEN.Tween([0, 200, {x:300}]).to([200, 400, {x:500}], 2000).on('update', function (object) {
round(object);
body.textContent = JSON.stringify(object);
}).start();
var tween = new TWEEN.Tween({x:'600 y.o'}).to({x:'200 y.o'}, 2000).delay(3000).on('update', function (object) {
//round(object);
body.textContent = JSON.stringify(object);
}).start();
</script>
</body>
</html>
================================================
FILE: examples/test.html
================================================
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, minimum-scale=1.0">
<title>es6-tween</title>
<style>
#container {
width: 200px;
height: auto;
margin: 0 auto;
position: relative;
display: block;
}
.line {
width: 200px;
height: 2px;
position: absolute;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="../bundled/Tween.js"></script>
<script src="https://unpkg.com/es6tween-plugin-render@0.0.16/render.min.js"></script>
<script>
TWEEN.autoPlay(true);
function random(min, max) {
return Math.random() * (max - min) + min;
}
function update (v) {
v.el.style.transform = 'translate3d(' + v.x + 'px, 0px, 0px)';
}
var nodes = [],
c = document.getElementById("container"),
easing = "quadraticInOut",
ratio = 0.9,
wIh = (window.innerHeight || screen.height - 40) * ratio,
wIw = window.innerWidth,
hwiw = (wIw / 5) * ratio,
frag = document.createDocumentFragment();
function createTest(count) {
var i;
for (i = 0; i < count; i++) {
var div = document.createElement("div"),
bg = (Math.random() * 0xffffff) >> 0,
r = bg >> 16 & 255,
g = bg >> 8 & 255,
b = bg & 255,
bgC = 'rgb(' + r + ',' + g + ', ' + b + ')',
l = Math.floor(random(-200, 200)),
dl = Math.floor(Math.random() * 1000),
tl = Math.floor(random(-200, 200));
div.setAttribute("class", "line");
div.style.top = [(Math.random() * wIh), "px"].join("");
div.style.left = l + 'px';
//div.style.transform = "translate3d(" + l + "px, 0px, 0px)";
div.style.backgroundColor = bgC;
var a = new TWEEN.Tween(div, { left : l }).to({ left: tl }, 1000).easing(TWEEN.Easing.Quadratic.InOut).repeat(Infinity).yoyo(true).start();
frag.appendChild(div);
}
c.appendChild(frag);
}
createTest(200);
</script>
</body>
</html>
================================================
FILE: jsdoc.json
================================================
{
"tags": {
"allowUnknownTags": true,
"dictionaries": [
"jsdoc"
]
},
"source": {
"include": [
"src"
],
"includePattern": ".js$",
"excludePattern": "(node_modules/|logo|docs|bundled|examples|performance|.vscode|.github)"
},
"plugins": [
"plugins/markdown"
],
"templates": {
"cleverLinks": false,
"monospaceLinks": true
},
"opts": {
"destination": "../es6-tween-gh/docs/",
"encoding": "utf8",
"private": true,
"recurse": true,
"template": "./node_modules/docdash"
}
}
================================================
FILE: package.json
================================================
{
"name": "es6-tween",
"version": "5.5.11",
"description": "ES6 implementation of amazing tween.js",
"browser": "bundled/Tween.min.js",
"cdn": "bundled/Tween.min.js",
"main": "bundled/Tween.js",
"module": "src/index.js",
"directories": {
"example": "examples"
},
"funding": {
"type": "patreon",
"url": "https://www.patreon.com/dalisoft"
},
"scripts": {
"source": "npx rollup -c",
"minify": "npx uglifyjs bundled/Tween.js -c -m -o bundled/Tween.min.js --source-map \"filename='bundled/Tween.min.js.map'\"",
"build": "npm run source && npm run minify",
"dev": "npx rollup -c -w",
"prepublishOnly": "npm run lint && npm run build",
"doc": "npx jsdoc --readme README.md --configure jsdoc.json",
"doc-md": "npx jsdoc2md src/** > API.md",
"test": "npm run lint && npm run source && npx ava",
"lint": "npx eslint ./src",
"lint-fix": "npx eslint ./src --fix"
},
"repository": {
"type": "git",
"url": "git+https://github.com/tweenjs/es6-tween.git"
},
"keywords": [
"tween",
"tweening",
"es6",
"numeric",
"interpolation",
"easing",
"emit"
],
"author": "es6-tween contributors",
"license": "MIT",
"bugs": {
"url": "https://github.com/tweenjs/es6-tween/issues"
},
"homepage": "https://es6-tween.js.org",
"devDependencies": {
"@babel/core": "^7.4.4",
"@babel/plugin-proposal-class-properties": "^7.4.4",
"@babel/preset-env": "^7.4.4",
"ava": "^5.1.0",
"docdash": "^1.1.0",
"eslint": "^5.16.0",
"eslint-config-standard": "^12.0.0",
"eslint-plugin-import": "^2.17.2",
"eslint-plugin-node": "^9.0.1",
"eslint-plugin-promise": "^4.1.1",
"eslint-plugin-standard": "^4.0.0",
"jsdoc": "^3.6.2",
"jsdoc-to-markdown": "^8.0.0",
"puppeteer": "^1.16.0",
"rollup": "^1.12.1",
"rollup-plugin-babel": "^4.3.2",
"uglify-js": "^3.5.12"
},
"dependencies": {},
"ava": {
"verbose": true,
"require": [
"esm"
],
"babel": {
"extensions": [
"js"
]
}
}
}
================================================
FILE: performance/TweenMax.js
================================================
/*!
* VERSION: 1.20.2
* DATE: 2017-06-30
* UPDATES AND DOCS AT: http://greensock.com
*
* Includes all of the following: TweenLite, TweenMax, TimelineLite, TimelineMax, EasePack, CSSPlugin, RoundPropsPlugin, BezierPlugin, AttrPlugin, DirectionalRotationPlugin
*
* @license Copyright (c) 2008-2017, GreenSock. All rights reserved.
* This work is subject to the terms at http://greensock.com/standard-license or for
* Club GreenSock members, the software agreement that was issued with your membership.
*
* @author: Jack Doyle, jack@greensock.com
**/
var _gsScope = (typeof (module) !== 'undefined' && module.exports && typeof (global) !== 'undefined') ? global : this || window; // helps ensure compatibility with AMD/RequireJS and CommonJS/Node
(_gsScope._gsQueue || (_gsScope._gsQueue = [])).push(function () {
'use strict'
_gsScope._gsDefine('TweenMax', ['core.Animation', 'core.SimpleTimeline', 'TweenLite'], function (Animation, SimpleTimeline, TweenLite) {
var _slice = function (a) { // don't use [].slice because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll()
var b = [],
l = a.length,
i
for (i = 0; i !== l; b.push(a[i++]));
return b
},
_applyCycle = function (vars, targets, i) {
var alt = vars.cycle,
p, val
for (p in alt) {
val = alt[p]
vars[p] = (typeof (val) === 'function') ? val(i, targets[i]) : val[i % val.length]
}
delete vars.cycle
},
TweenMax = function (target, duration, vars) {
TweenLite.call(this, target, duration, vars)
this._cycle = 0
this._yoyo = (this.vars.yoyo === true || !!this.vars.yoyoEase)
this._repeat = this.vars.repeat || 0
this._repeatDelay = this.vars.repeatDelay || 0
this._dirty = true // ensures that if there is any repeat, the totalDuration will get recalculated to accurately report it.
this.render = TweenMax.prototype.render // speed optimization (avoid prototype lookup on this "hot" method)
},
_tinyNum = 0.0000000001,
TweenLiteInternals = TweenLite._internals,
_isSelector = TweenLiteInternals.isSelector,
_isArray = TweenLiteInternals.isArray,
p = TweenMax.prototype = TweenLite.to({}, 0.1, {}),
_blankArray = []
TweenMax.version = '1.20.2'
p.constructor = TweenMax
p.kill()._gc = false
TweenMax.killTweensOf = TweenMax.killDelayedCallsTo = TweenLite.killTweensOf
TweenMax.getTweensOf = TweenLite.getTweensOf
TweenMax.lagSmoothing = TweenLite.lagSmoothing
TweenMax.ticker = TweenLite.ticker
TweenMax.render = TweenLite.render
p.invalidate = function () {
this._yoyo = (this.vars.yoyo === true || !!this.vars.yoyoEase)
this._repeat = this.vars.repeat || 0
this._repeatDelay = this.vars.repeatDelay || 0
this._yoyoEase = null
this._uncache(true)
return TweenLite.prototype.invalidate.call(this)
}
p.updateTo = function (vars, resetDuration) {
var curRatio = this.ratio,
immediate = this.vars.immediateRender || vars.immediateRender,
p
if (resetDuration && this._startTime < this._timeline._time) {
this._startTime = this._timeline._time
this._uncache(false)
if (this._gc) {
this._enabled(true, false)
} else {
this._timeline.insert(this, this._startTime - this._delay) // ensures that any necessary re-sequencing of Animations in the timeline occurs to make sure the rendering order is correct.
}
}
for (p in vars) {
this.vars[p] = vars[p]
}
if (this._initted || immediate) {
if (resetDuration) {
this._initted = false
if (immediate) {
this.render(0, true, true)
}
} else {
if (this._gc) {
this._enabled(true, false)
}
if (this._notifyPluginsOfEnabled && this._firstPT) {
TweenLite._onPluginEvent('_onDisable', this) // in case a plugin like MotionBlur must perform some cleanup tasks
}
if (this._time / this._duration > 0.998) { // if the tween has finished (or come extremely close to finishing), we just need to rewind it to 0 and then render it again at the end which forces it to re-initialize (parsing the new vars). We allow tweens that are close to finishing (but haven't quite finished) to work this way too because otherwise, the values are so small when determining where to project the starting values that binary math issues creep in and can make the tween appear to render incorrectly when run backwards.
var prevTime = this._totalTime
this.render(0, true, false)
this._initted = false
this.render(prevTime, true, false)
} else {
this._initted = false
this._init()
if (this._time > 0 || immediate) {
var inv = 1 / (1 - curRatio),
pt = this._firstPT, endValue
while (pt) {
endValue = pt.s + pt.c
pt.c *= inv
pt.s = endValue - pt.c
pt = pt._next
}
}
}
}
}
return this
}
p.render = function (time, suppressEvents, force) {
if (!this._initted) {
if (this._duration === 0 && this.vars.repeat) { // zero duration tweens that render immediately have render() called from TweenLite's constructor, before TweenMax's constructor has finished setting _repeat, _repeatDelay, and _yoyo which are critical in determining totalDuration() so we need to call invalidate() which is a low-kb way to get those set properly.
this.invalidate()
}
}
var totalDur = (!this._dirty) ? this._totalDuration : this.totalDuration(),
prevTime = this._time,
prevTotalTime = this._totalTime,
prevCycle = this._cycle,
duration = this._duration,
prevRawPrevTime = this._rawPrevTime,
isComplete, callback, pt, cycleDuration, r, type, pow, rawPrevTime, yoyoEase
if (time >= totalDur - 0.0000001 && time >= 0) { // to work around occasional floating point math artifacts.
this._totalTime = totalDur
this._cycle = this._repeat
if (this._yoyo && (this._cycle & 1) !== 0) {
this._time = 0
this.ratio = this._ease._calcEnd ? this._ease.getRatio(0) : 0
} else {
this._time = duration
this.ratio = this._ease._calcEnd ? this._ease.getRatio(1) : 1
}
if (!this._reversed) {
isComplete = true
callback = 'onComplete'
force = (force || this._timeline.autoRemoveChildren) // otherwise, if the animation is unpaused/activated after it's already finished, it doesn't get removed from the parent timeline.
}
if (duration === 0) {
if (this._initted || !this.vars.lazy || force) { // zero-duration tweens are tricky because we must discern the momentum/direction of time in order to determine whether the starting values should be rendered or the ending values. If the "playhead" of its timeline goes past the zero-duration tween in the forward direction or lands directly on it, the end values should be rendered, but if the timeline's "playhead" moves past it in the backward direction (from a postitive time to a negative time), the starting values must be rendered.
if (this._startTime === this._timeline._duration) { // if a zero-duration tween is at the VERY end of a timeline and that timeline renders at its end, it will typically add a tiny bit of cushion to the render time to prevent rounding errors from getting in the way of tweens rendering their VERY end. If we then reverse() that timeline, the zero-duration tween will trigger its onReverseComplete even though technically the playhead didn't pass over it again. It's a very specific edge case we must accommodate.
time = 0
}
if (prevRawPrevTime < 0 || (time <= 0 && time >= -0.0000001) || (prevRawPrevTime === _tinyNum && this.data !== 'isPause')) {
if (prevRawPrevTime !== time) { // note: when this.data is "isPause", it's a callback added by addPause() on a timeline that we should not be triggered when LEAVING its exact start time. In other words, tl.addPause(1).play(1) shouldn't pause.
force = true
if (prevRawPrevTime > _tinyNum) {
callback = 'onReverseComplete'
}
}
}
this._rawPrevTime = rawPrevTime = (!suppressEvents || time || prevRawPrevTime === time) ? time : _tinyNum // when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
}
}
} else if (time < 0.0000001) { // to work around occasional floating point math artifacts, round super small values to 0.
this._totalTime = this._time = this._cycle = 0
this.ratio = this._ease._calcEnd ? this._ease.getRatio(0) : 0
if (prevTotalTime !== 0 || (duration === 0 && prevRawPrevTime > 0)) {
callback = 'onReverseComplete'
isComplete = this._reversed
}
if (time < 0) {
this._active = false
if (duration === 0) {
if (this._initted || !this.vars.lazy || force) { // zero-duration tweens are tricky because we must discern the momentum/direction of time in order to determine whether the starting values should be rendered or the ending values. If the "playhead" of its timeline goes past the zero-duration tween in the forward direction or lands directly on it, the end values should be rendered, but if the timeline's "playhead" moves past it in the backward direction (from a postitive time to a negative time), the starting values must be rendered.
if (prevRawPrevTime >= 0) {
force = true
}
this._rawPrevTime = rawPrevTime = (!suppressEvents || time || prevRawPrevTime === time) ? time : _tinyNum // when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
}
}
}
if (!this._initted) { // if we render the very beginning (time == 0) of a fromTo(), we must force the render (normal tweens wouldn't need to render at a time of 0 when the prevTime was also 0). This is also mandatory to make sure overwriting kicks in immediately.
force = true
}
} else {
this._totalTime = this._time = time
if (this._repeat !== 0) {
cycleDuration = duration + this._repeatDelay
this._cycle = (this._totalTime / cycleDuration) >> 0 // originally _totalTime % cycleDuration but floating point errors caused problems, so I normalized it. (4 % 0.8 should be 0 but some browsers report it as 0.79999999!)
if (this._cycle !== 0) {
if (this._cycle === this._totalTime / cycleDuration && prevTotalTime <= time) {
this._cycle-- // otherwise when rendered exactly at the end time, it will act as though it is repeating (at the beginning)
}
}
this._time = this._totalTime - (this._cycle * cycleDuration)
if (this._yoyo) {
if ((this._cycle & 1) !== 0) {
this._time = duration - this._time
yoyoEase = this._yoyoEase || this.vars.yoyoEase // note: we don't set this._yoyoEase in _init() like we do other properties because it's TweenMax-specific and doing it here allows us to optimize performance (most tweens don't have a yoyoEase). Note that we also must skip the this.ratio calculation further down right after we _init() in this function, because we're doing it here.
if (yoyoEase) {
if (!this._yoyoEase) {
if (yoyoEase === true && !this._initted) { // if it's not initted and yoyoEase is true, this._ease won't have been populated yet so we must discern it here.
yoyoEase = this.vars.ease
this._yoyoEase = yoyoEase = !yoyoEase ? TweenLite.defaultEase : (yoyoEase instanceof Ease) ? yoyoEase : (typeof (yoyoEase) === 'function') ? new Ease(yoyoEase, this.vars.easeParams) : Ease.map[yoyoEase] || TweenLite.defaultEase
} else {
this._yoyoEase = yoyoEase = (yoyoEase === true) ? this._ease : (yoyoEase instanceof Ease) ? yoyoEase : Ease.map[yoyoEase]
}
}
this.ratio = yoyoEase ? 1 - yoyoEase.getRatio((duration - this._time) / duration) : 0
}
}
}
if (this._time > duration) {
this._time = duration
} else if (this._time < 0) {
this._time = 0
}
}
if (this._easeType && !yoyoEase) {
r = this._time / duration
type = this._easeType
pow = this._easePower
if (type === 1 || (type === 3 && r >= 0.5)) {
r = 1 - r
}
if (type === 3) {
r *= 2
}
if (pow === 1) {
r *= r
} else if (pow === 2) {
r *= r * r
} else if (pow === 3) {
r *= r * r * r
} else if (pow === 4) {
r *= r * r * r * r
}
if (type === 1) {
this.ratio = 1 - r
} else if (type === 2) {
this.ratio = r
} else if (this._time / duration < 0.5) {
this.ratio = r / 2
} else {
this.ratio = 1 - (r / 2)
}
} else if (!yoyoEase) {
this.ratio = this._ease.getRatio(this._time / duration)
}
}
if (prevTime === this._time && !force && prevCycle === this._cycle) {
if (prevTotalTime !== this._totalTime) {
if (this._onUpdate) {
if (!suppressEvents) { // so that onUpdate fires even during the repeatDelay - as long as the totalTime changed, we should trigger onUpdate.
this._callback('onUpdate')
}
}
}
return
} else if (!this._initted) {
this._init()
if (!this._initted || this._gc) { // immediateRender tweens typically won't initialize until the playhead advances (_time is greater than 0) in order to ensure that overwriting occurs properly. Also, if all of the tweening properties have been overwritten (which would cause _gc to be true, as set in _init()), we shouldn't continue otherwise an onStart callback could be called for example.
return
} else if (!force && this._firstPT && ((this.vars.lazy !== false && this._duration) || (this.vars.lazy && !this._duration))) { // we stick it in the queue for rendering at the very end of the tick - this is a performance optimization because browsers invalidate styles and force a recalculation if you read, write, and then read style data (so it's better to read/read/read/write/write/write than read/write/read/write/read/write). The down side, of course, is that usually you WANT things to render immediately because you may have code running right after that which depends on the change. Like imagine running TweenLite.set(...) and then immediately after that, creating a nother tween that animates the same property to another value; the starting values of that 2nd tween wouldn't be accurate if lazy is true.
this._time = prevTime
this._totalTime = prevTotalTime
this._rawPrevTime = prevRawPrevTime
this._cycle = prevCycle
TweenLiteInternals.lazyTweens.push(this)
this._lazy = [time, suppressEvents]
return
}
// _ease is initially set to defaultEase, so now that init() has run, _ease is set properly and we need to recalculate the ratio. Overall this is faster than using conditional logic earlier in the method to avoid having to set ratio twice because we only init() once but renderTime() gets called VERY frequently.
if (this._time && !isComplete && !yoyoEase) {
this.ratio = this._ease.getRatio(this._time / duration)
} else if (isComplete && this._ease._calcEnd && !yoyoEase) {
this.ratio = this._ease.getRatio((this._time === 0) ? 0 : 1)
}
}
if (this._lazy !== false) {
this._lazy = false
}
if (!this._active) {
if (!this._paused && this._time !== prevTime && time >= 0) {
this._active = true // so that if the user renders a tween (as opposed to the timeline rendering it), the timeline is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the tween already finished but the user manually re-renders it as halfway done.
}
}
if (prevTotalTime === 0) {
if (this._initted === 2 && time > 0) {
// this.invalidate();
this._init() // will just apply overwriting since _initted of (2) means it was a from() tween that had immediateRender:true
}
if (this._startAt) {
if (time >= 0) {
this._startAt.render(time, suppressEvents, force)
} else if (!callback) {
callback = '_dummyGS' // if no callback is defined, use a dummy value just so that the condition at the end evaluates as true because _startAt should render AFTER the normal render loop when the time is negative. We could handle this in a more intuitive way, of course, but the render loop is the MOST important thing to optimize, so this technique allows us to avoid adding extra conditional logic in a high-frequency area.
}
}
if (this.vars.onStart) {
if (this._totalTime !== 0 || duration === 0) {
if (!suppressEvents) {
this._callback('onStart')
}
}
}
}
pt = this._firstPT
while (pt) {
if (pt.f) {
pt.t[pt.p](pt.c * this.ratio + pt.s)
} else {
pt.t[pt.p] = pt.c * this.ratio + pt.s
}
pt = pt._next
}
if (this._onUpdate) {
if (time < 0) {
if (this._startAt && this._startTime) { // if the tween is positioned at the VERY beginning (_startTime 0) of its parent timeline, it's illegal for the playhead to go back further, so we should not render the recorded startAt values.
this._startAt.render(time, suppressEvents, force) // note: for performance reasons, we tuck this conditional logic inside less traveled areas (most tweens don't have an onUpdate). We'd just have it at the end before the onComplete, but the values should be updated before any onUpdate is called, so we ALSO put it here and then if it's not called, we do so later near the onComplete.
}
}
if (!suppressEvents) {
if (this._totalTime !== prevTotalTime || callback) {
this._callback('onUpdate')
}
}
}
if (this._cycle !== prevCycle) {
if (!suppressEvents) {
if (!this._gc) {
if (this.vars.onRepeat) {
this._callback('onRepeat')
}
}
}
}
if (callback) {
if (!this._gc || force) { // check gc because there's a chance that kill() could be called in an onUpdate
if (time < 0 && this._startAt && !this._onUpdate && this._startTime) { // if the tween is positioned at the VERY beginning (_startTime 0) of its parent timeline, it's illegal for the playhead to go back further, so we should not render the recorded startAt values.
this._startAt.render(time, suppressEvents, force)
}
if (isComplete) {
if (this._timeline.autoRemoveChildren) {
this._enabled(false, false)
}
this._active = false
}
if (!suppressEvents && this.vars[callback]) {
this._callback(callback)
}
if (duration === 0 && this._rawPrevTime === _tinyNum && rawPrevTime !== _tinyNum) { // the onComplete or onReverseComplete could trigger movement of the playhead and for zero-duration tweens (which must discern direction) that land directly back on their start time, we don't want to fire again on the next render. Think of several addPause()'s in a timeline that forces the playhead to a certain spot, but what if it's already paused and another tween is tweening the "time" of the timeline? Each time it moves [forward] past that spot, it would move back, and since suppressEvents is true, it'd reset _rawPrevTime to _tinyNum so that when it begins again, the callback would fire (so ultimately it could bounce back and forth during that tween). Again, this is a very uncommon scenario, but possible nonetheless.
this._rawPrevTime = 0
}
}
}
}
// ---- STATIC FUNCTIONS -----------------------------------------------------------------------------------------------------------
TweenMax.to = function (target, duration, vars) {
return new TweenMax(target, duration, vars)
}
TweenMax.from = function (target, duration, vars) {
vars.runBackwards = true
vars.immediateRender = (vars.immediateRender != false)
return new TweenMax(target, duration, vars)
}
TweenMax.fromTo = function (target, duration, fromVars, toVars) {
toVars.startAt = fromVars
toVars.immediateRender = (toVars.immediateRender != false && fromVars.immediateRender != false)
return new TweenMax(target, duration, toVars)
}
TweenMax.staggerTo = TweenMax.allTo = function (targets, duration, vars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
stagger = stagger || 0
var delay = 0,
a = [],
finalComplete = function () {
if (vars.onComplete) {
vars.onComplete.apply(vars.onCompleteScope || this, arguments)
}
onCompleteAll.apply(onCompleteAllScope || vars.callbackScope || this, onCompleteAllParams || _blankArray)
},
cycle = vars.cycle,
fromCycle = (vars.startAt && vars.startAt.cycle),
l, copy, i, p
if (!_isArray(targets)) {
if (typeof (targets) === 'string') {
targets = TweenLite.selector(targets) || targets
}
if (_isSelector(targets)) {
targets = _slice(targets)
}
}
targets = targets || []
if (stagger < 0) {
targets = _slice(targets)
targets.reverse()
stagger *= -1
}
l = targets.length - 1
for (i = 0; i <= l; i++) {
copy = {}
for (p in vars) {
copy[p] = vars[p]
}
if (cycle) {
_applyCycle(copy, targets, i)
if (copy.duration != null) {
duration = copy.duration
delete copy.duration
}
}
if (fromCycle) {
fromCycle = copy.startAt = {}
for (p in vars.startAt) {
fromCycle[p] = vars.startAt[p]
}
_applyCycle(copy.startAt, targets, i)
}
copy.delay = delay + (copy.delay || 0)
if (i === l && onCompleteAll) {
copy.onComplete = finalComplete
}
a[i] = new TweenMax(targets[i], duration, copy)
delay += stagger
}
return a
}
TweenMax.staggerFrom = TweenMax.allFrom = function (targets, duration, vars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
vars.runBackwards = true
vars.immediateRender = (vars.immediateRender != false)
return TweenMax.staggerTo(targets, duration, vars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope)
}
TweenMax.staggerFromTo = TweenMax.allFromTo = function (targets, duration, fromVars, toVars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
toVars.startAt = fromVars
toVars.immediateRender = (toVars.immediateRender != false && fromVars.immediateRender != false)
return TweenMax.staggerTo(targets, duration, toVars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope)
}
TweenMax.delayedCall = function (delay, callback, params, scope, useFrames) {
return new TweenMax(callback, 0, {delay: delay, onComplete: callback, onCompleteParams: params, callbackScope: scope, onReverseComplete: callback, onReverseCompleteParams: params, immediateRender: false, useFrames: useFrames, overwrite: 0})
}
TweenMax.set = function (target, vars) {
return new TweenMax(target, 0, vars)
}
TweenMax.isTweening = function (target) {
return (TweenLite.getTweensOf(target, true).length > 0)
}
var _getChildrenOf = function (timeline, includeTimelines) {
var a = [],
cnt = 0,
tween = timeline._first
while (tween) {
if (tween instanceof TweenLite) {
a[cnt++] = tween
} else {
if (includeTimelines) {
a[cnt++] = tween
}
a = a.concat(_getChildrenOf(tween, includeTimelines))
cnt = a.length
}
tween = tween._next
}
return a
},
getAllTweens = TweenMax.getAllTweens = function (includeTimelines) {
return _getChildrenOf(Animation._rootTimeline, includeTimelines).concat(_getChildrenOf(Animation._rootFramesTimeline, includeTimelines))
}
TweenMax.killAll = function (complete, tweens, delayedCalls, timelines) {
if (tweens == null) {
tweens = true
}
if (delayedCalls == null) {
delayedCalls = true
}
var a = getAllTweens((timelines != false)),
l = a.length,
allTrue = (tweens && delayedCalls && timelines),
isDC, tween, i
for (i = 0; i < l; i++) {
tween = a[i]
if (allTrue || (tween instanceof SimpleTimeline) || ((isDC = (tween.target === tween.vars.onComplete)) && delayedCalls) || (tweens && !isDC)) {
if (complete) {
tween.totalTime(tween._reversed ? 0 : tween.totalDuration())
} else {
tween._enabled(false, false)
}
}
}
}
TweenMax.killChildTweensOf = function (parent, complete) {
if (parent == null) {
return
}
var tl = TweenLiteInternals.tweenLookup,
a, curParent, p, i, l
if (typeof (parent) === 'string') {
parent = TweenLite.selector(parent) || parent
}
if (_isSelector(parent)) {
parent = _slice(parent)
}
if (_isArray(parent)) {
i = parent.length
while (--i > -1) {
TweenMax.killChildTweensOf(parent[i], complete)
}
return
}
a = []
for (p in tl) {
curParent = tl[p].target.parentNode
while (curParent) {
if (curParent === parent) {
a = a.concat(tl[p].tweens)
}
curParent = curParent.parentNode
}
}
l = a.length
for (i = 0; i < l; i++) {
if (complete) {
a[i].totalTime(a[i].totalDuration())
}
a[i]._enabled(false, false)
}
}
var _changePause = function (pause, tweens, delayedCalls, timelines) {
tweens = (tweens !== false)
delayedCalls = (delayedCalls !== false)
timelines = (timelines !== false)
var a = getAllTweens(timelines),
allTrue = (tweens && delayedCalls && timelines),
i = a.length,
isDC, tween
while (--i > -1) {
tween = a[i]
if (allTrue || (tween instanceof SimpleTimeline) || ((isDC = (tween.target === tween.vars.onComplete)) && delayedCalls) || (tweens && !isDC)) {
tween.paused(pause)
}
}
}
TweenMax.pauseAll = function (tweens, delayedCalls, timelines) {
_changePause(true, tweens, delayedCalls, timelines)
}
TweenMax.resumeAll = function (tweens, delayedCalls, timelines) {
_changePause(false, tweens, delayedCalls, timelines)
}
TweenMax.globalTimeScale = function (value) {
var tl = Animation._rootTimeline,
t = TweenLite.ticker.time
if (!arguments.length) {
return tl._timeScale
}
value = value || _tinyNum // can't allow zero because it'll throw the math off
tl._startTime = t - ((t - tl._startTime) * tl._timeScale / value)
tl = Animation._rootFramesTimeline
t = TweenLite.ticker.frame
tl._startTime = t - ((t - tl._startTime) * tl._timeScale / value)
tl._timeScale = Animation._rootTimeline._timeScale = value
return value
}
// ---- GETTERS / SETTERS ----------------------------------------------------------------------------------------------------------
p.progress = function (value, suppressEvents) {
return (!arguments.length) ? this._time / this.duration() : this.totalTime(this.duration() * ((this._yoyo && (this._cycle & 1) !== 0) ? 1 - value : value) + (this._cycle * (this._duration + this._repeatDelay)), suppressEvents)
}
p.totalProgress = function (value, suppressEvents) {
return (!arguments.length) ? this._totalTime / this.totalDuration() : this.totalTime(this.totalDuration() * value, suppressEvents)
}
p.time = function (value, suppressEvents) {
if (!arguments.length) {
return this._time
}
if (this._dirty) {
this.totalDuration()
}
if (value > this._duration) {
value = this._duration
}
if (this._yoyo && (this._cycle & 1) !== 0) {
value = (this._duration - value) + (this._cycle * (this._duration + this._repeatDelay))
} else if (this._repeat !== 0) {
value += this._cycle * (this._duration + this._repeatDelay)
}
return this.totalTime(value, suppressEvents)
}
p.duration = function (value) {
if (!arguments.length) {
return this._duration // don't set _dirty = false because there could be repeats that haven't been factored into the _totalDuration yet. Otherwise, if you create a repeated TweenMax and then immediately check its duration(), it would cache the value and the totalDuration would not be correct, thus repeats wouldn't take effect.
}
return Animation.prototype.duration.call(this, value)
}
p.totalDuration = function (value) {
if (!arguments.length) {
if (this._dirty) {
// instead of Infinity, we use 999999999999 so that we can accommodate reverses
this._totalDuration = (this._repeat === -1) ? 999999999999 : this._duration * (this._repeat + 1) + (this._repeatDelay * this._repeat)
this._dirty = false
}
return this._totalDuration
}
return (this._repeat === -1) ? this : this.duration((value - (this._repeat * this._repeatDelay)) / (this._repeat + 1))
}
p.repeat = function (value) {
if (!arguments.length) {
return this._repeat
}
this._repeat = value
return this._uncache(true)
}
p.repeatDelay = function (value) {
if (!arguments.length) {
return this._repeatDelay
}
this._repeatDelay = value
return this._uncache(true)
}
p.yoyo = function (value) {
if (!arguments.length) {
return this._yoyo
}
this._yoyo = value
return this
}
return TweenMax
}, true)
/*
* ----------------------------------------------------------------
* TimelineLite
* ----------------------------------------------------------------
*/
_gsScope._gsDefine('TimelineLite', ['core.Animation', 'core.SimpleTimeline', 'TweenLite'], function (Animation, SimpleTimeline, TweenLite) {
var TimelineLite = function (vars) {
SimpleTimeline.call(this, vars)
this._labels = {}
this.autoRemoveChildren = (this.vars.autoRemoveChildren === true)
this.smoothChildTiming = (this.vars.smoothChildTiming === true)
this._sortChildren = true
this._onUpdate = this.vars.onUpdate
var v = this.vars,
val, p
for (p in v) {
val = v[p]
if (_isArray(val)) {
if (val.join('').indexOf('{self}') !== -1) {
v[p] = this._swapSelfInParams(val)
}
}
}
if (_isArray(v.tweens)) {
this.add(v.tweens, 0, v.align, v.stagger)
}
},
_tinyNum = 0.0000000001,
TweenLiteInternals = TweenLite._internals,
_internals = TimelineLite._internals = {},
_isSelector = TweenLiteInternals.isSelector,
_isArray = TweenLiteInternals.isArray,
_lazyTweens = TweenLiteInternals.lazyTweens,
_lazyRender = TweenLiteInternals.lazyRender,
_globals = _gsScope._gsDefine.globals,
_copy = function (vars) {
var copy = {}, p
for (p in vars) {
copy[p] = vars[p]
}
return copy
},
_applyCycle = function (vars, targets, i) {
var alt = vars.cycle,
p, val
for (p in alt) {
val = alt[p]
vars[p] = (typeof (val) === 'function') ? val(i, targets[i]) : val[i % val.length]
}
delete vars.cycle
},
_pauseCallback = _internals.pauseCallback = function () {},
_slice = function (a) { // don't use [].slice because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll()
var b = [],
l = a.length,
i
for (i = 0; i !== l; b.push(a[i++]));
return b
},
p = TimelineLite.prototype = new SimpleTimeline()
TimelineLite.version = '1.20.2'
p.constructor = TimelineLite
p.kill()._gc = p._forcingPlayhead = p._hasPause = false
/* might use later...
//translates a local time inside an animation to the corresponding time on the root/global timeline, factoring in all nesting and timeScales.
function localToGlobal(time, animation) {
while (animation) {
time = (time / animation._timeScale) + animation._startTime;
animation = animation.timeline;
}
return time;
}
//translates the supplied time on the root/global timeline into the corresponding local time inside a particular animation, factoring in all nesting and timeScales
function globalToLocal(time, animation) {
var scale = 1;
time -= localToGlobal(0, animation);
while (animation) {
scale *= animation._timeScale;
animation = animation.timeline;
}
return time * scale;
}
*/
p.to = function (target, duration, vars, position) {
var Engine = (vars.repeat && _globals.TweenMax) || TweenLite
return duration ? this.add(new Engine(target, duration, vars), position) : this.set(target, vars, position)
}
p.from = function (target, duration, vars, position) {
return this.add(((vars.repeat && _globals.TweenMax) || TweenLite).from(target, duration, vars), position)
}
p.fromTo = function (target, duration, fromVars, toVars, position) {
var Engine = (toVars.repeat && _globals.TweenMax) || TweenLite
return duration ? this.add(Engine.fromTo(target, duration, fromVars, toVars), position) : this.set(target, toVars, position)
}
p.staggerTo = function (targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
var tl = new TimelineLite({onComplete: onCompleteAll, onCompleteParams: onCompleteAllParams, callbackScope: onCompleteAllScope, smoothChildTiming: this.smoothChildTiming}),
cycle = vars.cycle,
copy, i
if (typeof (targets) === 'string') {
targets = TweenLite.selector(targets) || targets
}
targets = targets || []
if (_isSelector(targets)) { // senses if the targets object is a selector. If it is, we should translate it into an array.
targets = _slice(targets)
}
stagger = stagger || 0
if (stagger < 0) {
targets = _slice(targets)
targets.reverse()
stagger *= -1
}
for (i = 0; i < targets.length; i++) {
copy = _copy(vars)
if (copy.startAt) {
copy.startAt = _copy(copy.startAt)
if (copy.startAt.cycle) {
_applyCycle(copy.startAt, targets, i)
}
}
if (cycle) {
_applyCycle(copy, targets, i)
if (copy.duration != null) {
duration = copy.duration
delete copy.duration
}
}
tl.to(targets[i], duration, copy, i * stagger)
}
return this.add(tl, position)
}
p.staggerFrom = function (targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
vars.immediateRender = (vars.immediateRender != false)
vars.runBackwards = true
return this.staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope)
}
p.staggerFromTo = function (targets, duration, fromVars, toVars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
toVars.startAt = fromVars
toVars.immediateRender = (toVars.immediateRender != false && fromVars.immediateRender != false)
return this.staggerTo(targets, duration, toVars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope)
}
p.call = function (callback, params, scope, position) {
return this.add(TweenLite.delayedCall(0, callback, params, scope), position)
}
p.set = function (target, vars, position) {
position = this._parseTimeOrLabel(position, 0, true)
if (vars.immediateRender == null) {
vars.immediateRender = (position === this._time && !this._paused)
}
return this.add(new TweenLite(target, 0, vars), position)
}
TimelineLite.exportRoot = function (vars, ignoreDelayedCalls) {
vars = vars || {}
if (vars.smoothChildTiming == null) {
vars.smoothChildTiming = true
}
var tl = new TimelineLite(vars),
root = tl._timeline,
tween, next
if (ignoreDelayedCalls == null) {
ignoreDelayedCalls = true
}
root._remove(tl, true)
tl._startTime = 0
tl._rawPrevTime = tl._time = tl._totalTime = root._time
tween = root._first
while (tween) {
next = tween._next
if (!ignoreDelayedCalls || !(tween instanceof TweenLite && tween.target === tween.vars.onComplete)) {
tl.add(tween, tween._startTime - tween._delay)
}
tween = next
}
root.add(tl, 0)
return tl
}
p.add = function (value, position, align, stagger) {
var curTime, l, i, child, tl, beforeRawTime
if (typeof (position) !== 'number') {
position = this._parseTimeOrLabel(position, 0, true, value)
}
if (!(value instanceof Animation)) {
if ((value instanceof Array) || (value && value.push && _isArray(value))) {
align = align || 'normal'
stagger = stagger || 0
curTime = position
l = value.length
for (i = 0; i < l; i++) {
if (_isArray(child = value[i])) {
child = new TimelineLite({tweens: child})
}
this.add(child, curTime)
if (typeof (child) !== 'string' && typeof (child) !== 'function') {
if (align === 'sequence') {
curTime = child._startTime + (child.totalDuration() / child._timeScale)
} else if (align === 'start') {
child._startTime -= child.delay()
}
}
curTime += stagger
}
return this._uncache(true)
} else if (typeof (value) === 'string') {
return this.addLabel(value, position)
} else if (typeof (value) === 'function') {
value = TweenLite.delayedCall(0, value)
} else {
throw ('Cannot add ' + value + ' into the timeline; it is not a tween, timeline, function, or string.')
}
}
SimpleTimeline.prototype.add.call(this, value, position)
if (value._time) { // in case, for example, the _startTime is moved on a tween that has already rendered. Imagine it's at its end state, then the startTime is moved WAY later (after the end of this timeline), it should render at its beginning.
value.render((this.rawTime() - value._startTime) * value._timeScale, false, false)
}
// if the timeline has already ended but the inserted tween/timeline extends the duration, we should enable this timeline again so that it renders properly. We should also align the playhead with the parent timeline's when appropriate.
if (this._gc || this._time === this._duration) {
if (!this._paused) {
if (this._duration < this.duration()) {
// in case any of the ancestors had completed but should now be enabled...
tl = this
beforeRawTime = (tl.rawTime() > value._startTime) // if the tween is placed on the timeline so that it starts BEFORE the current rawTime, we should align the playhead (move the timeline). This is because sometimes users will create a timeline, let it finish, and much later append a tween and expect it to run instead of jumping to its end state. While technically one could argue that it should jump to its end state, that's not what users intuitively expect.
while (tl._timeline) {
if (beforeRawTime && tl._timeline.smoothChildTiming) {
tl.totalTime(tl._totalTime, true) // moves the timeline (shifts its startTime) if necessary, and also enables it.
} else if (tl._gc) {
tl._enabled(true, false)
}
tl = tl._timeline
}
}
}
}
return this
}
p.remove = function (value) {
if (value instanceof Animation) {
this._remove(value, false)
var tl = value._timeline = value.vars.useFrames ? Animation._rootFramesTimeline : Animation._rootTimeline // now that it's removed, default it to the root timeline so that if it gets played again, it doesn't jump back into this timeline.
value._startTime = (value._paused ? value._pauseTime : tl._time) - ((!value._reversed ? value._totalTime : value.totalDuration() - value._totalTime) / value._timeScale) // ensure that if it gets played again, the timing is correct.
return this
} else if (value instanceof Array || (value && value.push && _isArray(value))) {
var i = value.length
while (--i > -1) {
this.remove(value[i])
}
return this
} else if (typeof (value) === 'string') {
return this.removeLabel(value)
}
return this.kill(null, value)
}
p._remove = function (tween, skipDisable) {
SimpleTimeline.prototype._remove.call(this, tween, skipDisable)
var last = this._last
if (!last) {
this._time = this._totalTime = this._duration = this._totalDuration = 0
} else if (this._time > this.duration()) {
this._time = this._duration
this._totalTime = this._totalDuration
}
return this
}
p.append = function (value, offsetOrLabel) {
return this.add(value, this._parseTimeOrLabel(null, offsetOrLabel, true, value))
}
p.insert = p.insertMultiple = function (value, position, align, stagger) {
return this.add(value, position || 0, align, stagger)
}
p.appendMultiple = function (tweens, offsetOrLabel, align, stagger) {
return this.add(tweens, this._parseTimeOrLabel(null, offsetOrLabel, true, tweens), align, stagger)
}
p.addLabel = function (label, position) {
this._labels[label] = this._parseTimeOrLabel(position)
return this
}
p.addPause = function (position, callback, params, scope) {
var t = TweenLite.delayedCall(0, _pauseCallback, params, scope || this)
t.vars.onComplete = t.vars.onReverseComplete = callback
t.data = 'isPause'
this._hasPause = true
return this.add(t, position)
}
p.removeLabel = function (label) {
delete this._labels[label]
return this
}
p.getLabelTime = function (label) {
return (this._labels[label] != null) ? this._labels[label] : -1
}
p._parseTimeOrLabel = function (timeOrLabel, offsetOrLabel, appendIfAbsent, ignore) {
var clippedDuration, i
// if we're about to add a tween/timeline (or an array of them) that's already a child of this timeline, we should remove it first so that it doesn't contaminate the duration().
if (ignore instanceof Animation && ignore.timeline === this) {
this.remove(ignore)
} else if (ignore && ((ignore instanceof Array) || (ignore.push && _isArray(ignore)))) {
i = ignore.length
while (--i > -1) {
if (ignore[i] instanceof Animation && ignore[i].timeline === this) {
this.remove(ignore[i])
}
}
}
clippedDuration = (this.duration() > 99999999999) ? this.recent().endTime(false) : this._duration // in case there's a child that infinitely repeats, users almost never intend for the insertion point of a new child to be based on a SUPER long value like that so we clip it and assume the most recently-added child's endTime should be used instead.
if (typeof (offsetOrLabel) === 'string') {
return this._parseTimeOrLabel(offsetOrLabel, (appendIfAbsent && typeof (timeOrLabel) === 'number' && this._labels[offsetOrLabel] == null) ? timeOrLabel - clippedDuration : 0, appendIfAbsent)
}
offsetOrLabel = offsetOrLabel || 0
if (typeof (timeOrLabel) === 'string' && (isNaN(timeOrLabel) || this._labels[timeOrLabel] != null)) { // if the string is a number like "1", check to see if there's a label with that name, otherwise interpret it as a number (absolute value).
i = timeOrLabel.indexOf('=')
if (i === -1) {
if (this._labels[timeOrLabel] == null) {
return appendIfAbsent ? (this._labels[timeOrLabel] = clippedDuration + offsetOrLabel) : offsetOrLabel
}
return this._labels[timeOrLabel] + offsetOrLabel
}
offsetOrLabel = parseInt(timeOrLabel.charAt(i - 1) + '1', 10) * Number(timeOrLabel.substr(i + 1))
timeOrLabel = (i > 1) ? this._parseTimeOrLabel(timeOrLabel.substr(0, i - 1), 0, appendIfAbsent) : clippedDuration
} else if (timeOrLabel == null) {
timeOrLabel = clippedDuration
}
return Number(timeOrLabel) + offsetOrLabel
}
p.seek = function (position, suppressEvents) {
return this.totalTime((typeof (position) === 'number') ? position : this._parseTimeOrLabel(position), (suppressEvents !== false))
}
p.stop = function () {
return this.paused(true)
}
p.gotoAndPlay = function (position, suppressEvents) {
return this.play(position, suppressEvents)
}
p.gotoAndStop = function (position, suppressEvents) {
return this.pause(position, suppressEvents)
}
p.render = function (time, suppressEvents, force) {
if (this._gc) {
this._enabled(true, false)
}
var totalDur = (!this._dirty) ? this._totalDuration : this.totalDuration(),
prevTime = this._time,
prevStart = this._startTime,
prevTimeScale = this._timeScale,
prevPaused = this._paused,
tween, isComplete, next, callback, internalForce, pauseTween, curTime
if (time >= totalDur - 0.0000001 && time >= 0) { // to work around occasional floating point math artifacts.
this._totalTime = this._time = totalDur
if (!this._reversed) {
if (!this._hasPausedChild()) {
isComplete = true
callback = 'onComplete'
internalForce = !!this._timeline.autoRemoveChildren // otherwise, if the animation is unpaused/activated after it's already finished, it doesn't get removed from the parent timeline.
if (this._duration === 0) {
if ((time <= 0 && time >= -0.0000001) || this._rawPrevTime < 0 || this._rawPrevTime === _tinyNum) {
if (this._rawPrevTime !== time && this._first) {
internalForce = true
if (this._rawPrevTime > _tinyNum) {
callback = 'onReverseComplete'
}
}
}
}
}
}
this._rawPrevTime = (this._duration || !suppressEvents || time || this._rawPrevTime === time) ? time : _tinyNum // when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
time = totalDur + 0.0001 // to avoid occasional floating point rounding errors - sometimes child tweens/timelines were not being fully completed (their progress might be 0.999999999999998 instead of 1 because when _time - tween._startTime is performed, floating point errors would return a value that was SLIGHTLY off). Try (999999999999.7 - 999999999999) * 1 = 0.699951171875 instead of 0.7.
} else if (time < 0.0000001) { // to work around occasional floating point math artifacts, round super small values to 0.
this._totalTime = this._time = 0
if (prevTime !== 0 || (this._duration === 0 && this._rawPrevTime !== _tinyNum && (this._rawPrevTime > 0 || (time < 0 && this._rawPrevTime >= 0)))) {
callback = 'onReverseComplete'
isComplete = this._reversed
}
if (time < 0) {
this._active = false
if (this._timeline.autoRemoveChildren && this._reversed) { // ensures proper GC if a timeline is resumed after it's finished reversing.
internalForce = isComplete = true
callback = 'onReverseComplete'
} else if (this._rawPrevTime >= 0 && this._first) { // when going back beyond the start, force a render so that zero-duration tweens that sit at the very beginning render their start values properly. Otherwise, if the parent timeline's playhead lands exactly at this timeline's startTime, and then moves backwards, the zero-duration tweens at the beginning would still be at their end state.
internalForce = true
}
this._rawPrevTime = time
} else {
this._rawPrevTime = (this._duration || !suppressEvents || time || this._rawPrevTime === time) ? time : _tinyNum // when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
if (time === 0 && isComplete) { // if there's a zero-duration tween at the very beginning of a timeline and the playhead lands EXACTLY at time 0, that tween will correctly render its end values, but we need to keep the timeline alive for one more render so that the beginning values render properly as the parent's playhead keeps moving beyond the begining. Imagine obj.x starts at 0 and then we do tl.set(obj, {x:100}).to(obj, 1, {x:200}) and then later we tl.reverse()...the goal is to have obj.x revert to 0. If the playhead happens to land on exactly 0, without this chunk of code, it'd complete the timeline and remove it from the rendering queue (not good).
tween = this._first
while (tween && tween._startTime === 0) {
if (!tween._duration) {
isComplete = false
}
tween = tween._next
}
}
time = 0 // to avoid occasional floating point rounding errors (could cause problems especially with zero-duration tweens at the very beginning of the timeline)
if (!this._initted) {
internalForce = true
}
}
} else {
if (this._hasPause && !this._forcingPlayhead && !suppressEvents) {
if (time >= prevTime) {
tween = this._first
while (tween && tween._startTime <= time && !pauseTween) {
if (!tween._duration) {
if (tween.data === 'isPause' && !tween.ratio && !(tween._startTime === 0 && this._rawPrevTime === 0)) {
pauseTween = tween
}
}
tween = tween._next
}
} else {
tween = this._last
while (tween && tween._startTime >= time && !pauseTween) {
if (!tween._duration) {
if (tween.data === 'isPause' && tween._rawPrevTime > 0) {
pauseTween = tween
}
}
tween = tween._prev
}
}
if (pauseTween) {
this._time = time = pauseTween._startTime
this._totalTime = time + (this._cycle * (this._totalDuration + this._repeatDelay))
}
}
this._totalTime = this._time = this._rawPrevTime = time
}
if ((this._time === prevTime || !this._first) && !force && !internalForce && !pauseTween) {
return
} else if (!this._initted) {
this._initted = true
}
if (!this._active) {
if (!this._paused && this._time !== prevTime && time > 0) {
this._active = true // so that if the user renders the timeline (as opposed to the parent timeline rendering it), it is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the timeline already finished but the user manually re-renders it as halfway done, for example.
}
}
if (prevTime === 0) {
if (this.vars.onStart) {
if (this._time !== 0 || !this._duration) {
if (!suppressEvents) {
this._callback('onStart')
}
}
}
}
curTime = this._time
if (curTime >= prevTime) {
tween = this._first
while (tween) {
next = tween._next // record it here because the value could change after rendering...
if (curTime !== this._time || (this._paused && !prevPaused)) { // in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete
break
} else if (tween._active || (tween._startTime <= curTime && !tween._paused && !tween._gc)) {
if (pauseTween === tween) {
this.pause()
}
if (!tween._reversed) {
tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force)
} else {
tween.render(((!tween._dirty) ? tween._totalDuration : tween.totalDuration()) - ((time - tween._startTime) * tween._timeScale), suppressEvents, force)
}
}
tween = next
}
} else {
tween = this._last
while (tween) {
next = tween._prev // record it here because the value could change after rendering...
if (curTime !== this._time || (this._paused && !prevPaused)) { // in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete
break
} else if (tween._active || (tween._startTime <= prevTime && !tween._paused && !tween._gc)) {
if (pauseTween === tween) {
pauseTween = tween._prev // the linked list is organized by _startTime, thus it's possible that a tween could start BEFORE the pause and end after it, in which case it would be positioned before the pause tween in the linked list, but we should render it before we pause() the timeline and cease rendering. This is only a concern when going in reverse.
while (pauseTween && pauseTween.endTime() > this._time) {
pauseTween.render((pauseTween._reversed ? pauseTween.totalDuration() - ((time - pauseTween._startTime) * pauseTween._timeScale) : (time - pauseTween._startTime) * pauseTween._timeScale), suppressEvents, force)
pauseTween = pauseTween._prev
}
pauseTween = null
this.pause()
}
if (!tween._reversed) {
tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force)
} else {
tween.render(((!tween._dirty) ? tween._totalDuration : tween.totalDuration()) - ((time - tween._startTime) * tween._timeScale), suppressEvents, force)
}
}
tween = next
}
}
if (this._onUpdate) {
if (!suppressEvents) {
if (_lazyTweens.length) { // in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onUpdate on a timeline that reports/checks tweened values.
_lazyRender()
}
this._callback('onUpdate')
}
}
if (callback) {
if (!this._gc) {
if (prevStart === this._startTime || prevTimeScale !== this._timeScale) {
if (this._time === 0 || totalDur >= this.totalDuration()) { // if one of the tweens that was rendered altered this timeline's startTime (like if an onComplete reversed the timeline), it probably isn't complete. If it is, don't worry, because whatever call altered the startTime would complete if it was necessary at the new time. The only exception is the timeScale property. Also check _gc because there's a chance that kill() could be called in an onUpdate
if (isComplete) {
if (_lazyTweens.length) { // in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onComplete on a timeline that reports/checks tweened values.
_lazyRender()
}
if (this._timeline.autoRemoveChildren) {
this._enabled(false, false)
}
this._active = false
}
if (!suppressEvents && this.vars[callback]) {
this._callback(callback)
}
}
}
}
}
}
p._hasPausedChild = function () {
var tween = this._first
while (tween) {
if (tween._paused || ((tween instanceof TimelineLite) && tween._hasPausedChild())) {
return true
}
tween = tween._next
}
return false
}
p.getChildren = function (nested, tweens, timelines, ignoreBeforeTime) {
ignoreBeforeTime = ignoreBeforeTime || -9999999999
var a = [],
tween = this._first,
cnt = 0
while (tween) {
if (tween._startTime < ignoreBeforeTime) {
// do nothing
} else if (tween instanceof TweenLite) {
if (tweens !== false) {
a[cnt++] = tween
}
} else {
if (timelines !== false) {
a[cnt++] = tween
}
if (nested !== false) {
a = a.concat(tween.getChildren(true, tweens, timelines))
cnt = a.length
}
}
tween = tween._next
}
return a
}
p.getTweensOf = function (target, nested) {
var disabled = this._gc,
a = [],
cnt = 0,
tweens, i
if (disabled) {
this._enabled(true, true) // getTweensOf() filters out disabled tweens, and we have to mark them as _gc = true when the timeline completes in order to allow clean garbage collection, so temporarily re-enable the timeline here.
}
tweens = TweenLite.getTweensOf(target)
i = tweens.length
while (--i > -1) {
if (tweens[i].timeline === this || (nested && this._contains(tweens[i]))) {
a[cnt++] = tweens[i]
}
}
if (disabled) {
this._enabled(false, true)
}
return a
}
p.recent = function () {
return this._recent
}
p._contains = function (tween) {
var tl = tween.timeline
while (tl) {
if (tl === this) {
return true
}
tl = tl.timeline
}
return false
}
p.shiftChildren = function (amount, adjustLabels, ignoreBeforeTime) {
ignoreBeforeTime = ignoreBeforeTime || 0
var tween = this._first,
labels = this._labels,
p
while (tween) {
if (tween._startTime >= ignoreBeforeTime) {
tween._startTime += amount
}
tween = tween._next
}
if (adjustLabels) {
for (p in labels) {
if (labels[p] >= ignoreBeforeTime) {
labels[p] += amount
}
}
}
return this._uncache(true)
}
p._kill = function (vars, target) {
if (!vars && !target) {
return this._enabled(false, false)
}
var tweens = (!target) ? this.getChildren(true, true, false) : this.getTweensOf(target),
i = tweens.length,
changed = false
while (--i > -1) {
if (tweens[i]._kill(vars, target)) {
changed = true
}
}
return changed
}
p.clear = function (labels) {
var tweens = this.getChildren(false, true, true),
i = tweens.length
this._time = this._totalTime = 0
while (--i > -1) {
tweens[i]._enabled(false, false)
}
if (labels !== false) {
this._labels = {}
}
return this._uncache(true)
}
p.invalidate = function () {
var tween = this._first
while (tween) {
tween.invalidate()
tween = tween._next
}
return Animation.prototype.invalidate.call(this)
}
p._enabled = function (enabled, ignoreTimeline) {
if (enabled === this._gc) {
var tween = this._first
while (tween) {
tween._enabled(enabled, true)
tween = tween._next
}
}
return SimpleTimeline.prototype._enabled.call(this, enabled, ignoreTimeline)
}
p.totalTime = function (time, suppressEvents, uncapped) {
this._forcingPlayhead = true
var val = Animation.prototype.totalTime.apply(this, arguments)
this._forcingPlayhead = false
return val
}
p.duration = function (value) {
if (!arguments.length) {
if (this._dirty) {
this.totalDuration() // just triggers recalculation
}
return this._duration
}
if (this.duration() !== 0 && value !== 0) {
this.timeScale(this._duration / value)
}
return this
}
p.totalDuration = function (value) {
if (!arguments.length) {
if (this._dirty) {
var max = 0,
tween = this._last,
prevStart = 999999999999,
prev, end
while (tween) {
prev = tween._prev // record it here in case the tween changes position in the sequence...
if (tween._dirty) {
tween.totalDuration() // could change the tween._startTime, so make sure the tween's cache is clean before analyzing it.
}
if (tween._startTime > prevStart && this._sortChildren && !tween._paused) { // in case one of the tweens shifted out of order, it needs to be re-inserted into the correct position in the sequence
this.add(tween, tween._startTime - tween._delay)
} else {
prevStart = tween._startTime
}
if (tween._startTime < 0 && !tween._paused) { // children aren't allowed to have negative startTimes unless smoothChildTiming is true, so adjust here if one is found.
max -= tween._startTime
if (this._timeline.smoothChildTiming) {
this._startTime += tween._startTime / this._timeScale
}
this.shiftChildren(-tween._startTime, false, -9999999999)
prevStart = 0
}
end = tween._startTime + (tween._totalDuration / tween._timeScale)
if (end > max) {
max = end
}
tween = prev
}
this._duration = this._totalDuration = max
this._dirty = false
}
return this._totalDuration
}
return (value && this.totalDuration()) ? this.timeScale(this._totalDuration / value) : this
}
p.paused = function (value) {
if (!value) { // if there's a pause directly at the spot from where we're unpausing, skip it.
var tween = this._first,
time = this._time
while (tween) {
if (tween._startTime === time && tween.data === 'isPause') {
tween._rawPrevTime = 0 // remember, _rawPrevTime is how zero-duration tweens/callbacks sense directionality and determine whether or not to fire. If _rawPrevTime is the same as _startTime on the next render, it won't fire.
}
tween = tween._next
}
}
return Animation.prototype.paused.apply(this, arguments)
}
p.usesFrames = function () {
var tl = this._timeline
while (tl._timeline) {
tl = tl._timeline
}
return (tl === Animation._rootFramesTimeline)
}
p.rawTime = function (wrapRepeats) {
return (wrapRepeats && (this._paused || (this._repeat && this.time() > 0 && this.totalProgress() < 1))) ? this._totalTime % (this._duration + this._repeatDelay) : this._paused ? this._totalTime : (this._timeline.rawTime(wrapRepeats) - this._startTime) * this._timeScale
}
return TimelineLite
}, true)
/*
* ----------------------------------------------------------------
* TimelineMax
* ----------------------------------------------------------------
*/
_gsScope._gsDefine('TimelineMax', ['TimelineLite', 'TweenLite', 'easing.Ease'], function (TimelineLite, TweenLite, Ease) {
var TimelineMax = function (vars) {
TimelineLite.call(this, vars)
this._repeat = this.vars.repeat || 0
this._repeatDelay = this.vars.repeatDelay || 0
this._cycle = 0
this._yoyo = (this.vars.yoyo === true)
this._dirty = true
},
_tinyNum = 0.0000000001,
TweenLiteInternals = TweenLite._internals,
_lazyTweens = TweenLiteInternals.lazyTweens,
_lazyRender = TweenLiteInternals.lazyRender,
_globals = _gsScope._gsDefine.globals,
_easeNone = new Ease(null, null, 1, 0),
p = TimelineMax.prototype = new TimelineLite()
p.constructor = TimelineMax
p.kill()._gc = false
TimelineMax.version = '1.20.2'
p.invalidate = function () {
this._yoyo = (this.vars.yoyo === true)
this._repeat = this.vars.repeat || 0
this._repeatDelay = this.vars.repeatDelay || 0
this._uncache(true)
return TimelineLite.prototype.invalidate.call(this)
}
p.addCallback = function (callback, position, params, scope) {
return this.add(TweenLite.delayedCall(0, callback, params, scope), position)
}
p.removeCallback = function (callback, position) {
if (callback) {
if (position == null) {
this._kill(null, callback)
} else {
var a = this.getTweensOf(callback, false),
i = a.length,
time = this._parseTimeOrLabel(position)
while (--i > -1) {
if (a[i]._startTime === time) {
a[i]._enabled(false, false)
}
}
}
}
return this
}
p.removePause = function (position) {
return this.removeCallback(TimelineLite._internals.pauseCallback, position)
}
p.tweenTo = function (position, vars) {
vars = vars || {}
var copy = {ease: _easeNone, useFrames: this.usesFrames(), immediateRender: false},
Engine = (vars.repeat && _globals.TweenMax) || TweenLite,
duration, p, t
for (p in vars) {
copy[p] = vars[p]
}
copy.time = this._parseTimeOrLabel(position)
duration = (Math.abs(Number(copy.time) - this._time) / this._timeScale) || 0.001
t = new Engine(this, duration, copy)
copy.onStart = function () {
t.target.paused(true)
if (t.vars.time !== t.target.time() && duration === t.duration()) { // don't make the duration zero - if it's supposed to be zero, don't worry because it's already initting the tween and will complete immediately, effectively making the duration zero anyway. If we make duration zero, the tween won't run at all.
t.duration(Math.abs(t.vars.time - t.target.time()) / t.target._timeScale)
}
if (vars.onStart) { // in case the user had an onStart in the vars - we don't want to overwrite it.
vars.onStart.apply(vars.onStartScope || vars.callbackScope || t, vars.onStartParams || []) // don't use t._callback("onStart") or it'll point to the copy.onStart and we'll get a recursion error.
}
}
return t
}
p.tweenFromTo = function (fromPosition, toPosition, vars) {
vars = vars || {}
fromPosition = this._parseTimeOrLabel(fromPosition)
vars.startAt = {onComplete: this.seek, onCompleteParams: [fromPosition], callbackScope: this}
vars.immediateRender = (vars.immediateRender !== false)
var t = this.tweenTo(toPosition, vars)
return t.duration((Math.abs(t.vars.time - fromPosition) / this._timeScale) || 0.001)
}
p.render = function (time, suppressEvents, force) {
if (this._gc) {
this._enabled(true, false)
}
var totalDur = (!this._dirty) ? this._totalDuration : this.totalDuration(),
dur = this._duration,
prevTime = this._time,
prevTotalTime = this._totalTime,
prevStart = this._startTime,
prevTimeScale = this._timeScale,
prevRawPrevTime = this._rawPrevTime,
prevPaused = this._paused,
prevCycle = this._cycle,
tween, isComplete, next, callback, internalForce, cycleDuration, pauseTween, curTime
if (time >= totalDur - 0.0000001 && time >= 0) { // to work around occasional floating point math artifacts.
if (!this._locked) {
this._totalTime = totalDur
this._cycle = this._repeat
}
if (!this._reversed) {
if (!this._hasPausedChild()) {
isComplete = true
callback = 'onComplete'
internalForce = !!this._timeline.autoRemoveChildren // otherwise, if the animation is unpaused/activated after it's already finished, it doesn't get removed from the parent timeline.
if (this._duration === 0) {
if ((time <= 0 && time >= -0.0000001) || prevRawPrevTime < 0 || prevRawPrevTime === _tinyNum) {
if (prevRawPrevTime !== time && this._first) {
internalForce = true
if (prevRawPrevTime > _tinyNum) {
callback = 'onReverseComplete'
}
}
}
}
}
}
this._rawPrevTime = (this._duration || !suppressEvents || time || this._rawPrevTime === time) ? time : _tinyNum // when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
if (this._yoyo && (this._cycle & 1) !== 0) {
this._time = time = 0
} else {
this._time = dur
time = dur + 0.0001 // to avoid occasional floating point rounding errors - sometimes child tweens/timelines were not being fully completed (their progress might be 0.999999999999998 instead of 1 because when _time - tween._startTime is performed, floating point errors would return a value that was SLIGHTLY off). Try (999999999999.7 - 999999999999) * 1 = 0.699951171875 instead of 0.7. We cannot do less then 0.0001 because the same issue can occur when the duration is extremely large like 999999999999 in which case adding 0.00000001, for example, causes it to act like nothing was added.
}
} else if (time < 0.0000001) { // to work around occasional floating point math artifacts, round super small values to 0.
if (!this._locked) {
this._totalTime = this._cycle = 0
}
this._time = 0
if (prevTime !== 0 || (dur === 0 && prevRawPrevTime !== _tinyNum && (prevRawPrevTime > 0 || (time < 0 && prevRawPrevTime >= 0)) && !this._locked)) { // edge case for checking time < 0 && prevRawPrevTime >= 0: a zero-duration fromTo() tween inside a zero-duration timeline (yeah, very rare)
callback = 'onReverseComplete'
isComplete = this._reversed
}
if (time < 0) {
this._active = false
if (this._timeline.autoRemoveChildren && this._reversed) {
internalForce = isComplete = true
callback = 'onReverseComplete'
} else if (prevRawPrevTime >= 0 && this._first) { // when going back beyond the start, force a render so that zero-duration tweens that sit at the very beginning render their start values properly. Otherwise, if the parent timeline's playhead lands exactly at this timeline's startTime, and then moves backwards, the zero-duration tweens at the beginning would still be at their end state.
internalForce = true
}
this._rawPrevTime = time
} else {
this._rawPrevTime = (dur || !suppressEvents || time || this._rawPrevTime === time) ? time : _tinyNum // when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
if (time === 0 && isComplete) { // if there's a zero-duration tween at the very beginning of a timeline and the playhead lands EXACTLY at time 0, that tween will correctly render its end values, but we need to keep the timeline alive for one more render so that the beginning values render properly as the parent's playhead keeps moving beyond the begining. Imagine obj.x starts at 0 and then we do tl.set(obj, {x:100}).to(obj, 1, {x:200}) and then later we tl.reverse()...the goal is to have obj.x revert to 0. If the playhead happens to land on exactly 0, without this chunk of code, it'd complete the timeline and remove it from the rendering queue (not good).
tween = this._first
while (tween && tween._startTime === 0) {
if (!tween._duration) {
isComplete = false
}
tween = tween._next
}
}
time = 0 // to avoid occasional floating point rounding errors (could cause problems especially with zero-duration tweens at the very beginning of the timeline)
if (!this._initted) {
internalForce = true
}
}
} else {
if (dur === 0 && prevRawPrevTime < 0) { // without this, zero-duration repeating timelines (like with a simple callback nested at the very beginning and a repeatDelay) wouldn't render the first time through.
internalForce = true
}
this._time = this._rawPrevTime = time
if (!this._locked) {
this._totalTime = time
if (this._repeat !== 0) {
cycleDuration = dur + this._repeatDelay
this._cycle = (this._totalTime / cycleDuration) >> 0 // originally _totalTime % cycleDuration but floating point errors caused problems, so I normalized it. (4 % 0.8 should be 0 but it gets reported as 0.79999999!)
if (this._cycle !== 0) {
if (this._cycle === this._totalTime / cycleDuration && prevTotalTime <= time) {
this._cycle-- // otherwise when rendered exactly at the end time, it will act as though it is repeating (at the beginning)
}
}
this._time = this._totalTime - (this._cycle * cycleDuration)
if (this._yoyo) {
if ((this._cycle & 1) !== 0) {
this._time = dur - this._time
}
}
if (this._time > dur) {
this._time = dur
time = dur + 0.0001 // to avoid occasional floating point rounding error
} else if (this._time < 0) {
this._time = time = 0
} else {
time = this._time
}
}
}
if (this._hasPause && !this._forcingPlayhead && !suppressEvents) {
time = this._time
if (time >= prevTime || (this._repeat && prevCycle !== this._cycle)) {
tween = this._first
while (tween && tween._startTime <= time && !pauseTween) {
if (!tween._duration) {
if (tween.data === 'isPause' && !tween.ratio && !(tween._startTime === 0 && this._rawPrevTime === 0)) {
pauseTween = tween
}
}
tween = tween._next
}
} else {
tween = this._last
while (tween && tween._startTime >= time && !pauseTween) {
if (!tween._duration) {
if (tween.data === 'isPause' && tween._rawPrevTime > 0) {
pauseTween = tween
}
}
tween = tween._prev
}
}
if (pauseTween && pauseTween._startTime < dur) {
this._time = time = pauseTween._startTime
this._totalTime = time + (this._cycle * (this._totalDuration + this._repeatDelay))
}
}
}
if (this._cycle !== prevCycle) {
if (!this._locked) {
/*
make sure children at the end/beginning of the timeline are rendered properly. If, for example,
a 3-second long timeline rendered at 2.9 seconds previously, and now renders at 3.2 seconds (which
would get transated to 2.8 seconds if the timeline yoyos or 0.2 seconds if it just repeats), there
could be a callback or a short tween that's at 2.95 or 3 seconds in which wouldn't render. So
we need to push the timeline to the end (and/or beginning depending on its yoyo value). Also we must
ensure that zero-duration tweens at the very beginning or end of the TimelineMax work.
*/
var backwards = (this._yoyo && (prevCycle & 1) !== 0),
wrap = (backwards === (this._yoyo && (this._cycle & 1) !== 0)),
recTotalTime = this._totalTime,
recCycle = this._cycle,
recRawPrevTime = this._rawPrevTime,
recTime = this._time
this._totalTime = prevCycle * dur
if (this._cycle < prevCycle) {
backwards = !backwards
} else {
this._totalTime += dur
}
this._time = prevTime // temporarily revert _time so that render() renders the children in the correct order. Without this, tweens won't rewind correctly. We could arhictect things in a "cleaner" way by splitting out the rendering queue into a separate method but for performance reasons, we kept it all inside this method.
this._rawPrevTime = (dur === 0) ? prevRawPrevTime - 0.0001 : prevRawPrevTime
this._cycle = prevCycle
this._locked = true // prevents changes to totalTime and skips repeat/yoyo behavior when we recursively call render()
prevTime = (backwards) ? 0 : dur
this.render(prevTime, suppressEvents, (dur === 0))
if (!suppressEvents) {
if (!this._gc) {
if (this.vars.onRepeat) {
this._cycle = recCycle // in case the onRepeat alters the playhead or invalidates(), we shouldn't stay locked or use the previous cycle.
this._locked = false
this._callback('onRepeat')
}
}
}
if (prevTime !== this._time) { // in case there's a callback like onComplete in a nested tween/timeline that changes the playhead position, like via seek(), we should just abort.
return
}
if (wrap) {
this._cycle = prevCycle // if there's an onRepeat, we reverted this above, so make sure it's set properly again. We also unlocked in that scenario, so reset that too.
this._locked = true
prevTime = (backwards) ? dur + 0.0001 : -0.0001
this.render(prevTime, true, false)
}
this._locked = false
if (this._paused && !prevPaused) { // if the render() triggered callback that paused this timeline, we should abort (very rare, but possible)
return
}
this._time = recTime
this._totalTime = recTotalTime
this._cycle = recCycle
this._rawPrevTime = recRawPrevTime
}
}
if ((this._time === prevTime || !this._first) && !force && !internalForce && !pauseTween) {
if (prevTotalTime !== this._totalTime) {
if (this._onUpdate) {
if (!suppressEvents) { // so that onUpdate fires even during the repeatDelay - as long as the totalTime changed, we should trigger onUpdate.
this._callback('onUpdate')
}
}
}
return
} else if (!this._initted) {
this._initted = true
}
if (!this._active) {
if (!this._paused && this._totalTime !== prevTotalTime && time > 0) {
this._active = true // so that if the user renders the timeline (as opposed to the parent timeline rendering it), it is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the timeline already finished but the user manually re-renders it as halfway done, for example.
}
}
if (prevTotalTime === 0) {
if (this.vars.onStart) {
if (this._totalTime !== 0 || !this._totalDuration) {
if (!suppressEvents) {
this._callback('onStart')
}
}
}
}
curTime = this._time
if (curTime >= prevTime) {
tween = this._first
while (tween) {
next = tween._next // record it here because the value could change after rendering...
if (curTime !== this._time || (this._paused && !prevPaused)) { // in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete
break
} else if (tween._active || (tween._startTime <= this._time && !tween._paused && !tween._gc)) {
if (pauseTween === tween) {
this.pause()
}
if (!tween._reversed) {
tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force)
} else {
tween.render(((!tween._dirty) ? tween._totalDuration : tween.totalDuration()) - ((time - tween._startTime) * tween._timeScale), suppressEvents, force)
}
}
tween = next
}
} else {
tween = this._last
while (tween) {
next = tween._prev // record it here because the value could change after rendering...
if (curTime !== this._time || (this._paused && !prevPaused)) { // in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete
break
} else if (tween._active || (tween._startTime <= prevTime && !tween._paused && !tween._gc)) {
if (pauseTween === tween) {
pauseTween = tween._prev // the linked list is organized by _startTime, thus it's possible that a tween could start BEFORE the pause and end after it, in which case it would be positioned before the pause tween in the linked list, but we should render it before we pause() the timeline and cease rendering. This is only a concern when going in reverse.
while (pauseTween && pauseTween.endTime() > this._time) {
pauseTween.render((pauseTween._reversed ? pauseTween.totalDuration() - ((time - pauseTween._startTime) * pauseTween._timeScale) : (time - pauseTween._startTime) * pauseTween._timeScale), suppressEvents, force)
pauseTween = pauseTween._prev
}
pauseTween = null
this.pause()
}
if (!tween._reversed) {
tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force)
} else {
tween.render(((!tween._dirty) ? tween._totalDuration : tween.totalDuration()) - ((time - tween._startTime) * tween._timeScale), suppressEvents, force)
}
}
tween = next
}
}
if (this._onUpdate) {
if (!suppressEvents) {
if (_lazyTweens.length) { // in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onUpdate on a timeline that reports/checks tweened values.
_lazyRender()
}
this._callback('onUpdate')
}
}
if (callback) {
if (!this._locked) {
if (!this._gc) {
if (prevStart === this._startTime || prevTimeScale !== this._timeScale) {
if (this._time === 0 || totalDur >= this.totalDuration()) { // if one of the tweens that was rendered altered this timeline's startTime (like if an onComplete reversed the timeline), it probably isn't complete. If it is, don't worry, because whatever call altered the startTime would complete if it was necessary at the new time. The only exception is the timeScale property. Also check _gc because there's a chance that kill() could be called in an onUpdate
if (isComplete) {
if (_lazyTweens.length) { // in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onComplete on a timeline that reports/checks tweened values.
_lazyRender()
}
if (this._timeline.autoRemoveChildren) {
this._enabled(false, false)
}
this._active = false
}
if (!suppressEvents && this.vars[callback]) {
this._callback(callback)
}
}
}
}
}
}
}
p.getActive = function (nested, tweens, timelines) {
if (nested == null) {
nested = true
}
if (tweens == null) {
tweens = true
}
if (timelines == null) {
timelines = false
}
var a = [],
all = this.getChildren(nested, tweens, timelines),
cnt = 0,
l = all.length,
i, tween
for (i = 0; i < l; i++) {
tween = all[i]
if (tween.isActive()) {
a[cnt++] = tween
}
}
return a
}
p.getLabelAfter = function (time) {
if (!time) {
if (time !== 0) { // faster than isNan()
time = this._time
}
}
var labels = this.getLabelsArray(),
l = labels.length,
i
for (i = 0; i < l; i++) {
if (labels[i].time > time) {
return labels[i].name
}
}
return null
}
p.getLabelBefore = function (time) {
if (time == null) {
time = this._time
}
var labels = this.getLabelsArray(),
i = labels.length
while (--i > -1) {
if (labels[i].time < time) {
return labels[i].name
}
}
return null
}
p.getLabelsArray = function () {
var a = [],
cnt = 0,
p
for (p in this._labels) {
a[cnt++] = {time: this._labels[p], name: p}
}
a.sort(function (a, b) {
return a.time - b.time
})
return a
}
p.invalidate = function () {
this._locked = false // unlock and set cycle in case invalidate() is called from inside an onRepeat
return TimelineLite.prototype.invalidate.call(this)
}
// ---- GETTERS / SETTERS -------------------------------------------------------------------------------------------------------
p.progress = function (value, suppressEvents) {
return (!arguments.length) ? (this._time / this.duration()) || 0 : this.totalTime(this.duration() * ((this._yoyo && (this._cycle & 1) !== 0) ? 1 - value : value) + (this._cycle * (this._duration + this._repeatDelay)), suppressEvents)
}
p.totalProgress = function (value, suppressEvents) {
return (!arguments.length) ? (this._totalTime / this.totalDuration()) || 0 : this.totalTime(this.totalDuration() * value, suppressEvents)
}
p.totalDuration = function (value) {
if (!arguments.length) {
if (this._dirty) {
TimelineLite.prototype.totalDuration.call(this) // just forces refresh
// Instead of Infinity, we use 999999999999 so that we can accommodate reverses.
this._totalDuration = (this._repeat === -1) ? 999999999999 : this._duration * (this._repeat + 1) + (this._repeatDelay * this._repeat)
}
return this._totalDuration
}
return (this._repeat === -1 || !value) ? this : this.timeScale(this.totalDuration() / value)
}
p.time = function (value, suppressEvents) {
if (!arguments.length) {
return this._time
}
if (this._dirty) {
this.totalDuration()
}
if (value > this._duration) {
value = this._duration
}
if (this._yoyo && (this._cycle & 1) !== 0) {
value = (this._duration - value) + (this._cycle * (this._duration + this._repeatDelay))
} else if (this._repeat !== 0) {
value += this._cycle * (this._duration + this._repeatDelay)
}
return this.totalTime(value, suppressEvents)
}
p.repeat = function (value) {
if (!arguments.length) {
return this._repeat
}
this._repeat = value
return this._uncache(true)
}
p.repeatDelay = function (value) {
if (!arguments.length) {
return this._repeatDelay
}
this._repeatDelay = value
return this._uncache(true)
}
p.yoyo = function (value) {
if (!arguments.length) {
return this._yoyo
}
this._yoyo = value
return this
}
p.currentLabel = function (value) {
if (!arguments.length) {
return this.getLabelBefore(this._time + 0.00000001)
}
return this.seek(value, true)
}
return TimelineMax
}, true);
/*
* ----------------------------------------------------------------
* BezierPlugin
* ----------------------------------------------------------------
*/
(function () {
var _RAD2DEG = 180 / Math.PI,
_r1 = [],
_r2 = [],
_r3 = [],
_corProps = {},
_globals = _gsScope._gsDefine.globals,
Segment = function (a, b, c, d) {
if (c === d) { // if c and d match, the final autoRotate value could lock at -90 degrees, so differentiate them slightly.
c = d - (d - b) / 1000000
}
if (a === b) { // if a and b match, the starting autoRotate value could lock at -90 degrees, so differentiate them slightly.
b = a + (c - a) / 1000000
}
this.a = a
this.b = b
this.c = c
this.d = d
this.da = d - a
this.ca = c - a
this.ba = b - a
},
_correlate = ',x,y,z,left,top,right,bottom,marginTop,marginLeft,marginRight,marginBottom,paddingLeft,paddingTop,paddingRight,paddingBottom,backgroundPosition,backgroundPosition_y,',
cubicToQuadratic = function (a, b, c, d) {
var q1 = {a: a},
q2 = {},
q3 = {},
q4 = {c: d},
mab = (a + b) / 2,
mbc = (b + c) / 2,
mcd = (c + d) / 2,
mabc = (mab + mbc) / 2,
mbcd = (mbc + mcd) / 2,
m8 = (mbcd - mabc) / 8
q1.b = mab + (a - mab) / 4
q2.b = mabc + m8
q1.c = q2.a = (q1.b + q2.b) / 2
q2.c = q3.a = (mabc + mbcd) / 2
q3.b = mbcd - m8
q4.b = mcd + (d - mcd) / 4
q3.c = q4.a = (q3.b + q4.b) / 2
return [q1, q2, q3, q4]
},
_calculateControlPoints = function (a, curviness, quad, basic, correlate) {
var l = a.length - 1,
ii = 0,
cp1 = a[0].a,
i, p1, p2, p3, seg, m1, m2, mm, cp2, qb, r1, r2, tl
for (i = 0; i < l; i++) {
seg = a[ii]
p1 = seg.a
p2 = seg.d
p3 = a[ii + 1].d
if (correlate) {
r1 = _r1[i]
r2 = _r2[i]
tl = ((r2 + r1) * curviness * 0.25) / (basic ? 0.5 : _r3[i] || 0.5)
m1 = p2 - (p2 - p1) * (basic ? curviness * 0.5 : (r1 !== 0 ? tl / r1 : 0))
m2 = p2 + (p3 - p2) * (basic ? curviness * 0.5 : (r2 !== 0 ? tl / r2 : 0))
mm = p2 - (m1 + (((m2 - m1) * ((r1 * 3 / (r1 + r2)) + 0.5) / 4) || 0))
} else {
m1 = p2 - (p2 - p1) * curviness * 0.5
m2 = p2 + (p3 - p2) * curviness * 0.5
mm = p2 - (m1 + m2) / 2
}
m1 += mm
m2 += mm
seg.c = cp2 = m1
if (i !== 0) {
seg.b = cp1
} else {
seg.b = cp1 = seg.a + (seg.c - seg.a) * 0.6 // instead of placing b on a exactly, we move it inline with c so that if the user specifies an ease like Back.easeIn or Elastic.easeIn which goes BEYOND the beginning, it will do so smoothly.
}
seg.da = p2 - p1
seg.ca = cp2 - p1
seg.ba = cp1 - p1
if (quad) {
qb = cubicToQuadratic(p1, cp1, cp2, p2)
a.splice(ii, 1, qb[0], qb[1], qb[2], qb[3])
ii += 4
} else {
ii++
}
cp1 = m2
}
seg = a[ii]
seg.b = cp1
seg.c = cp1 + (seg.d - cp1) * 0.4 // instead of placing c on d exactly, we move it inline with b so that if the user specifies an ease like Back.easeOut or Elastic.easeOut which goes BEYOND the end, it will do so smoothly.
seg.da = seg.d - seg.a
seg.ca = seg.c - seg.a
seg.ba = cp1 - seg.a
if (quad) {
qb = cubicToQuadratic(seg.a, cp1, seg.c, seg.d)
a.splice(ii, 1, qb[0], qb[1], qb[2], qb[3])
}
},
_parseAnchors = function (values, p, correlate, prepend) {
var a = [],
l, i, p1, p2, p3, tmp
if (prepend) {
values = [prepend].concat(values)
i = values.length
while (--i > -1) {
if (typeof ((tmp = values[i][p])) === 'string') {
if (tmp.charAt(1) === '=') {
values[i][p] = prepend[p] + Number(tmp.charAt(0) + tmp.substr(2)) // accommodate relative values. Do it inline instead of breaking it out into a function for speed reasons
}
}
}
}
l = values.length - 2
if (l < 0) {
a[0] = new Segment(values[0][p], 0, 0, values[0][p])
return a
}
for (i = 0; i < l; i++) {
p1 = values[i][p]
p2 = values[i + 1][p]
a[i] = new Segment(p1, 0, 0, p2)
if (correlate) {
p3 = values[i + 2][p]
_r1[i] = (_r1[i] || 0) + (p2 - p1) * (p2 - p1)
_r2[i] = (_r2[i] || 0) + (p3 - p2) * (p3 - p2)
}
}
a[i] = new Segment(values[i][p], 0, 0, values[i + 1][p])
return a
},
bezierThrough = function (values, curviness, quadratic, basic, correlate, prepend) {
var obj = {},
props = [],
first = prepend || values[0],
i, p, a, j, r, l, seamless, last
correlate = (typeof (correlate) === 'string') ? ',' + correlate + ',' : _correlate
if (curviness == null) {
curviness = 1
}
for (p in values[0]) {
props.push(p)
}
// check to see if the last and first values are identical (well, within 0.05). If so, make seamless by appending the second element to the very end of the values array and the 2nd-to-last element to the very beginning (we'll remove those segments later)
if (values.length > 1) {
last = values[values.length - 1]
seamless = true
i = props.length
while (--i > -1) {
p = props[i]
if (Math.abs(first[p] - last[p]) > 0.05) { // build in a tolerance of +/-0.05 to accommodate rounding errors.
seamless = false
break
}
}
if (seamless) {
values = values.concat() // duplicate the array to avoid contaminating the original which the user may be reusing for other tweens
if (prepend) {
values.unshift(prepend)
}
values.push(values[1])
prepend = values[values.length - 3]
}
}
_r1.length = _r2.length = _r3.length = 0
i = props.length
while (--i > -1) {
p = props[i]
_corProps[p] = (correlate.indexOf(',' + p + ',') !== -1)
obj[p] = _parseAnchors(values, p, _corProps[p], prepend)
}
i = _r1.length
while (--i > -1) {
_r1[i] = Math.sqrt(_r1[i])
_r2[i] = Math.sqrt(_r2[i])
}
if (!basic) {
i = props.length
while (--i > -1) {
if (_corProps[p]) {
a = obj[props[i]]
l = a.length - 1
for (j = 0; j < l; j++) {
r = (a[j + 1].da / _r2[j] + a[j].da / _r1[j]) || 0
_r3[j] = (_r3[j] || 0) + r * r
}
}
}
i = _r3.length
while (--i > -1) {
_r3[i] = Math.sqrt(_r3[i])
}
}
i = props.length
j = quadratic ? 4 : 1
while (--i > -1) {
p = props[i]
a = obj[p]
_calculateControlPoints(a, curviness, quadratic, basic, _corProps[p]) // this method requires that _parseAnchors() and _setSegmentRatios() ran first so that _r1, _r2, and _r3 values are populated for all properties
if (seamless) {
a.splice(0, j)
a.splice(a.length - j, j)
}
}
return obj
},
_parseBezierData = function (values, type, prepend) {
type = type || 'soft'
var obj = {},
inc = (type === 'cubic') ? 3 : 2,
soft = (type === 'soft'),
props = [],
a, b, c, d, cur, i, j, l, p, cnt, tmp
if (soft && prepend) {
values = [prepend].concat(values)
}
if (values == null || values.length < inc + 1) { throw 'invalid Bezier data' }
for (p in values[0]) {
props.push(p)
}
i = props.length
while (--i > -1) {
p = props[i]
obj[p] = cur = []
cnt = 0
l = values.length
for (j = 0; j < l; j++) {
a = (prepend == null) ? values[j][p] : (typeof ((tmp = values[j][p])) === 'string' && tmp.charAt(1) === '=') ? prepend[p] + Number(tmp.charAt(0) + tmp.substr(2)) : Number(tmp)
if (soft) {
if (j > 1) {
if (j < l - 1) {
cur[cnt++] = (a + cur[cnt - 2]) / 2
}
}
}
cur[cnt++] = a
}
l = cnt - inc + 1
cnt = 0
for (j = 0; j < l; j += inc) {
a = cur[j]
b = cur[j + 1]
c = cur[j + 2]
d = (inc === 2) ? 0 : cur[j + 3]
cur[cnt++] = tmp = (inc === 3) ? new Segment(a, b, c, d) : new Segment(a, (2 * b + a) / 3, (2 * b + c) / 3, c)
}
cur.length = cnt
}
return obj
},
_addCubicLengths = function (a, steps, resolution) {
var inc = 1 / resolution,
j = a.length,
d, d1, s, da, ca, ba, p, i, inv, bez, index
while (--j > -1) {
bez = a[j]
s = bez.a
da = bez.d - s
ca = bez.c - s
ba = bez.b - s
d = d1 = 0
for (i = 1; i <= resolution; i++) {
p = inc * i
inv = 1 - p
d = d1 - (d1 = (p * p * da + 3 * inv * (p * ca + inv * ba)) * p)
index = j * resolution + i - 1
steps[index] = (steps[index] || 0) + d * d
}
}
},
_parseLengthData = function (obj, resolution) {
resolution = resolution >> 0 || 6
var a = [],
lengths = [],
d = 0,
total = 0,
threshold = resolution - 1,
segments = [],
curLS = [], // current length segments array
p, i, l, index
for (p in obj) {
_addCubicLengths(obj[p], a, resolution)
}
l = a.length
for (i = 0; i < l; i++) {
d += Math.sqrt(a[i])
index = i % resolution
curLS[index] = d
if (index === threshold) {
total += d
index = (i / resolution) >> 0
segments[index] = curLS
lengths[index] = total
d = 0
curLS = []
}
}
return {length: total, lengths: lengths, segments: segments}
},
BezierPlugin = _gsScope._gsDefine.plugin({
propName: 'bezier',
priority: -1,
version: '1.3.8',
API: 2,
global: true,
// gets called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run.
init: function (target, vars, tween) {
this._target = target
if (vars instanceof Array) {
vars = {values: vars}
}
this._func = {}
this._mod = {}
this._props = []
this._timeRes = (vars.timeResolution == null) ? 6 : parseInt(vars.timeResolution, 10)
var values = vars.values || [],
first = {},
second = values[0],
autoRotate = vars.autoRotate || tween.vars.orientToBezier,
p, isFunc, i, j, prepend
this._autoRotate = autoRotate ? (autoRotate instanceof Array) ? autoRotate : [['x', 'y', 'rotation', ((autoRotate === true) ? 0 : Number(autoRotate) || 0)]] : null
for (p in second) {
this._props.push(p)
}
i = this._props.length
while (--i > -1) {
p = this._props[i]
this._overwriteProps.push(p)
isFunc = this._func[p] = (typeof (target[p]) === 'function')
first[p] = (!isFunc) ? parseFloat(target[p]) : target[ ((p.indexOf('set') || typeof (target['get' + p.substr(3)]) !== 'function') ? p : 'get' + p.substr(3)) ]()
if (!prepend) {
if (first[p] !== values[0][p]) {
prepend = first
}
}
}
this._beziers = (vars.type !== 'cubic' && vars.type !== 'quadratic' && vars.type !== 'soft') ? bezierThrough(values, isNaN(vars.curviness) ? 1 : vars.curviness, false, (vars.type === 'thruBasic'), vars.correlate, prepend) : _parseBezierData(values, vars.type, first)
this._segCount = this._beziers[p].length
if (this._timeRes) {
var ld = _parseLengthData(this._beziers, this._timeRes)
this._length = ld.length
this._lengths = ld.lengths
this._segments = ld.segments
this._l1 = this._li = this._s1 = this._si = 0
this._l2 = this._lengths[0]
this._curSeg = this._segments[0]
this._s2 = this._curSeg[0]
this._prec = 1 / this._curSeg.length
}
if ((autoRotate = this._autoRotate)) {
this._initialRotations = []
if (!(autoRotate[0] instanceof Array)) {
this._autoRotate = autoRotate = [autoRotate]
}
i = autoRotate.length
while (--i > -1) {
for (j = 0; j < 3; j++) {
p = autoRotate[i][j]
this._func[p] = (typeof (target[p]) === 'function') ? target[ ((p.indexOf('set') || typeof (target['get' + p.substr(3)]) !== 'function') ? p : 'get' + p.substr(3)) ] : false
}
p = autoRotate[i][2]
this._initialRotations[i] = (this._func[p] ? this._func[p].call(this._target) : this._target[p]) || 0
this._overwriteProps.push(p)
}
}
this._startRatio = tween.vars.runBackwards ? 1 : 0 // we determine the starting ratio when the tween inits which is always 0 unless the tween has runBackwards:true (indicating it's a from() tween) in which case it's 1.
return true
},
// called each time the values should be updated, and the ratio gets passed as the only parameter (typically it's a value between 0 and 1, but it can exceed those when using an ease like Elastic.easeOut or Back.easeOut, etc.)
set: function (v) {
var segments = this._segCount,
func = this._func,
target = this._target,
notStart = (v !== this._startRatio),
curIndex, inv, i, p, b, t, val, l, lengths, curSeg
if (!this._timeRes) {
curIndex = (v < 0) ? 0 : (v >= 1) ? segments - 1 : (segments * v) >> 0
t = (v - (curIndex * (1 / segments))) * segments
} else {
lengths = this._lengths
curSeg = this._curSeg
v *= this._length
i = this._li
// find the appropriate segment (if the currently cached one isn't correct)
if (v > this._l2 && i < segments - 1) {
l = segments - 1
while (i < l && (this._l2 = lengths[++i]) <= v) { }
this._l1 = lengths[i - 1]
this._li = i
this._curSeg = curSeg = this._segments[i]
this._s2 = curSeg[(this._s1 = this._si = 0)]
} else if (v < this._l1 && i > 0) {
while (i > 0 && (this._l1 = lengths[--i]) >= v) { }
if (i === 0 && v < this._l1) {
this._l1 = 0
} else {
i++
}
this._l2 = lengths[i]
this._li = i
this._curSeg = curSeg = this._segments[i]
this._s1 = curSeg[(this._si = curSeg.length - 1) - 1] || 0
this._s2 = curSeg[this._si]
}
curIndex = i
// now find the appropriate sub-segment (we split it into the number of pieces that was defined by "precision" and measured each one)
v -= this._l1
i = this._si
if (v > this._s2 && i < curSeg.length - 1) {
l = curSeg.length - 1
while (i < l && (this._s2 = curSeg[++i]) <= v) { }
this._s1 = curSeg[i - 1]
this._si = i
} else if (v < this._s1 && i > 0) {
while (i > 0 && (this._s1 = curSeg[--i]) >= v) { }
if (i === 0 && v < this._s1) {
this._s1 = 0
} else {
i++
}
this._s2 = curSeg[i]
this._si = i
}
t = ((i + (v - this._s1) / (this._s2 - this._s1)) * this._prec) || 0
}
inv = 1 - t
i = this._props.length
while (--i > -1) {
p = this._props[i]
b = this._beziers[p][curIndex]
val = (t * t * b.da + 3 * inv * (t * b.ca + inv * b.ba)) * t + b.a
if (this._mod[p]) {
val = this._mod[p](val, target)
}
if (func[p]) {
target[p](val)
} else {
target[p] = val
}
}
if (this._autoRotate) {
var ar = this._autoRotate,
b2, x1, y1, x2, y2, add, conv
i = ar.length
while (--i > -1) {
p = ar[i][2]
add = ar[i][3] || 0
conv = (ar[i][4] === true) ? 1 : _RAD2DEG
b = this._beziers[ar[i][0]]
b2 = this._beziers[ar[i][1]]
if (b && b2) { // in case one of the properties got overwritten.
b = b[curIndex]
b2 = b2[curIndex]
x1 = b.a + (b.b - b.a) * t
x2 = b.b + (b.c - b.b) * t
x1 += (x2 - x1) * t
x2 += ((b.c + (b.d - b.c) * t) - x2) * t
y1 = b2.a + (b2.b - b2.a) * t
y2 = b2.b + (b2.c - b2.b) * t
y1 += (y2 - y1) * t
y2 += ((b2.c + (b2.d - b2.c) * t) - y2) * t
val = notStart ? Math.atan2(y2 - y1, x2 - x1) * conv + add : this._initialRotations[i]
if (this._mod[p]) {
val = this._mod[p](val, target) // for modProps
}
if (func[p]) {
target[p](val)
} else {
target[p] = val
}
}
}
}
}
}),
p = BezierPlugin.prototype
BezierPlugin.bezierThrough = bezierThrough
BezierPlugin.cubicToQuadratic = cubicToQuadratic
BezierPlugin._autoCSS = true // indicates that this plugin can be inserted into the "css" object using the autoCSS feature of TweenLite
BezierPlugin.quadraticToCubic = function (a, b, c) {
return new Segment(a, (2 * b + a) / 3, (2 * b + c) / 3, c)
}
BezierPlugin._cssRegister = function () {
var CSSPlugin = _globals.CSSPlugin
if (!CSSPlugin) {
return
}
var _internals = CSSPlugin._internals,
_parseToProxy = _internals._parseToProxy,
_setPluginRatio = _internals._setPluginRatio,
CSSPropTween = _internals.CSSPropTween
_internals._registerComplexSpecialProp('bezier', {parser: function (t, e, prop, cssp, pt, plugin) {
if (e instanceof Array) {
e = {values: e}
}
plugin = new BezierPlugin()
var values = e.values,
l = values.length - 1,
pluginValues = [],
v = {},
i, p, data
if (l < 0) {
return pt
}
for (i = 0; i <= l; i++) {
data = _parseToProxy(t, values[i], cssp, pt, plugin, (l !== i))
pluginValues[i] = data.end
}
for (p in e) {
v[p] = e[p] // duplicate the vars object because we need to alter some things which would cause problems if the user plans to reuse the same vars object for another tween.
}
v.values = pluginValues
pt = new CSSPropTween(t, 'bezier', 0, 0, data.pt, 2)
pt.data = data
pt.plugin = plugin
pt.setRatio = _setPluginRatio
if (v.autoRotate === 0) {
v.autoRotate = true
}
if (v.autoRotate && !(v.autoRotate instanceof Array)) {
i = (v.autoRotate === true) ? 0 : Number(v.autoRotate)
v.autoRotate = (data.end.left != null) ? [['left', 'top', 'rotation', i, false]] : (data.end.x != null) ? [['x', 'y', 'rotation', i, false]] : false
}
if (v.autoRotate) {
if (!cssp._transform) {
cssp._enableTransforms(false)
}
data.autoRotate = cssp._target._gsTransform
data.proxy.rotation = data.autoRotate.rotation || 0
cssp._overwriteProps.push('rotation')
}
plugin._onInitTween(data.proxy, v, cssp._tween)
return pt
}})
}
p._mod = function (lookup) {
var op = this._overwriteProps,
i = op.length,
val
while (--i > -1) {
val = lookup[op[i]]
if (val && typeof (val) === 'function') {
this._mod[op[i]] = val
}
}
}
p._kill = function (lookup) {
var a = this._props,
p, i
for (p in this._beziers) {
if (p in lookup) {
delete this._beziers[p]
delete this._func[p]
i = a.length
while (--i > -1) {
if (a[i] === p) {
a.splice(i, 1)
}
}
}
}
a = this._autoRotate
if (a) {
i = a.length
while (--i > -1) {
if (lookup[a[i][2]]) {
a.splice(i, 1)
}
}
}
return this._super._kill.call(this, lookup)
}
}())
/*
* ----------------------------------------------------------------
* CSSPlugin
* ----------------------------------------------------------------
*/
_gsScope._gsDefine('plugins.CSSPlugin', ['plugins.TweenPlugin', 'TweenLite'], function (TweenPlugin, TweenLite) {
/** @constructor **/
var CSSPlugin = function () {
TweenPlugin.call(this, 'css')
this._overwriteProps.length = 0
this.setRatio = CSSPlugin.prototype.setRatio // speed optimization (avoid prototype lookup on this "hot" method)
},
_globals = _gsScope._gsDefine.globals,
_hasPriority, // turns true whenever a CSSPropTween instance is created that has a priority other than 0. This helps us discern whether or not we should spend the time organizing the linked list or not after a CSSPlugin's _onInitTween() method is called.
_suffixMap, // we set this in _onInitTween() each time as a way to have a persistent variable we can use in other methods like _parse() without having to pass it around as a parameter and we keep _parse() decoupled from a particular CSSPlugin instance
_cs, // computed style (we store this in a shared variable to conserve memory and make minification tighter
_overwriteProps, // alias to the currently instantiating CSSPlugin's _overwriteProps array. We use this closure in order to avoid having to pass a reference around from method to method and aid in minification.
_specialProps = {},
p = CSSPlugin.prototype = new TweenPlugin('css')
p.constructor = CSSPlugin
CSSPlugin.version = '1.20.0'
CSSPlugin.API = 2
CSSPlugin.defaultTransformPerspective = 0
CSSPlugin.defaultSkewType = 'compensated'
CSSPlugin.defaultSmoothOrigin = true
p = 'px' // we'll reuse the "p" variable to keep file size down
CSSPlugin.suffixMap = {top: p, right: p, bottom: p, left: p, width: p, height: p, fontSize: p, padding: p, margin: p, perspective: p, lineHeight: ''}
var _numExp = /(?:\-|\.|\b)(\d|\.|e\-)+/g,
_relNumExp = /(?:\d|\-\d|\.\d|\-\.\d|\+=\d|\-=\d|\+=.\d|\-=\.\d)+/g,
_valuesExp = /(?:\+=|\-=|\-|\b)[\d\-\.]+[a-zA-Z0-9]*(?:%|\b)/gi, // finds all the values that begin with numbers or += or -= and then a number. Includes suffixes. We use this to split complex values apart like "1px 5px 20px rgb(255,102,51)"
_NaNExp = /(?![+-]?\d*\.?\d+|[+-]|e[+-]\d+)[^0-9]/g, // also allows scientific notation and doesn't kill the leading -/+ in -= and +=
_suffixExp = /(?:\d|\-|\+|=|#|\.)*/g,
_opacityExp = /opacity *= *([^)]*)/i,
_opacityValExp = /opacity:([^;]*)/i,
_alphaFilterExp = /alpha\(opacity *=.+?\)/i,
_rgbhslExp = /^(rgb|hsl)/,
_capsExp = /([A-Z])/g,
_camelExp = /-([a-z])/gi,
_urlExp = /(^(?:url\(\"|url\())|(?:(\"\))$|\)$)/gi, // for pulling out urls from url(...) or url("...") strings (some browsers wrap urls in quotes, some don't when reporting things like backgroundImage)
_camelFunc = function (s, g) { return g.toUpperCase() },
_horizExp = /(?:Left|Right|Width)/i,
_ieGetMatrixExp = /(M11|M12|M21|M22)=[\d\-\.e]+/gi,
_ieSetMatrixExp = /progid\:DXImageTransform\.Microsoft\.Matrix\(.+?\)/i,
_commasOutsideParenExp = /,(?=[^\)]*(?:\(|$))/gi, // finds any commas that are not within parenthesis
_complexExp = /[\s,\(]/i, // for testing a string to find if it has a space, comma, or open parenthesis (clues that it's a complex value)
_DEG2RAD = Math.PI / 180,
_RAD2DEG = 180 / Math.PI,
_forcePT = {},
_dummyElement = {style: {}},
_doc = _gsScope.document || {createElement: function () { return _dummyElement }},
_createElement = function (type, ns) {
return _doc.createElementNS ? _doc.createElementNS(ns || 'http://www.w3.org/1999/xhtml', type) : _doc.createElement(type)
},
_tempDiv = _createElement('div'),
_tempImg = _createElement('img'),
_internals = CSSPlugin._internals = {_specialProps: _specialProps}, // provides a hook to a few internal methods that we need to access from inside other plugins
_agent = (_gsScope.navigator || {}).userAgent || '',
_autoRound,
_reqSafariFix, // we won't apply the Safari transform fix until we actually come across a tween that affects a transform property (to maintain best performance).
_isSafari,
_isFirefox, // Firefox has a bug that causes 3D transformed elements to randomly disappear unless a repaint is forced after each update on each element.
_isSafariLT6, // Safari (and Android 4 which uses a flavor of Safari) has a bug that prevents changes to "top" and "left" properties from rendering properly if changed on the same frame as a transform UNLESS we set the element's WebkitBackfaceVisibility to hidden (weird, I know). Doing this for Android 3 and earlier seems to actually cause other problems, though (fun!)
_ieVers,
_supportsOpacity = (function () { // we set _isSafari, _ieVers, _isFirefox, and _supportsOpacity all in one function here to reduce file size slightly, especially in the minified version.
var i = _agent.indexOf('Android'),
a = _createElement('a')
_isSafari = (_agent.indexOf('Safari') !== -1 && _agent.indexOf('Chrome') === -1 && (i === -1 || parseFloat(_agent.substr(i + 8, 2)) > 3))
_isSafariLT6 = (_isSafari && (parseFloat(_agent.substr(_agent.indexOf('Version/') + 8, 2)) < 6))
_isFirefox = (_agent.indexOf('Firefox') !== -1)
if ((/MSIE ([0-9]{1,}[\.0-9]{0,})/).exec(_agent) || (/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/).exec(_agent)) {
_ieVers = parseFloat(RegExp.$1)
}
if (!a) {
return false
}
a.style.cssText = 'top:1px;opacity:.55;'
return /^0.55/.test(a.style.opacity)
}()),
_getIEOpacity = function (v) {
return (_opacityExp.test(((typeof (v) === 'string') ? v : (v.currentStyle ? v.currentStyle.filter : v.style.filter) || '')) ? (parseFloat(RegExp.$1) / 100) : 1)
},
_log = function (s) { // for logging messages, but in a way that won't throw errors in old versions of IE.
if (_gsScope.console) {
console.log(s)
}
},
_target, // when initting a CSSPlugin, we set this variable so that we can access it from within many other functions without having to pass it around as params
_index, // when initting a CSSPlugin, we set this variable so that we can access it from within many other functions without having to pass it around as params
_prefixCSS = '', // the non-camelCase vendor prefix like "-o-", "-moz-", "-ms-", or "-webkit-"
_prefix = '', // camelCase vendor prefix like "O", "ms", "Webkit", or "Moz".
// @private feed in a camelCase property name like "transform" and it will check to see if it is valid as-is or if it needs a vendor prefix. It returns the corrected camelCase property name (i.e. "WebkitTransform" or "MozTransform" or "transform" or null if no such property is found, like if the browser is IE8 or before, "transform" won't be found at all)
_checkPropPrefix = function (p, e) {
e = e || _tempDiv
var s = e.style,
a, i
if (s[p] !== undefined) {
return p
}
p = p.charAt(0).toUpperCase() + p.substr(1)
a = ['O', 'Moz', 'ms', 'Ms', 'Webkit']
i = 5
while (--i > -1 && s[a[i] + p] === undefined) { }
if (i >= 0) {
_prefix = (i === 3) ? 'ms' : a[i]
_prefixCSS = '-' + _prefix.toLowerCase() + '-'
return _prefix + p
}
return null
},
_getComputedStyle = _doc.defaultView ? _doc.defaultView.getComputedStyle : function () {},
/**
* @private Returns the css style for a particular property of an element. For example, to get whatever the current "left" css value for an element with an ID of "myElement", you could do:
* var currentLeft = CSSPlugin.getStyle( document.getElementById("myElement"), "left");
*
* @param {!Object} t Target element whose style property you want to query
* @param {!string} p Property name (like "left" or "top" or "marginTop", etc.)
* @param {Object=} cs Computed style object. This just provides a way to speed processing if you're going to get several properties on the same element in quick succession - you can reuse the result of the getComputedStyle() call.
* @param {boolean=} calc If true, the value will not be read directly from the element's "style" property (if it exists there), but instead the getComputedStyle() result will be used. This can be useful when you want to ensure that the browser itself is interpreting the value.
* @param {string=} dflt Default value that should be returned in the place of null, "none", "auto" or "auto auto".
* @return {?string} The current property value
*/
_getStyle = CSSPlugin.getStyle = function (t, p, cs, calc, dflt) {
var rv
if (!_supportsOpacity) {
if (p === 'opacity') { // several versions of IE don't use the standard "opacity" property - they use things like filter:alpha(opacity=50), so we parse that here.
return _getIEOpacity(t)
}
}
if (!calc && t.style[p]) {
rv = t.style[p]
} else if ((cs = cs || _getComputedStyle(t))) {
rv = cs[p] || cs.getPropertyValue(p) || cs.getPropertyValue(p.replace(_capsExp, '-$1').toLowerCase())
} else if (t.currentStyle) {
rv = t.currentStyle[p]
}
return (dflt != null && (!rv || rv === 'none' || rv === 'auto' || rv === 'auto auto')) ? dflt : rv
},
/**
* @private Pass the target element, the property name, the numeric value, and the suffix (like "%", "em", "px", etc.) and it will spit back the equivalent pixel number.
* @param {!Object} t Target element
* @param {!string} p Property name (like "left", "top", "marginLeft", etc.)
* @param {!number} v Value
* @param {string=} sfx Suffix (like "px" or "%" or "em")
* @param {boolean=} recurse If true, the call is a recursive one. In some browsers (like IE7/8), occasionally the value isn't accurately reported initially, but if we run the function again it will take effect.
* @return {number} value in pixels
*/
_convertToPixels = _internals.convertToPixels = function (t, p, v, sfx, recurse) {
if (sfx === 'px' || (!sfx && p !== 'lineHeight')) { return v }
if (sfx === 'auto' || !v) { return 0 }
var horiz = _horizExp.test(p),
node = t,
style = _tempDiv.style,
neg = (v < 0),
precise = (v === 1),
pix, cache, time
if (neg) {
v = -v
}
if (precise) {
v *= 100
}
if (p === 'lineHeight' && !sfx) { // special case of when a simple lineHeight (without a unit) is used. Set it to the value, read back the computed value, and then revert.
cache = _getComputedStyle(t).lineHeight
t.style.lineHeight = v
pix = parseFloat(_getComputedStyle(t).lineHeight)
t.style.lineHeight = cache
} else if (sfx === '%' && p.indexOf('border') !== -1) {
pix = (v / 100) * (horiz ? t.clientWidth : t.clientHeight)
} else {
style.cssText = 'border:0 solid red;position:' + _getStyle(t, 'position') + ';line-height:0;'
if (sfx === '%' || !node.appendChild || sfx.charAt(0) === 'v' || sfx === 'rem') {
node = t.parentNode || _doc.body
if (_getStyle(node, 'display').indexOf('flex') !== -1) { // Edge and IE11 have a bug that causes offsetWidth to report as 0 if the container has display:flex and the child is position:relative. Switching to position: absolute solves it.
style.position = 'absolute'
}
cache = node._gsCache
time = TweenLite.ticker.frame
if (cache && horiz && cache.time === time) { // performance optimization: we record the width of elements along with the ticker frame so that we can quickly get it again on the same tick (seems relatively safe to assume it wouldn't change on the same tick)
return cache.width * v / 100
}
style[(horiz ? 'width' : 'height')] = v + sfx
} else {
style[(horiz ? 'borderLeftWidth' : 'borderTopWidth')] = v + sfx
}
node.appendChild(_tempDiv)
pix = parseFloat(_tempDiv[(horiz ? 'offsetWidth' : 'offsetHeight')])
node.removeChild(_tempDiv)
if (horiz && sfx === '%' && CSSPlugin.cacheWidths !== false) {
cache = node._gsCache = node._gsCache || {}
cache.time = time
cache.width = pix / v * 100
}
if (pix === 0 && !recurse) {
pix = _convertToPixels(t, p, v, sfx, true)
}
}
if (precise) {
pix /= 100
}
return neg ? -pix : pix
},
_calculateOffset = _internals.calculateOffset = function (t, p, cs) { // for figuring out "top" or "left" in px when it's "auto". We need to factor in margin with the offsetLeft/offsetTop
if (_getStyle(t, 'position', cs) !== 'absolute') { return 0 }
var dim = ((p === 'left') ? 'Left' : 'Top'),
v = _getStyle(t, 'margin' + dim, cs)
return t['offset' + dim] - (_convertToPixels(t, p, parseFloat(v), v.replace(_suffixExp, '')) || 0)
},
// @private returns at object containing ALL of the style properties in camelCase and their associated values.
_getAllStyles = function (t, cs) {
var s = {},
i, tr, p
if ((cs = cs || _getComputedStyle(t, null))) {
if ((i = cs.length)) {
while (--i > -1) {
p = cs[i]
if (p.indexOf('-transform') === -1 || _transformPropCSS === p) { // Some webkit browsers duplicate transform values, one non-prefixed and one prefixed ("transform" and "WebkitTransform"), so we must weed out the extra one here.
s[p.replace(_camelExp, _camelFunc)] = cs.getPropertyValue(p)
}
}
} else { // some browsers behave differently - cs.length is always 0, so we must do a for...in loop.
for (i in cs) {
if (i.indexOf('Transform') === -1 || _transformProp === i) { // Some webkit browsers duplicate transform values, one non-prefixed and one prefixed ("transform" and "WebkitTransform"), so we must weed out the extra one here.
s[i] = cs[i]
}
}
}
} else if ((cs = t.currentStyle || t.style)) {
for (i in cs) {
if (typeof (i) === 'string' && s[i] === undefined) {
s[i.replace(_camelExp, _camelFunc)] = cs[i]
}
}
}
if (!_supportsOpacity) {
s.opacity = _getIEOpacity(t)
}
tr = _getTransform(t, cs, false)
s.rotation = tr.rotation
s.skewX = tr.skewX
s.scaleX = tr.scaleX
s.scaleY = tr.scaleY
s.x = tr.x
s.y = tr.y
if (_supports3D) {
s.z = tr.z
s.rotationX = tr.rotationX
s.rotationY = tr.rotationY
s.scaleZ = tr.scaleZ
}
if (s.filters) {
delete s.filters
}
return s
},
// @private analyzes two style objects (as returned by _getAllStyles()) and only looks for differences between them that contain tweenable values (like a number or color). It returns an object with a "difs" property which refers to an object containing only those isolated properties and values for tweening, and a "firstMPT" property which refers to the first MiniPropTween instance in a linked list that recorded all the starting values of the different properties so that we can revert to them at the end or beginning of the tween - we don't want the cascading to get messed up. The forceLookup parameter is an optional generic object with properties that should be forced into the results - this is necessary for className tweens that are overwriting others because imagine a scenario where a rollover/rollout adds/removes a class and the user swipes the mouse over the target SUPER fast, thus nothing actually changed yet and the subsequent comparison of the properties would indicate they match (especially when px rounding is taken into consideration), thus no tweening is necessary even though it SHOULD tween and remove those properties after the tween (otherwise the inline styles will contaminate things). See the className SpecialProp code for details.
_cssDif = function (t, s1, s2, vars, forceLookup) {
var difs = {},
style = t.style,
val, p, mpt
for (p in s2) {
if (p !== 'cssText') {
if (p !== 'length') {
if (isNaN(p)) {
if (s1[p] !== (val = s2[p]) || (forceLookup && forceLookup[p])) {
if (p.indexOf('Origin') === -1) {
if (typeof (val) === 'number' || typeof (val) === 'string') {
difs[p] = (val === 'auto' && (p === 'left' || p === 'top')) ? _calculateOffset(t, p) : ((val === '' || val === 'auto' || val === 'none') && typeof (s1[p]) === 'string' && s1[p].replace(_NaNExp, '') !== '') ? 0 : val // if the ending value is defaulting ("" or "auto"), we check the starting value and if it can be parsed into a number (a string which could have a suffix too, like 700px), then we swap in 0 for "" or "auto" so that things actually tween.
if (style[p] !== undefined) { // for className tweens, we must remember which properties already existed inline - the ones that didn't should be removed when the tween isn't in progress because they were only introduced to facilitate the transition between classes.
mpt = new MiniPropTween(style, p, style[p], mpt)
}
}
}
}
}
}
}
}
if (vars) {
for (p in vars) { // copy properties (except className)
if (p !== 'className') {
difs[p] = vars[p]
}
}
}
return {difs: difs, firstMPT: mpt}
},
_dimensions = {width: ['Left', 'Right'], height: ['Top', 'Bottom']},
_margins = ['marginLeft', 'marginRight', 'marginTop', 'marginBottom'],
/**
* @private Gets the width or height of an element
* @param {!Object} t Target element
* @param {!string} p Property name ("width" or "height")
* @param {Object=} cs Computed style object (if one exists). Just a speed optimization.
* @return {number} Dimension (in pixels)
*/
_getDimension = function (t, p, cs) {
if ((t.nodeName + '').toLowerCase() === 'svg') { // Chrome no longer supports offsetWidth/offsetHeight on SVG elements.
return (cs || _getComputedStyle(t))[p] || 0
} else if (t.getCTM && _isSVG(t)) {
return t.getBBox()[p] || 0
}
var v = parseFloat((p === 'width') ? t.offsetWidth : t.offsetHeight),
a = _dimensions[p],
i = a.length
cs = cs || _getComputedStyle(t, null)
while (--i > -1) {
v -= parseFloat(_getStyle(t, 'padding' + a[i], cs, true)) || 0
v -= parseFloat(_getStyle(t, 'border' + a[i] + 'Width', cs, true)) || 0
}
return v
},
// @private Parses position-related complex strings like "top left" or "50px 10px" or "70% 20%", etc. which are used for things like transformOrigin or backgroundPosition. Optionally decorates a supplied object (recObj) with the following properties: "ox" (offsetX), "oy" (offsetY), "oxp" (if true, "ox" is a percentage not a pixel value), and "oxy" (if true, "oy" is a percentage not a pixel value)
_parsePosition = function (v, recObj) {
if (v === 'contain' || v === 'auto' || v === 'auto auto') { // note: Firefox uses "auto auto" as default whereas Chrome uses "auto".
return v + ' '
}
if (v == null || v === '') {
v = '0 0'
}
var a = v.split(' '),
x = (v.indexOf('left') !== -1) ? '0%' : (v.indexOf('right') !== -1) ? '100%' : a[0],
y = (v.indexOf('top') !== -1) ? '0%' : (v.indexOf('bottom') !== -1) ? '100%' : a[1],
i
if (a.length > 3 && !recObj) { // multiple positions
a = v.split(', ').join(',').split(',')
v = []
for (i = 0; i < a.length; i++) {
v.push(_parsePosition(a[i]))
}
return v.join(',')
}
if (y == null) {
y = (x === 'center') ? '50%' : '0'
} else if (y === 'center') {
y = '50%'
}
if (x === 'center' || (isNaN(parseFloat(x)) && (x + '').indexOf('=') === -1)) { // remember, the user could flip-flop the values and say "bottom center" or "center bottom", etc. "center" is ambiguous because it could be used to describe horizontal or vertical, hence the isNaN(). If there's an "=" sign in the value, it's relative.
x = '50%'
}
v = x + ' ' + y + ((a.length > 2) ? ' ' + a[2] : '')
if (recObj) {
recObj.oxp = (x.indexOf('%') !== -1)
recObj.oyp = (y.indexOf('%') !== -1)
recObj.oxr = (x.charAt(1) === '=')
recObj.oyr = (y.charAt(1) === '=')
recObj.ox = parseFloat(x.replace(_NaNExp, ''))
recObj.oy = parseFloat(y.replace(_NaNExp, ''))
recObj.v = v
}
return recObj || v
},
/**
* @private Takes an ending value (typically a string, but can be a number) and a starting value and returns the change between the two, looking for relative value indicators like += and -= and it also ignores suffixes (but make sure the ending value starts with a number or +=/-= and that the starting value is a NUMBER!)
* @param {(number|string)} e End value which is typically a string, but could be a number
* @param {(number|string)} b Beginning value which is typically a string but could be a number
* @return {number} Amount of change between the beginning and ending values (relative values that have a "+=" or "-=" are recognized)
*/
_parseChange = function (e, b) {
if (typeof (e) === 'function') {
e = e(_index, _target)
}
return (typeof (e) === 'string' && e.charAt(1) === '=') ? parseInt(e.charAt(0) + '1', 10) * parseFloat(e.substr(2)) : (parseFloat(e) - parseFloat(b)) || 0
},
/**
* @private Takes a value and a default number, checks if the value is relative, null, or numeric and spits back a normalized number accordingly. Primarily used in the _parseTransform() function.
* @param {Object} v Value to be parsed
* @param {!number} d Default value (which is also used for relative calculations if "+=" or "-=" is found in the first parameter)
* @return {number} Parsed value
*/
_parseVal = function (v, d) {
if (typeof (v) === 'function') {
v = v(_index, _target)
}
return (v == null) ? d : (typeof (v) === 'string' && v.charAt(1) === '=') ? parseInt(v.charAt(0) + '1', 10) * parseFloat(v.substr(2)) + d : parseFloat(v) || 0
},
/**
* @private Translates strings like "40deg" or "40" or 40rad" or "+=40deg" or "270_short" or "-90_cw" or "+=45_ccw" to a numeric radian angle. Of course a starting/default value must be fed in too so that relative values can be calculated properly.
* @param {Object} v Value to be parsed
* @param {!number} d Default value (which is also used for relative calculations if "+=" or "-=" is found in the first parameter)
* @param {string=} p property name for directionalEnd (optional - only used when the parsed value is directional ("_short", "_cw", or "_ccw" suffix). We need a way to store the uncompensated value so that at the end of the tween, we set it to exactly what was requested with no directional compensation). Property name would be "rotation", "rotationX", or "rotationY"
* @param {Object=} directionalEnd An object that will store the raw end values for directional angles ("_short", "_cw", or "_ccw" suffix). We need a way to store the uncompensated value so that at the end of the tween, we set it to exactly what was requested with no directional compensation.
* @return {number} parsed angle in radians
*/
_parseAngle = function (v, d, p, directionalEnd) {
var min = 0.000001,
cap, split, dif, result, isRelative
if (typeof (v) === 'function') {
v = v(_index, _target)
}
if (v == null) {
result = d
} else if (typeof (v) === 'number') {
result = v
} else {
cap = 360
split = v.split('_')
isRelative = (v.charAt(1) === '=')
dif = (isRelative ? parseInt(v.charAt(0) + '1', 10) * parseFloat(split[0].substr(2)) : parseFloat(split[0])) * ((v.indexOf('rad') === -1) ? 1 : _RAD2DEG) - (isRelative ? 0 : d)
if (split.length) {
if (directionalEnd) {
directionalEnd[p] = d + dif
}
if (v.indexOf('short') !== -1) {
dif = dif % cap
if (dif !== dif % (cap / 2)) {
dif = (dif < 0) ? dif + cap : dif - cap
}
}
if (v.indexOf('_cw') !== -1 && dif < 0) {
dif = ((dif + cap * 9999999999) % cap) - ((dif / cap) | 0) * cap
} else if (v.indexOf('ccw') !== -1 && dif > 0) {
dif = ((dif - cap * 9999999999) % cap) - ((dif / cap) | 0) * cap
}
}
result = d + dif
}
if (result < min && result > -min) {
result = 0
}
return result
},
_colorLookup = {aqua: [0, 255, 255],
lime: [0, 255, 0],
silver: [192, 192, 192],
black: [0, 0, 0],
maroon: [128, 0, 0],
teal: [0, 128, 128],
blue: [0, 0, 255],
navy: [0, 0, 128],
white: [255, 255, 255],
fuchsia: [255, 0, 255],
olive: [128, 128, 0],
yellow: [255, 255, 0],
orange: [255, 165, 0],
gray: [128, 128, 128],
purple: [128, 0, 128],
green: [0, 128, 0],
red: [255, 0, 0],
pink: [255, 192, 203],
cyan: [0, 255, 255],
transparent: [255, 255, 255, 0]},
_hue = function (h, m1, m2) {
h = (h < 0) ? h + 1 : (h > 1) ? h - 1 : h
return ((((h * 6 < 1) ? m1 + (m2 - m1) * h * 6 : (h < 0.5) ? m2 : (h * 3 < 2) ? m1 + (m2 - m1) * (2 / 3 - h) * 6 : m1) * 255) + 0.5) | 0
},
/**
* @private Parses a color (like #9F0, #FF9900, rgb(255,51,153) or hsl(108, 50%, 10%)) into an array with 3 elements for red, green, and blue or if toHSL parameter is true, it will populate the array with hue, saturation, and lightness values. If a relative value is found in an hsl() or hsla() string, it will preserve those relative prefixes and all the values in the array will be strings instead of numbers (in all other cases it will be populated with numbers).
* @param {(string|number)} v The value the should be parsed which could be a string like #9F0 or rgb(255,102,51) or rgba(255,0,0,0.5) or it could be a number like 0xFF00CC or even a named color like red, blue, purple, etc.
* @param {(boolean)} toHSL If true, an hsl() or hsla() value will be returned instead of rgb() or rgba()
* @return {Array.<number>} An array containing red, green, and blue (and optionally alpha) in that order, or if the toHSL parameter was true, the array will contain hue, saturation and lightness (and optionally alpha) in that order. Always numbers unless there's a relative prefix found in an hsl() or hsla() string and toHSL is true.
*/
_parseColor = CSSPlugin.parseColor = function (v, toHSL) {
var a, r, g, b, h, s, l, max, min, d, wasHSL
if (!v) {
a = _colorLookup.black
} else if (typeof (v) === 'number') {
a = [v >> 16, (v >> 8) & 255, v & 255]
} else {
if (v.charAt(v.length - 1) === ',') { // sometimes a trailing comma is included and we should chop it off (typically from a comma-delimited list of values like a textShadow:"2px 2px 2px blue, 5px 5px 5px rgb(255,0,0)" - in this example "blue," has a trailing comma. We could strip it out inside parseComplex() but we'd need to do it to the beginning and ending values plus it wouldn't provide protection from other potential scenarios like if the user passes in a similar value.
v = v.substr(0, v.length - 1)
}
if (_colorLookup[v]) {
a = _colorLookup[v]
} else if (v.charAt(0) === '#') {
if (v.length === 4) { // for shorthand like #9F0
r = v.charAt(1)
g = v.charAt(2)
b = v.charAt(3)
v = '#' + r + r + g + g + b + b
}
v = parseInt(v.substr(1), 16)
a = [v >> 16, (v >> 8) & 255, v & 255]
} else if (v.substr(0, 3) === 'hsl') {
a = wasHSL = v.match(_numExp)
if (!toHSL) {
h = (Number(a[0]) % 360) / 360
s = Number(a[1]) / 100
l = Number(a[2]) / 100
g = (l <= 0.5) ? l * (s + 1) : l + s - l * s
r = l * 2 - g
if (a.length > 3) {
a[3] = Number(v[3])
}
a[0] = _hue(h + 1 / 3, r, g)
a[1] = _hue(h, r, g)
a[2] = _hue(h - 1 / 3, r, g)
} else if (v.indexOf('=') !== -1) { // if relative values are found, just return the raw strings with the relative prefixes in place.
return v.match(_relNumExp)
}
} else {
a = v.match(_numExp) || _colorLookup.transparent
}
a[0] = Number(a[0])
a[1] = Number(a[1])
a[2] = Number(a[2])
if (a.length > 3) {
a[3] = Number(a[3])
}
}
if (toHSL && !wasHSL) {
r = a[0] / 255
g = a[1] / 255
b = a[2] / 255
max = Math.max(r, g, b)
min = Math.min(r, g, b)
l = (max + min) / 2
if (max === min) {
h = s = 0
} else {
d = max - min
s = l > 0.5 ? d / (2 - max - min) : d / (max + min)
h = (max === r) ? (g - b) / d + (g < b ? 6 : 0) : (max === g) ? (b - r) / d + 2 : (r - g) / d + 4
h *= 60
}
a[0] = (h + 0.5) | 0
a[1] = (s * 100 + 0.5) | 0
a[2] = (l * 100 + 0.5) | 0
}
return a
},
_formatColors = function (s, toHSL) {
var colors = s.match(_colorExp) || [],
charIndex = 0,
parsed = '',
i, color, temp
if (!colors.length) {
return s
}
for (i = 0; i < colors.length; i++) {
color = colors[i]
temp = s.substr(charIndex, s.indexOf(color, charIndex) - charIndex)
charIndex += temp.length + color.length
color = _parseColor(color, toHSL)
if (color.length === 3) {
color.push(1)
}
parsed += temp + (toHSL ? 'hsla(' + color[0] + ',' + color[1] + '%,' + color[2] + '%,' + color[3] : 'rgba(' + color.join(',')) + ')'
}
return parsed + s.substr(charIndex)
},
_colorExp = '(?:\\b(?:(?:rgb|rgba|hsl|hsla)\\(.+?\\))|\\B#(?:[0-9a-f]{3}){1,2}\\b' // we'll dynamically build this Regular Expression to conserve file size. After building it, it will be able to find rgb(), rgba(), # (hexadecimal), and named color values like red, blue, purple, etc.
for (p in _colorLookup) {
_colorExp += '|' + p + '\\b'
}
_colorExp = new RegExp(_colorExp + ')', 'gi')
CSSPlugin.colorStringFilter = function (a) {
var combined = a[0] + ' ' + a[1],
toHSL
if (_colorExp.test(combined)) {
toHSL = (combined.indexOf('hsl(') !== -1 || combined.indexOf('hsla(') !== -1)
a[0] = _formatColors(a[0], toHSL)
a[1] = _formatColors(a[1], toHSL)
}
_colorExp.lastIndex = 0
}
if (!TweenLite.defaultStringFilter) {
TweenLite.defaultStringFilter = CSSPlugin.colorStringFilter
}
/**
* @private Returns a formatter function that handles taking a string (or number in some cases) and returning a consistently formatted one in terms of delimiters, quantity of values, etc. For example, we may get boxShadow values defined as "0px red" or "0px 0px 10px rgb(255,0,0)" or "0px 0px 20px 20px #F00" and we need to ensure that what we get back is described with 4 numbers and a color. This allows us to feed it into the _parseComplex() method and split the values up appropriately. The neat thing about this _getFormatter() function is that the dflt defines a pattern as well as a default, so for example, _getFormatter("0px 0px 0px 0px #777", true) not only sets the default as 0px for all distances and #777 for the color, but also sets the pattern such that 4 numbers and a color will always get returned.
* @param {!string} dflt The default value and pattern to follow. So "0px 0px 0px 0px #777" will ensure that 4 numbers and a color will always get returned.
* @param {boolean=} clr If true, the values should be searched for color-related data. For example, boxShadow values typically contain a color whereas borderRadius don't.
* @param {boolean=} collapsible If true, the value is a top/left/right/bottom style one that acts like margin or padding, where if only one value is received, it's used for all 4; if 2 are received, the first is duplicated for 3rd (bottom) and the 2nd is duplicated for the 4th spot (left), etc.
* @return {Function} formatter function
*/
var _getFormatter = function (dflt, clr, collapsible, multi) {
if (dflt == null) {
return function (v) { return v }
}
var dColor = clr ? (dflt.match(_colorExp) || [''])[0] : '',
dVals = dflt.split(dColor).join('').match(_valuesExp) || [],
pfx = dflt.substr(0, dflt.indexOf(dVals[0])),
sfx = (dflt.charAt(dflt.length - 1) === ')') ? ')' : '',
delim = (dflt.indexOf(' ') !== -1) ? ' ' : ',',
numVals = dVals.length,
dSfx = (numVals > 0) ? dVals[0].replace(_numExp, '') : '',
formatter
if (!numVals) {
return function (v) { return v }
}
if (clr) {
formatter = function (v) {
var color, vals, i, a
if (typeof (v) === 'number') {
v += dSfx
} else if (multi && _commasOutsideParenExp.test(v)) {
a = v.replace(_commasOutsideParenExp, '|').split('|')
for (i = 0; i < a.length; i++) {
a[i] = formatter(a[i])
}
return a.join(',')
}
color = (v.match(_colorExp) || [dColor])[0]
vals = v.split(color).join('').match(_valuesExp) || []
i = vals.length
if (numVals > i--) {
while (++i < numVals) {
vals[i] = collapsible ? vals[(((i - 1) / 2) | 0)] : dVals[i]
}
}
return pfx + vals.join(delim) + delim + color + sfx + (v.indexOf('inset') !== -1 ? ' inset' : '')
}
return formatter
}
formatter = function (v) {
var vals, a, i
if (typeof (v) === 'number') {
v += dSfx
} else if (multi && _commasOutsideParenExp.test(v)) {
a = v.replace(_commasOutsideParenExp, '|').split('|')
for (i = 0; i < a.length; i++) {
a[i] = formatter(a[i])
}
return a.join(',')
}
vals = v.match(_valuesExp) || []
i = vals.length
if (numVals > i--) {
while (++i < numVals) {
vals[i] = collapsible ? vals[(((i - 1) / 2) | 0)] : dVals[i]
}
}
return pfx + vals.join(delim) + sfx
}
return formatter
},
/**
* @private returns a formatter function that's used for edge-related values like marginTop, marginLeft, paddingBottom, paddingRight, etc. Just pass a comma-delimited list of property names related to the edges.
* @param {!string} props a comma-delimited list of property names in order from top to left, like "marginTop,marginRight,marginBottom,marginLeft"
* @return {Function} a formatter function
*/
_getEdgeParser = function (props) {
props = props.split(',')
return function (t, e, p, cssp, pt, plugin, vars) {
var a = (e + '').split(' '),
i
vars = {}
for (i = 0; i < 4; i++) {
vars[props[i]] = a[i] = a[i] || a[(((i - 1) / 2) >> 0)]
}
return cssp.parse(t, vars, pt, plugin)
}
},
// @private used when other plugins must tween values first, like BezierPlugin or ThrowPropsPlugin, etc. That plugin's setRatio() gets called first so that the values are updated, and then we loop through the MiniPropTweens which handle copying the values into their appropriate slots so that they can then be applied correctly in the main CSSPlugin setRatio() method. Remember, we typically create a proxy object that has a bunch of uniquely-named properties that we feed to the sub-plugin and it does its magic normally, and then we must interpret those values and apply them to the css because often numbers must get combined/concatenated, suffixes added, etc. to work with css, like boxShadow could have 4 values plus a color.
_setPluginRatio = _internals._setPluginRatio = function (v) {
this.plugin.setRatio(v)
var d = this.data,
proxy = d.proxy,
mpt = d.firstMPT,
min = 0.000001,
val, pt, i, str, p
while (mp
gitextract_2t0s81jl/ ├── .babelrc ├── .editorconfig ├── .eslintignore ├── .eslintrc.json ├── .github/ │ ├── FUNDING.yml │ └── ISSUE_TEMPLATE/ │ ├── bug_report.md │ ├── feature_request.md │ └── regular-issue.md ├── .gitignore ├── .npmignore ├── .prettierrc ├── .travis.yml ├── API.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── examples/ │ ├── basic.html │ └── test.html ├── jsdoc.json ├── package.json ├── performance/ │ ├── TweenMax.js │ ├── es6-tween.html │ ├── gsap.html │ ├── kute.html │ └── kute.js ├── rollup.config.js ├── src/ │ ├── Easing.js │ ├── Interpolation.js │ ├── Interpolator.js │ ├── NodeCache.js │ ├── PlaybackPosition.js │ ├── Timeline.js │ ├── Tween.js │ ├── constants.js │ ├── core.js │ ├── index.js │ ├── selector.js │ └── shim.js ├── test.js └── withPage.js
SYMBOL INDEX (117 symbols across 8 files)
FILE: src/Easing.js
method None (line 11) | None (k) {
method In (line 17) | In (k) {
method Out (line 21) | Out (k) {
method InOut (line 25) | InOut (k) {
method In (line 35) | In (k) {
method Out (line 39) | Out (k) {
method InOut (line 43) | InOut (k) {
method In (line 53) | In (k) {
method Out (line 57) | Out (k) {
method InOut (line 61) | InOut (k) {
method In (line 71) | In (k) {
method Out (line 75) | Out (k) {
method InOut (line 79) | InOut (k) {
method In (line 89) | In (k) {
method Out (line 93) | Out (k) {
method InOut (line 97) | InOut (k) {
method In (line 103) | In (k) {
method Out (line 107) | Out (k) {
method InOut (line 111) | InOut (k) {
method In (line 129) | In (k) {
method Out (line 133) | Out (k) {
method InOut (line 137) | InOut (k) {
method In (line 147) | In (k) {
method Out (line 159) | Out (k) {
method InOut (line 171) | InOut (k) {
method In (line 191) | In (k) {
method Out (line 197) | Out (k) {
method InOut (line 203) | InOut (k) {
method In (line 215) | In (k) {
method Out (line 219) | Out (k) {
method InOut (line 233) | InOut (k) {
FILE: src/Interpolation.js
method Linear (line 14) | Linear (v, k, value) {
method Bezier (line 29) | Bezier (v, k, value) {
method CatmullRom (line 70) | CatmullRom (v, k, value) {
method Linear (line 96) | Linear (p0, p1, t, v) {
method Reset (line 136) | Reset (value) {
method Bernstein (line 153) | Bernstein (n, i) {
method CatmullRom (line 178) | CatmullRom (p0, p1, p2, p3, t, v) {
FILE: src/PlaybackPosition.js
class PlaybackPosition (line 1) | class PlaybackPosition {
method constructor (line 2) | constructor () {
method parseLabel (line 7) | parseLabel (name, offset) {
method addLabel (line 40) | addLabel (name, offset) {
method setLabel (line 45) | setLabel (name, offset) {
method eraseLabel (line 52) | eraseLabel (name) {
FILE: src/Timeline.js
class Timeline (line 41) | class Timeline extends Tween {
method constructor (line 42) | constructor (params) {
method mapTotal (line 57) | mapTotal (fn) {
method timingOrder (line 61) | timingOrder (fn) {
method getTiming (line 68) | getTiming (mode, nodes, params, offset = 0) {
method fromTo (line 101) | fromTo (nodes, from, to, params) {
method from (line 141) | from (nodes, from, params) {
method to (line 153) | to (nodes, to, params) {
method addLabel (line 164) | addLabel (name, offset) {
method map (line 169) | map (fn) {
method add (line 185) | add (tween, position) {
method restart (line 218) | restart () {
method easing (line 226) | easing (easing) {
method interpolation (line 230) | interpolation (interpolation) {
method update (line 234) | update (time) {
method progress (line 325) | progress (value) {
FILE: src/Tween.js
class Tween (line 40) | class Tween {
method fromTo (line 51) | static fromTo (node, object, to, params = {}) {
method to (line 70) | static to (node, to, params) {
method from (line 82) | static from (node, from, params) {
method constructor (line 85) | constructor (node, object) {
method setMaxListener (line 126) | setMaxListener (count = 15) {
method on (line 137) | on (event, callback) {
method once (line 157) | once (event, callback) {
method off (line 179) | off (event, callback) {
method emit (line 196) | emit (event, arg1, arg2, arg3) {
method isPlaying (line 217) | isPlaying () {
method isStarted (line 226) | isStarted () {
method reverse (line 236) | reverse (state) {
method reversed (line 249) | reversed () {
method pause (line 258) | pause () {
method play (line 276) | play () {
method restart (line 297) | restart (noDelay) {
method seek (line 314) | seek (time, keepPlaying) {
method duration (line 339) | duration (amount) {
method to (line 352) | to (properties, duration = 1000, maybeUsed) {
method render (line 376) | render () {
method start (line 472) | start (time) {
method stop (line 491) | stop () {
method delay (line 518) | delay (amount) {
method chainedTweens (line 530) | chainedTweens () {
method repeat (line 548) | repeat (amount) {
method reverseDelay (line 562) | reverseDelay (amount) {
method yoyo (line 575) | yoyo (state, _easingReverse) {
method easing (line 591) | easing (_easingFunction) {
method interpolation (line 603) | interpolation (_interpolationFunction) {
method reassignValues (line 616) | reassignValues (time) {
method update (line 642) | update (time, preserve, forceTime) {
FILE: src/constants.js
constant FRAME_MS (line 2) | const FRAME_MS = 50 / 3
constant TOO_LONG_FRAME_MS (line 3) | const TOO_LONG_FRAME_MS = 250
constant CHAINED_TWEENS (line 5) | const CHAINED_TWEENS = '_chainedTweens'
constant EVENT_CALLBACK (line 8) | const EVENT_CALLBACK = 'Callback'
constant EVENT_UPDATE (line 9) | const EVENT_UPDATE = 'update'
constant EVENT_COMPLETE (line 10) | const EVENT_COMPLETE = 'complete'
constant EVENT_START (line 11) | const EVENT_START = 'start'
constant EVENT_REPEAT (line 12) | const EVENT_REPEAT = 'repeat'
constant EVENT_REVERSE (line 13) | const EVENT_REVERSE = 'reverse'
constant EVENT_PAUSE (line 14) | const EVENT_PAUSE = 'pause'
constant EVENT_PLAY (line 15) | const EVENT_PLAY = 'play'
constant EVENT_RESTART (line 16) | const EVENT_RESTART = 'restart'
constant EVENT_STOP (line 17) | const EVENT_STOP = 'stop'
constant EVENT_SEEK (line 18) | const EVENT_SEEK = 'seek'
constant STRING_PROP (line 21) | const STRING_PROP = 'STRING_PROP'
constant NUM_REGEX (line 23) | const NUM_REGEX = /\s+|([A-Za-z?().,{}:""[\]#%]+)|([-+]=+)?([-+]+)?(?:\d...
function deepCopy (line 26) | function deepCopy (source) {
function decomposeString (line 61) | function decomposeString (fromValue) {
function decompose (line 80) | function decompose (prop, obj, from, to) {
constant RGB (line 151) | const RGB = 'rgb('
constant RGBA (line 152) | const RGBA = 'rgba('
function recompose (line 156) | function recompose (prop, obj, from, to, t, originalT, stringBuffer) {
FILE: test.js
method get (line 68) | get () {
method set (line 71) | set (x) {
FILE: withPage.js
function describe (line 7) | function describe (jsHandle) {
Condensed preview — 41 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (578K chars).
[
{
"path": ".babelrc",
"chars": 287,
"preview": "{\n \"exclude\": [\"node_modules/**\", \"bundled/**\", \"performance/**\", \"logo/**\", \"examples/**\"],\n \"presets\": [\n [\n "
},
{
"path": ".editorconfig",
"chars": 0,
"preview": ""
},
{
"path": ".eslintignore",
"chars": 147,
"preview": "# /node_modules/* and /bower_components/* in the project root are ignored by default\n\n# Ignore\n.github/*\nbundled/*\nexamp"
},
{
"path": ".eslintrc.json",
"chars": 319,
"preview": "{\n \"env\": {\n \"browser\": true,\n \"es6\": true,\n \"node\": true\n },\n \"extends\": \"standard\",\n "
},
{
"path": ".github/FUNDING.yml",
"chars": 666,
"preview": "# These are supported funding model platforms\n\n# github: dalisoft\npatreon: dalisoft # Replace with a single Patreon user"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 834,
"preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Describe the b"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 595,
"preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Is your fea"
},
{
"path": ".github/ISSUE_TEMPLATE/regular-issue.md",
"chars": 696,
"preview": "---\nname: Regular issue\nabout: For regular issue\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n|Issue name|Issue description|"
},
{
"path": ".gitignore",
"chars": 103,
"preview": "dist/\ndocs/\nfull/\nbundled/\nlite/\nguide_notes/\nnode_modules/\nnpm-debug.log\nyarn-error.log\n.vscode\n.idea\n"
},
{
"path": ".npmignore",
"chars": 193,
"preview": ".gitignore\n.git\n.github\nbower.json\ntsconfig.json\ntslint.json\nassets\ndocs\nexamples\nlogo\nperformance\nguide_notes\nCONTRIBUT"
},
{
"path": ".prettierrc",
"chars": 136,
"preview": "{\n \"singleQuote\": true,\n \"printWidth\": 120,\n \"trailingComma\": \"es5\",\n \"arrowParens\": \"always\",\n \"bracketS"
},
{
"path": ".travis.yml",
"chars": 157,
"preview": "language: node_js\ncache:\n directories:\n - node_modules\nnotifications:\n email: false\nnode_js:\n - '12'\nbefore_script"
},
{
"path": "API.md",
"chars": 19966,
"preview": "<a name=\"TWEEN\"></a>\n\n## TWEEN : <code>object</code>\nLightweight, effecient and modular ES6 version of tween.js\n\n**Kind*"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 3213,
"preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
},
{
"path": "CONTRIBUTING.md",
"chars": 1211,
"preview": "# CONTRIBUTING\n\n## Before reporting a bug\n\n---\n\nIf you find something that you believe to be a bug, please\n\n1. search th"
},
{
"path": "LICENSE",
"chars": 1092,
"preview": "MIT License\n\nCopyright (c) 2018 tween.js and es6-tween contributors\n\nPermission is hereby granted, free of charge, to an"
},
{
"path": "README.md",
"chars": 7031,
"preview": "# es6-tween\n\n## This project development suspended due of no support from community and no financial support to author\n\n"
},
{
"path": "examples/basic.html",
"chars": 1068,
"preview": "<!DOCTYPE html>\n<html>\n<head>\n<title>Tween.js - Basic Demo</title>\n<meta name=\"viewport\" content=\"width=device-width, in"
},
{
"path": "examples/test.html",
"chars": 1895,
"preview": "<html>\n\n<head>\n\t<meta charset=\"UTF-8\">\n\t<meta name=\"viewport\" content=\"width=device-width, minimum-scale=1.0\">\n\t<title>e"
},
{
"path": "jsdoc.json",
"chars": 650,
"preview": "{\n \"tags\": {\n \"allowUnknownTags\": true,\n \"dictionaries\": [\n \"jsdoc\"\n ]\n },\n \"so"
},
{
"path": "package.json",
"chars": 2078,
"preview": "{\n \"name\": \"es6-tween\",\n \"version\": \"5.5.11\",\n \"description\": \"ES6 implementation of amazing tween.js\",\n \"browser\": "
},
{
"path": "performance/TweenMax.js",
"chars": 394024,
"preview": "/*!\n * VERSION: 1.20.2\n * DATE: 2017-06-30\n * UPDATES AND DOCS AT: http://greensock.com\n *\n * Includes all of the follow"
},
{
"path": "performance/es6-tween.html",
"chars": 1950,
"preview": "<html>\n\n<head>\n\t<meta charset=\"UTF-8\">\n\t<meta name=\"viewport\" content=\"width=device-width, minimum-scale=1.0\">\n\t<title>e"
},
{
"path": "performance/gsap.html",
"chars": 1630,
"preview": "<html>\n\n<head>\n\t<meta charset=\"UTF-8\">\n\t<meta name=\"viewport\" content=\"width=device-width, minimum-scale=1.0\">\n\t<title>G"
},
{
"path": "performance/kute.html",
"chars": 1675,
"preview": "<html>\n\n<head>\n\t<meta charset=\"UTF-8\">\n\t<meta name=\"viewport\" content=\"width=device-width, minimum-scale=1.0\">\n\t<title>K"
},
{
"path": "performance/kute.js",
"chars": 41495,
"preview": "/* KUTE.js - The Light Tweening Engine\n * by dnp_theme\n * Licensed under MIT-License\n */\n(function (root, factory) {\n i"
},
{
"path": "rollup.config.js",
"chars": 230,
"preview": "import babel from 'rollup-plugin-babel'\n\nexport default {\n input: 'src/index.js',\n output: {\n format: 'umd',\n fi"
},
{
"path": "src/Easing.js",
"chars": 4032,
"preview": "/**\n * List of full easings\n * @namespace TWEEN.Easing\n * @example\n * import {Tween, Easing} from 'es6-tween'\n *\n * // t"
},
{
"path": "src/Interpolation.js",
"chars": 6222,
"preview": "import { isRGBColor, RGBA, STRING_PROP } from './constants'\n\n/**\n * List of full Interpolation\n * @namespace TWEEN.Inter"
},
{
"path": "src/Interpolator.js",
"chars": 1581,
"preview": "import { decompose, recompose, decomposeString } from './constants'\n\n/**\n * Tween helper for plugins\n * @namespace TWEEN"
},
{
"path": "src/NodeCache.js",
"chars": 1061,
"preview": "import { remove } from './core'\n\nexport const Store = {}\nexport default function (node, object, tween) {\n if (!node || "
},
{
"path": "src/PlaybackPosition.js",
"chars": 1728,
"preview": "export default class PlaybackPosition {\n constructor () {\n this.totalTime = 0\n this.labels = []\n this.offsets "
},
{
"path": "src/Timeline.js",
"chars": 8862,
"preview": "import { add, now, remove, isRunning, isLagSmoothing } from './core'\nimport PlaybackPosition from './PlaybackPosition'\ni"
},
{
"path": "src/Tween.js",
"chars": 21843,
"preview": "import { add, now, Plugins, remove, isRunning, isLagSmoothing } from './core'\nimport Easing from './Easing'\nimport Inter"
},
{
"path": "src/constants.js",
"chars": 9778,
"preview": "// Frame lag-fix constants\nexport const FRAME_MS = 50 / 3\nexport const TOO_LONG_FRAME_MS = 250\n\nexport const CHAINED_TWE"
},
{
"path": "src/core.js",
"chars": 6097,
"preview": "/* global process */\nimport { requestAnimationFrame, cancelAnimationFrame, root } from './shim'\n\n/**\n * Get browser/Node"
},
{
"path": "src/index.js",
"chars": 730,
"preview": "import {\n add,\n onTick,\n autoPlay,\n get,\n getAll,\n has,\n isRunning,\n now,\n onRequestTick,\n FrameThrottle,\n To"
},
{
"path": "src/selector.js",
"chars": 918,
"preview": "export default function (selector, collection, allowRaw) {\n if (!selector) {\n return null\n }\n\n const isGlobalScope"
},
{
"path": "src/shim.js",
"chars": 455,
"preview": "/* global global, self */\nexport let root =\n typeof self !== 'undefined'\n ? self\n : typeof window !== 'undefined'"
},
{
"path": "test.js",
"chars": 11793,
"preview": "/* global TWEEN */\n\nimport test from 'ava'\n\nimport { Easing, Tween, Timeline, update, getAll, removeAll } from './src'\n\n"
},
{
"path": "withPage.js",
"chars": 976,
"preview": "import puppeteer from 'puppeteer'\n\nconst fs = require('fs')\nconst path = require('path')\n\n// Parse\nfunction describe (js"
}
]
About this extraction
This page contains the full source code of the tweenjs/es6-tween GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 41 files (546.3 KB), approximately 152.1k tokens, and a symbol index with 117 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.