인터랙티브 랜딩 페이지 - 커서 스크러빙 비디오 배경
Wikiprompt, 무료 프롬프트 백과사전에서
인터랙티브 랜딩 페이지 - 커서 스크러빙 비디오 배경 React, TypeScript, Tailwind CSS를 사용하여 커서 스크러빙 비디오 배경, 커스텀 커서, 고정 레이아웃 요소를 갖춘 인터랙티브 랜딩 페이지를 구축하기 위한 상세 프롬프트입니다.
프롬프트 내용저장
🌐
<div class="hero-wrapper">
<div class="video-background">
<video id="video1" muted playsInline preload="auto" class="video-layer"></video>
<video id="video2" muted playsInline preload="auto" class="video-layer"></video>
</div>
<div class="custom-cursor" id="customCursor">
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="24" cy="24" r="22.75" stroke="white" stroke-width="2.5" fill="none"/>
<path d="M16 32L24 16L32 32" stroke="white" stroke-width="2" fill="none"/>
<path d="M20 26H28" stroke="white" stroke-width="2" fill="none"/>
</svg>
</div>
<div class="layout-elements">
<div class="logo">
<svg viewBox="0 0 355 110" xmlns="http://www.w3.org/2000/svg" class="logo-svg">
<text x="0" y="70" font-family="Inter Tight, sans-serif" font-weight="500" font-size="48" fill="white">prmpt</text>
<circle cx="300" cy="55" r="18" fill="none" stroke="white" stroke-width="2"/>
<text x="290" y="62" font-family="Inter Tight, sans-serif" font-weight="500" font-size="24" fill="white">R</text>
</svg>
</div>
<div class="nav">
<span class="about-text">ABOUT</span>
<svg class="hamburger" width="30" height="30" viewBox="0 0 30 30" xmlns="http://www.w3.org/2000/svg">
<line x1="5" y1="10" x2="25" y2="10" stroke="white" stroke-width="2"/>
<line x1="5" y1="20" x2="25" y2="20" stroke="white" stroke-width="2"/>
</svg>
<span class="cart-text">[ CART ]</span>
</div>
<div class="caption">
<p>Build a fullscreen hero section in React + TypeScript + Vite + Tailwind CSS v4 + motion (framer-motion successor). Use the Inter Tight Google Font (weight 500 only). The page background is white.</p>
</div>
</div>
</div>
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter+Tight:wght@500&display=swap');
.hero-wrapper {
position: relative;
width: 100vw;
height: 100vh;
overflow: hidden;
background: white;
cursor: none;
font-family: 'Inter Tight', sans-serif;
font-weight: 500;
}
.video-background {
position: fixed;
inset: 0;
overflow: hidden;
z-index: 1;
}
.video-layer {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
opacity: 0;
transition: opacity 0.3s ease;
display: none;
}
.video-layer.visible {
display: block;
opacity: 1;
}
.custom-cursor {
position: fixed;
pointer-events: none;
z-index: 50;
transform: translate(-50%, -50%);
mix-blend-mode: exclusion;
display: none;
}
.layout-elements {
position: fixed;
inset: 0;
pointer-events: none;
z-index: 20;
mix-blend-mode: exclusion;
color: white;
}
.logo {
position: fixed;
top: 32px;
left: 32px;
z-index: 20;
}
.logo-svg {
width: 355px;
height: auto;
}
.nav {
position: fixed;
top: 32px;
right: 32px;
z-index: 20;
display: flex;
align-items: center;
gap: 50px;
}
.about-text {
font-size: 15px;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.hamburger {
display: block;
}
.cart-text {
font-size: 15px;
letter-spacing: 0.05em;
}
.caption {
position: fixed;
left: 32px;
top: 244px;
max-width: 692px;
z-index: 20;
}
.caption p {
font-size: 12px;
line-height: 140%;
letter-spacing: -0.04em;
margin: 0;
}
@media (max-width: 1024px) and (min-width: 768px) {
.logo {
top: 16px;
left: 16px;
}
.logo-svg {
width: 266px;
}
.nav {
top: 16px;
right: 16px;
gap: 20px;
}
.about-text {
display: none;
}
.hamburger {
width: 24px;
height: 24px;
}
.cart-text {
font-size: 13px;
}
.caption {
left: 16px;
top: 180px;
max-width: calc(50vw - 48px);
}
}
@media (max-width: 767px) {
.logo {
top: 16px;
left: 16px;
}
.logo-svg {
width: 124px;
}
.nav {
top: 16px;
right: 16px;
gap: 20px;
}
.about-text {
display: none;
}
.hamburger {
width: 24px;
height: 24px;
}
.cart-text {
font-size: 13px;
}
.caption {
left: 16px;
top: 118px;
max-width: calc(100vw - 32px);
}
}
@media (hover: hover) and (pointer: fine) {
.custom-cursor {
display: block;
}
}
</style>
<script>
(function() {
const video1 = document.getElementById('video1');
const video2 = document.getElementById('video2');
const cursor = document.getElementById('customCursor');
const heroWrapper = document.querySelector('.hero-wrapper');
// Video URLs (with spaces removed)
const url1 = 'https://d8j0ntlcm91z4.cloudfront.net/user_39ca84eAE';
const url2 = 'https://d8j0ntlcm91z4.cloudfront.net/user_39ca84eAE';
video1.src = url1;
video2.src = url2;
let videosLoaded = 0;
const onLoaded = () => {
videosLoaded++;
if (videosLoaded === 2) {
video1.classList.add('visible');
video2.classList.add('visible');
}
};
video1.addEventListener('loadeddata', onLoaded);
video2.addEventListener('loadeddata', onLoaded);
// Desktop scrubbing
let isDesktop = window.matchMedia('(min-width: 1024px)').matches;
let activeSide = 'right'; // start with video1 (right side)
let rafId = null;
let mouseX = window.innerWidth / 2;
function scrub() {
const vw = window.innerWidth;
const centerX = vw / 2;
const deadZone = Math.max(30, vw * 0.05);
if (mouseX > centerX + deadZone) {
// right side
if (activeSide !== 'right') {
activeSide = 'right';
video1.style.display = 'block';
video2.style.display = 'none';
video1.currentTime = 0;
}
const progress = (mouseX - centerX - deadZone) / (vw - centerX - deadZone);
const clamped = Math.min(1, Math.max(0, progress));
if (!video1.seeking) {
video1.currentTime = clamped * video1.duration;
}
} else if (mouseX < centerX - deadZone) {
// left side
if (activeSide !== 'left') {
activeSide = 'left';
video2.style.display = 'block';
video1.style.display = 'none';
video2.currentTime = 0;
}
const progress = (centerX - deadZone - mouseX) / (centerX - deadZone);
const clamped = Math.min(1, Math.max(0, progress));
if (!video2.seeking) {
video2.currentTime = clamped * video2.duration;
}
} else {
// dead zone: keep active video at 0
const activeVideo = activeSide === 'right' ? video1 : video2;
if (!activeVideo.seeking && activeVideo.currentTime !== 0) {
activeVideo.currentTime = 0;
}
}
rafId = requestAnimationFrame(scrub);
}
function initDesktop() {
if (rafId) cancelAnimationFrame(rafId);
video1.style.display = 'block';
video2.style.display = 'none';
activeSide = 'right';
video1.currentTime = 0;
video2.currentTime = 0;
rafId = requestAnimationFrame(scrub);
}
// Mobile/tablet autoplay
let mobileInterval = null;
function initMobile() {
if (rafId) cancelAnimationFrame(rafId);
video1.style.display = 'block';
video2.style.display = 'none';
video1.currentTime = 0;
video2.currentTime = 0;
video1.play().catch(() => {});
video2.pause();
mobileInterval = setInterval(() => {
if (video1.ended) {
video1.style.display = 'none';
video2.style.display = 'block';
video2.currentTime = 0;
video2.play().catch(() => {});
} else if (video2.ended) {
video2.style.display = 'none';
video1.style.display = 'block';
video1.currentTime = 0;
video1.play().catch(() => {});
}
}, 100);
}
function handleResize() {
const newIsDesktop = window.matchMedia('(min-width: 1024px)').matches;
if (newIsDesktop !== isDesktop) {
isDesktop = newIsDesktop;
if (isDesktop) {
if (mobileInterval) clearInterval(mobileInterval);
video1.pause();
video2.pause();
initDesktop();
} else {
if (rafId) cancelAnimationFrame(rafId);
initMobile();
}
}
}
// Mouse tracking
document.addEventListener('mousemove', (e) => {
mouseX = e.clientX;
if (isDesktop) {
cursor.style.left = e.clientX + 'px';
cursor.style.top = e.clientY + 'px';
}
});
// Initial setup
if (isDesktop) {
initDesktop();
} else {
initMobile();
}
window.addEventListener('resize', handleResize);
})();
</script>
전체 프롬프트를 보려면 로그인하세요
Continue with:
By logging in, you agree to our Terms of Use and Privacy Policy
사용법
이 프롬프트는 coding와 함께 사용하도록 설계되었습니다. 위의 프롬프트 내용을 복사하여 원하는 AI 도구에 붙여넣으세요.
최상의 결과를 얻으려면 자리 표시자(대괄호 또는 대문자로 표시)를 특정 요구 사항으로 사용자 지정할 수 있습니다.
토론
댓글 0개