-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathdragon.js
118 lines (90 loc) · 3.63 KB
/
dragon.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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// Copyright (c) 2011, Kevin Cantu <[email protected]>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// The software is provided "as is" and the author disclaims all warranties
// with regard to this software including all implied warranties of
// merchantability and fitness. In no event shall the author be liable for
// any special, direct, indirect, or consequential damanges or any damages
// whatsoever resulting from loss of use, data, your immortal soul, or
// profits, whether in an action of contract, negligence, or other
// tortious action, arising out of or in connection with the use or
// performance of this software.
// dragon.js: a library to draw dragon curves
// ------------------------------------------
// Tested on Chrome 8.0. Enjoy!
var DRAGON = (function () {
// MATRIX MATH
// -----------
var matrix = {
mult: function ( m, v ) {
return [ m[0][0] * v[0] + m[0][1] * v[1],
m[1][0] * v[0] + m[1][1] * v[1] ];
},
minus: function ( a, b ) {
return [ a[0]-b[0], a[1]-b[1] ];
},
plus: function ( a, b ) {
return [ a[0]+b[0], a[1]+b[1] ];
}
};
// SVG STUFF
// ---------
// Turn a pair of points into an SVG path like "M1 1L2 2".
var toSVGpath = function (a, b) { // type system fail
return "M" + a[0] + " " + a[1] + "L" + b[0] + " " + b[1];
};
// DRAGON MAKING
// -------------
// Make a dragon with a better fractal algorithm
var fractalMakeDragon = function (svgid, ptA, ptC, state, lr, interval) {
// make a new <path>
var path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path.setAttribute( "class", "dragon");
path.setAttribute( "d", toSVGpath(ptA, ptC) );
// append the new path to the existing <svg>
var svg = document.getElementById(svgid); // call could be eliminated
svg.appendChild(path);
// if we have more iterations to go...
if (state > 1) {
// make a new point, either to the left or right
var growNewPoint = function (ptA, ptC, lr) {
var left = [[ 1/2,-1/2 ],
[ 1/2, 1/2 ]];
var right = [[ 1/2, 1/2 ],
[-1/2, 1/2 ]];
return matrix.plus(ptA, matrix.mult( lr ? left : right,
matrix.minus(ptC, ptA) ));
};
var ptB = growNewPoint(ptA, ptC, lr, state);
// then recurse using each new line, one left, one right
var recurse = function () {
// when recursing deeper, delete this svg path
svg.removeChild(path);
// then invoke again for new pair, decrementing the state
fractalMakeDragon(svgid, ptB, ptA, state-1, lr, interval);
fractalMakeDragon(svgid, ptB, ptC, state-1, lr, interval);
};
window.setTimeout(recurse, interval);
}
};
// Export these functions
// ----------------------
return {
fractal: fractalMakeDragon
// ARGUMENTS
// ---------
// svgid id of <svg> element
// ptA first point [x,y] (from top left)
// ptC second point [x,y]
// state number indicating how many steps to recurse
// lr true/false to make new point on left or right
// CONFIG
// ------
// CSS rules should be made for the following
// svg#fractal
// svg path.dragon
};
}());