© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
#25. Design and Setting! Keep 내가 맡은 파트! [깃으로 웹 배포하는 법 알아보기] setting 들어가서 → pages 들어가기 pages에서 branch 설정 사이트 확인
[개발 환경 세팅] js와 html, css는 vscode에 내제되어 있는 것 같다..
[코딩] html: 웹 브라우저가 해석할 수 있게 하는 것 Example of 무한 스크롤 Example of 눈 부심 Example of 만화 프레임
html
div: 보이지 않는 틀 → 여기에 id 넣어서 작성한다.
css
id를 가지는 것들이 작성되는 곳 → xml 파일과 같은 역할을 하는 것 같다.
js
모든 동작을 하는 곳: 이번에는 이거 쓸 일 많이 없을 듯
[추가 아이디어] 자리 선택은 첨에만 → 나중에는 ‘자리 바꾸기’로 순서대로 보여주기 자리 선택 → 산출물 및 후기 보기 → 자리 바꿔 앉기 (이 때 부터는 그냥 순서대로 앉게하는 게 좋을 듯) 만약 대사가 없으면 어떤 interaction을 주어야 할까? → 아니면 interaction은 mad page에서만? 배경에 간단한 interaction을 줘도 될 것 같다 → 배경에 interaction을 준다면 어떻게 효과적인 interaction을 줄 수 있을까? → 낙서할 수 있는 interaction 시간의 흐름을 효과적으로 전달할 수 있는 음악? 무한 스크롤을 → 컨텐츠가 올라가게 해도 OK
interaction: 이걸 보는 사람이 자기 기억에 대입할 수 있는 상호작용? → 이 웹을 봤을 때 자기 기억이라고 할 수 있을 만한 상호 작용 만들기
배경? 아님? 다른거? 뭘 바꿔야지 이 효과를 줄 수 있을까?
or 그냥 이미지 크게하는 거 괜찮은 애니매이션 효과 써서 해보기
→ 만화 컷에서는 눈 부시는 interaction, 만화볼 때는 마우스 옮길 때 마다 그리기 + 타이핑 interaction + 자리 바꿀 때는 종이 넘기는 interaction (자리 돌아가기)
ending: 뒷 모습이었던 사람들이 앞을 보는 사진 or stop 모션으로 우리 분반 사람들이 앞을 보는 사진
interaction: 종이가 젖는 interaction
네이버 블로그 | ✿황냥◟(∗❛ᴗ❛∗)◞ෆ 찡긋✿ [CSS] CSS animation 애니메이션 사이트 모음 [CSS] CSS animation 애니메이션 사이트 모음
CSS animation 애니메이션 사이트 모음 https://www.framer.com/motion/ https://animate.style http://...
// script.js
document.addEventListener('DOMContentLoaded', () => {
const container = document.getElementById('webtoon-container');
let loading = false;
let page = 1;
const SCROLL_STEP = 1; // 스크롤 한 번에 이동할 픽셀 수
const SCROLL_INTERVAL = 10; // 스크롤 간격 (밀리초)
const LOAD_INTERVAL = 2000; // 새로운 항목을 로드하는 간격 (밀리초)
// 웹툰 항목을 불러오는 함수
const loadWebtoons = async () => {
if (loading) return;
loading = true;
// 샘플 웹툰 데이터를 사용
const sampleWebtoons = [
{ image: 'https://via.placeholder.com/400x300?text=Webtoon+1', title: 'Webtoon Title 1', description: 'Description 1' },
{ image: 'https://via.placeholder.com/400x300?text=Webtoon+2', title: 'Webtoon Title 2', description: 'Description 2' },
{ image: 'https://via.placeholder.com/400x300?text=Webtoon+3', title: 'Webtoon Title 3', description: 'Description 3' },
{ image: 'https://via.placeholder.com/400x300?text=Webtoon+4', title: 'Webtoon Title 4', description: 'Description 4' },
{ image: 'https://via.placeholder.com/400x300?text=Webtoon+5', title: 'Webtoon Title 5', description: 'Description 5' },
];
// 웹툰 항목을 컨테이너에 추가
sampleWebtoons.forEach(webtoon => {
const item = document.createElement('div');
item.classList.add('webtoon-item');
item.innerHTML = `
<img src="${webtoon.image}" alt="${webtoon.title}">
<h2>${webtoon.title}</h2>
<p>${webtoon.description}</p>
`;
container.appendChild(item);
});
loading = false;
page++;
};
// 부드러운 스크롤 함수
const smoothScroll = (targetPosition, duration) => {
const startPosition = window.pageYOffset;
const distance = targetPosition - startPosition;
let startTime = null;
const animation = currentTime => {
if (startTime === null) startTime = currentTime;
const timeElapsed = currentTime - startTime;
const run = ease(timeElapsed, startPosition, distance, duration);
window.scrollTo(0, run);
if (timeElapsed < duration) requestAnimationFrame(animation);
};
const ease = (t, b, c, d) => {
t /= d / 2;
if (t < 1) return c / 2 * t * t + b;
t--;
return -c / 2 * (t * (t - 2) - 1) + b;
};
requestAnimationFrame(animation);
};
// 일정 시간마다 자동 스크롤
setInterval(() => {
if (!loading) {
const targetPosition = window.pageYOffset + window.innerHeight;
smoothScroll(targetPosition, SCROLL_INTERVAL * 100);
loadWebtoons();
}
}, LOAD_INTERVAL);
// 초기 로드
loadWebtoons();
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Infinite Scroll Webtoon</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div id="webtoon-container">
<!-- 웹툰 항목들이 여기에 추가될 것입니다 -->
</div>
<script src="script.js"></script>
</body>
</html>
/* styles.css */
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
background-color: #f0f0f0;
}
#webtoon-container {
width: 80%;
max-width: 600px;
margin: 20px auto;
background-color: #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
border-radius: 10px;
overflow: hidden;
}
.webtoon-item {
padding: 20px;
border-bottom: 1px solid #ddd;
}
.webtoon-item:last-child {
border-bottom: none;
}
.webtoon-item img {
max-width: 100%;
height: auto;
display: block;
margin: 0 auto 10px;
}
.webtoon-item h2 {
font-size: 1.2em;
margin: 0 0 10px;
}
.webtoon-item p {
font-size: 1em;
margin: 0;
}
// script.js
document.addEventListener('DOMContentLoaded', () => {
const flash = document.getElementById('flash');
// 페이지 로드 후 1초 뒤에 점차 어두워지는 애니메이션 실행
setTimeout(() => {
flash.style.opacity = '0';
}, 1000);
// 애니메이션이 끝난 후 요소를 제거
flash.addEventListener('transitionend', () => {
flash.remove();
});
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Blinding Flash Effect</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div id="flash"></div>
<div class="content">
<!-- <h1>Welcome to the Blinding Flash Effect</h1>
<p>This is a sample web page demonstrating a blinding flash effect when the page loads. Enjoy the visual effect!</p>
<img src="images/a.png" alt="Available Seats"> -->
</div>
<script src="script.js"></script>
</body>
</html>
/* styles.css */
body {
margin: 0;
padding: 0;
overflow: hidden;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background-color: #f0f0f0;
flex-direction: column;
background: url('images/image.png') no-repeat center center fixed;
background-size: cover;
flex-direction: column;
}
#flash {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: white;
z-index: 100;
opacity: 1;
transition: opacity 2s ease-in-out;
}
.content {
text-align: center;
padding: 20px;
background-color: white;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
h1 {
font-size: 2em;
margin: 0 0 10px;
}
p {
font-size: 1.2em;
margin: 0;
}
document.addEventListener('DOMContentLoaded', () => {
const flash = document.getElementById('flash');
setTimeout(() => {
flash.style.opacity = '0';
}, 1000);
flash.addEventListener('transitionend', () => {
flash.remove();
});
const cells = document.querySelectorAll('.comic-cell');
cells.forEach(cell => {
const bubble = cell.querySelector('.bubble');
const text = bubble.getAttribute('data-text');
bubble.innerHTML = `<span class="typing-animation">${text}</span>`;
cell.addEventListener('mouseover', () => {
const typingElement = bubble.querySelector('.typing-animation');
typingElement.style.animation = 'none';
void typingElement.offsetWidth; // Trigger reflow
typingElement.style.animation = null; // Reset animation
});
});
});
body {
margin: 0;
padding: 0;
overflow: hidden;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background-color: #f0f0f0;
background: url('images/a.jpg') no-repeat center center fixed;
background-size: cover;
flex-direction: column;
}
#flash {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: white;
z-index: 100;
opacity: 1;
transition: opacity 2s ease-in-out;
}
.content {
text-align: center;
padding: 20px;
background-color: white;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
h1 {
font-size: 2em;
margin: 0 0 10px;
}
p {
font-size: 1.2em;
margin: 0;
}
button {
margin-top: 20px;
padding: 10px 20px;
font-size: 1em;
cursor: pointer;
border: none;
border-radius: 5px;
background-color: #007BFF;
color: white;
transition: background-color 0.3s ease;
}
button:hover {
background-color: #0056b3;
}
.comic-container {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3, 200px);
gap: 10px;
width: 90vw;
height: 80vh;
background-color: white;
padding: 20px;
}
.comic-cell {
border: 1px solid #000;
background-color: #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
position: relative;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
}
.comic-cell img {
width: 100%;
height: 100%;
object-fit: cover;
opacity: 0;
transition: opacity 1s ease-in-out, transform 1s ease-in-out;
transform: scale(1.1);
}
.comic-cell:hover img {
opacity: 1;
transform: scale(1);
}
.bubble {
position: absolute;
bottom: 10px;
left: 10px;
background: white;
border: 1px solid black;
border-radius: 15px;
padding: 10px;
max-width: 80%;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
display: none;
}
.bubble:after {
content: '';
position: absolute;
bottom: -10px;
left: 20px;
border-width: 10px 10px 0;
border-style: solid;
border-color: white transparent;
display: block;
width: 0;
}
.comic-cell:hover .bubble {
display: block;
}
@keyframes typing {
from {
width: 0;
}
to {
width: 100%;
}
}
@keyframes blink-caret {
from, to {
border-color: transparent;
}
50% {
border-color: black;
}
}
.typing-animation {
overflow: hidden;
white-space: nowrap;
border-right: 2px solid black;
animation: typing 3.5s steps(40, end), blink-caret .75s step-end infinite;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Blinding Flash Effect</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div id="flash"></div>
<div class="content">
<h1>Welcome to the Blinding Flash Effect</h1>
<p>This is a sample web page demonstrating a blinding flash effect when the page loads. Enjoy the visual effect!</p>
<img src="images/a.png" alt="Available Seats">
<button onclick="goToPage2()">Go to Another Page</button>
</div>
<script src="script.js"></script>
<script>
function goToPage2() {
window.location.href = 'page2.html'; // 이동할 페이지 URL
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Second Page</title>
<link rel="stylesheet" href="styles.css">
<style>
/* page2.html에만 적용되는 스타일 */
body {
background-color: white; /* page2.html의 배경을 흰색으로 설정 */
background: none; /* 배경 이미지를 제거 */
}
.comic-cell.special {
grid-column: span 2; /* 두 칸을 차지 */
grid-row: span 2; /* 두 줄을 차지 */
border-radius: 15px; /* 모서리를 둥글게 */
}
</style>
</head>
<body>
<div class="comic-container">
<div class="comic-cell">
<img src="images/ex.png" alt="Quest Image 1">
<div class="bubble" data-text="퀘스트 1 설명"></div>
</div>
<div class="comic-cell">
<img src="images/ex.png" alt="Quest Image 2">
<div class="bubble" data-text="퀘스트 2 설명"></div>
</div>
<div class="comic-cell special">
<img src="images/ex.png" alt="Samurai">
<div class="bubble" data-text="사무라이 설명"></div>
</div>
<div class="comic-cell">
<img src="images/ex.png" alt="Study">
<div class="bubble" data-text="공부 설명"></div>
</div>
<div class="comic-cell">
<p>내 이야기를 들어볼래?</p>
<div class="bubble" data-text="내 이야기를 들어볼래?"></div>
</div>
</div>
<button onclick="goBack()">Go Back to Home Page</button>
<script src="script.js"></script>
<script>
function goBack() {
window.location.href = 'index.html'; // 메인 페이지로 이동하는 URL
}
</script>
</body>
</html>