Commit 5c08d5d2 authored by JetLu's avatar JetLu 🚴🏻

add: composite

parent 218a062d
This diff is collapsed.
......@@ -17,7 +17,7 @@ npm i git+ssh://git@gitlab2.dui88.com:lufei/moto.git
## 文档
```js
import {curve, tween, easing} from 'moto'
import {curve, tween, easing, composite, utils} from 'moto'
// 二次贝塞尔曲线
curve.bezier({
......@@ -61,6 +61,22 @@ const anime = tween({
})
setTimeout(() => anime.stop(), 2e3)
// 组合模式
composite({
position: curve.bezier({
p1: {x: 0, y: 0},
p2: {x: 50, y: 50},
p3: {x: 100, y: 0},
duration: 1,
ease: easing.easeInOut
}),
scale: tween({from: 1, to: 2}),
color: tween({from: utils.hex2rgb(0xff33cc), to: utils.hex2rgb(0xffcc33)})
}).start(v => {
const {position, scale, color} = v
//...
})
```
**`curve.bezier(options)`**
......@@ -72,6 +88,16 @@ options`{object}`:
- duration: 动画持续时间(单位:`s`),默认 `1`
- ease: 时间函数,默认 `easing.linear`
**`curve.cubicBezier(options)`**
options`{object}`:
- p1: 起始点 `{x, y}`
- p2: 控制点 `{x, y}`
- p3: 控制点 `{x, y}`
- p4: 结束点 `{x, y}`
- duration: 动画持续时间(单位:`s`),默认 `1`
- ease: 时间函数,默认 `easing.linear`
**`curve.catmullRom(points, [v])`**
- points: 路径点数组 `[{x, y}...]`
......@@ -86,10 +112,20 @@ options`{object}`:
- duration: 动画持续时间(单位:`s`),默认 `1`
- ease: 时间函数,默认 `easing.linear`
**`composite(options)`**
options`{object}`:
- 键值`{string}`: 动画`{tween || curve}`
以上函数都返回一个`object`:
**`start({function} || {object})`**
- update:
- v: 当前值
- complete:
- `update(v)`:
- `v`: 当前值
- `complete()`: 结束回调
**`start()`** 返回一个`object`:
- `stop()`: 结束动画
import {curve, easing, tween} from './core'
import {curve, easing, tween, composite, utils} from './core'
HTMLElement.prototype.on = function(...args) {
this.addEventListener(...args)
......@@ -32,7 +32,7 @@ document.body.on('pointerdown', ev => {
}
})
async function run(action) {
function run(action) {
const dots = document.querySelectorAll('.dot')
document.querySelectorAll('.mini-dot').forEach(child => child.remove())
......@@ -41,13 +41,30 @@ async function run(action) {
if (action === 'bezier') {
if (dots.length < 2) return alert('至少 2 个点!')
const points = Array.prototype.map.call(dots, dot => JSON.parse(dot.dataset.position))
curve.bezier({
p1: {x: player.offsetLeft, y: player.offsetTop},
p2: points[0],
p3: points[1],
duration: 1,
ease: easing.easeInOut
}).start(trace)
composite({
position: curve.bezier({
p1: {x: player.offsetLeft, y: player.offsetTop},
p2: points[0],
p3: points[1],
duration: 1,
ease: easing.easeInOut
}),
scale: tween({from: 1, to: 2}),
color: tween({from: utils.hex2rgb(0xff33cc), to: utils.hex2rgb(0xffcc33)})
}).start(v => {
player.style.left = `${v.position.x}px`
player.style.top = `${v.position.y}px`
player.style.backgroundColor = utils.rgb2hex(v.color)
player.style.transform = `translate(-50%, -50%) scale(${v.scale})`
const dot = document.createElement('i')
dot.classList.add('mini-dot')
dot.style.left = player.style.left
dot.style.top = player.style.top
document.body.appendChild(dot)
})
} else if (action === 'cubicBezier') {
if (dots.length < 3) return alert('至少 3 个点!')
const points = Array.prototype.map.call(dots, dot => JSON.parse(dot.dataset.position))
......@@ -64,7 +81,7 @@ async function run(action) {
const points = Array.prototype.map.call(dots, dot => JSON.parse(dot.dataset.position))
points.unshift({x: player.offsetLeft, y: player.offsetTop})
curve.catmullRom(points).start(trace)
curve.catmullRom(points, 10).start(trace)
} else if (action === 'tween') {
if (dots.length < 1) return alert('至少 1 个点!')
......@@ -102,3 +119,9 @@ function clear() {
function distance(a, b) {
return Math.sqrt((a.x - b.x) ** 2 + (a.y - b.y) ** 2)
}
function hex2string(hex) {
hex = hex.toString(16)
hex = '000000'.substr(0, 6 - hex.length) + hex
return `#${hex}`
}
\ No newline at end of file
export default function(action) {
const keys = Object.keys(action)
function start(option) {
const result = {}
let update, complete, total = {start: 0, end: 0}
if (option instanceof Function) update = option
else ({update, complete} = option)
const animes = keys.map(key => {
total.start++
return action[key].start({
update: v => {
result[key] = v
total.start === keys.length && update(result)
},
complete: () => {
total.end++
total.end === keys.length && complete && complete()
}
})
})
return {
stop() {
animes.forEach(anime => anime.stop())
}
}
}
return {start}
}
\ No newline at end of file
export * as easing from './easing'
export * as curve from './curve'
export tween from './tween'
export composite from './composite'
export * as utils from './utils'
......@@ -6,8 +6,7 @@ export default function(option) {
function start(option) {
const complex = isNaN(from)
let update, complete, id, delta, result,
t = 0
let update, complete, id, delta, result, t = 0
complex ? (delta = {}, result = {}, Object.keys(from).forEach(key => {
delta[key] = to[key] - from[key]
......@@ -19,9 +18,11 @@ export default function(option) {
!function loop() {
t += 1 / 60 / duration
t > 1 ? t = 1 : null
if (complex) for (const key in delta) {
result[key] = from[key] + delta[key] * ease(t)
} else result = from + delta * ease(t)
update(result)
t === 1 ? complete && complete() : id = requestAnimationFrame(loop)
}()
......
export function hex2rgb(hex) {
return {
r: (hex >> 16) & 0xff,
g: (hex >> 8) & 0xff,
b: hex & 0xff,
}
}
export function rgb2hex(color) {
color = ((color.r << 16) + (color.g << 8) + (color.b | 0)).toString(16)
return `#${'000000'.substring(0, 6 - color.length)}${color}`
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment