|
7 | 7 | function draw(pos, state, dispatch) {
|
8 | 8 | let prev = pos;
|
9 | 9 | function drawPixel(pos, state) {
|
10 |
| - line(prev, pos, state, dispatch); |
| 10 | + const drawn = [{ x: pos.x, y: pos.y, color: state.color }, ...drawLine(prev, pos, state.color)]; |
| 11 | + dispatch({ picture: state.picture.draw(drawn) }); |
11 | 12 | if (pos != prev) {
|
12 | 13 | prev = pos;
|
13 | 14 | }
|
|
16 | 17 | return drawPixel;
|
17 | 18 | }
|
18 | 19 |
|
19 |
| - const aroundDiag = [ |
20 |
| - { dx: -1, dy: 0 }, |
21 |
| - { dx: 1, dy: 0 }, |
22 |
| - { dx: 0, dy: -1 }, |
23 |
| - { dx: 0, dy: 1 }, |
24 |
| - { dx: -1, dy: -1 }, |
25 |
| - { dx: -1, dy: 1 }, |
26 |
| - { dx: 1, dy: -1 }, |
27 |
| - { dx: 1, dy: 1 }, |
28 |
| - ]; |
29 |
| - |
30 |
| - function line(start, end, state, dispatch) { |
31 |
| - const fullDistance = Math.floor(Math.sqrt((start.x - end.x) ** 2 + (start.y - end.y) ** 2)); |
32 |
| - const drawn = [{ x: start.x, y: start.y, color: state.color, distance: fullDistance }]; |
33 |
| - |
34 |
| - for (let done = 0; done < drawn.length; done++) { |
35 |
| - const distances = []; |
36 |
| - for (let { dx, dy } of aroundDiag) { |
37 |
| - const x = drawn[done].x + dx; |
38 |
| - const y = drawn[done].y + dy; |
39 |
| - distances.push({ x, y, distance: Math.sqrt((x - end.x) ** 2 + (y - end.y) ** 2) }); |
| 20 | + function drawLine(start, end, color) { |
| 21 | + const drawn = []; |
| 22 | + const xDiff = Math.abs(start.x - end.x); |
| 23 | + const yDiff = Math.abs(start.y - end.y); |
| 24 | + |
| 25 | + if (xDiff > yDiff) { |
| 26 | + // horizontal-ish line |
| 27 | + if (start.x > end.x) { |
| 28 | + [start, end] = [end, start]; |
| 29 | + } |
| 30 | + const m = (end.y - start.y) / (end.x - start.x); |
| 31 | + |
| 32 | + for (let step = 1; step <= xDiff; step++) { |
| 33 | + drawn.push({ x: start.x + step, y: Math.floor(start.y + m * step), color }); |
| 34 | + } |
| 35 | + } else { |
| 36 | + // vertical-ish line |
| 37 | + if (start.y > end.y) { |
| 38 | + [start, end] = [end, start]; |
40 | 39 | }
|
41 |
| - const minDistance = distances.reduce( |
42 |
| - (min, curr) => (curr.distance < fullDistance && curr.distance < min.distance ? curr : min), |
43 |
| - distances[0] |
44 |
| - ); |
45 |
| - if (drawn[done].distance > minDistance.distance) { |
46 |
| - drawn.push({ x: minDistance.x, y: minDistance.y, color: state.color, distance: minDistance.distance }); |
| 40 | + const m = (end.x - start.x) / (end.y - start.y); |
| 41 | + |
| 42 | + for (let step = 1; step <= yDiff; step++) { |
| 43 | + drawn.push({ x: Math.floor(start.x + m * step), y: start.y + step, color }); |
47 | 44 | }
|
48 | 45 | }
|
49 |
| - dispatch({ picture: state.picture.draw(drawn) }); |
| 46 | + |
| 47 | + return drawn; |
| 48 | + } |
| 49 | + |
| 50 | + function line(start, state, dispatch) { |
| 51 | + return (end) => { |
| 52 | + const drawn = drawLine(start, end, state.color); |
| 53 | + dispatch({ picture: state.picture.draw(drawn) }); |
| 54 | + }; |
50 | 55 | }
|
51 | 56 |
|
52 | 57 | let dom = startPixelEditor({
|
|
0 commit comments