<div class="hero-01" id="js-hero-01">
<div class="hero-01__kv">
<div class="hero-01__kv-title"><span class="hero-01__kv-sub-title"><span>サブタイトル1行目</span><span>サブタイトル2行目</span></span><span class="hero-01__kv-main-title"><span>MAIN TITLE 01</span><span>MAIN TITLE 02 長い文字列長い文字列</span></span></div>
<div class="hero-01__kv-bg"><img src="https://picsum.photos/id/100/1280/1280" /></div>
</div>
<div class="hero-01__content">
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
</div>
</div>
.hero-01#js-hero-01
.hero-01__kv
.hero-01__kv-title
span.hero-01__kv-sub-title
span サブタイトル1行目
span サブタイトル2行目
span.hero-01__kv-main-title
span MAIN TITLE 01
span MAIN TITLE 02 長い文字列長い文字列
.hero-01__kv-bg
img(src="https://picsum.photos/id/100/1280/1280")
.hero-01__content
- for (var i = 0; i < 40; i++)
p #{ text }
{
"text": "テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。"
}
$BLOCK_NAME: '.hero-01';
// 変数
$kv_height: 100vh;
$content_padding: 24px;
#{ $BLOCK_NAME } {
position: relative;
min-height: $kv_height;
padding-top: $kv_height;
&__kv {
position: fixed;
top: 0;
left: 0;
right: 0;
height: $kv_height;
overflow: hidden;
}
&__kv-title {
position: absolute;
bottom: 0;
left: 0;
right: 0;
padding: $content_padding;
z-index: 1;
display: flex;
flex-direction: column;
gap: 16px;
line-height: 1;
font-weight: bold;
max-width: unquote('min(500px, 100%)');
}
&__kv-sub-title {
display: flex;
flex-direction: column;
gap: 8px;
> span {
--progress: 0;
transition: transform 0.1s;
transform: translateX(calc((-550px) * var(--progress)))
skewX(calc(45deg * var(--progress)));
&:nth-child(1) {
--progress: max(0, min(1, calc((var(--anim-progress)) / 0.7)));
}
&:nth-child(2) {
--progress: max(0, min(1, calc((var(--anim-progress) - 0.1) / 0.7)));
}
}
}
&__kv-main-title {
display: flex;
flex-direction: column;
gap: 8px;
font-size: 32px;
> span {
--progress: 0;
transition: transform 0.1s;
transform: translateX(calc((-550px) * var(--progress)))
skewX(calc(45deg * var(--progress)));
&:nth-child(1) {
--progress: max(0, min(1, calc((var(--anim-progress) - 0.2) / 0.7)));
}
&:nth-child(2) {
--progress: max(0, min(1, calc((var(--anim-progress) - 0.3) / 0.7)));
}
}
}
&__kv-bg {
position: absolute;
inset: 0;
transform: scale(calc(1 + 0.5 * var(--anim-progress)));
transform-origin: top right;
opacity: calc(1 - var(--anim-progress));
transition: opacity 0.2s, transform 0.2s;
> img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
&__content {
position: relative;
z-index: 1;
padding: $content_padding;
padding-top: 320px;
}
}
'use strict';
import { gsap } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
gsap.registerPlugin(ScrollTrigger);
export const hero01 = () => {
const anim = new Anim31('js-hero-01');
anim.init();
};
class Anim31 {
el: HTMLElement;
contentEl: HTMLElement;
constructor(elId: string) {
this.el = document.getElementById(elId);
this.contentEl = this.el?.querySelector('.hero-01__content');
}
/**
* 初期化
*/
init(): void {
if (!this.el) return;
this.scrollHandler();
}
/**
* スクロール連動のイベント設定
*/
scrollHandler(): void {
ScrollTrigger.create({
trigger: this.contentEl,
start: 'top bottom',
end: '+=400',
onUpdate: (e) => {
this.el.style.setProperty('--anim-progress', e.progress.toString());
},
});
}
}