본문 바로가기

Web Project

[자바 스크립트] 그림판

<!DOCTYPE html>
<html lang="ko">

<head>
    <meta charset="UTF-8">

    <title>Painter</title>

    <script src="js/jquery.min.js"></script>

    <script>
        $(document).ready(
            function() {
                init();
            }
        );

        const max_width = 650;
        const max_height = 450;

        var canvas = null;
        var context = null;

        var width = null;
        var height = null;

        var bgColor = null;
        var lineWidth = null;
        var lineColor = null;

        function init() {
            while (true) { // 올바른 가로 세로 길이를 입력받을 때까지 반복
                width = prompt("캔버스의 가로 길이를 입력하세요. (최대 " + max_width + "px)");
                height = prompt("캔버스의 세로 길이를 입력하세요. (최대 " + max_height + "px)");

                if (width <= max_width && height <= max_height) { // 가로 세로 길이가 범위 내면 반복 종료
                    break;
                }
                else { // 범위 밖이면 경고 출력 후 반복
                    if (width > max_width) {
                        alert("width의 값이 " + max_width + "px를 넘습니다!");
                    }

                    if (height > max_height) {
                        alert("height의 값이 " + max_height + "px를 넘습니다!");
                    }
                }
            }

            // canvas를 만들고 입력받은 width와 height 값으로 설정해줌
            canvas = document.createElement("canvas");
            canvas.id = "myCanvas";
            canvas.width = parseInt(width); // prompt를 통해 입력받은 value는 string이므로 parseInt를 통해 정수로 변환
            canvas.height = parseInt(height);

            // 만든 canvas를 dom 제어를 통해 html에 추가
            document.getElementById("canvas_wrap").appendChild(canvas); // #canvas_wrap의 자식으로 canvas 추가

            // canvas의 context를 참조하여 속성 설정
            context = canvas.getContext("2d"); // 2D 캔버스로 설정
            context.fillStyle = "white"; // 캔버스의 배경색
            context.fillRect(0, 0, width, height);
            context.lineWidth = 2; // 캔버스의 선 굵기를 2로
            context.strokeStyle = "black"; // 캔버스의 선 색상을 검은색으로

            // dom 제어를 통해 html에 캔버스의 속성 표시
            document.getElementById("canvas_size").innerText = width + "x" + height;
            bgColor = document.getElementById("val_bgColor");
            lineWidth = document.getElementById("val_lineWidth");
            lineColor = document.getElementById("val_lineColor");
            bgColor.value = context.fillStyle; // <input value="white">
            lineWidth.value = context.lineWidth; // <input value="2">
            lineColor.value = context.strokeStyle; // <input value="black">
        }

        $(function() {
            $(document).on( // html 문서 전체에서 실행
                {
                    "mousemove": function(e) { // 마우스가 움직일 경우 실행
                        // 가장 왼쪽 위 기준 좌표 출력
                        $(".posX").text(e.pageX);
                        $(".posY").text(e.pageY);

                        // 캔버스 객체 기준 좌표 출력
                        $(".off_posX").text(e.offsetX);
                        $(".off_posY").text(e.offsetY);

                        move(e);
                    },

                    "mouseup": function(e) { // 마우스를 누른 후 놓았을 때 실행
                        up(e);
                    }
                }
            );

            // 실제로 그려지는 영역은 캔버스 내부이므로
            // down 함수는 캔버스 내에서만 실행
            $("#myCanvas").on("mousedown", function(e) {
                down(e);
            });
        });

        var drawing = false;
        var startX = 0;
        var startY = 0;

        // 마우스를 놓은 상태에서는 선을 그리지 않으므로,
        // 드로잉 불가능 상태로 전환
        function up(e) {
            drawing = false;
        }

        // 마우스를 눌렀을 때는 선을 그려야 하기 때문에,
        // 현재 위치를 저장하고 드로잉 가능 상태로 전환
        function down(e) {
            startX = e.offsetX;
            startY = e.offsetY;

            drawing = true;
        }

        function move(e) {
            if (!drawing) { // 선을 그리는 상태가 아닐 경우 함수 종료
                return;
            }

            // 선을 그리는 상태일 경우 실행
            var curX = e.offsetX;
            var curY = e.offsetY;

            draw(curX, curY); // start 위치부터 cur 위치까지 그려줌

            // 그리고 나면 현재 위치가 시작점이 됨
            startX = curX;
            startY = curY;
        }

        function draw(curX, curY) {
            context.beginPath(); // 캔버스에서 경로를 만듦 (점 들의 집합을 만듦)
            context.moveTo(startX, startY); // 시작 위치로 이동
            context.lineTo(curX, curY); // 시작 위치부터 현재 위치까지 선의 경로를 만듦
            context.stroke(); // 그리기 (한 번 휘젓기)
        }

        function SetBG() { // <input>에서 지정한 값대로 배경색 재설정
            context.fillStyle = val_bgColor.value;
            context.fillRect(0, 0, width, height);
        }

        function setCanvas() { // <input>에서 지정한 값대로 캔버스를 재설정
            context.strokeStyle = lineColor.value;
            context.lineWidth = parseInt(lineWidth.value);
        }
    </script>

    <style>
        #wrap {
            width: 1000px;
            height: 630px;
            margin: 0 auto;
            border: 1px solid black;
            border-radius: 5px;
        }

        #wrap>h1 {
            text-align: center;
        }

        #canvas_wrap {
            float: left;
            margin-top: 10px;
            margin-left: 10px;
            width: 65%;
        }

        #myCanvas {
            border: 1px solid #999999;
        }

        #info_panel {
            float: left;
            margin-top: 10px;
            margin-left: 20px;
            margin-right: 10px;
            width: 15%;
        }

        #tool_panel {
            float: left;
            margin-top: 10px;
            margin-right: 10px;
            width: 15%;
        }

        h2 {
            font-size: 0.9em;
        }

        p {
            font-size: 0.7em;
        }

        h2, p {
            margin: 0;
            margin-bottom: 10px;
            text-align: right;
        }

        button {
            padding: 1px;
        }

        input {
            width: 55px;
            text-align: right;
        }

        input[type=number] {
            text-align: left;
        }
    </style>
</head>

<body>
<div id="wrap">

    <h1>Painter by JavaScript</h1>

    <div id="canvas_wrap">
    </div>

    <div id="info_panel">
        <h2>[마우스 위치]</h2>
        <p>* 브라우저 기준<br />X : <span class="posX">0</span>px<br />Y : <span class="posY">0</span>px</p>
        <p>* 캔버스 기준<br />X : <span class="off_posX">0</span>px<br />Y : <span class="off_posY">0</span>px</p>
        <br />

        <h2>[캔버스 크기]</h2>
        <p id="canvas_size"></p>
    </div>

    <div id="tool_panel">
        <h2>[캔버스 속성]</h2>
        <p>배경 색상: <input type="text" id="val_bgColor" value=""></p>
        <p><button onclick="SetBG()">배경색 채우기</button></p>
        <br />
        <p>선 색상: <input type="text" id="val_lineColor" value=""></p>
        <p>선 굵기: <input type="number" id="val_lineWidth" value=""></p>
        <p><button onclick="setCanvas()">캔버스 재설정</button></p>
    </div>

</div>
</body>
</html>