scroll-section-3에서 reload 했을 때 원래 자리를 찾지 못합니다.
307
작성한 질문수 8
안녕하세요.
코드를 재구성하면서 따라가고 있는데 마지막 scroll-section-3에서 문자가 보이는 화면에서 새로고침을 했을 때, pageYOffset이 제자리에 있지 않고 위로 이동하는 현상이 발생합니다.
디버깅을 한다고 했는데 도저히 모르겠어서 질문드립니다. 도움 주시면 감사하겠습니다.
# index.html
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>AirMug Pro</title>
<link rel="stylesheet" href="style.css">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;900&display=swap" rel="stylesheet">
</head>
<body class="before-load">
<div class="loading">
<svg class="loading-circle">
<circle cx="50%" cy="50%" r="25"></circle>
</svg>
</div>
<nav class="global-nav">
<div class="global-nav-links">
<a href="#">Rooms</a>
<a href="#">Ideas</a>
<a href="#">Stores</a>
<a href="#">Contact</a>
</div>
</nav>
<nav class="local-nav">
<div class="local-nav-links">
<a href="#" class="product-name">AirMug Pro</a>
<div class="local-nav-right">
<a href="#">Overview</a>
<a href="#">Specification</a>
<a href="#">Purchase</a>
</div>
</div>
</nav>
<div class="container">
<div class="scroll-section" id="scroll-section-0">
<div class="sticky-elem sticky-elem-canvas">
<canvas id="video-canvas-0" width="1920" height="1080"></canvas>
</div>
<h1>AirMug Pro</h1>
<div class="sticky-elem main-message" id="main-message-a">
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eveniet, quisquam.
</div>
<div class="sticky-elem main-message" id="main-message-b">
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Eaque, mollitia.
</div>
<div class="sticky-elem main-message" id="main-message-c">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Cupiditate, dolorem.
</div>
<div class="sticky-elem main-message" id="main-message-d">
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Obcaecati cumque, vitae iste aperiam tempora impedit. Voluptatem nobis nihil deleniti sint!
</div>
</div>
<div class="scroll-section" id="scroll-section-1">
<p class="description">
<strong>AirMug Pro</strong>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Dicta commodi illo voluptates quae, reiciendis laborum quam beatae similique recusandae itaque. Exercitationem, aspernatur quidem, qui alias eveniet aliquid neque numquam labore voluptates, harum ipsum error quam magni voluptatibus atque repellat pariatur assumenda deleniti quaerat reprehenderit. Tempore quaerat soluta praesentium esse error id a quod voluptate minima asperiores maxime repudiandae nobis molestias ipsam unde sunt consectetur quidem modi tempora enim, quas voluptas ad. Amet eveniet quas inventore excepturi tempore nisi ullam sed iusto harum, voluptatum earum libero, dolorum omnis. Voluptatum, sit. Repellendus explicabo aut, modi dolorum nihil delectus nam minus mollitia quaerat.
</p>
</div>
<div class="scroll-section" id="scroll-section-2">
<div class="sticky-elem sticky-elem-canvas">
<canvas id="video-canvas-1" width="1920" height="1080"></canvas>
</div>
<div class="sticky-elem desc-message" id="desc-message-a">
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ipsam, quidem unde? Delectus optio architecto consectetur accusantium fugiat odit animi doloremque.
<div class="pin"></div>
</div>
<div class="sticky-elem desc-message" id="desc-message-b">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quos, consequuntur? Suscipit ut maiores voluptatem, pariatur in consequatur sapiente delectus iure odio ipsa soluta atque modi!
<div class="pin"></div>
</div>
<div class="sticky-elem desc-message" id="desc-message-c">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Eum dolore ut sunt, inventore distinctio saepe sit! Iure fugit neque, ducimus enim rem odit maiores consectetur.
<div class="pin"></div>
</div>
</div>
<div class="scroll-section" id="scroll-section-3">
<p class="mid-message">
<strong>Retina Mug</strong><br>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione.
</p>
<canvas class="image-blend-canvas" id="video-canvas-2" width="1920" height="1080"></canvas>
<p class="canvas-caption">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusantium unde molestiae aliquam sit, incidunt rerum aliquid sunt animi quasi provident sapiente obcaecati autem maiores ex libero minima tempore? Cumque eligendi recusandae sint tenetur ducimus iusto, excepturi ullam in veritatis maxime, libero dolores eveniet dolor odit reiciendis aliquam itaque? Distinctio, corporis dolorem. Delectus iure asperiores, quia veritatis modi sequi aperiam iusto nulla, et ea non nihil consectetur, eos nemo. Obcaecati perferendis ut assumenda distinctio est nam autem deleniti. Culpa beatae recusandae et incidunt iste dolorem error quia, fugit dicta in, tenetur dolore ad ab? Tenetur, eius. Mollitia beatae esse quibusdam nam doloremque fuga architecto rerum rem? Minus quae praesentium iusto rem maxime tempora hic distinctio, est non laborum ipsam cupiditate quis, quod totam at itaque perspiciatis repudiandae nesciunt vero officiis natus doloribus inventore unde? Dolores amet molestiae cupiditate aliquam ratione doloribus enim libero odio maiores atque inventore doloremque officia consequuntur ut, pariatur quis dolorum fugiat. Placeat dolore earum aperiam odit beatae perspiciatis, at provident pariatur recusandae neque facilis exercitationem officia unde consectetur quam assumenda. Ex vero quis fugit magnam, excepturi, voluptates debitis ipsum dolorem iste incidunt natus laboriosam dolores quibusdam. Accusantium numquam facere ullam quos totam nam aliquid magni delectus laudantium!
</p>
</div>
</div>
<footer class="footer">Copyright by Whi</footer>
<script src="main.js"></script>
</body>
</html>
# main.js
class Website {
constructor() {
this.enterNewScene = false;
this.acc = 0.1;
this.delayedYOffset = 0;
this.rafState = false;
this.rafId;
this.sceneInfo = [
{
type: 'sticky',
heightNum: 5,
scrollHeight: 0,
objs: {
container: document.querySelector('#scroll-section-0'),
localNav: document.querySelector('.local-nav'),
canvas: document.querySelector('#video-canvas-0'),
context: document.querySelector('#video-canvas-0').getContext('2d'),
messageA: document.querySelector('#main-message-a'),
messageB: document.querySelector('#main-message-b'),
messageC: document.querySelector('#main-message-c'),
messageD: document.querySelector('#main-message-d'),
videoImages: [],
},
values: {
messageA_opacity_in: [0, 1, {start: 0.1, end: 0.2}],
messageB_opacity_in: [0, 1, {start: 0.3, end: 0.4}],
messageC_opacity_in: [0, 1, {start: 0.5, end: 0.6}],
messageD_opacity_in: [0, 1, {start: 0.7, end: 0.8}],
messageA_opacity_out: [1, 0, {start: 0.25, end: 0.3}],
messageB_opacity_out: [1, 0, {start: 0.45, end: 0.5}],
messageC_opacity_out: [1, 0, {start: 0.65, end: 0.7}],
messageD_opacity_out: [1, 0, {start: 0.85, end: 0.9}],
canvas_opacity: [1, 0, {start: 0.9, end: 1.0}],
canvas: [0, 299, {start: 0, end: 1}],
},
},
{
type: 'normal',
scrollHeight: 0,
objs: {
container: document.querySelector('#scroll-section-1'),
}
},
{
type: 'sticky',
heightNum: 5,
scrollHeight: 0,
objs: {
container: document.querySelector('#scroll-section-2'),
canvas: document.querySelector('#video-canvas-1'),
context: document.querySelector('#video-canvas-1').getContext('2d'),
messageA: document.querySelector('#desc-message-a'),
messageB: document.querySelector('#desc-message-b'),
messageC: document.querySelector('#desc-message-c'),
pinA: document.querySelector('#desc-message-a .pin'),
pinB: document.querySelector('#desc-message-b .pin'),
pinC: document.querySelector('#desc-message-c .pin'),
videoImages: [],
},
values: {
messageA_opacity_in: [0, 1, {start: 0.25, end: 0.3}],
messageB_opacity_in: [0, 1, {start: 0.6, end: 0.65}],
messageC_opacity_in: [0, 1, {start: 0.87, end: 0.92}],
messageA_opacity_out: [1, 0, {start: 0.4, end: 0.45}],
messageB_opacity_out: [1, 0, {start: 0.68, end: 0.73}],
messageC_opacity_out: [1, 0, {start: 0.95, end: 1}],
messageA_translateY_in: [20, 0, {start: 0.25, end: 0.3}],
messageB_translateY_in: [30, 0, {start: 0.6, end: 0.65}],
messageC_translateY_in: [30, 0, {start: 0.87, end: 0.92}],
messageA_translateY_out: [0, -20, {start: 0.4, end: 0.45}],
messageB_translateY_out: [0, -20, {start: 0.68, end: 0.73}],
messageC_translateY_out: [0, -20, {start: 0.95, end: 1}],
pinA_scaleY: [0.5, 1, {start: 0.25, end: 0.3}],
pinB_scaleY: [0.5, 1, {start: 0.6, end: 0.80}],
pinC_scaleY: [0.5, 1, {start: 0.87, end: 0.92}],
canvas_opacity: [1, 0, {start: 0.9, end: 1.0}],
canvas: [0, 959, {start: 0, end: 1}],
}
},
{
type: 'sticky',
heightNum: 5,
scrollHeight: 0,
objs: {
container: document.querySelector('#scroll-section-3'),
canvas: document.querySelector('#video-canvas-2'),
context: document.querySelector('#video-canvas-2').getContext('2d'),
images: [],
},
values: {
rect1X: [0, 0, {start: 0, end: 0}],
rect2X: [0, 0, {start: 0, end: 0}],
rectStartY: 0,
blendHeight: [0, 0, {start: 0, end: 0}],
canvas_scale: [0, 0, {start: 0, end: 0}],
},
}
]
this.prepareVideoImages();
this.addEventListener();
}
setLayout() {
for (let idx = 0; idx < this.sceneInfo.length; idx++) {
const info = this.sceneInfo[idx];
if (info.type === 'sticky') {
info.scrollHeight = info.heightNum * window.innerHeight;
} else {
info.scrollHeight = info.objs.container.offsetHeight;
}
info.objs.container.style.height = `${info.heightNum * window.innerHeight}px`;
}
let totalScrollHeight = 0;
this.currentScene = 0;
for (let idx = 0; idx < this.sceneInfo.length; idx++) {
totalScrollHeight += this.sceneInfo[idx].scrollHeight;
if (totalScrollHeight > this.yOffset) {
this.currentScene = idx;
break;
}
}
document.body.setAttribute('id', `show-scene-${this.currentScene}`);
const heightRatio = window.innerHeight / 1080;
this.sceneInfo[0].objs.canvas.style.transform = `translate3d(-50%, -50%, 0) scale(${heightRatio})`;
}
scrollLoop() {
if (this.enterNewScene) {
return
}
this.prevScrollHeight = 0;
for (let idx = 0; idx < this.currentScene; idx++) {
this.prevScrollHeight += this.sceneInfo[idx].scrollHeight;
}
if (this.yOffset > this.prevScrollHeight + this.sceneInfo[this.currentScene].scrollHeight) {
this.enterNewScene = true;
this.currentScene += 1;
// TODO: REFACTOR
this.prevScrollHeight = 0;
for (let idx = 0; idx < this.currentScene; idx++) {
this.prevScrollHeight += this.sceneInfo[idx].scrollHeight;
}
} else if (this.yOffset < this.prevScrollHeight) {
this.enterNewScene = true;
this.currentScene -= 1;
this.prevScrollHeight = 0;
for (let idx = 0; idx < this.currentScene; idx++) {
this.prevScrollHeight += this.sceneInfo[idx].scrollHeight;
}
}
document.body.setAttribute('id', `show-scene-${this.currentScene}`);
this.playAnimation();
this.enterNewScene = false;
}
playAnimation() {
const sceneScrollHeight = this.yOffset - this.prevScrollHeight;
const sceneScrollRatio = sceneScrollHeight / this.sceneInfo[this.currentScene].scrollHeight;
const objs = this.sceneInfo[this.currentScene].objs;
const values = this.sceneInfo[this.currentScene].values;
let imgIdx;
let canvasHeightRatio;
let canvasWidthRatio;
let canvasRescaleRatio;
switch (this.currentScene) {
case 0:
imgIdx = Math.round(this.calcValues(values.canvas, sceneScrollRatio));
canvasHeightRatio = window.innerHeight / objs.canvas.height;
canvasWidthRatio = window.innerWidth / objs.canvas.width;
canvasRescaleRatio = canvasHeightRatio;
if (canvasWidthRatio > canvasHeightRatio) {
canvasRescaleRatio = canvasWidthRatio;
}
objs.canvas.style.transform = `translate3d(-50%, -50%, 0) scale(${canvasRescaleRatio})`;
// objs.context.drawImage(objs.videoImages[imgIdx], 0, 0);
if (sceneScrollRatio < 0.22) {
objs.messageA.style.opacity = this.calcValues(values.messageA_opacity_in, sceneScrollRatio);
} else {
objs.messageA.style.opacity = this.calcValues(values.messageA_opacity_out, sceneScrollRatio);
}
if (sceneScrollRatio < 0.42) {
objs.messageB.style.opacity = this.calcValues(values.messageB_opacity_in, sceneScrollRatio);
} else {
objs.messageB.style.opacity = this.calcValues(values.messageB_opacity_out, sceneScrollRatio);
}
if (sceneScrollRatio < 0.62) {
objs.messageC.style.opacity = this.calcValues(values.messageC_opacity_in, sceneScrollRatio);
} else {
objs.messageC.style.opacity = this.calcValues(values.messageC_opacity_out, sceneScrollRatio);
}
if (sceneScrollRatio < 0.82) {
objs.messageD.style.opacity = this.calcValues(values.messageD_opacity_in, sceneScrollRatio);
} else {
objs.messageD.style.opacity = this.calcValues(values.messageD_opacity_out, sceneScrollRatio);
}
if (sceneScrollRatio > 0.85) {
objs.canvas.style.opacity = this.calcValues(values.canvas_opacity, sceneScrollRatio);
}
break;
case 1:
break;
case 2:
imgIdx = Math.round(this.calcValues(values.canvas, sceneScrollRatio));
canvasHeightRatio = window.innerHeight / objs.canvas.height;
canvasWidthRatio = window.innerWidth / objs.canvas.width;
canvasRescaleRatio = canvasHeightRatio;
if (canvasWidthRatio > canvasHeightRatio) {
canvasRescaleRatio = canvasWidthRatio;
}
objs.canvas.style.transform = `translate3d(-50%, -50%, 0) scale(${canvasRescaleRatio})`;
// objs.context.drawImage(objs.videoImages[imgIdx], 0, 0);
if (sceneScrollRatio < 0.35) {
objs.messageA.style.opacity = this.calcValues(values.messageA_opacity_in, sceneScrollRatio);
objs.messageA.style.transform = `translate3d(0, ${this.calcValues(values.messageA_translateY_in, sceneScrollRatio)}%, 0)`;
objs.pinA.style.transform = `scaleY(${this.calcValues(values.pinA_scaleY, sceneScrollRatio)})`;
} else {
objs.messageA.style.opacity = this.calcValues(values.messageA_opacity_out, sceneScrollRatio);
objs.messageA.style.transform = `translate3d(0, ${this.calcValues(values.messageA_translateY_out, sceneScrollRatio)}%, 0)`;
objs.pinA.style.transform = `scaleY(${this.calcValues(values.pinA_scaleY, sceneScrollRatio)})`;
}
if (sceneScrollRatio < 0.67) {
objs.messageB.style.opacity = this.calcValues(values.messageB_opacity_in, sceneScrollRatio);
objs.messageB.style.transform = `translate3d(0, ${this.calcValues(values.messageB_translateY_in, sceneScrollRatio)}%, 0)`;
objs.pinB.style.transform = `scaleY(${this.calcValues(values.pinB_scaleY, sceneScrollRatio)})`;
} else {
objs.messageB.style.opacity = this.calcValues(values.messageB_opacity_out, sceneScrollRatio);
objs.messageB.style.transform = `translate3d(0, ${this.calcValues(values.messageB_translateY_out, sceneScrollRatio)}%, 0)`;
objs.pinB.style.transform = `scaleY(${this.calcValues(values.pinB_scaleY, sceneScrollRatio)})`;
}
if (sceneScrollRatio < 0.94) {
objs.messageC.style.opacity = this.calcValues(values.messageC_opacity_in, sceneScrollRatio);
objs.messageC.style.transform = `translate3d(0, ${this.calcValues(values.messageC_translateY_in, sceneScrollRatio)}%, 0)`;
objs.pinC.style.transform = `scaleY(${this.calcValues(values.pinC_scaleY, sceneScrollRatio)})`;
} else {
objs.messageC.style.opacity = this.calcValues(values.messageC_opacity_out, sceneScrollRatio);
objs.messageC.style.transform = `translate3d(0, ${this.calcValues(values.messageC_translateY_out, sceneScrollRatio)}%, 0)`;
objs.pinC.style.transform = `scaleY(${this.calcValues(values.pinC_scaleY, sceneScrollRatio)})`;
}
if (sceneScrollRatio > 0.85) {
objs.canvas.style.opacity = this.calcValues(values.canvas_opacity, sceneScrollRatio);
}
break;
case 3:
canvasHeightRatio = window.innerHeight / objs.canvas.height;
canvasWidthRatio = window.innerWidth / objs.canvas.width;
canvasRescaleRatio = canvasHeightRatio;
if (canvasWidthRatio > canvasHeightRatio) {
canvasRescaleRatio = canvasWidthRatio;
}
const recalculatedInnerWidth = window.innerWidth / canvasRescaleRatio;
const recalculatedInnerHeight = window.innerHeight / canvasRescaleRatio;
if (!values.rectStartY) {
values.rectStartY = objs.canvas.offsetTop + (objs.canvas.height - objs.canvas.height * canvasRescaleRatio) / 2;
values.rect1X[2].start = (window.innerHeight / 2) / this.sceneInfo[this.currentScene].scrollHeight;
values.rect1X[2].end = values.rectStartY / this.sceneInfo[this.currentScene].scrollHeight;
values.rect2X[2].start = (window.innerHeight / 2) / this.sceneInfo[this.currentScene].scrollHeight;
values.rect2X[2].end = values.rectStartY / this.sceneInfo[this.currentScene].scrollHeight;
}
objs.canvas.style.transform = `scale(${canvasRescaleRatio})`;
objs.context.fillStyle = 'white';
objs.context.drawImage(objs.images[0], 0, 0);
const whiteRectWidth = 0.15 * recalculatedInnerWidth;
values.rect1X[0] = (objs.canvas.width - recalculatedInnerWidth) / 2;
values.rect1X[1] = values.rect1X[0] - whiteRectWidth;
values.rect2X[0] = values.rect1X[0] + recalculatedInnerWidth - whiteRectWidth;
values.rect2X[1] = values.rect2X[0] + whiteRectWidth;
objs.context.fillRect(
parseInt(this.calcValues(values.rect1X, sceneScrollRatio)), 0,
parseInt(whiteRectWidth), objs.canvas.height);
objs.context.fillRect(
parseInt(this.calcValues(values.rect2X, sceneScrollRatio)), 0,
parseInt(whiteRectWidth), objs.canvas.height);
if (sceneScrollRatio < values.rect1X[2].end) {
objs.canvas.classList.remove('sticky');
} else {
objs.canvas.classList.add('sticky');
objs.canvas.style.top = `-${(objs.canvas.height - objs.canvas.height * canvasRescaleRatio) / 2}px`;
if (!values.blendHeight[1]) {
values.blendHeight[0] = 0;
values.blendHeight[1] = objs.canvas.height;
values.blendHeight[2].start = values.rect1X[2].end;
values.blendHeight[2].end = values.blendHeight[2].start + 0.2;
}
const blendImageheight = this.calcValues(values.blendHeight, sceneScrollRatio);
objs.context.drawImage(
objs.images[1],
0, objs.canvas.height - blendImageheight, objs.canvas.width, blendImageheight,
0, objs.canvas.height - blendImageheight, objs.canvas.width, blendImageheight);
if (values.blendHeight[2].end < sceneScrollRatio) {
if (!values.canvas_scale[0]) {
values.canvas_scale[0] = canvasRescaleRatio;
values.canvas_scale[1] = 0.5;
values.canvas_scale[2].start = values.blendHeight[2].end
values.canvas_scale[2].end = values.canvas_scale[2].start + 0.2;
}
objs.canvas.style.transform = `scale(${this.calcValues(values.canvas_scale, sceneScrollRatio)})`;
if (values.canvas_scale[2].end < sceneScrollRatio) {
objs.canvas.classList.remove('sticky');
objs.canvas.style.marginTop = `${0.4 * this.sceneInfo[this.currentScene].scrollHeight}px`;
} else {
objs.canvas.style.marginTop = 0;
}
}
}
break;
}
}
calcValues(data, currPos) {
let result;
const [startVal, endVal, valRange] = data;
const { start: startRange, end: endRange } = valRange;
if (currPos <= startRange) {
result = startVal;
} else if (endRange <= currPos) {
result = endVal;
} else {
result = startVal + (endVal - startVal) * (currPos - startRange) / (endRange - startRange)
}
return result;
}
prepareVideoImages() {
let imgElem;
for (let idx = 0; idx < 300; idx++) {
imgElem = new Image();
imgElem.src = `./video/001/IMG_${6726 + idx}.JPG`;
this.sceneInfo[0].objs.videoImages.push(imgElem);
}
let imgElem2;
for (let idx = 0; idx < 960; idx++) {
imgElem2 = new Image();
imgElem2.src = `./video/002/IMG_${7027 + idx}.JPG`;
this.sceneInfo[2].objs.videoImages.push(imgElem2);
}
let imgElem3;
const imgPaths = ['./images/blend-image-1.jpg', './images/blend-image-2.jpg']
for (const imgPath of imgPaths) {
imgElem3 = new Image();
imgElem3.src = imgPath;
this.sceneInfo[3].objs.images.push(imgElem3);
}
}
loop() {
this.delayedYOffset = this.delayedYOffset + (this.yOffset - this.delayedYOffset) * this.acc;
if (!this.enterNewScene) {
if (this.currentScene === 0 || this.currentScene === 2) {
const sceneScrollHeight = this.delayedYOffset - this.prevScrollHeight;
const sceneScrollRatio = sceneScrollHeight / this.sceneInfo[this.currentScene].scrollHeight;
const values = this.sceneInfo[this.currentScene].values;
const objs = this.sceneInfo[this.currentScene].objs;
let imgIdx = parseInt(this.calcValues(values.canvas, sceneScrollRatio));
if (objs.videoImages[imgIdx]) {
objs.context.drawImage(objs.videoImages[imgIdx], 0, 0);
}
}
}
this.rafId = requestAnimationFrame(this.loop.bind(this));
if (Math.abs(this.yOffset - this.delayedYOffset) < 1) {
cancelAnimationFrame(this.rafId)
this.rafState = false;
}
}
checkMenu() {
if (this.yOffset > 44) {
this.sceneInfo[0].objs.localNav.classList.add('local-nav-sticky');
} else {
this.sceneInfo[0].objs.localNav.classList.remove('local-nav-sticky');
}
}
addEventListener() {
window.addEventListener('load', () => {
document.body.classList.remove('before-load');
this.setLayout();
debugger;
// this.sceneInfo[0].objs.context.drawImage(this.sceneInfo[0].objs.videoImages[0], 0, 0);
this.yOffset = window.pageYOffset;
console.log('yoffset', this.yOffset)
let tempYOffSet = this.yOffset;
let tempScrollCount = 0;
if (tempYOffSet > 0) {
let siId = setInterval(() => {
window.scrollTo(0, tempYOffSet);
tempYOffSet += 5;
tempScrollCount++;
if (tempScrollCount > 20) {
clearInterval(siId);
}
}, 20)
}
window.addEventListener('scroll', () => {
this.yOffset = window.pageYOffset;
this.scrollLoop();
this.checkMenu();
if (!this.rafState) {
this.rafId = requestAnimationFrame(this.loop.bind(this));
this.rafState = true;
}
})
document.querySelector('.loading').addEventListener('transitionend', (e) => {
document.body.removeChild(e.currentTarget);
})
})
}
}
const website = new Website();
# style.css
html {
font-size: 12px;
font-family: 'Noto Sans KR', sans-serif;
}
body {
overflow-x: hidden;
position: relative;
margin: 0;
}
div, span, article, section, header, footer, aside, p, ul, li, fieldset, legend, label, a, nav, form {
box-sizing: border-box;
}
body * {
overflow-x: hidden;
}
body.before-load {
overflow: hidden;
}
.before-load .global-nav,
.before-load .local-nav,
.before-load .container,
.before-load .footer {
display: none;
}
.loading {
position: fixed;
display: flex;
align-items: center;
justify-content: center;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 100;
opacity: 0;
background: white;
transition: 2.0s;
}
.before-load .loading {
opacity: 1;
}
@keyframes loading-circle-ani {
0% { stroke-dashoffset: 157; }
75% { stroke-dashoffset: -147; }
100% { stroke-dashoffset: -157; }
}
@keyframes loading-spin {
100% { transform: rotate(360deg); }
}
.loading-circle {
width: 54px;
height: 54px;
animation: loading-spin 3s infinite;
}
.loading-circle circle {
stroke: black;
stroke-width: 4;
stroke-dasharray: 157;
stroke-dashoffset: 0;
fill: transparent;
animation: loading-circle-ani 3s infinite;
}
div {
box-sizing: border-box;
}
a {
text-decoration: none;
color: black;
}
.global-nav {
position: absolute;
width: 100%;
top: 0;
left: 0;
height: 44px;
z-index: 5;
}
.global-nav-links,
.local-nav-links {
display: flex;
align-items: center;
justify-content: space-between;
max-width: 1000px;
margin: 0 auto;
padding: 0 1rem;
height: 100%;
}
.local-nav {
position: absolute;
width: 100%;
left: 0;
top: 50px;
height: 55px;
z-index: 6;
border-bottom: 1px solid #888888;
}
.local-nav-sticky {
position: fixed;
top: 0;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: saturate(180%) blur(15px);
}
.local-nav-right a {
margin-left: 2em;
}
.product-name {
font-size: 1.3rem;
font-weight: 700;
}
.footer {
position: relative;
bottom: 0;
height: 45px;
width: 100%;
background: orange;
display: flex;
align-items: center;
justify-content: center;
}
.scroll-section {
position: relative;
padding-top: 50vh;
width: 100%;
margin: 0 auto;
}
.scroll-section h1 {
font-size: 3rem;
top: -10vh;
text-align: center;
position: relative;
}
.main-message {
top: 45vh;
font-size: 1.3rem;
text-align: center;
margin: 0 auto;
opacity: 0;
}
.sticky-elem {
position: fixed;
left: 0;
width: 100%;
display: none;
}
.sticky-elem-canvas {
top: 0;
height: 100%;
}
.sticky-elem-canvas canvas {
position: absolute;
left: 50%;
top: 50%;
}
.description {
font-size: 1.3rem;
max-width: 1000px;
margin: 0 auto;
padding: 0 1rem;
}
.description strong {
font-size: 3em;
float: left;
margin-right: 0.5em;
}
.mid-message {
font-size: 1.4rem;
text-align: center;
margin: 0 auto;
padding-left: 1rem;
padding-right: 1rem;
}
.mid-message .strong {
font-size: 3em;
font-weight: 600;
}
.image-blend-canvas.sticky{
position: fixed;
top: 0;
}
#scroll-section-3 {
display: flex;
flex-direction: column;
align-items: center;
}
.canvas-caption {
font-size: 1.2rem;
color: rgb(41, 37, 37);
max-width: 1000px;
margin: 0 auto;
margin-top: -10vh;
padding: 0 1rem;
padding-bottom: 3rem;
}
.desc-message {
font-size: 1rem;
width: 20%;
}
#desc-message-a {
left: 40%;
top: 30%;
}
#desc-message-b {
left: 40%;
top: 25%;
}
#desc-message-c {
left: 40%;
top: 10%;
}
#show-scene-0 #scroll-section-0 .sticky-elem {
display: block;
}
#show-scene-1 #scroll-section-1 .sticky-elem {
display: block;
}
#show-scene-2 #scroll-section-2 .sticky-elem {
display: block;
}
.pin {
height: 10rem;
width: 1px;
background: black;
}
@media (min-width: 1024px) {
html {
font-size: 14px;
}
#scroll-section-0 h1 {
font-size: 9vw;
}
.main-message {
font-size: 4vw;
}
.description {
font-size: 2rem;
}
.description strong {
font-size: 6rem;
}
#scroll-section-2 .main-message {
font-size: 6vw;
}
#scroll-section-2 .b {
top: 20%;
left: 53%;
}
#scroll-section-2 .c {
left: 55%;
}
.main-message small {
font-size: 1.5vw;
}
.desc-message {
width: 20%;
}
.mid-message {
font-size: 4vw;
}
.canvas-caption {
margin-top: -8rem;
padding: 0;
font-size: 2rem;
}
}
답변 3
0
아, 약간은 차이가 있을 수 있을듯한데 혹시 제가 드린 완성파일도 똑같이 동작하나요? 만약 완성파일은 괜찮은데 이것만 그런거라면 뭔가 차이가 있다는건데.. 저도 시간날때 휘님 하신것처럼 클래스로 한번 바꾸어 볼게요^^
0
class로 바꾸어보고 계시네요^^
제가 테스트 해보니 큰 이상은 발견하지 못했는데,
완성파일의 이 부분을 보시면,
콘텐츠 양에 따라 높이 계산 오차를 방지하도록 before-load 클래스를 제거하기 전에 setLayout을 한번 더 호출해주는데,
작성하신 소스에는 그 부분이 빠져있습니다.
이렇게 추가하고 테스트를 해보시면 어떨까 싶네요~
일단 더 간단한 형태인 @simple-version에 있는 버전으로 수정해보셔도 좋을 것 같습니다^^
이미지 배경 문의
0
67
1
[크로스브라우징] safari에서 동영상 영역 미노출
0
107
1
항상 궁금했는데 크림슨 컬러 선택하셨을때 활용했던 사이트 좀 알려주세요~
0
109
2
vue강의는안하시나요?!
0
101
1
스크롤 속도에 따른 messageA_opacity_out
0
115
1
drawImage(objs.videoImages[sequence], 0, 0); error
0
89
1
선생님 캔버스 width 크기는 이미지 크기에맞게 해줘야하나요?
0
127
0
선생님 안녕하세요. 혹시 메인개발(?)분야가 뭔지 궁금합니다.
0
206
1
React에서 load 상태를 어떻게 감지할 수 있을까요?
0
679
1
[섹션7-3: 버그수정 2] tempYOffset 오류
0
195
1
스크롤할 때 캔버스로 하신 이유가 있으신가요? 그냥 성능 떄문에 캔버스로 하신건가요?
0
313
2
게속 오류떠서 글 작성해봐요....
0
506
2
Vanilla JavaScript로 SPA 만드는 자료 혹은 선택 기준을 추천해주실 수 있으신가요?
1
488
1
특정 타이밍 스크롤 애니메이션 적용하기 섹션 수강중입니다.
0
455
2
[#svg, #이미지프레임과 텍스트 싱크] 스크롤 값에 움직이는 svg path, 이미지프레임과 텍스트 싱크 맞추는 것, 2가지 질문이 있습니다.
0
451
2
페이지가 처음 로딩 되었을 때 애니메이션 처리가 되지 않는 느낌입니다
0
432
1
섹션2 번째, opacity=0 되지 않고 잔상이 남습니다.
0
533
1
원래 쿼리셀렉터에서는 띄워쓰기 하면안되나요?
0
593
2
라이브러리 질문
1
412
2
translateY대신 애플에서 사용한 것 처럼 matrix로 scale의 크기를 주려고 하는데
0
409
1
[스크롤 높이 세팅] scrollHeight값이 3990아닌 4645로만 나오는데 뭐가 문제일까요? ㅠㅠ
0
598
2
scrollLoop 함수 질문
0
476
2
도메인 웹호스팅시 이미지가 안 뜨는데 누가 좀 알려주세요ㅠㅜ
0
1235
2
load 이벤트시 첫 비디오 이미지가 뜨네요.
0
506
2






