1 | <!DOCTYPE html>
|
---|
2 | <html>
|
---|
3 | <head>
|
---|
4 | <meta charset="UTF-8">
|
---|
5 | <title>Nyan Rainbow</title>
|
---|
6 | <link rel="stylesheet" href="../css/style.css">
|
---|
7 | <script type="text/javascript" src="../../dist/paper.js"></script>
|
---|
8 | <script type="text/javascript" src="http://paperjs.org/assets/mediaelement/mediaelement.js"></script>
|
---|
9 | <script type="text/paperscript" canvas="canvas">
|
---|
10 | // A tribute to Nyan Cat http://www.youtube.com/watch?v=QH2-TGUlwu4
|
---|
11 | var mediaElement;
|
---|
12 | var playing = false;
|
---|
13 | MediaElement('nyan', {
|
---|
14 | pluginPath: '/assets/mediaelement/',
|
---|
15 | success: function(me) {
|
---|
16 | mediaElement = me;
|
---|
17 | me.play();
|
---|
18 | me.addEventListener('timeupdate', function(time) {
|
---|
19 | if (me.currentTime > 3.7)
|
---|
20 | playing = true;
|
---|
21 | });
|
---|
22 | }
|
---|
23 | });
|
---|
24 |
|
---|
25 | var mousePos = view.center + [view.bounds.width / 3, 100];
|
---|
26 | var position = view.center;
|
---|
27 |
|
---|
28 | function onFrame(event) {
|
---|
29 | position += (mousePos - position) / 10;
|
---|
30 | var vector = (view.center - position) / 10;
|
---|
31 | moveStars(vector * 3);
|
---|
32 | moveRainbow(vector, event);
|
---|
33 | }
|
---|
34 |
|
---|
35 | function onMouseMove(event) {
|
---|
36 | mousePos = event.point;
|
---|
37 | }
|
---|
38 |
|
---|
39 | function onKeyDown(event) {
|
---|
40 | if (event.key == 'space')
|
---|
41 | project.activeLayer.selected = !project.activeLayer.selected;
|
---|
42 | }
|
---|
43 |
|
---|
44 | var moveStars = new function() {
|
---|
45 | // The amount of symbol we want to place;
|
---|
46 | var count = 50;
|
---|
47 |
|
---|
48 | // Create a symbol, which we will use to place instances of later:
|
---|
49 | var path = new Path.Circle({
|
---|
50 | center: new Point(0, 0),
|
---|
51 | radius: 5,
|
---|
52 | fillColor: 'white',
|
---|
53 | strokeColor: 'black'
|
---|
54 | });
|
---|
55 |
|
---|
56 | var symbol = new Symbol(path);
|
---|
57 |
|
---|
58 | // Place the instances of the symbol:
|
---|
59 | for (var i = 0; i < count; i++) {
|
---|
60 | // The center position is a random point in the view:
|
---|
61 | var center = Point.random() * view.size;
|
---|
62 | var placed = symbol.place(center);
|
---|
63 | placed.scale(i / count + 0.01);
|
---|
64 | placed.data = {
|
---|
65 | vector: new Point({
|
---|
66 | angle: Math.random() * 360,
|
---|
67 | length : (i / count) * Math.random() / 5
|
---|
68 | })
|
---|
69 | };
|
---|
70 | }
|
---|
71 |
|
---|
72 | var vector = new Point({
|
---|
73 | angle: 45,
|
---|
74 | length: 0
|
---|
75 | });
|
---|
76 |
|
---|
77 | function keepInView(item) {
|
---|
78 | var position = item.position;
|
---|
79 | var viewBounds = view.bounds;
|
---|
80 | if (position.isInside(viewBounds))
|
---|
81 | return;
|
---|
82 | var itemBounds = item.bounds;
|
---|
83 | if (position.x > viewBounds.width + 5) {
|
---|
84 | position.x = -item.bounds.width;
|
---|
85 | }
|
---|
86 |
|
---|
87 | if (position.x < -itemBounds.width - 5) {
|
---|
88 | position.x = viewBounds.width;
|
---|
89 | }
|
---|
90 |
|
---|
91 | if (position.y > viewBounds.height + 5) {
|
---|
92 | position.y = -itemBounds.height;
|
---|
93 | }
|
---|
94 |
|
---|
95 | if (position.y < -itemBounds.height - 5) {
|
---|
96 | position.y = viewBounds.height
|
---|
97 | }
|
---|
98 | }
|
---|
99 |
|
---|
100 | return function(vector) {
|
---|
101 | // Run through the active layer's children list and change
|
---|
102 | // the position of the placed symbols:
|
---|
103 | var layer = project.activeLayer;
|
---|
104 | for (var i = 0; i < count; i++) {
|
---|
105 | var item = layer.children[i];
|
---|
106 | var size = item.bounds.size;
|
---|
107 | var length = vector.length / 10 * size.width / 10;
|
---|
108 | item.position += vector.normalize(length) + item.data.vector;
|
---|
109 | keepInView(item);
|
---|
110 | }
|
---|
111 | };
|
---|
112 | };
|
---|
113 |
|
---|
114 | var moveRainbow = new function() {
|
---|
115 | var paths = [];
|
---|
116 | var colors = ['red', 'orange', 'yellow', 'lime', 'blue', 'purple'];
|
---|
117 | for (var i = 0; i < colors.length; i++) {
|
---|
118 | var path = new Path({
|
---|
119 | fillColor: colors[i]
|
---|
120 | });
|
---|
121 | paths.push(path);
|
---|
122 | }
|
---|
123 |
|
---|
124 | var count = 30;
|
---|
125 | var group = new Group(paths);
|
---|
126 | var headGroup;
|
---|
127 | var eyePosition = new Point();
|
---|
128 | var eyeFollow = (Point.random() - 0.5);
|
---|
129 | var blinkTime = 200;
|
---|
130 | function createHead(vector, count) {
|
---|
131 | var eyeVector = (eyePosition - eyeFollow);
|
---|
132 | eyePosition -= eyeVector / 4;
|
---|
133 | if (eyeVector.length < 0.00001)
|
---|
134 | eyeFollow = (Point.random() - 0.5);
|
---|
135 | if (headGroup)
|
---|
136 | headGroup.remove();
|
---|
137 | var top = paths[0].lastSegment.point;
|
---|
138 | var bottom = paths[paths.length - 1].firstSegment.point;
|
---|
139 | var radius = (bottom - top).length / 2;
|
---|
140 | var circle = new Path.Circle({
|
---|
141 | center: top + (bottom - top) / 2,
|
---|
142 | radius: radius,
|
---|
143 | fillColor: 'black'
|
---|
144 | });
|
---|
145 | circle.scale(vector.length / 100, 1);
|
---|
146 | circle.rotate(vector.angle, circle.center);
|
---|
147 |
|
---|
148 | innerCircle = circle.clone();
|
---|
149 | innerCircle.scale(0.5);
|
---|
150 | innerCircle.fillColor = (count % blinkTime < 3)
|
---|
151 | || (count % (blinkTime + 5) < 3) ? 'black' : 'white';
|
---|
152 | if (count % (blinkTime + 40) == 0)
|
---|
153 | blinkTime = Math.round(Math.random() * 40) + 200;
|
---|
154 | var eye = circle.clone();
|
---|
155 | eye.position += eyePosition * radius;
|
---|
156 | eye.scale(0.15, innerCircle.position);
|
---|
157 | eye.fillColor = 'black';
|
---|
158 | headGroup = new Group(circle, innerCircle, eye);
|
---|
159 | }
|
---|
160 |
|
---|
161 | return function(vector, event) {
|
---|
162 | var vector = (view.center - position) / 10;
|
---|
163 |
|
---|
164 | if (vector.length < 5)
|
---|
165 | vector.length = 5;
|
---|
166 | count += vector.length / 100;
|
---|
167 | group.translate(vector);
|
---|
168 | var rotated = vector.rotate(90);
|
---|
169 | var middle = paths.length / 2;
|
---|
170 | for (var j = 0; j < paths.length; j++) {
|
---|
171 | var path = paths[j];
|
---|
172 | var nyanSwing = playing ? Math.sin(event.count / 2) * vector.length : 1;
|
---|
173 | var unitLength = vector.length * (2 + Math.sin(event.count / 10)) / 2;
|
---|
174 | var length = (j - middle) * unitLength + nyanSwing;
|
---|
175 | var top = view.center + rotated.normalize(length);
|
---|
176 | var bottom = view.center + rotated.normalize(length + unitLength);
|
---|
177 | path.add(top);
|
---|
178 | path.insert(0, bottom);
|
---|
179 | if (path.segments.length > 200) {
|
---|
180 | var index = Math.round(path.segments.length / 2);
|
---|
181 | path.segments[index].remove();
|
---|
182 | path.segments[index - 1].remove();
|
---|
183 | }
|
---|
184 | path.smooth();
|
---|
185 | }
|
---|
186 | createHead(vector, event.count);
|
---|
187 | if (mediaElement)
|
---|
188 | mediaElement.setVolume(vector.length / 200);
|
---|
189 | }
|
---|
190 | }
|
---|
191 | </script>
|
---|
192 | <style>
|
---|
193 | body {
|
---|
194 | background: black;
|
---|
195 | }
|
---|
196 | </style>
|
---|
197 | </head>
|
---|
198 | <body>
|
---|
199 | <audio id="nyan" src="http://dl.dropbox.com/u/31703/nyan.mp3" autoplay autobuffer preload=none loop style="display:none"></audio>
|
---|
200 | <canvas id="canvas" resize hidpi="off"></canvas>
|
---|
201 | </body>
|
---|
202 | </html> |
---|