1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
import { qs, getProgress } from './helpers'
import { easeElasticOut } from 'd3-ease'
export function getLoader () {
let topEle = qs('.top')
let bottomEle = qs('.bottom')
let distance = document.documentElement.clientHeight / 2
let ticket = false
let closed = false
let opening = false
let openWaiting = false
const animation = (ease, cb, duration, finaly = () => {}) => {
const tick = () => {
let progress = Math.min(ease((getProgress(data))), 1)
// d3.easeExpOut has problem, t can not reach to 1, so I mannually fix it
// progress = progress > 0.999 ? 1 : progress
if (progress < 1) {
cb(progress)
window.requestAnimationFrame(tick)
} else {
window.performance.clearMarks(data.id)
cb(progress)
finaly()
}
}
const data = {
duration,
id: window.requestAnimationFrame(tick)
}
}
const loading = () => {
console.log('loading', ticket)
if (ticket) return
ticket = true
close(() => {
closed = true
if (openWaiting) {
open()
}
})
}
const loaded = () => {
console.log('loaded: ', ticket, opening)
if (!ticket) return
if (opening) return
opening = true
if (closed) {
open()
} else {
openWaiting = true
}
}
function close (cb) {
animation(easeElasticOut, progress => {
topEle.style.top = -((1 - progress) * distance) + 'px'
bottomEle.style.top = (1 - progress) * distance + distance + 'px'
}, 1000, cb)
}
function open (cb) {
animation(easeElasticOut, progress => {
topEle.style.top = -(progress * distance) + 'px'
bottomEle.style.top = progress * distance + distance + 'px'
}, 1000, () => {
opening = false
closed = false
openWaiting = false
ticket = false
})
}
return {
loading,
loaded
}
}
|