당신과 나의 미래가 React 앱에서 캔버스 요소를 설정하는 시간을 절약할 수 있도록, HTML 캔버스를 React 후크와 함께 사용하는 방법에 대한 최종 버전을 공유하겠습니다.
1단계: 캔버스 요소 렌더링
// src/components/Canvas.js
const Canvas = () => {
return (
<canvas
width="100"
height="100"
/>
)
};
export default Canvas;
TypeScript
복사
width및 height속성은 캔버스 요소에 의해 생성된 이미지에 대해
이미지 해상도와 종횡비(image resolution and the aspect ratio)라는 두 가지를 결정합니다 .
이미지 해상도 Image resolution
이미지에는 100 x 100 픽셀이 있습니다. 이 경우 이미지 너비의 1/100보다 얇은 선을 그리면 하위 픽셀 렌더링으로 끝나므로 성능상의 이유로 인해 이를 피해야 합니다(MDN 기여자 2019b 참조). 가장 얇은 선이 예를 들어 이미지 너비의 1/200이면 너비="200"을 설정해야 합니다.
종횡비 Aspect ratio
위의 예에서는 영상의 가로 세로 비율을 1:1(즉, 정사각형)로 정의합니다.
너비 및 높이 속성을 지정하지 못한 경우(HTML 캔버스의 많은 문서처럼), 기본 가로 세로 비율은 2:1(너비 300px 및 높이 150px)이 적용됩니다.
Corey의 (2019) - React 후크를 사용하여 캔버스 요소를 렌더링하는 방법에 대한 유용한 기사는 width및 height속성을 지정하지 않아 이 함정에 빠진 것으로 보입니다.
지금까지는 React와 아무 관련이 없습니다. HTML 캔버스를 사용할 때마다 width및 height속성을 설정해야 합니다.
2단계: 캔버스 요소 참조
<canvas> 요소로 이미지를 그리려면 먼저 자바스크립트에서 참조해야 합니다. HTML 캔버스(예: MDN Contributors 2019a )에 대한 소개 튜토리얼에서는 document.getElementById(id)를 사용하도록 안내합니다. 여기서 id는 캔버스 요소의 id 속성 값입니다.
useRef()를 가리키는 변수를 작성한 후 이 변수를 캔버스 요소의 ref 특성 값으로 사용합니다.
// src/components/Canvas.js
const Canvas = () => {
const canvas = React.useRef(); // ADDED
return (
<canvas
ref={canvas} // ADDED
width="100"
height="100"
/>
)
};
export default Canvas;
TypeScript
복사
이러한 방식으로 캔버스 요소가 화면에 렌더링되면, JavaScript 코드에서는 canvas.current라고 할 수 있습니다.
3단계: 캔버스 컨텍스트 만들기
캔버스 요소에 이미지를 그리려면 CanvasRenderingContext2D 객체를 작성해야 합니다(종종 코드에서 context또는 ctx와 같은 변수 이름 할당).
이 단계는 HTML 캔버스를 리액트와 함께 사용할 때 가장 까다로운 부분입니다. 해결책은 useEffect hook입니다
// src/components/Canvas.js
const Canvas = () => {
const canvas = useRef(); // ADDED
useEffect(() => {
const context = canvas.current.getContext('2d');
});
return (
<canvas
ref={canvas}
width="100"
height="100"
/>
)
};
export default Canvas;
TypeScript
복사
이전 단계에서 설명한 바와 같이 canvas.current는 위의 코드에 있는 <canvas> 요소를 가리킨다.
하지만 리액트가 실제로 캔버스 요소를 화면에 렌더링하기 전까지는 null입니다. 리액트가 구성 요소를 렌더링한 후 코드 세트를 실행하려면 useEffect hook으로 묶어야 합니다(리액트 구성 요소 수명 주기 동안 useEffect 코드 블록이 실행되는 시점은 West 2019 참조).
따라서 코드 블록 내에서 canvas.current는 <canvas> 요소를 참조한다.
4단계: 이미지 그리기
그러나 지금까지 작성한 코드를 재사용하려면 이미지를 그리는 코드와 분리하는 것이 가장 좋습니다. 그래서 우리는 Canvas 컴포넌트에 Prop으로 이미지를 그리는 함수를 전달합니다 (이 아이디어는 Nanda 2020 에서 빌렸습니다 ).
// src/components/Canvas.js
import PropTypes from 'prop-types'; // ADDED
const Canvas = ( {draw} ) => { // CHANGED
const canvas = React.useRef();
useEffect(() => {
const context = canvas.current.getContext('2d');
draw(context); // ADDED
});
return (
<canvas
ref={canvas}
width="100"
height="100"
/>
)
};
Canvas.propTypes = { // ADDED
draw: PropTypes.func.isRequired,
};
export default Canvas;
TypeScript
복사
이 draw()함수는 다른 파일에 정의될 이미지를 그립니다. 다양한 그리기 방법에 접근하기 위해 context를 인수로 받습니다.
5단계: 구성 요소를 재사용 가능하게 만들기
이제 이 Canvas 컴포넌트를 재사용하려면 해당 구성 요소의 width 및 height 속성을 하드 코딩하지 마십시오. 이미지마다 해상도와 가로 세로 비율이 다릅니다.
따라서 이 두 값을 추가 props로 변환합니다.
// src/components/Canvas.js
import PropTypes from 'prop-types';
const Canvas = ( {draw, height, width} ) => { // CHANGED
const canvas = React.useRef();
useEffect(() => {
const context = canvas.current.getContext('2d');
draw(context);
});
return (
<canvas
ref={canvas}
width={width} // CHANGED
height={height} // CHANGED
/>
)
}
Canvas.propTypes = { // ADDED
draw: PropTypes.func.isRequired,
height: PropTypes.number.isRequired, // ADDED
width: PropTypes.number.isRequired, // ADDED
};
export default Canvas;
TypeScript
복사
사용의 한 가지 이점은 를 PropTypes추가 .isRequired하면 prop 값 설정을 잊어버린 경우 콘솔에 경고가 표시된다는 것입니다. 위에서 언급했듯이(1단계 참조) width및 height속성은 성능과 이미지 왜곡 방지를 위해 가장 잘 지정됩니다. 위의 코드를 사용하면 해당 값을 지정하는 것을 잊었을 때 경고가 표시됩니다.
6단계: 캔버스 구성 요소 렌더링
마지막으로 parent 컴포넌트에서 draw() 함수를 지정하여 Canvas 컴포넌트를 렌더링합니다.
// src/App.js
import Canvas from './components/Canvas'; // Change the path according to the directory structure of your project
const draw = context => {
// Insert your code to draw an image
};
function App() {
return (
<Canvas draw={draw} height={100} width={100} />
);
}
export default App;
TypeScript
복사