📌 작성자 개발 환경
OS: Mac OS
Tool: Visual Studio Code

1 분 소요

til

Custom 버튼 레이아웃

커스텀 페이지에서 그림판 구현을 위한 그림판 버튼 구현 버튼 구성

  1. 펜 굵기 버튼
    펜의 굵기를 설정할 수 있는 버튼
  2. 펜/지우개 버튼
    펜과 지우개 모드를 변경할 수 있는 버튼
  3. 컬러 버튼
    펜의 색상을 변경할 수 있는 버튼
  4. 이미지 업로드 버튼
    로컬에서 그림판에 이미지를 업로드할 수 있는 버튼
  5. 앞으로/뒤로 가기 버튼
    이전 요소 undo/redu 버튼

버튼 레이아웃


각각의 버튼들은 .tsx파일로 5개로 만들어 CustomContent.tsx에 다음과 같이 import하였다.

import ColorInput from './ColorInput';
import EraseButton from './EraseButton';
import RangeInput from './RangeInput';
import UploadButton from './UploadButton';
import UndoButton from './UndoButton';
import RedoButton from './RedoButton';

  return (
    <ContentContainer>
      <RangeInputContainer>
        <RangeInput value={size} onChange={handleChangeSize} />
        <ColorInput value={color} onChange={handleChangeColor} />
        <EraseButton eraser={eraser} onClick={handleEraseButtonClick} />
        <UploadButton onUpload={handleUploadImage} />
        <UndoButton onUndo={handleUndoButtonClick} />
        <RedoButton onRedo={handleRedoButtonClick} />
      </RangeInputContainer>

til

펜 굵기 버튼

//RangeInput.tsx
import styled from "styled-components";
import React from "react";

const InputStyled = styled.input.attrs({
  type: "range",
  min: "1",
  max: "100",
})`
  position: relative;
  z-index: 20;
  -webkit-appearance: none;
  background-color: blue;
  border-radius: 20px;
  height: 8px;
  width: 27%;
  right: 15px;
  margin-top: 10px;
  margin-left: 20px;
  &::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 17px;
    height: 17px;
    background-color: var(--dark-purple);
    border-radius: 50%;
    cursor: pointer;
  }

  &::-moz-range-thumb {
    width: 25px;
    height: 25px;
    border-radius: 50%;
    background-color: yellow;
    cursor: pointer;
  }

  &:focus {
    animation: 1s pulse infinite;
    outline: none;
  }

  &:hover {
    background-color: var(--purple);
    transform: scale(1.15);
  }

  background-color: var(--light-purple);
  top: calc(5px + 50%);

  transition: background-color 0.2s ease-in-out, transform 0.2s ease-in-out;
`;

interface RangeInputProps {
  value: number;
  onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
}

function RangeInput({ value, onChange }: RangeInputProps) {
  return <InputStyled type="range" value={value} onChange={onChange} />;
}

export default RangeInput;

RangeInputProps 인터페이스를 정의하여 RangeInput 컴포넌트가 onChange props를 받도록 하였고, RangeInput 컴포넌트를 내보냈다.

interface RangeInputProps {
  value: number;
  onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
}

function RangeInput({ value, onChange }: RangeInputProps) {
  return <InputStyled type="range" value={value} onChange={onChange} />;
}

export default RangeInput;
//CustomContent.tsx
const handleChangeSize = (event: React.ChangeEvent<HTMLInputElement>) => {
  setSize(Number(event.target.value));
};

CustomContent.tsx에서 handleChangeSize함수로 펜을 그릴때 사용한 함수 handleMouseMove에서 ctx.lineWidth를 size변수로 조정하여 펜의 굵기를 조절하였다.

//handleMouseMove
} 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();
    }
  };

결과


til til
펜 굵기 조정 til 펜 굵기 조정 결과

댓글남기기