Best Fit Rectangle
Calculates point averages to come up with the best fitting rectangle
by wio_dude
HTML
<input id="clear" type="button" value="clear" />
<input id="segments" type="checkbox" checked />
<label for="segments">edge colors</label>
<input id="averages" type="checkbox" checked />
<label for="segments">average points</label>
<input id="fitrect" type="checkbox" checked />
<label for="segments">best fit rectangle</label>
<br/>
<canvas id="draw" height="500" width="500"></canvas>
CSS
canvas {
background-color: yellow
}
JavaScript
const draw = document.getElementById('draw')
const clear = document.getElementById('clear')
const segments = document.getElementById('segments')
const averages = document.getElementById('averages')
const fitrect = document.getElementById('fitrect')
const ctx = draw.getContext('2d')
class DrawingCanvas {
constructor(opts) {
this.canvas = opts.canvas
this.tool = opts.tool
this.tools = opts.tools
this.listeners = [
['mousedown', this.drawStart.bind(this)],
['mousemove', this.drawContinue.bind(this)],
['mouseup', this.drawEnd.bind(this)]
]
this.addListeners()
}
addListeners() {
for (const [type, handler] in liteners) {
this.canvas.addEventListener(type, handler)
}
}
removeListeners() {
for (const [type, handler] in liteners) {
this.canvas.removeEventListener(type, handler)
}
}
canvasCoords(evt) {
const rect = this.canvas.getBoundingClientRect()
return [
evt.clientX - rect.left,
evt.clientY - rect.top
]
}
drawStart(evt) {
if (this.tool in this.tools) {
const tool = this.tools[this.tool]
tool.drawStart(this.canvasCoords(evt))
}
}
drawContinue(evt) {
if (this.tool in this.tools) {
const tool = this.tools[this.tool]
tool.drawStart(this.canvasCoords(evt))
}
}
drawEnd(evt) {
if (this.tool in this.tools) {
const tool = this.tools[this.tool]
tool.drawStart(this.canvasCoords(evt))
}
}
}
clear.addEventListener('click', (evt) => {
drawing.lines = []
drawing.drawing = false
drawing.maxDist = 0
})
function last(a) {
return a[a.length - 1]
}
function pointsIter(points) {
return {
points,
[Symbol.iterator]() {
return {
points: this.points,
index: 1,
next() {
if (this.index >= this.points.length) {
return {
done: true
}
}
const value = [
this.points[this.index - 1],
...