-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdraw.js
97 lines (85 loc) · 2.78 KB
/
draw.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
const canvas = document.getElementById('draw')
const {abs, PI, cos, sin, min, max, sqrt} = Math
const square = x => x*x
const ctx = canvas.getContext('2d')
canvas.width = window.innerWidth - 20
canvas.height = window.innerHeight - 20
let shapes = []
let currentShape = undefined
const blankCanvas = () => {
ctx.fillStyle = 'white'
ctx.fillRect(0, 0, canvas.width, canvas.height)
}
const beginDrawing = (x, y) => {
ctx.lineWidth = 5
ctx.strokeStyle = 'black'
currentShape = [[x, y]]
ctx.moveTo(x, y)
ctx.beginPath()
}
const continueDrawing = (x, y) => {
if (currentShape) {
ctx.lineTo(x, y)
currentShape = [...currentShape, [x, y]]
ctx.stroke()
}
}
const finishDrawing = () => {
shapes = shapes.filter(el=>el).concat([currentShape])
shapeRecognition(knownRunes, currentShape)
if (shapes.length % 2 === 0) { // TODO rm this is for debug
drawShapeComparison(...shapes.slice(-2))
}
currentShape = undefined
ctx.stroke()
}
const eraseLastShape = () => {
const shapesLength = shapes.filter(el => el).length
if (shapesLength === 0 || currentShape) { return }
blankCanvas()
shapes = shapes.slice(0, shapesLength-1).filter(el => el)
ctx.strokeStyle = 'black'
ctx.lineWidth = 5
shapes.forEach(shape => {
ctx.beginPath()
shape.forEach(([x, y]) => ctx.lineTo(x, y))
ctx.stroke()
})
}
function handleShapes() {
canvas.addEventListener('mousedown', e => {
return (e.buttons === 4 || e.buttons === 2) ?
eraseLastShape()
: beginDrawing(e.offsetX, e.offsetY)
})
canvas.addEventListener('mouseup', e => {
if (e.buttons === 0 && currentShape) {
finishDrawing()
}
})
canvas.addEventListener('mousemove', e => continueDrawing(e.offsetX, e.offsetY))
}
const drawShapeComparison = (shapeA, shapeB) => {
const comparison = compareShape(shapeA)(shapeB)
const [xfa, yfa] = shapeA[0]
const [xfb, yfb] = shapeB[0]
const middlePoint = [(xfa + xfb) / 2, (yfa + yfb) /2]
ctx.font = '24px serif'
ctx.fillText(comparison.toString(), ...middlePoint)
}
function shapeRecognition(referenceShapes, unknownShape, options = {threshold: 0.50}) {
const compare = compareShape(unknownShape)
const closestShape = referenceShapes
.reduce((mostSimilar, shape) => {
const similarity = compare(shape.design)
if (similarity < mostSimilar.similarity) {
return {...shape, similarity}
}
return mostSimilar
}, {similarity: Infinity})
console.log('shape', closestShape.name, 'similarity :', closestShape.similarity);
if (closestShape.similarity > options.threshold) {
return closestShape
}
}
handleShapes()