CSS&JS/👀Study and Copy

[RIPT][JS][CANVAS] canvas로 드래그 가능한 사각형/원 만들기

arancia_ 2023. 4. 17. 13:02

튜토리얼 사이트 

 

html5-canvas Tutorial => Dragging circles & rectangles around the...

Learn html5-canvas - Dragging circles & rectangles around the Canvas

riptutorial.com

데모페이지  :https://ohikmyeong.github.io/rip-tutorial-canvas/dragging/01_drag_circle_rectangle.html

 

Dragging circles & rectangles around the Canvas

 

ohikmyeong.github.io

  • 배경이 그려진 캔버스위에 두개의 개체를 마우스 다운&드래그 할 수 있다
  • 나중에 드래그 되는 개체의 z-index값이 더 높다
  • 두 개체가 같은 위치에 있을 경우 마지막으로 드래그 하고 있던 개체만 반영된다.

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
import {resize_canvas} from "./../common/resizeCanvas.js";
resize_canvas();
 
const $cv = document.getElementById('cv');
const ctx = $cv.getContext("2d");
const rect = {x: 50, y: 50, width: 100, height: 100, fillcolor: '#B2A4FF'};
const circ = {x:100, y:100, rad:50, fillcolor : '#FFB4B4'}
const bgGrad = ctx.createLinearGradient(0,0,0,$cv.height);
const img = new Image();
img.src = "https://images.unsplash.com/photo-1681210744266-c6a23b8ed176?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=698&q=80";
let dragging = null;
let posX,posY;
 
function draw_rect(x,y){
    const {width,height,fillcolor} = rect;
    if(x != null && y != null){
        // rect.x = x - (width / 2) ;
        // rect.y = y - (height / 2);
        rect.x = x;
        rect.y = y;
    }
    ctx.fillStyle = fillcolor;
    ctx.strokeStyle = "black"
    ctx.lineWidth = 5;
    ctx.fillRect(rect.x,rect.y,width,height);
    ctx.strokeRect(rect.x,rect.y,width,height);
}//draw_rect
 
function draw_circle(x,y){
    const {rad,fillcolor} = circ;
    if(x != null && y != null){
        circ.x = x;
        circ.y = y;
    }
    ctx.fillStyle = fillcolor;
    ctx.beginPath();
    ctx.arc(circ.x, circ.y, rad, 02 * Math.PI, false);
    ctx.fill();
    ctx.stroke();
    ctx.closePath();
}//draw_circle
 
function is_circ(x,y){
    const {x:cx, y:cy, rad} = circ;
 
    if(x < cx - rad) return false;
    if(x > cx + rad) return false;
    if(y < cy - rad) return false;
    if(y > cy + rad) return false;
 
    return true;
}//is_circle
 
function is_rect(x,y){
    const {x:rx,y:ry,width:rWid,height:rHei} = rect;
 
    if(x < rx) return false;
    if(x > rx + rWid) return false;
    if(y < ry) return false;
    if(y > ry + rHei) return false;
 
    return true;
}//is_rect
 
function reset(){
    const {width, height} = $cv;
    // ctx.clearRect(0,0,width, height);
    ctx.drawImage(img,0,0,width,height);
    bgGrad.addColorStop(0,"#000000");
    bgGrad.addColorStop(0.5,"#000000aa");
    bgGrad.addColorStop(1,"transparent");
    ctx.fillStyle = bgGrad;
    ctx.fillRect(0,0,width,height);
}//reset
 
function get_xy(e){
    const {left,top} = $cv.getBoundingClientRect();
    const x = e.clientX - left;
    const y = e.clientY - top;
    return [x,y];
}//get_xy
 
const on_mouse_move = e =>{
    const [x,y] = get_xy(e);
    reset();
    
    switch(dragging){
        case "rect" : {
            draw_circle();
            draw_rect(x - posX,y - posY);
        }break;
        case "circ" : {
            draw_rect();
            draw_circle(x,y);
        }break;
    }
}//on_mouse_move
 
const cancel = () =>{
    dragging = null;
    window.removeEventListener('mousemove',on_mouse_move);
    add_mousedown();
}//cancel
 
const on_mouse_down = (e)=>{
    const [x,y] = get_xy(e);
    if(!is_circ(x,y) && !is_rect(x,y)){
        dragging = null;
        add_mousedown();
        return;
    }
    
    posX = x - rect.x;
    posY = y - rect.y;
 
    if(is_rect(x,y)){
        if(is_circ(x,y) && (dragging == "circ" || dragging == null)){
            dragging = "circ";
        }else{
            dragging = "rect";
        }
    }else if(is_circ(x,y)){
        dragging = "circ";
    }
    window.addEventListener('mousemove',on_mouse_move);
    window.addEventListener('mouseup', cancel, {once:true})
}//on_mouse_down
 
function add_mousedown(){
    window.addEventListener('mousedown',on_mouse_down,{once:true})
}//add_mousedown
 
 
img.addEventListener('load',()=>{
    reset();
    draw_rect();
    draw_circle();
    add_mousedown();
});
cs