[MainProject] 커스텀 그림판 펜 그리기/지우기
그림판 색상 변경 버튼
커스텀 페이지에서 그림판 색상 변경 구현을 위한 그림판 펜/지우개 버튼
구현
버튼 레이아웃
// PenEraseButton.tsx
import styled from "styled-components";
import eraser from "../../../assets/images/img_modal/eraser.png";
import pencil from "../../../assets/images/img_modal/pencil.png";
const ButtonStyled =
styled.div <
{ eraser: boolean } >
`
position: relative;
z-index: 20;
width: 30px;
height: 30px;
margin-left: 20px;
border: none;
cursor: grab;
background-image: url(${(props) => (props.eraser ? eraser : pencil)});
background-repeat: no-repeat;
background-size: cover;
background-position: center;
&::before {
content: '';
position: absolute;
top: -6px;
left: -6px;
right: -6px;
bottom: -6px;
border-radius: 50%;
background-color: rgba(0, 0, 0, 0.1);
transform: scale(0);
transition: transform 0.2s ease-in-out;
}
&:hover::before {
transform: scale(1);
}
&:active {
filter: brightness(1.2);
}
`;
interface EraseButtonProps {
onClick: () => void;
eraser: boolean;
}
function EraseButton({ eraser, onClick }: EraseButtonProps) {
const handleButtonClick = () => {
onClick();
};
return (
<ButtonStyled eraser={eraser} onClick={handleButtonClick}></ButtonStyled>
);
}
export default EraseButton;
그림판에서 펜과 지우개 기능은 하나의 버튼으로 만들어 그리기모드/지우개모드로 변경되는 방식으로 구현하였다.
레이아웃은 다음과 같이 구현하였다.
펜(그리기모드) 버튼
지우개(지우개모드) 버튼
버튼 모드
interface EraseButtonProps {
onClick: () => void;
eraser: boolean;
}
인터페이스 정의
function EraseButton({ eraser, onClick }: EraseButtonProps) {
const handleButtonClick = () => {
onClick();
};
return (
<ButtonStyled eraser={eraser} onClick={handleButtonClick}></ButtonStyled>
);
}
eraser
와 onClick
프롭스를 받는다. 버튼이 어떤 모드(지우기 또는 그리기)로 설정되어 있는지와 클릭 이벤트 핸들러를 받는다.
캔버스에 적용
handleMouseMove 함수
마우스가 캔버스 위에서 움직일 때 호출되는 함수
그림을 그리는 동작과 이 후에 이미지 드래그를 처리할때 사용
const handleMouseMove = (
event: React.MouseEvent<HTMLCanvasElement, MouseEvent>
) => {
// 현재 마우스 커서의 좌표를 계산
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext("2d");
if (!ctx) return;
const rect = canvas.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
// 이미지 드래그 중인 경우
if (isDragging && draggedImageIndex >= 0) {
const draggedImage = images[draggedImageIndex];
// 드래그 중인 이미지의 위치를 마우스 커서 위치로 업데이트
const newImages = images.map((imageData, index) => {
if (index === draggedImageIndex) {
return {
...imageData,
x: x - draggedImage.width / 2,
y: y - draggedImage.height / 2,
};
}
return imageData;
});
setImages(newImages);
updateImages(newImages); // 이미지 상태를 업데이트
} else {
// 그리기 모드일 때
if (event.buttons !== 1) return;
// 그리기 관련 설정을 설정
ctx.globalCompositeOperation = eraser ? "destination-out" : "source-over";
ctx.lineWidth = size;
ctx.strokeStyle = eraser ? "rgba(0,0,0,1)" : color;
// 선을 그림
ctx.lineTo(x, y);
ctx.stroke();
}
};
- 그리기 모드일 때, ctx.globalCompositeOperation을 설정하여 지우개 모드인지 그리기 모드인지 결정한다.
ctx.lineWidth
와ctx.strokeStyle
를 설정하여 선의 두께와 색상을 지정한다.ctx.lineTo(x, y)
와ctx.stroke()
를 사용하여 선을 그린다.
handleEraseButtonClick 함수
const handleEraseButtonClick = () => {
setEraser(!eraser); // 지우개 모드 전환
setDrawingMode(false); // 그리기 모드 비활성화
setIsDragging(false); // 이미지 드래그 비활성화
};
- setEraser(!eraser)를 사용하여 현재 지우개 모드의 상태를 토글
- setDrawingMode(false)를 사용하여 그리기 모드를 비활성화
- setIsDragging(false)를 사용하여 이미지 드래그를 비활성화
정리
이 두 함수는 사용자의 상호작용에 따라 그림 그리기와 이미지 드래그, 지우개 모드 전환을 관리한다. 이를 통해 사용자가 캔버스를 자유롭게 조작하고 그림을 그리며 편집할 수 있게 된다.
댓글남기기