React.js를 사용하여 빌드된 동적 그라디언트 생성기

그래디언트 생성기는 재미있을 것 같습니다. 나는 주로 mycolor.space 웹 사이트를 사용하여 다양한 형식의 그라디언트를 생성합니다. 주말에 나는 나만의 그래디언트 생성기를 만들기로 결정했고 비슷한 mycolor.space 복제본을 만들었습니다. 여기에서 데모를 살펴보십시오.

프로젝트의 소스 코드는 여기에서, 라이브 데모는 여기에서 찾을 수 있습니다.





그라디언트 생성기에는 방향과 색상을 변경하는 옵션이 있습니다. 색상 매개변수를 사용하여 이들 사이에서 가장 관련성이 높은 3개의 색상을 생성합니다.

환경 준비



먼저 create-react-app을 사용하여 반응 앱을 만들고 tailwindcss에 대한 지원을 추가합니다.

npx create-react-app color-generator-react
cd color-generator-react


이제 프로젝트로 cd하고 Chroma-js인 유일한 종속 항목을 추가합니다.

yarn add chroma-js
OR
npm install chroma-js


TailwindCSS 추가




yarn add -D tailwindcss postcss autoprefixer
OR
npm install -D tailwindcss postcss autoprefixer


아래 코드는 tailwindcss.config.js 파일을 생성합니다. -p 플래그를 전달했으므로 tailwindcss와 함께 사용할 기본 구성으로 postcss.config.js 파일도 생성합니다.

npx tailwindcss init -p


이제 자산 폴더에 tailwind.css 파일을 생성해 보겠습니다.

mkdir assets
cd assets
touch tailwind.css // Linux
OR 
echo. > tailwind.css // Windows


생성된tailwind.css 파일에 아래의 tailwindcss 지시문을 추가합니다.

@tailwind base;
@tailwind components;
@tailwind utilities;


축하합니다. Tailwindcss가 프로젝트에 성공적으로 추가되었습니다.

tailwindcss가 추가되면 계속해서 프로젝트 작업을 시작할 수 있습니다. 하지만 그 전에 chroma-js에 대해 간단히 소개하겠습니다.

Chroma-js 소개



Chroma-js는 색상 조작, 변환 및 스케일링과 관련하여 놀라운 소프트웨어입니다. 어두워지거나 밝아지는 것부터 색조 조작에 이르기까지 모든 종류의 조작에 필요한 모든 것이 있습니다. 또한 다양한 색상 공간에서 결과를 제공합니다. 다양한 형식에서 색상을 읽고, 변환하고, 분석하고, 조작할 수 있습니다.

우리는 Chroma-js를 사용하여 실제로 주어진 2개의 매개변수에서 3개의 색상을 더 생성하고 5가지 색상의 그라데이션을 만들 것입니다.

레이아웃을 구축하자



단순화를 위해 단일 주요 구성 요소만 있습니다. 아래 마크업은 flexbox 속성을 사용하여 div 사이의 모든 항목을 중앙에 배치합니다.

    <div className="flex items-center bg-gray-900 justify-center md:fixed h-screen inset-0 px-10">
    /* All the content is centered. */
    </div>


색상 확산 방향을 변경하는 컨트롤을 만들려면 App.js 파일에 아래 코드를 추가합니다.


          <div className="flex items-center justify-center p-2 gap-2 flex-wrap md:gap-5">

              <button title="to top" onClick={() => changeOrientation("to top") }>
              <img src={arrow} alt="arrow to top" />
              </button>

              <button title="to right top" onClick={() => changeOrientation("to right top") }>
              <img src={arrow} alt="arrow to right top" className="transform rotate-45" />
              </button>

              <button title="to right" onClick={() => changeOrientation("to right") }>
              <img src={arrow} alt="arrow to right" className="transform rotate-90" />
              </button>

              <button title="to right bottom" onClick={() => changeOrientation("to right bottom") }>
              <img src={arrow} alt="arrow to right bottom" className="rotate-135" />
              </button>

              <button title="to bottom" onClick={() => changeOrientation("to bottom") }>
              <img src={arrow} alt="arrow to bottom" className="transform rotate-180" />
              </button>

              <button title="to bottom left" onClick={() => changeOrientation("to bottom left") }>
              <img src={arrow} alt="arrow to bottom left" className="rotate-225" />
              </button>

              <button title="to left" onClick={() => changeOrientation("to left") }>
              <img src={arrow} alt="arrow to left" className="transform -rotate-90" />
              </button>

              <button title="to left top" onClick={() => changeOrientation("to left top") }>
              <img src={arrow} alt="arrow to left top" className="transform rotate-180" />
              </button>

              <button onClick={() => changeOrientation("circle") }>
              <img src={radial} alt="radial" className="px-1.5" />
              </button>

          </div>



일부를 회전시키려면 이 CSS를 App.css 파일에 추가하십시오.

.rotate-135 {
    transform: rotate(135deg);
}

.rotate-225 {
    transform: rotate(225deg);
}
button:focus{
    border: 2px solid white;
    border-radius:50%;
    outline: none;
    transition: all 220ms ease-in;
}



이제 다음과 같아야 합니다.

![[direction-controls.png]]

이제 사용자로부터 색상 입력을 받는 2개의 버튼과 아래에 작은 CSS 코드 상자를 추가하겠습니다.

<h2 className="text-xl text-white text-center py-3 mt-5 italic font-cursive">Enter Colors & press Enter.</h2>
<div className="text-white text-center py-2 rounded mb-3  text-white w-40 mx-auto">
  <h2 className="bg-amber-700">{error}</h2>
</div>


