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, 0, 2 * 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 |