작성자 없음
작성자 정보가 삭제된 글입니다.
작성
·
54
0
function setCanvasImages() {
let imgElem;
for(let i = 0; i < sceneInfo.values.videoImageCount; i++) {
imgElem = new Image();
imgElem.src = `./images/picdiet 1/${1 + i}.jpg`;
sceneInfo[0].objs.videoImages.push(imgElem);
}
// /home/ibmuser01/src/images/picdiet 1/1.jpg
}
setCanvasImages();
function setLayout() {
// 각 스크롤 섹션의 높이 세팅
for (let i = 0; i < sceneInfo.length; i++) {
if (sceneInfo[i].type === 'sticky') {
sceneInfo[i].scrollHeight = sceneInfo[i].heightNum * window.innerHeight;
} else if (sceneInfo[i].type === 'normal') {
sceneInfo[i].scrollHeight = sceneInfo[i].objs.content.offsetHeight + window.innerHeight * 0.5;
}
sceneInfo[i].objs.container.style.height = `${sceneInfo[i].scrollHeight}px`;
}
yOffset = window.pageYOffset;
let totalScrollHeight = 0;
for (let i = 0; i < sceneInfo.length; i++) {
totalScrollHeight += sceneInfo[i].scrollHeight;
if (totalScrollHeight >= yOffset) {
currentScene = i;
break;
}
}
document.body.setAttribute('id', `show-scene-${currentScene}`);
}
function calcValues(values, currentYOffset) {
let rv;
// 현재 씬(스크롤섹션)에서 스크롤된 범위를 비율로 구하기
const scrollHeight = sceneInfo[currentScene].scrollHeight;
const scrollRatio = currentYOffset / scrollHeight;
if (values.length === 3) {
// start ~ end 사이에 애니메이션 실행
const partScrollStart = values[2].start * scrollHeight;
const partScrollEnd = values[2].end * scrollHeight;
const partScrollHeight = partScrollEnd - partScrollStart;
if (currentYOffset >= partScrollStart && currentYOffset <= partScrollEnd) {
rv = (currentYOffset - partScrollStart) / partScrollHeight * (values[1] - values[0]) + values[0];
} else if (currentYOffset < partScrollStart) {
rv = values[0];
} else if (currentYOffset > partScrollEnd) {
rv = values[1];
}
} else {
rv = scrollRatio * (values[1] - values[0]) + values[0];
}
return rv;
}
function playAnimation() {
const objs = sceneInfo[currentScene].objs;
const values = sceneInfo[currentScene].values;
const currentYOffset = yOffset - prevScrollHeight;
const scrollHeight = sceneInfo[currentScene].scrollHeight;
const scrollRatio = currentYOffset / scrollHeight;
switch (currentScene) {
case 0:
let sequence = Math.round(calcValues(values.imageSequence, currentYOffset));
objs.context.drawImage(objs.videoImages[sequence], 0, 0);
if (scrollRatio <= 0.22) {
// in
objs.messageA.style.opacity = calcValues(values.messageA_opacity_in, currentYOffset);
objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_in, currentYOffset)}%, 0)`;
} else {
// out
objs.messageA.style.opacity = calcValues(values.messageA_opacity_out, currentYOffset);
objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_out, currentYOffset)}%, 0)`;
}
if (scrollRatio <= 0.42) {
// in
objs.messageB.style.opacity = calcValues(values.messageB_opacity_in, currentYOffset);
objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_in, currentYOffset)}%, 0)`;
} else {
// out
objs.messageB.style.opacity = calcValues(values.messageB_opacity_out, currentYOffset);
objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_out, currentYOffset)}%, 0)`;
}
if (scrollRatio <= 0.62) {
// in
objs.messageC.style.opacity = calcValues(values.messageC_opacity_in, currentYOffset);
objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_in, currentYOffset)}%, 0)`;
} else {
// out
objs.messageC.style.opacity = calcValues(values.messageC_opacity_out, currentYOffset);
objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_out, currentYOffset)}%, 0)`;
}
if (scrollRatio <= 0.82) {
// in
objs.messageD.style.opacity = calcValues(values.messageD_opacity_in, currentYOffset);
objs.messageD.style.transform = `translate3d(0, ${calcValues(values.messageD_translateY_in, currentYOffset)}%, 0)`;
} else {
// out
objs.messageD.style.opacity = calcValues(values.messageD_opacity_out, currentYOffset);
objs.messageD.style.transform = `translate3d(0, ${calcValues(values.messageD_translateY_out, currentYOffset)}%, 0)`;
}
break;
case 2:
// console.log('2 play');
if (scrollRatio <= 0.25) {
// in
objs.messageA.style.opacity = calcValues(values.messageA_opacity_in, currentYOffset);
objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_in, currentYOffset)}%, 0)`;
} else {
// out
objs.messageA.style.opacity = calcValues(values.messageA_opacity_out, currentYOffset);
objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_out, currentYOffset)}%, 0)`;
}
if (scrollRatio <= 0.57) {
// in
objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_in, currentYOffset)}%, 0)`;
objs.messageB.style.opacity = calcValues(values.messageB_opacity_in, currentYOffset);
objs.pinB.style.transform = `scaleY(${calcValues(values.pinB_scaleY, currentYOffset)})`;
} else {
// out
objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_out, currentYOffset)}%, 0)`;
objs.messageB.style.opacity = calcValues(values.messageB_opacity_out, currentYOffset);
objs.pinB.style.transform = `scaleY(${calcValues(values.pinB_scaleY, currentYOffset)})`;
}
if (scrollRatio <= 0.83) {
// in
objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_in, currentYOffset)}%, 0)`;
objs.messageC.style.opacity = calcValues(values.messageC_opacity_in, currentYOffset);
objs.pinC.style.transform = `scaleY(${calcValues(values.pinC_scaleY, currentYOffset)})`;
} else {
// out
objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_out, currentYOffset)}%, 0)`;
objs.messageC.style.opacity = calcValues(values.messageC_opacity_out, currentYOffset);
objs.pinC.style.transform = `scaleY(${calcValues(values.pinC_scaleY, currentYOffset)})`;
}
break;
case 3:
// console.log('3 play');
break;
}
}
function scrollLoop() {
enterNewScene = false;
prevScrollHeight = 0;
for (let i = 0; i < currentScene; i++) {
prevScrollHeight += sceneInfo[i].scrollHeight;
}
if (yOffset > prevScrollHeight + sceneInfo[currentScene].scrollHeight){
enterNewScene = true;
currentScene++;
document.body.setAttribute('id', `show-scene-${currentScene}`);
}
if(yOffset < prevScrollHeight){
enterNewScene = true;
if(currentScene === 0) return;
currentScene--;
document.body.setAttribute('id', `show-scene-${currentScene}`);
}
if(enterNewScene) return;
playAnimation();
}
window.addEventListener('scroll', () => {
yOffset = window.pageYOffset;
scrollLoop();
});
window.addEventListener('load', setLayout);
window.addEventListener('resize', setLayout);
})();
main.js:181 Uncaught TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(CSSImageValue or HTMLCanvasElement or HTMLImageElement or HTMLVideoElement or ImageBitmap or OffscreenCanvas or SVGImageElement or VideoFrame)'.
at playAnimation (main.js:181:30)
at scrollLoop (main.js:292:9)
at main.js:297:9
이러한 에러가 나요.
이미지 파일은
여기에 저장되어있슴돠.
답변 1
0
안녕하세요, 인프런 AI 인턴입니다.
류도형님께서 경험 중인 문제는 CanvasRenderingContext2D
의 drawImage
메소드에 전달된 이미지 객체가 올바른 타입이 아닐 때 발생하는 에러입니다. 이 문제는 주로 이미지가 제대로 로드되지 않았거나, 배열 접근에 문제가 있거나, 경로 설정이 잘못되었을 때 발생할 수 있습니다.
다음은 문제 해결에 도움이 될 몇 가지 방법입니다:
이미지 로딩 상태 확인: 이미지가 완전히 로드되기 전에 drawImage
가 실행될 수 있습니다. 이미지를 로드한 후에 drawImage
를 실행하도록 보장해야 합니다.
imgElem.onload = function() {
sceneInfo[0].objs.videoImages.push(imgElem);
};
경로 확인: 이미지 경로가 정확한지 확인하세요. 현재 코드에서는 이미지가 ./images/picdiet 1/{number}.jpg
경로에 있다고 설정되어 있으나, 이미지 경로에서 스페이스가 들어가 있는 부분이 브라우저에 따라 문제가 될 수 있습니다. 만약 URL 인코딩이 안 된다면, 경로의 폴더 이름을 변경해서 공백을 제거하거나 %20
으로 대체할 수 있습니다.
이미지 확장자 확인: 이미지 파일의 확장자는 대소문자를 구분해야 하므로 .jpg
인지 .JPG
인지 확인하고, 코드에서 일관되게 사용해야 합니다. 예를 들어:
imgElem.src = `./images/picdiet%201/${1 + i}.jpg`;
콘솔 사용: console.log(sequence)
를 사용하여 calcValues
에서 얻어지는 sequence
값이 배열의 유효한 인덱스인지 확인해보세요. 이 값이 항상 올바른 수준인지 확인하는 것이 중요합니다.
데이터 초기화 확인: sceneInfo
배열과 그 내부의 객체 및 배열이 올바르게 초기화되었는지 확인하세요. 초기화 시마다 배열이 비어있지 않고 목적에 맞는 값들이 할당되어 있는지 체크해야 합니다.
이러한 방법을 통해 문제를 해결할 수 있습니다. 추가적으로, 유사한 문제를 다룬 기존 질문을 참고해 보시기 바랍니다:
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.