前置き
スクロールエフェクトのアニメーション
青い背景が左からニョキっと出てきます👀
動きがあるとスクロールしたくなりますよね🎵
今回はシンプルですが、
背景やタイトルを動かしたり
アイテムを浮き出させたり、使い方は様々です🌟
構成
大まかにこんな感じです🍒
・mouted()でDOMから
Y座標を取ってきてdata更新
・Y座標を1増やし(下げる)watchを反応させる
対応するsection idにanimationクラスを付与
完成コード
) pages
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 |
<template> <div class="page"> <p>スクロールしてみよう</p> <section id="first"> <p>もう少し</p> </section> <section id="second"> <div class="bg"> <p>ここが動く</p> <div /> </div> </section> <section id="third"> <p>伸びたね</p> </section> </div> </template> <script> import Vue from 'vue' export default { data () { return { positionY: 0, positions: { second: 0, }, } }, watch: { positionY(to, from) { const scrollOffset = to + 100 let el if (this.positions.second <= scrollOffset) { el = document.getElementById('second') el.setAttribute('class', 'animation') } }, }, mounted() { window.addEventListener('scroll', this.checkScroll) this.positions = { second: document.getElementById('second').getBoundingClientRect().top, } this.positionY++ }, methods: { checkScroll() { this.positionY = window.scrollY ? window.scrollY : window.pageYOffset }, } } </script> <style lang="scss" scoped> #second { > .bg { width: 100%; height: 100%; div { width: 25%; height: 200px; background: linear-gradient(269.76deg, #1F3345 0%, #333A56 100.52%); transition: all 3s cubic-bezier(0.215, 0.61, 0.355, 1); display: block; } } &.animation { > .bg { div { width: 100% !important; display: block; } } } } </style> |
解説
今回はいつものようにStep順ではなく
構成で全体感を説明しているため、
部分的に分けて解説していきます!
- template
- script
- style
template
section id
watchでスクロールによる
idへのクラスを付与するためです!
スクロールしていき
この領域に入ったらアニメーション開始💃✨
script
data
positionY
Y軸を取得しwatchを反応させるため
positions
該当idの一番上の位置を代入させるため
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<script> import Vue from 'vue' export default { data () { return { positionY: 0, positions: { second: 0, }, } }, } </script> |
mounted()
解説はインラインのコメントにて。
基本的にスクロールや座標の指定は
DOMの表示位置から取るため
大体のことはここに書きます✍️
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<script> import Vue from 'vue' export default { mounted() { // スクロールイベントを追加 window.addEventListener('scroll', this.checkScroll) this.positions = { // section id="second"のtopのY座標をdataのsecondに代入 second: document.getElementById('second').getBoundingClientRect().top, } // watchを反応させるために1だけ下げる this.positionY++ }, } </script> |
methods
解説はインラインのコメントにて。
先ほどのmountedで実行している関数です。
ページ内容に関係なく今いる位置の一番上の
Y軸の位置を取れば良いだけなのでDOM関係なし!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<script> import Vue from 'vue' export default { methods: { checkScroll() { // window.scrollYでY軸取得できる // this.positionY = window.scrollYのみでもOK // IE対応のために三項演算 式1? 式2: 式3 this.positionY = window.scrollY ? window.scrollY : window.pageYOffset }, } } </script> |
watch
解説はインラインにて。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<script> import Vue from 'vue' export default { watch: { // dataのpositionY // fromが変化する前の値, toが変化後の値 positionY(to, from) { // sectionがy=0の1番上に来た時点ではなく、 // + 100の位置に来た時点で反応させたい const scrollOffset = to + 100 let el // secondのtopの位置が50、それ以下(上)になったら if (this.positions.second <= scrollOffset) { // id="second"に el = document.getElementById('second') // animationというクラスを追加 el.setAttribute('class', 'animation') } }, }, } </script> |
スクロールにより
途中でanimationクラスが
追加されているのが分かりますね👀
style
それぞれを書けばOK!
- 通常時
- animationクラス付与時
変化が分かりやすいように
transitionは3秒と長めにとりました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<style lang="scss" scoped> #second { > .bg { width: 100%; height: 100%; div { width: 25%; height: 200px; background: linear-gradient(269.76deg, #1F3345 0%, #333A56 100.52%); transition: all 3s cubic-bezier(0.215, 0.61, 0.355, 1); } } &.animation { > .bg { div { width: 100% !important; } } } } </style> |