<div className="flex items-center justify-center flex-wrap">
    <form className="flex gap-5 justify-center items-center flex-wrap">

        <input type="text"
             ref={hex}
             defaultValue={color1}
             style={icolor1}
             className="rounded px-2 py-3 text-center shadow-2xl font-bold bg-red-900" 
             name="hex" />

        <input type="text"
             ref={hex2}
             defaultValue={color2}
             style={icolor2}
             className="rounded px-2 py-3 text-center shadow-2xl font-bold bg-red-700" 
             name="hex2"/>

        <input
              type="submit"
              className="hidden"
              onClick={(e) => doJob(e)}
              />

      </form>
</div>

  <div className="box md:w-[640px] w-[350px] h-auto mx-auto break-all mt-4 p-2 ">
      <p className="p-3 text-gray-200 font-mono text-base md:text-xl text-center font-semibold">
          <span className="text-gray-100">background-image: </span> { cssCode }
      </p>
  </div>




.font-cursive {
    font-family: cursive;
}

.box{
    background: rgba( 255, 254, 254, 0.05 );
    box-shadow: 0 8px 32px 0 rgba( 31, 38, 135, 0.37 );
    backdrop-filter: blur( 9.5px );
    -webkit-backdrop-filter: blur( 9.5px );
    border-radius: 10px;
    border: 1px solid rgba( 255, 255, 255, 0.18 );
}


마크업과 CSS를 추가하면 다음과 같아야 합니다. 이제 이 시점에서 우리는 앱의 기본 레이아웃 구축을 완료했습니다.

markup-complete-tutorial

기능 추가



우선 색상과 버튼에 대한 모든 변수와 참조를 선언해야 합니다. React Functional 구성 요소에서 상태를 사용하기 위해 useState 후크를 사용합니다.


    const [color1, setColor1] = useState("#FF6347"); //input box one default color
    const [color2, setColor2] = useState("#0000FF"); //input box2 one default color

    //dynamically generated colors using chroma js
    const [generated1, setGenerated1] = useState("");
    const [generated2, setGenerated2] = useState("");
    const [generated3, setGenerated3] = useState("");

  //css controls
    const [direction, setDirection] = useState("linear-gradient");
    const [orientation, setOrientation] = useState("to right bottom");

    //errors var
    const [error, setError] = useState("")

  //color vars for dynamic color for the input text
    const [invertedcolor1, setinvertedColor1 ] = useState("")
    const [invertedcolor2, setinvertedColor2 ] = useState("")

    //refs to both the inputs
    const hex = useRef(color1);
    const hex2 = useRef(color2);

  //String style built for the div background to display the gradient color
  const ulStyle = { backgroundImage: direction + "("+orientation+","+color1 +","+generated1 +","+generated2 +","+generated3 +","+color2+")"}

  //string generated to copy by the user
    const cssCode = direction+ "("+orientation+","+color1 +","+generated1 +","+generated2 +","+generated3 +","+color2+");";




이제 화살표 버튼을 선택하면 아래와 같이 전달된 방향 문자열과 함께 changeOrientation 함수가 실행됩니다.

<button title="to right" onClick={() => changeOrientation("to right") }>
              <img src={arrow} alt="arrow to right" className="transform rotate-90" />
</button>



함수를 처리하기 위해 함수 아래에 작성할 것입니다.


    const changeOrientation = function (ori){

    //condition to check if the passed in string is circle
    //if circle the radial gradient is generated
    //else linear gradient

        if(ori === "circle"){
          //setting the direction variable & orientation
            setDirection("radial-gradient")
            setOrientation(ori)
        }else{
            setDirection("linear-gradient")
            setOrientation(ori)
        }

    }



이제 배경색이 어떤 것이든 동적으로 배경색에 따라 입력 상자 색상을 어둡거나 밝게 설정해야 합니다. 또한 사용자 입력에서 3개의 동적 색상을 생성해야 합니다. 이를 처리하기 위해 아래 기능이 있습니다.


  //the background color and text color style for inputs
  const icolor1 = { background: color1, color:invertedcolor1 }
    const icolor2 = { background: color2, color:invertedcolor2 }

    function checkContrast(color){

                //checking the luminance of the color
                const contrast = chroma(color).luminance();

        //returning the color based on the luminance of the background
                if(contrast > 0.6){
                    return "#000"
                }else{
                    return "#fff"
                }
    }


동적 색상 생성기 기능.


const generateColors = function () {
    //check if both the colors are valid colors
        if(chroma.valid(color1) && chroma.valid(color2)){

      //use the chroma-js scale feature to interpolate
      //between two color values and generate 3 more
      //dynamic colors including both input colors

            let word = chroma.scale([color1,color2])
                .mode('lch').colors(5);

      //set the generated colors.
      //Due to just 3 colors, I did not use loop.
            setGenerated1(word[1]);
            setGenerated2(word[2]);
            setGenerated3(word[3]);

      //At this moment, setting the text color of the input boxes
            setinvertedColor1(checkContrast(color1))
            setinvertedColor2(checkContrast(color2))

      //Setting the error to empty string
            setError("")

        }else{
          //if not set the error
            setError("Color are no valid.")
        }

    }



이제 누군가 색상을 입력하고 Enter 버튼을 누를 때마다 이벤트가 매개변수로 전달되는 doJob(e)라는 함수가 실행됩니다.

    function doJob(e){
        //prevents default submission of the form
        e.preventDefault();
        //setting new values of the input colors
        //everything else changes on their own as the
        //values are reactive
        setColor1(hex.current.value);
        setColor2(hex2.current.value);

    }
  //use the hook instead of componentDidMount 
    useEffect(() => {
      //generating colors on the mount
        generateColors();
    });


yarn start or npm run start를 사용하여 앱을 실행하면 localhost:3000에서 앱의 출력이 표시되어야 합니다.

final-output

좋은 웹페이지 즐겨찾기