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
|
<style>
body,html{margin:0;padding:0;}
#hud { position: absolute; top: 0; left: 0; pointer-events: none; }
canvas { position: absolute; top: 0; left: 0; }
#mask { pointer-events: none; }
#scratch { display: none; }
</style>
<canvas id="canvas"></canvas>
<canvas id="mask"></canvas>
<canvas id="scratch"></canvas>
<div id="hud"></div>
<script src="/assets/javascripts/vendor/bower_components/jquery/dist/jquery.min.js"></script>
<script src="/assets/javascripts/vendor/bower_components/lodash/dist/lodash.min.js"></script>
<script src="/assets/javascripts/vendor/canvasutilities.js"></script>
<script src="/assets/javascripts/vendor/jsBezier-0.6.js"></script>
<script src="/assets/javascripts/vendor/tube.js"></script>
<script src="/assets/javascripts/math/util.js"></script>
<script src="/assets/javascripts/math/point.js"></script>
<script src="/assets/javascripts/math/vec2.js"></script>
<script src="/assets/javascripts/util/mouse.js"></script>
<script src="/assets/javascripts/util/uid.js"></script>
<script>
var ctx = canvas.getContext('2d')
var maskCtx = mask.getContext('2d')
var scratchCtx = scratch.getContext('2d')
var w = mask.width = canvas.width = window.innerWidth
var h = mask.height = canvas.height = window.innerHeight
var drawing = false
var lastPoint = new point (0, 0), newPoint = new point (0, 0)
var mymouse = new mouse({
el: canvas,
down: function(e, cursor){
drawing = true
lastPoint.x = cursor.a.x
lastPoint.y = cursor.a.y
maskCtx.clearRect(0,0,w,h)
drawLine(lastPoint, lastPoint)
// imagedata = ctx.getImageData( 0, 0, canvas.width, canvas.height )
// data = imagedata.data
},
drag: function(e, cursor){
newPoint.x = cursor.b.x
newPoint.y = cursor.b.y
drawLine(lastPoint, newPoint)
lastPoint.x = newPoint.x
lastPoint.y = newPoint.y
},
up: function(e, cursor, new_cursor){
drawing = false
ctx.globalCompositeOperation = "multiply"
ctx.drawImage(mask, 0, 0)
maskCtx.clearRect(0,0,w,h)
},
})
function drawLine (u, v, A, B, C, D) {
var radius = 20
var xmin = Math.min(u.x, v.x)
var ymin = Math.min(u.y, v.y)
var w = scratch.width = abs(u.x - v.x) + radius*2
var h = scratch.height = abs(u.y - v.y) + radius*2
var p = new point (0,0)
var radius2 = radius * radius
// if (w == h && h == radius*2) return
var imagedata = ctx.createImageData(w, h)
var d = imagedata.data
var i, j, t, dist
for (i = 0; i < w; i++) {
for (j = 0; j < h; j++) {
t = (j * w + i) * 4
p.x = xmin + i - radius
p.y = ymin + j - radius
dist = distToSegmentSquared( p, u, v )
if (dist > radius2) {
d[t+3] = 0
}
else {
d[t+0] = d[t+1] = d[t+2] = round( bezier( sqrt(dist)/radius, 0, 0, 1, 1) * 255)
d[t+3] = 255
}
}
}
scratchCtx.putImageData(imagedata, 0, 0)
maskCtx.globalCompositeOperation = 'darken';
maskCtx.drawImage(scratch, xmin - radius, ymin - radius)
}
for (var i = 0; i < 11; i++) {
drawLine( new point( 100, 100 + 40 * i), new point (400, 100 + 40 * i ), 0, 0, lerp(i/10, -2, 1), 1 )
}
// drawLine( new point( 100, 100 ), new point( 100, 400 ) )
// drawLine( new point( 100, 100 ), new point( 400, 100 ) )
// drawLine( new point( 100, 100 ), new point( 400, 400 ) )
function bezier(t,a,b,c,d) {
var s = (1-t)
return s*s*s*a + 3*s*s*b + 3*s*t*t*c + t*t*t*d
}
function sqr(x) { return x * x }
function dist2(v, w) { return sqr(v.x - w.x) + sqr(v.y - w.y) }
function distToSegmentSquared (p, v, w) {
var l2 = dist2(v, w)
if (l2 == 0) return dist2(p, v)
var t = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2
if (t < 0) return dist2(p, v)
if (t > 1) return dist2(p, w)
return dist2(p, { x: v.x + t * (w.x - v.x),
y: v.y + t * (w.y - v.y) })
}
</script>
|