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 ...@@ -17,7 +17,7 @@ npm i git+ssh://git@gitlab2.dui88.com:lufei/moto.git
## 文档 ## 文档
```js ```js
import {curve, tween, easing} from 'moto' import {curve, tween, easing, composite, utils} from 'moto'
// 二次贝塞尔曲线 // 二次贝塞尔曲线
curve.bezier({ curve.bezier({
...@@ -61,6 +61,22 @@ const anime = tween({ ...@@ -61,6 +61,22 @@ const anime = tween({
}) })
setTimeout(() => anime.stop(), 2e3) 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)`** **`curve.bezier(options)`**
...@@ -72,6 +88,16 @@ options`{object}`: ...@@ -72,6 +88,16 @@ options`{object}`:
- duration: 动画持续时间(单位:`s`),默认 `1` - duration: 动画持续时间(单位:`s`),默认 `1`
- ease: 时间函数,默认 `easing.linear` - 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])`** **`curve.catmullRom(points, [v])`**
- points: 路径点数组 `[{x, y}...]` - points: 路径点数组 `[{x, y}...]`
...@@ -86,10 +112,20 @@ options`{object}`: ...@@ -86,10 +112,20 @@ options`{object}`:
- duration: 动画持续时间(单位:`s`),默认 `1` - duration: 动画持续时间(单位:`s`),默认 `1`
- ease: 时间函数,默认 `easing.linear` - ease: 时间函数,默认 `easing.linear`
**`composite(options)`**
options`{object}`:
- 键值`{string}`: 动画`{tween || curve}`
以上函数都返回一个`object`: 以上函数都返回一个`object`:
**`start({function} || {object})`** **`start({function} || {object})`**
- update: - `update(v)`:
- v: 当前值 - `v`: 当前值
- complete: - `complete()`: 结束回调
**`start()`** 返回一个`object`:
- `stop()`: 结束动画
import {curve, easing, tween} from './core' import {curve, easing, tween, composite, utils} from './core'
HTMLElement.prototype.on = function(...args) { HTMLElement.prototype.on = function(...args) {
this.addEventListener(...args) this.addEventListener(...args)
...@@ -32,7 +32,7 @@ document.body.on('pointerdown', ev => { ...@@ -32,7 +32,7 @@ document.body.on('pointerdown', ev => {
} }
}) })
async function run(action) { function run(action) {
const dots = document.querySelectorAll('.dot') const dots = document.querySelectorAll('.dot')
document.querySelectorAll('.mini-dot').forEach(child => child.remove()) document.querySelectorAll('.mini-dot').forEach(child => child.remove())
...@@ -41,13 +41,30 @@ async function run(action) { ...@@ -41,13 +41,30 @@ async function run(action) {
if (action === 'bezier') { if (action === 'bezier') {
if (dots.length < 2) return alert('至少 2 个点!') if (dots.length < 2) return alert('至少 2 个点!')
const points = Array.prototype.map.call(dots, dot => JSON.parse(dot.dataset.position)) const points = Array.prototype.map.call(dots, dot => JSON.parse(dot.dataset.position))
curve.bezier({
p1: {x: player.offsetLeft, y: player.offsetTop}, composite({
p2: points[0], position: curve.bezier({
p3: points[1], p1: {x: player.offsetLeft, y: player.offsetTop},
duration: 1, p2: points[0],
ease: easing.easeInOut p3: points[1],
}).start(trace) 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') { } else if (action === 'cubicBezier') {
if (dots.length < 3) return alert('至少 3 个点!') if (dots.length < 3) return alert('至少 3 个点!')
const points = Array.prototype.map.call(dots, dot => JSON.parse(dot.dataset.position)) const points = Array.prototype.map.call(dots, dot => JSON.parse(dot.dataset.position))
...@@ -64,7 +81,7 @@ async function run(action) { ...@@ -64,7 +81,7 @@ async function run(action) {
const points = Array.prototype.map.call(dots, dot => JSON.parse(dot.dataset.position)) const points = Array.prototype.map.call(dots, dot => JSON.parse(dot.dataset.position))
points.unshift({x: player.offsetLeft, y: player.offsetTop}) points.unshift({x: player.offsetLeft, y: player.offsetTop})
curve.catmullRom(points).start(trace) curve.catmullRom(points, 10).start(trace)
} else if (action === 'tween') { } else if (action === 'tween') {
if (dots.length < 1) return alert('至少 1 个点!') if (dots.length < 1) return alert('至少 1 个点!')
...@@ -102,3 +119,9 @@ function clear() { ...@@ -102,3 +119,9 @@ function clear() {
function distance(a, b) { function distance(a, b) {
return Math.sqrt((a.x - b.x) ** 2 + (a.y - b.y) ** 2) 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 easing from './easing'
export * as curve from './curve' export * as curve from './curve'
export tween from './tween' export tween from './tween'
export composite from './composite'
export * as utils from './utils'
...@@ -6,8 +6,7 @@ export default function(option) { ...@@ -6,8 +6,7 @@ export default function(option) {
function start(option) { function start(option) {
const complex = isNaN(from) const complex = isNaN(from)
let update, complete, id, delta, result, let update, complete, id, delta, result, t = 0
t = 0
complex ? (delta = {}, result = {}, Object.keys(from).forEach(key => { complex ? (delta = {}, result = {}, Object.keys(from).forEach(key => {
delta[key] = to[key] - from[key] delta[key] = to[key] - from[key]
...@@ -19,9 +18,11 @@ export default function(option) { ...@@ -19,9 +18,11 @@ export default function(option) {
!function loop() { !function loop() {
t += 1 / 60 / duration t += 1 / 60 / duration
t > 1 ? t = 1 : null t > 1 ? t = 1 : null
if (complex) for (const key in delta) { if (complex) for (const key in delta) {
result[key] = from[key] + delta[key] * ease(t) result[key] = from[key] + delta[key] * ease(t)
} else result = from + delta * ease(t) } else result = from + delta * ease(t)
update(result) update(result)
t === 1 ? complete && complete() : id = requestAnimationFrame(loop) 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