데모페이지 :https://ohikmyeong.github.io/rip-tutorial-canvas/dragging/01_drag_circle_rectangle.html
- 배경이 그려진 캔버스위에 두개의 개체를 마우스 다운&드래그 할 수 있다
- 나중에 드래그 되는 개체의 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 |
'CSS&JS > 👀Study and Copy' 카테고리의 다른 글
[HPP]hacker effect text 랜덤으로 다른문자열로 대체되는 텍스트 효과 (0) | 2023.06.14 |
---|---|
[Hyperplexed] 인터랙티브한 마우스 커서 (0) | 2023.06.13 |
[JS] 자바스크립트 클래스 멀티 상속 (JavaScript Class Multiple Inheritance) (0) | 2023.03.31 |
[WDS]open meteo OPEN API로 현재 지역 날씨 알려주는 웹 만들기(클론코딩) (0) | 2023.02.02 |
[JS] vanilla JS로 Masonry Layout 구현하기(2) (0) | 2023.01.25 |