본문 바로가기

자바스크립트

[javascript html 캔버스] 그림판

반응형
Document
이 브라우저는 캔버스를 지원하지 않습니다.

<스크린 터치 이벤트가 없어서 모바일에서는 안 될 수 있음>

<그린거 마우스 우 클릭해서 이미지 저장하면 png 이미지 파일로 만들 수 있음>

    <style>

        .canvas_box{
            text-align: center;    
            transition: all 2s ease-in-out;
            
        }
        .canvas:hover{
            -webkit-box-shadow: 5px 5px 15px 5px #FF8080, -9px 5px 15px 5px #FFE488, -7px -5px 15px 5px #8CFF85, 12px -5px 15px 5px #80C7FF, 12px 10px 15px 7px #E488FF, -10px 10px 15px 7px #FF616B, -10px -7px 27px 1px #8E5CFF, 5px 5px 15px 5px rgba(0,0,0,0); 
            box-shadow: 5px 5px 15px 5px #FF8080, -9px 5px 15px 5px #FFE488, -7px -5px 15px 5px #8CFF85, 12px -5px 15px 5px #80C7FF, 12px 10px 15px 7px #E488FF, -10px 10px 15px 7px #FF616B, -10px -7px 27px 1px #8E5CFF, 5px 5px 15px 5px rgba(0,0,0,0);
        }

        canvas{
            background:radial-gradient(rgb(255, 255, 255),rgb(222, 218, 218));
            box-shadow: 5px 5px 10px 5px black;
        }
        .color{
            border: none;
            border-radius: 50px;
            padding: 20px;
        }

        .color_box{
            margin-top: 1rem;
            text-align: center;
        }

        .color:hover{
            cursor: pointer;
        }
        .color_box .color:first-child{
            background-color: red ;
        }
        .color_box .color:nth-child(2){
            background-color: blue;
        }
        .color_box .color:nth-child(3){
            background-color: green;
        }
        .color_box .color:nth-child(4){
            background-color: tomato;
        }
        .color_box .color:nth-child(5){
            background-color: black;
        }

        .image_color{
            background-image: url('/캔버스2강/number0.png');
            background-position: center;
            background-size: cover;
            width: 40px;
            height: 40px;
            border: none;
            border-radius: 20px;
            background-color: #000000;
        
        }

    </style>
</head>
<body>
    <div class="canvas_box">
        <canvas class="canvas" width="800" height="600">
            이거 보임? 그럼 캔버스 못 씀
        </canvas>
    </div>
    <div class="color_box">
        <button class="color" data-type ='color' data-color="red"></button>
        <button class="color" data-type ='color' data-color="blue"></button>
        <button class="color" data-type ='color' data-color="green"></button>
        <button class="color" data-type ='color' data-color="tomato"></button>
        <button class="color" data-type ='color' data-color="black"></button>
        <button class="color image_color" data-type ="image"></button>
    </div>
    <script>

        const image_color = document.querySelector('.image_color')
        const canvas = document.querySelector('.canvas');
        const context = canvas.getContext('2d');
        const color = document.querySelectorAll('.color');
      
        //이미지 요소를 새로 생성하고, 그 요소에 속성이 src 인 것을 추가
        const imgElement = document.createElement('img');
        imgElement.src ='/캔버스2강/number0.png'
           
        // 변수 선언
        let shift=0;
        let count=0;
        let state = false
        let colorSelect;
        let drawMode;

        //레디안 값 구하기 위한 함수
        function radial(angle){
            return angle * Math.PI/180
        }

        //그림판에 그림 그리는 함수 모드의 분기에 따라 이미지, 칼라 각각 그려짐
        function draw(e){

            //state 가 false 라면 함수를 종료하고, 아니라면 아래 분기 실행
        if(state === false) return

        switch(drawMode){
            case('color'): //drawMode 가 color 라면 실행하는 영역
                context.beginPath();
                context.arc(e.offsetX, e.offsetY, 10, 0, radial(360), false);
                context.fill();
                break;

            case('image'): //drawMode 가 image 라면 실행하는 영역
                context.beginPath();
                context.drawImage(imgElement,e.offsetX-45, e.offsetY-30,100,100)
                context.fill();
                break;
        }
        
        // 위 과정을 거친 후, 리페인트, 리플로우 준비가 완료되면 다시 draw 함수 호출
        requestAnimationFrame(draw);
        }
        
        function stateTrue(){
            state = true;
        }

        function stateFalse(){
            state = false;
        }

        // 마우스가 다운 혹은 업되면 state 가 true 로 변경
        canvas.addEventListener('mousedown', stateTrue)
        canvas.addEventListener('mouseup',stateFalse)

        //마우스 움직일 시 그림을 그리는 실질적인 함수인 draw 호출 및 실행
        canvas.addEventListener('mousemove',draw)

        // 컬러 버튼 클릭시 해당 컬러의 데이터 속성값이 모드 변수에 저장
        function colorChange(){
        color.forEach((colorEl)=>{
           colorEl.addEventListener('click',()=>{
                colorSelect = colorEl.getAttribute('data-color')
                context.fillStyle =colorSelect 
                drawMode = colorEl.getAttribute('data-type')
                
           })
        })
     }
       // 이미지 버튼 클릭시 모드 변수에 데이터 타입을 전달하는 함수
        function imageDraw(){
            window.addEventListener('load',()=>{
                image_color.addEventListener('click',()=>{
                    drawMode = image_color.getAttribute('data-type')
                })
            })
        }

     colorChange()
   </script>
</body>
</html>
반응형