デザインのタイプ
【GSAPエッジレス・コンパクトスライダー】
高さを400pxに最適化し、画像の中央を軸とした精密なトリミングを施したスタイリッシュなスライダー。
まつさん
ホームページを全画面にしている方にぴったりなインパクトあるデザインです。
ホームページを全画面にしている方にぴったりなインパクトあるデザインです。
Dream Big
Some journeys alone
Follow your path
Stay Hungry
Win
デザインの特徴
- コンパクトな高解像度表示
高さを400pxに調整し、中央トリミングを維持。あらゆる画面サイズで美しく収まります。 - テンプレート干渉ゼロ
Blogger特有の余白(Padding/Orange Area)をCSSで完全にシャットアウト。 - GSAP高度同期アニメーション
スライド・フェード・視差がミリ秒単位で重なり合う、シネマティックな画面遷移。
3. 紹介コード
※BloggerのHTMLビューに貼り付けて使用する完全版コードです。
<div id="tpd-slider-container">
<header><nav id="tpd-nav"><a data-index="0">Dream</a><a data-index="1">Some</a><a data-index="2">Follow</a><a data-index="3">Stay</a><a data-index="4">Win</a></nav></header>
<div class="section" style="visibility: visible; opacity: 1; z-index: 5;">
<div class="background" style="background-image: url('https://images.unsplash.com/photo-1435348773030-a1d74f568bc2?q=80&w=2070');"></div>
<h2>Dream Big</h2>
</div>
<div class="section">
<div class="background" style="background-image: url('https://images.unsplash.com/photo-1489846986031-7cea03ab8fd0?q=80&w=2070');"></div>
<h2>Some journeys alone</h2>
</div>
<div class="section">
<div class="background" style="background-image: url('https://images.unsplash.com/photo-1484359755660-c7ed8f31f0cc?q=80&w=2070');"></div>
<h2>Follow your path</h2>
</div>
<div class="section">
<div class="background" style="background-image: url('https://images.unsplash.com/photo-1517825738774-7de9363ef735?q=80&w=2070');"></div>
<h2>Stay Hungry</h2>
</div>
<div class="section">
<div class="background" style="background-image: url('https://images.unsplash.com/photo-1604948501466-4e9c339b9c24?q=80&w=2070');"></div>
<h2>Win</h2>
</div>
</div>
<style>
/* --- CSS Area --- */
#tpd-slider-container {
position: relative !important;
width: 100% !important;
height: 400px; /* ← 高さを400pxに固定 */
background-color: #000;
overflow: hidden;
margin: 2em 0;
padding: 0 !important;
}
/* ナビゲーション */
#tpd-slider-container header {
position: absolute;
top: 0;
width: 100%;
height: 60px;
z-index: 100;
display: flex !important;
align-items: center;
justify-content: center;
background: rgba(0,0,0,0.1) !important;
}
#tpd-slider-container nav#tpd-nav {
background: transparent !important;
display: flex !important;
gap: 15px !important;
border: none !important;
}
#tpd-slider-container nav#tpd-nav a {
color: #fff !important;
text-decoration: none !important;
font-family: 'Nunito Sans', sans-serif !important;
font-size: 13px !important;
letter-spacing: 0.2em !important;
text-transform: uppercase !important;
cursor: pointer !important;
padding: 10px !important;
}
/* セクション設定:オレンジ色の余白(Padding)をリセット */
#tpd-slider-container .section {
position: absolute;
top: 0;
left: 0;
width: 100% !important;
height: 100% !important;
padding: 0 !important;
margin: 0 !important;
visibility: hidden;
opacity: 0;
overflow: hidden;
will-change: transform, opacity;
display: block !important;
}
/* 背景画像:センター位置固定 & 隙間防止 */
#tpd-slider-container .background {
position: absolute;
top: -15% !important;
left: -15% !important;
width: 130% !important;
height: 130% !important;
max-width: none !important;
min-width: 130% !important;
margin: 0 !important;
padding: 0 !important;
background-size: cover !important;
background-position: center center !important; /* ← 中央トリミング */
background-repeat: no-repeat !important;
will-change: transform;
}
#tpd-slider-container .background::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.4) !important;
}
/* 中央文字 */
#tpd-slider-container h2 {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 10;
width: 90%;
margin: 0 !important;
font-family: 'Playfair Display', serif !important;
font-size: clamp(1.2rem, 4vw, 2.5rem) !important;
color: #fff !important;
text-align: center !important;
letter-spacing: 0.3em !important;
pointer-events: none;
line-height: 1.2 !important;
border: none !important;
}
</style>
<script>
(function() {
const container = document.querySelector('#tpd-slider-container');
const sections = container.querySelectorAll(".section");
let currentIndex = 0;
let animating = false;
const directions = ['left', 'right', 'up', 'down'];
function animateSection(targetIndex) {
if (animating || targetIndex === currentIndex) return;
animating = true;
const currentSection = sections[currentIndex];
const targetSection = sections[targetIndex];
const currentBg = currentSection.querySelector('.background');
const targetBg = targetSection.querySelector('.background');
const direction = directions[Math.abs(targetIndex - currentIndex) % 4];
let sectionFromX = 0, sectionFromY = 0;
let bgFromX = 0, bgFromY = 0;
if (direction === 'left') { sectionFromX = 105; bgFromX = -15; }
if (direction === 'right') { sectionFromX = -105; bgFromX = 15; }
if (direction === 'up') { sectionFromY = 105; bgFromY = -15; }
if (direction === 'down') { sectionFromY = -105; bgFromY = 15; }
gsap.set(targetSection, {
xPercent: sectionFromX,
yPercent: sectionFromY,
opacity: 0,
visibility: "visible",
zIndex: 10
});
gsap.set(targetBg, { xPercent: bgFromX, yPercent: bgFromY, scale: 1.1 });
gsap.set(currentSection, { zIndex: 5 });
const tl = gsap.timeline({
onComplete: () => {
animating = false;
currentIndex = targetIndex;
sections.forEach((s, i) => { if(i !== currentIndex) gsap.set(s, {visibility: "hidden", opacity: 0}); });
}
});
tl.to(currentSection, {
xPercent: direction === 'left' ? -30 : direction === 'right' ? 30 : 0,
yPercent: direction === 'up' ? -30 : direction === 'down' ? 30 : 0,
opacity: 0,
duration: 1.4,
ease: "expo.inOut"
}, 0);
tl.to(currentBg, {
xPercent: direction === 'left' ? 15 : direction === 'right' ? -15 : 0,
yPercent: direction === 'up' ? 15 : direction === 'down' ? -15 : 0,
duration: 1.4,
ease: "expo.inOut"
}, 0);
tl.to(targetSection, {
xPercent: 0,
yPercent: 0,
opacity: 1,
duration: 1.4,
ease: "expo.inOut"
}, 0);
tl.to(targetBg, {
xPercent: 0,
yPercent: 0,
scale: 1,
duration: 1.4,
ease: "expo.inOut"
}, 0);
}
container.querySelectorAll("#tpd-nav a").forEach((a, idx) => {
a.addEventListener("click", () => animateSection(idx));
});
container.addEventListener('wheel', (e) => {
if (animating) return;
if (Math.abs(e.deltaY) < 25) return;
e.preventDefault();
const nextIndex = e.deltaY > 0
? (currentIndex + 1) % sections.length
: (currentIndex - 1 + sections.length) % sections.length;
animateSection(nextIndex);
}, { passive: false });
})();
</script>


コメントを投稿