inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

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

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

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

171

과연

작성한 질문수 14

0

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

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

svg javascript HTML/CSS 인터랙티브-웹 웹 디자인 클론코딩

답변 1

0

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;

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

이미지 배경 문의

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

681

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