CSS&JS/⚡Thinkers

[JS,Canvas] 캔버스로 화살표 선 만들기

arancia_ 2023. 11. 29. 15:28

HTML

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>canvas 화살표 선 사각형</title>
    <link rel="stylesheet" href="./style.css">
    <script src="./main.js" type="module"></script>
</head>
<body>
    <canvas id="cv"></canvas>
</body>
</html>
cs

JS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
const $cv = document.getElementById('cv');
const ctx = $cv.getContext('2d');
 
/** 사이즈 조정 */
function resize_canvas() {
    const size = Math.min(window.innerWidth, 500);
    $cv.width = size;
    $cv.height = size;
}//resize_canvas
 
/** 리셋 */
function reset_canvas() {
    ctx.clearRect(00, $cv.width, $cv.height);
}//reset_canvas
 
/** 그리기 */
function draw_canvas() {
    const wid = $cv.width;
    const hei = $cv.height;
    const xCenter = wid / 2;
    const yCenter = hei / 2;
    const size = wid * 0.6;
    const xStart = (wid - size) / 2;
    const yStart = (hei - size) / 2;
    const lineWidth = 8;
    const lineWidthHalf = lineWidth / 2;
    const borderColor = "#001122";
 
    /* 1.사각형 선 그리기 */
    ctx.beginPath();
    ctx.fillStyle = "#cccccc"
    ctx.strokeStyle = borderColor;
    ctx.lineWidth = lineWidth;
    ctx.strokeRect(xStart + lineWidthHalf, yStart + lineWidthHalf, size - lineWidth, size - lineWidth);
    ctx.closePath();
 
    /* 2.화살표 테두리 그리기 */
    draw_arrow_line({
        xStart: xStart,
        yStart: yStart,
        size: size,
        lineWidth: lineWidth,
        borderColor,
        direction: "right"
    });
 
    draw_arrow_line({
        xStart: xStart,
        yStart: yStart + size,
        size: size,
        lineWidth: lineWidth,
        borderColor,
        direction: "left"
    });
 
    draw_arrow_line({
        xStart: xStart + size,
        yStart: yStart,
        size: size,
        lineWidth: lineWidth,
        borderColor,
        direction: "down"
    });
 
    draw_arrow_line({
        xStart: xStart,
        yStart: yStart,
        size: size,
        lineWidth: lineWidth,
        borderColor,
        direction: "up"
    });
}//draw_canvas
 
/**
 * 화살표 선 그리기
 * @param {*} INFO 
 */
function draw_arrow_line(INFO = {}) {
    const { xStart, yStart, size, lineWidth, direction, borderColor } = INFO;
    const lineWidthHalf = lineWidth / 2;
    const arrowXStart = xStart + lineWidth;
    const arrowXEnd = (xStart + size) - (lineWidth * 2);
    ctx.strokeStyle = borderColor;
    ctx.lineWidth = lineWidth / 3;
 
    switch (direction) {
        case "right": {
            const arrowYStart = yStart - (lineWidth * 0.8);
            const arrowYCenter = yStart + lineWidthHalf;
            const arrowYEnd = yStart + (lineWidth * 0.8+ lineWidth;
            for (let i = arrowXStart + lineWidthHalf; i <= arrowXEnd; i += lineWidth * 2) {
                ctx.beginPath();
                ctx.moveTo(i, arrowYStart);
                ctx.lineTo(i + lineWidth, arrowYCenter);
                ctx.lineTo(i, arrowYEnd);
                ctx.stroke();
                ctx.closePath();
            }//for
        } break;
 
        case "left": {
            const arrowYStart = yStart - (lineWidth * 0.8- lineWidth;
            const arrowYCenter = yStart - lineWidthHalf;
            const arrowYEnd = yStart + lineWidth;
            for (let i = arrowXStart + (lineWidth * 2); i <= arrowXEnd; i += lineWidth * 2) {
                ctx.beginPath();
                ctx.moveTo(i, arrowYStart);
                ctx.lineTo(i - lineWidth, arrowYCenter);
                ctx.lineTo(i, arrowYEnd);
                ctx.stroke();
                ctx.closePath();
            }//for
        } break;
 
        case "down" : {
            const x = xStart - (lineWidth * 2);
            const x2 = xStart - lineWidthHalf;
            const x3 = arrowXStart; 
            for(let i = yStart + (lineWidth * 2); i < yStart + size - (lineWidth * 2); i += lineWidth * 2){
                ctx.beginPath();
                ctx.moveTo(x,i);
                ctx.lineTo(x2, i + lineWidth);
                ctx.lineTo(x3, i);
                ctx.stroke();
                ctx.closePath();
            }//for
        }break;
 
        case "up" : {
            const x = xStart - lineWidth;
            const x2 = xStart + lineWidthHalf;
            const x3 = xStart + (lineWidth * 2); 
            for(let i = yStart + (lineWidth * 3); i < yStart + size - (lineWidth); i += lineWidth * 2){
                ctx.beginPath();
                ctx.moveTo(x,i);
                ctx.lineTo(x2, i - lineWidth);
                ctx.lineTo(x3, i);
                ctx.stroke();
                ctx.closePath();
            }//for
        }break;
    }//switch
}//draw_arrow_line
 
/* --------------------------------------------- */
 
/* (실행)사이즈 조정 */
resize_canvas();
draw_canvas();
 
/* (EVENT) RESIZE */
window.addEventListener('resize', () => {
    resize_canvas();
    reset_canvas();
    draw_canvas();
});
cs