6.1から続きます
3:スライドアニメーションをスクロールの監視で発火する
HTMLの記述
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div id="container">
<!-- <div class="cover-slide hover-darken inview">
<div class="bg-img-zoom img-bg50"></div>
</div> -->
<div class="cover-slide hover-darken">
<img class="img-zoom" src="images/image-1.jpg" alt="" />
</div>
<div class="cover-slide hover-darken">
<img class="img-zoom" src="images/image-1.jpg" alt="" />
</div>
<div class="cover-slide hover-darken">
<img class="img-zoom" src="images/image-1.jpg" alt="" />
</div>
<div class="cover-slide hover-darken">
<img class="img-zoom" src="images/image-1.jpg" alt="" />
</div>
</div>
<script src="scroll-polyfill.js"></script>
<script src="scroll.js"></script>
<script src="main.js"></script>
</body>
</html>
SCSSの記述
@import "mixin";
// 画像のズレを修正する設定
img {
max-width: 100%;
// 画像とのズレ(余白)を解消する
vertical-align: bottom;
}
.cover-slide {
position: relative;
// パン(拡大)したときの余分な部分をカット
overflow: hidden;
margin-bottom: 80vh;
&::after {
// 疑似要素に必須の設定
content: "";
position: absolute;
z-index: 2;
// 画像に必要な設定
top: 0;
left: 0;
right: 0;
bottom: 0;
// ココまで
background-color: #eaebe6;
opacity: 0;
}
&.inview {
&::after {
opacity: 1;
@include animation(
$name: kf-cover-slide,
$duration: 1.6s,
$timing-function: ease-in-out
);
}
}
}
// アニメーションに最適なプロパティ(パフォーマンスが良い)
@keyframes kf-cover-slide {
0% {
// アニメーションの起点の設定
transform-origin: left;
transform: scaleX(0);
}
50% {
transform-origin: left;
transform: scaleX(1);
}
50.1% {
transform-origin: right;
transform: scaleX(1);
}
100% {
transform-origin: right;
transform: scaleX(0);
}
}
.img-zoom {
// 初期状態は透明にする
opacity: 0;
.inview & {
// inviewが発火されたとき透明度解除しつつ、アニメーション
opacity: 1;
transition: transform 0.3s ease;
@include animation(
$name: kf-img-show,
$duration: 1.6s,
$timing-function: ease-in-out,
// アニメーションが終わったときの設定を残さない(解除)
$fill-mode: normal
);
// ホバーしたときに拡大するようにする
&:hover {
transform: scale(1.05);
}
}
}
@keyframes kf-img-show {
0% {
opacity: 0;
}
50% {
opacity: 0;
}
// 50%になってからパン(拡大)した画像を出したいので
50.1% {
opacity: 1;
transform: scale(1.5);
}
100% {
opacity: 1;
}
}
// ホバーしたときに暗くする設定
.hover-darken {
&::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
// 画像の上に表示したい
z-index: 1;
transition: background-color 0.3s ease;
pointer-events: none;
@include animation(
$name: kf-img-show,
$duration: 1.6s,
$timing-function: ease-in-out,
$fill-mode: normal
);
}
&:hover::before {
background-color: rgba(0, 0, 0, 0.4);
}
}
// .bg-img-zoomを使うときの設定
.bg-img-zoom {
background-image: url(images/image-1.jpg);
// リピートなし
background-repeat: no-repeat;
// ポジションをセンター
background-position: center;
background-size: cover;
width: 100%;
height: 400px;
// 上(80行目)の.img-zoomの設定を読み込む
@extend .img-zoom
}
.img-bg50 {
position: relative;
// アスペクト比を保ちたいときの設定
&::before {
display: block;
content: '';
padding-top: 50%;
}
}
main.jsの記述
document.addEventListener('DOMContentLoaded', function () {
const cb = function (el, isIntersecting) {
if(isIntersecting) {
// 画像の位置に画面内に入ってきたときにエレメントのクラスにインビューを追加する
el.classList.add('inview');
}
}
// クラスcover-slideに適用したい
const so = new ScrollObserver('.cover-slide', cb);
});
scroll.js,mixinは2と同じなので省略
7に続きます。