# 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
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

# 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
Last Updated: 1/16/2020, 8:19:39 AM