# hover
# timing control
# css
CSS :hover
Select mouse over interaction with selector. The CSS transition cancels the animation immediately when the mouse is out.
1
2
3
4
# js
If you want to complete the animation up to the mouse over style, use JS to control the state. The execution of the animation is managed by looking at the animation end flag and mouse hover state flag in the Promise
callback.
1
2
3
4
import _event from './utility/EventListener'
class HoverControl {
/**
* マウスオーバーした時のインタラクションのコントロール
* アニメーションを必ず100%の進捗率まで進める
*
* @param target {HTMLElement}
* @param overFunc {function} Promise を返す関数を受け取る
* @param outFunc {function} Promise を返す関数を受け取る
*/
constructor(target, overFunc, outFunc) {
/**
* ターゲット要素
* @type {HTMLElement}
*/
this.target = target
/**
* マウスオーバーした時に実行する関数
* @type {function}
*/
this.overFunc = overFunc
/**
* マウスアウトした時に実行する関数
* @type {function}
*/
this.outFunc = outFunc
/**
* マウスが乗っているかどうか
* @type {boolean}
*/
this.isOver = false
/**
* アニメーションが進行中かどうか
* @type {boolean}
*/
this.isPlaying = false
this.eventList = []
this.init()
return this
}
/**
* initialize
*/
init() {
this.eventList.push(new _event(this.target, 'mouseover', this.rollOverHandle.bind(this)))
this.eventList.push(new _event(this.target, 'mouseout', this.rollOutHandle.bind(this)))
}
/**
* over handle
* @param e {object} mouse event
*/
rollOverHandle(e) {
// console.log('rollOverHandle')
this.isOver = true
if (!this.isPlaying) {
this.startRollOver(e)
}
}
/**
* out handle
*/
rollOutHandle() {
// console.log('rollOutHandle')
this.isOver = false
if (!this.isPlaying) {
this.startRollOut()
}
}
/**
* roll over animation
* @param e {object} mouse event
* @returns {Promise<void>}
*/
async startRollOver(e) {
// console.log('startRollOver')
this.isPlaying = true
await this.overFunc.call(this, this.target, e)
this.completeRollOver()
}
/**
* roll out animation
* @returns {Promise<void>}
*/
async startRollOut() {
// console.log('startRollOut')
this.isPlaying = true
await this.outFunc.call(this, this.target)
this.completeRollOut()
}
/**
* finished roll over animation
*/
completeRollOver() {
// console.log('completeRollOver')
this.isPlaying = false
if (!this.isOver) {
this.startRollOut()
}
}
/**
* finished roll out animation
*/
completeRollOut() {
this.isPlaying = false
if (this.isOver) {
this.startRollOver()
}
}
destroy() {
this.eventList.forEach(event => event.destroy())
}
}
export default HoverControl
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import { gsap } from 'gsap/all'
import HoverControlScript from './HoverControlScript';
const el = document.getElementById('el');
const animationTarget = el.querySelector('.target__inner');
new HoverControlScript(el, () => {
return new Promise(resolve => {
gsap.set(animationTarget, {
transformOrigin: '0% 50%',
});
gsap.to(animationTarget, 0.6, {
scaleX: 1,
backgroundColor: '#FF6473',
ease: 'Expo.easeOut',
onComplete: () => {
resolve()
},
});
});
}, () => {
return new Promise(resolve => {
gsap.set(animationTarget, {
transformOrigin: '100% 50%',
});
gsap.to(animationTarget, 0.5, {
scaleX: 0,
ease: 'Expo.easeOut',
onComplete: () => {
resolve()
},
});
});
});
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
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
# rect
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { gsap } from 'gsap/all'
import HoverControlScript from './HoverControlScript';
const over = el =>
new Promise(resolve => {
gsap.to(el, 0.6, {
scale: 1,
backgroundColor: '#FF6473',
fontSize: '32px',
borderWidth: '20px',
ease: 'Expo.easeOut',
onComplete: () => {
resolve()
},
})
})
const out = el =>
new Promise(resolve => {
gsap.to(el, 0.5, {
scale: 1,
backgroundColor: '#25ECB7',
fontSize: '16px',
borderWidth: '0px',
ease: 'Expo.easeInOut',
onComplete: () => {
resolve()
},
})
})
;[...this.$refs.target].forEach(el => {
new HoverControlScript(el, over, out);
});
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
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