인프런 커뮤니티 질문&답변

과연님의 프로필 이미지
과연

작성한 질문수

애플 웹사이트 인터랙션 클론!

캔버스 드로우 애니메이션 2

동작(?)을 안해요..!

작성

·

126

0

https://github.com/jellybrown/apple_clone/blob/master/js/main.js

제가 빼먹은게 있나요...? 어려워서 돌려봤는데 어디서 뭘빼먹었는지 모르겠어요 ㅠ.ㅠ

답변 1

0

1분코딩님의 프로필 이미지
1분코딩
지식공유자

마지막 섹션에 이미지 블렌딩 처리하는 부분 말씀일까요?
sceneInfo에 // 3 부분의 values를 아래와 같이 업데이트 하시고,

values: {
			rect1X: [ 0, 0, { start: 0, end: 0 } ],
			rect2X: [ 0, 0, { start: 0, end: 0 } ],
			blendHeight: [ 0, 0, { start: 0, end: 0 } ],
			canvas_scale: [ 0, 0, { start: 0, end: 0 } ],
			canvasCaption_opacity: [ 0, 1, { start: 0, end: 0 } ],
			canvasCaption_translateY: [ 20, 0, { start: 0, end: 0 } ],
			rectStartY: 0
		},

playAnimation 함수의 case 3: 부분을 아래처럼 해보세요~

case 3:
		  let step = 0;
		  // 가로/세로 모두 꽉 차게 하기 위해 여기서 세팅(계산 필요)
		  const widthRatio = window.innerWidth / objs.canvas.width;
		  const heightRatio = window.innerHeight / objs.canvas.height;
		  let canvasScaleRatio;

		  if (widthRatio <= heightRatio) {
			  // 캔버스보다 브라우저 창이 홀쭉한 경우
			  canvasScaleRatio = heightRatio;
		  } else {
			  // 캔버스보다 브라우저 창이 납작한 경우
			  canvasScaleRatio = widthRatio;
		  }

		  objs.canvas.style.transform = `scale(${canvasScaleRatio})`;
		  objs.context.fillStyle = 'white';
		  objs.context.drawImage(objs.images[0], 0, 0);

		  // 캔버스 사이즈에 맞춰 가정한 innerWidth와 innerHeight
		  const recalculatedInnerWidth = document.body.offsetWidth / canvasScaleRatio;
		  const recalculatedInnerHeight = window.innerHeight / canvasScaleRatio;

		  if (!values.rectStartY) {
			  // values.rectStartY = objs.canvas.getBoundingClientRect().top;
			  values.rectStartY = objs.canvas.offsetTop + (objs.canvas.height - objs.canvas.height * canvasScaleRatio) / 2;
			  values.rect1X[2].start = (window.innerHeight / 2) / scrollHeight;
			  values.rect2X[2].start = (window.innerHeight / 2) / scrollHeight;
			  values.rect1X[2].end = values.rectStartY / scrollHeight;
			  values.rect2X[2].end = values.rectStartY / scrollHeight;
		  }

		  const whiteRectWidth = recalculatedInnerWidth * 0.15;
		  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(calcValues(values.rect1X, currentYOffset)),
			  0,
			  parseInt(whiteRectWidth),
			  objs.canvas.height
		  );
		  objs.context.fillRect(
			  parseInt(calcValues(values.rect2X, currentYOffset)),
			  0,
			  parseInt(whiteRectWidth),
			  objs.canvas.height
		  );

		  if (scrollRatio < values.rect1X[2].end) {
			  step = 1;
			  // console.log('캔버스 닿기 전');
			  objs.canvas.classList.remove('sticky');
		  } else {
			  step = 2;
			  // console.log('캔버스 닿은 후');
			  // 이미지 블렌드
			  // values.blendHeight: [ 0, 0, { start: 0, end: 0 } ]
			  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 blendHeight = calcValues(values.blendHeight, currentYOffset);

			  objs.context.drawImage(objs.images[1],
				  0, objs.canvas.height - blendHeight, objs.canvas.width, blendHeight,
				  0, objs.canvas.height - blendHeight, objs.canvas.width, blendHeight
			  );

			  objs.canvas.classList.add('sticky');
			  objs.canvas.style.top = `${-(objs.canvas.height - objs.canvas.height * canvasScaleRatio) / 2}px`;

			  if (scrollRatio > values.blendHeight[2].end) {
				  values.canvas_scale[0] = canvasScaleRatio;
				  values.canvas_scale[1] = document.body.offsetWidth / (1.5 * objs.canvas.width);
				  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(${calcValues(values.canvas_scale, currentYOffset)})`;
				  objs.canvas.style.marginTop = 0;
			  }

			  if (scrollRatio > values.canvas_scale[2].end
				  && values.canvas_scale[2].end > 0) {
				  objs.canvas.classList.remove('sticky');
				  objs.canvas.style.marginTop = `${scrollHeight * 0.4}px`;

				  values.canvasCaption_opacity[2].start = values.canvas_scale[2].end;
				  values.canvasCaption_opacity[2].end = values.canvasCaption_opacity[2].start + 0.1;
				  values.canvasCaption_translateY[2].start = values.canvasCaption_opacity[2].start;
				  values.canvasCaption_translateY[2].end = values.canvasCaption_opacity[2].end;
				  objs.canvasCaption.style.opacity = calcValues(values.canvasCaption_opacity, currentYOffset);
				  objs.canvasCaption.style.transform = `translate3d(0, ${calcValues(values.canvasCaption_translateY, currentYOffset)}%, 0)`;
			  }
		  }
  
		  break;

이렇게 하면 이미지 블렌딩까지 핵심 동작은 처리가 되는 것으로 보입니다^^

과연님의 프로필 이미지
과연

작성한 질문수

질문하기