Intersection [circle, rectangle]
by exodus4d
HTML
<h5>Drag Circle or Rect: turns red if shapes intersect<br></h5>
<div class="ui">
<label class="label" title="Show debug">
<input type="checkbox" onchange="document.getElementById('canvas').classList.toggle('debug')">
</label>
<label class="label" title="Play">
<input type="checkbox" value="1" onchange="document.getElementById('canvas').style.setProperty('--play', ~~this.checked)" checked>
</label>
<label class="label" title="Duration (ms)">
<input type="range" min="500" max="8000" value="4000" oninput="document.getElementById('canvas').style.setProperty('--duration', this.value)">
</label>
</div>
<canvas class="" id="canvas" width="400" height="400" style="--play: 1"></canvas>
SCSS
* {
box-sizing: border-box;
font-family: sans-serif;
}
#canvas {
width: 400px;
height: 400px;
border: 1px solid blue;
margin-left: 20px;
}
.ui {
display: grid;
grid-auto-columns: minmax(200px, 300px);
grid-auto-rows: minmax(34px, max-content);
column-gap: 50px;
row-gap: 5px;
font-size: 16px;
max-width: 400px;
.label {
display: flex;
align-items: center;
column-gap: 10px;
justify-content: space-between;
padding: 0 8px;
font-family: inherit;
&::before {
content: attr(title);
white-space: nowrap;
}
}
}
JavaScript
class DOMCircle extends DOMPoint {
constructor(x, y, r) {
super(x, y);
this.r = r;
}
get r(){
return this._r || 0;
}
set r(r) {
this._r = parseInt(r);
}
}
// Scenary objects
const domCirc = new DOMCircle(70, 130, 10);
const domRect = new DOMRect(100, 100, 25, 180);
// Current activ dragging papth
let dragPath;
// Current position of dragged paths
let circPath, rectPath;
// Circle frame history store
let circPathHistory = [];
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
// Set canvas origin
ctx.setTransform(1, 0, 0, 1, 100.5, 100.5);
// Set default styles
ctx.fillStyle = 'skyblue';
ctx.strokeStyle = 'black';
const rad2deg = rad => rad * (180 / Math.PI);
const domRectList = domRect => Array.from(Object.keys(DOMRect.prototype), k => domRect[k]);
class Scenary extends Map {
set(key, shape) {
const shapeApi = {
shape,
mTranslate: new DOMMatrix(),
mTransform: new DOMMatrix(),
getTranslate() {
return this.mTranslate;
},
setTranslate(x = 0, y = 0){
this.mTranslate = new DOMMatrix([1, 0, 0, 1, x, y]);
},
translate(x = 0, y = 0){
this.mTranslate.translateSelf(x, y);
return this;
},
getTransform() {
return this.mTransform;
},
setTransform(mTransform = new DOMMatrix()){
this.mTransform = DOMMatrix.fromMatrix(mTransform);
},
transform(mTransform){
this.mTransform.multiplySelf(mTransform);
return this;
},
reset(){
this.setTranslate();
this.setTransform();
}
};
let shapeApiCustom;
if (shape instanceof DOMRect) {
shapeApiCustom = {
getShape() {
const {x, y} = new DOMPoint(shape.x, shape.y).matrixTransform(this.getTranslate());
return new DOMRect(x, y, this.shape.width, this.shape.height);
},
getCenter() {
return new DOMPoint(this.shape.x +...