HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
장지원 페이지/
몰입 캠프
몰입 캠프
/#25. Design and Setting!/
Keep

Keep

Scroll
html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Infinite Scrolling Image</title> <link rel="stylesheet" href="styles.css"> </head> <body> <div class="scroll-container"> <div class="scrolling-content"> <img src="images/image.png" alt="Scrolling Image" class="scrolling-image"> <img src="images/image.png" alt="Scrolling Image" class="scrolling-image"> <img src="images/image.png" alt="Scrolling Image" class="scrolling-image"> <img src="images/image.png" alt="Scrolling Image" class="scrolling-image"> <img src="images/image.png" alt="Scrolling Image" class="scrolling-image"> <img src="images/image.png" alt="Scrolling Image" class="scrolling-image"> </div> </div> <script src="script.js"></script> </body> </html>
css
/* styles.css */ body { margin: 0; padding: 0; overflow: hidden; height: 100vh; display: flex; justify-content: center; align-items: center; background-color: #f0f0f0; } .scroll-container { width: 100%; height: 100%; position: relative; overflow: hidden; } .scrolling-content { position: absolute; top: 100%; width: 100%; display: flex; flex-direction: column; animation: scroll-up 15s linear infinite; } .scrolling-image { width: 100%; height: auto; } @keyframes scroll-up { 0% { top: 100%; } 100% { top: -500%; } }
 

Keep interaction
눈물 흐르는 인터렉션
js
// script.js const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); canvas.width = window.innerWidth * 0.8; canvas.height = window.innerHeight * 0.8; const drops = []; function createDrop(x, y) { const drop = { x, y, radius: 1, maxRadius: Math.random() * 30 + 20, // 더 자연스러운 크기 speed: Math.random() * 0.2 + 0.1, // 느린 확산 속도 alpha: 1, color: 'rgba(200, 200, 200, ', // 기본 색상 연한 회색 expandSpeed: Math.random() * 0.1 + 0.05, // 확산 속도 fadeSpeed: Math.random() * 0.002 + 0.001 // 서서히 마르는 속도 }; drops.push(drop); } function drawDrop(drop) { const gradient = ctx.createRadialGradient(drop.x, drop.y, drop.radius * 0.2, drop.x, drop.y, drop.radius); gradient.addColorStop(0, `${drop.color}${drop.alpha})`); gradient.addColorStop(1, `${drop.color}0)`); ctx.beginPath(); ctx.arc(drop.x, drop.y, drop.radius, 0, Math.PI * 2); ctx.fillStyle = gradient; ctx.fill(); ctx.closePath(); } function updateDrops() { for (let i = drops.length - 1; i >= 0; i--) { const drop = drops[i]; drop.radius += drop.expandSpeed; drop.alpha -= drop.fadeSpeed; if (drop.alpha <= 0) { drops.splice(i, 1); } } } function animate() { ctx.clearRect(0, 0, canvas.width, canvas.height); drops.forEach(drawDrop); updateDrops(); requestAnimationFrame(animate); } canvas.addEventListener('click', (e) => { const rect = canvas.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; createDrop(x, y); }); animate();
css
/* styles.css */ body, html { margin: 0; padding: 0; width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; background: #f0f0f0; } canvas { border: 1px solid #ccc; background: url('images/image.png') no-repeat center center; background-size: cover; }
html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Interactive Wet Paper Effect</title> <link rel="stylesheet" href="styles.css"> </head> <body> <canvas id="canvas"></canvas> <script src="script.js"></script> </body> </html>
서서히 뒤 돌아보는 인터렉션
js
const imageSequence = [ 'images/image2.png', 'images/image1.png', 'images/image3.png', 'images/image4.png', ]; let currentIndex = 0; const interval = 300; // 이미지 변경 간격 (밀리초) document.getElementById('sequenceImage').addEventListener('click', function() { const imgElement = this; function changeImage() { currentIndex++; if (currentIndex < imageSequence.length) { imgElement.src = imageSequence[currentIndex]; if (currentIndex < imageSequence.length - 1) { setTimeout(changeImage, interval); } } } setTimeout(changeImage, interval); });
html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Image Sequence</title> <link rel="stylesheet" href="styles.css"> </head> <body> <div class="image-container"> <img id="sequenceImage" src="images/image2.png" alt="Image Sequence"> </div> <script src="script.js"></script> </body> </html>
css
.image-container { text-align: center; margin-top: 50px; } #sequenceImage { max-width: 100%; cursor: pointer; }
타이핑
js
// script.js 파일 function typeWriter(element, text, delay = 100) { let i = 0; function type() { if (i < text.length) { element.innerHTML += text.charAt(i); i++; setTimeout(type, delay); } } type(); } document.addEventListener('DOMContentLoaded', () => { const bubble1 = document.getElementById('bubble1'); const inputText = document.getElementById('inputText'); typeWriter(bubble1, "안녕하세요! 여기는 첫 번째 말풍선입니다."); inputText.addEventListener('input', () => { const bubble2 = document.getElementById('bubble2'); bubble2.textContent = inputText.value; }); inputText.addEventListener('keypress', (event) => { if (event.key === 'Enter') { event.preventDefault(); window.location.href = 'nextpage.html'; // 다음 페이지로 이동 } }); });
css
/* styles.css 파일 */ body { font-family: 'Arial', sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; background: url('images/background.png') no-repeat center center fixed; background-size: cover; } .comic-panel { position: relative; width: 80%; height: 80%; } .speech-bubble { position: absolute; padding: 10px; width: 30%; height: 40%; display: flex; align-items: center; justify-content: center; font-size: 1.3em; background: url('images/corpus1.png') no-repeat center center; background-size: cover; border: none; box-shadow: none; } #bubble1 { top: 15%; left: 10%; transform: rotate(-5deg); } #bubble2 { bottom: 15%; right: 10%; transform: rotate(5deg); } .speech-bubble:before { content: ''; position: absolute; width: 0; height: 0; border: 15px solid transparent; } #bubble1:before { bottom: -15px; left: 20px; border-top: 15px solid transparent; } #bubble2:before { top: -15px; right: 20px; border-bottom: 15px solid transparent; }
html
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>만화 형식 웹</title> <link rel="stylesheet" href="styles.css"> </head> <body> <div class="comic-panel"> <div class="comic-frame" id="frame1"> <div class="speech-bubble" id="bubble1"></div> </div> <div class="comic-frame" id="frame2"> <div class="speech-bubble" id="bubble2"> <textarea id="inputText" placeholder="여기에 입력하세요"></textarea> </div> </div> <div class="comic-frame" id="frame3"></div> <div class="comic-frame" id="frame4"></div> </div> <script src="script.js"></script> </body> </html>