UNPKG

paper

Version:

The Swiss Army Knife of Vector Graphics Scripting

203 lines (183 loc) 7.76 kB
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Nyan Rainbow</title> <link rel="stylesheet" href="../css/style.css"> <script type="text/javascript" src="../../dist/paper-full.js"></script> <script type="text/javascript" src="http://paperjs.org/assets/mediaelement/mediaelement.js"></script> <script type="text/paperscript" canvas="canvas"> // A tribute to Nyan Cat http://www.youtube.com/watch?v=QH2-TGUlwu4 var mediaElement; var playing = false; MediaElement('nyan', { pluginPath: '/assets/mediaelement/', success: function(me) { mediaElement = me; me.play(); me.addEventListener('timeupdate', function(time) { if (me.currentTime > 3.7) playing = true; }); } }); var mousePos = view.center + [view.bounds.width / 3, 100]; var position = view.center; function onFrame(event) { position += (mousePos - position) / 10; var vector = (view.center - position) / 10; moveStars(vector * 3); moveRainbow(vector, event); } function onMouseMove(event) { mousePos = event.point; } function onKeyDown(event) { if (event.key == 'space') project.activeLayer.selected = !project.activeLayer.selected; } var moveStars = new function() { // The amount of symbol we want to place; var count = 50; // Create a symbol, which we will use to place instances of later: var path = new Path.Circle({ center: new Point(0, 0), radius: 5, fillColor: 'white', strokeColor: 'black' }); var symbol = new SymbolDefinition(path); // Place the instances of the symbol: for (var i = 0; i < count; i++) { // The center position is a random point in the view: var center = Point.random() * view.size; var placed = symbol.place(center); placed.scale(i / count + 0.01); placed.data = { vector: new Point({ angle: Math.random() * 360, length : (i / count) * Math.random() / 5 }) }; } var vector = new Point({ angle: 45, length: 0 }); function keepInView(item) { var position = item.position; var viewBounds = view.bounds; if (position.isInside(viewBounds)) return; var itemBounds = item.bounds; if (position.x > viewBounds.width + 5) { position.x = -item.bounds.width; } if (position.x < -itemBounds.width - 5) { position.x = viewBounds.width; } if (position.y > viewBounds.height + 5) { position.y = -itemBounds.height; } if (position.y < -itemBounds.height - 5) { position.y = viewBounds.height } } return function(vector) { // Run through the active layer's children list and change // the position of the placed symbols: var layer = project.activeLayer; for (var i = 0; i < count; i++) { var item = layer.children[i]; var size = item.bounds.size; var length = vector.length / 10 * size.width / 10; item.position += vector.normalize(length) + item.data.vector; keepInView(item); } }; }; var moveRainbow = new function() { var paths = []; var colors = ['red', 'orange', 'yellow', 'lime', 'blue', 'purple']; for (var i = 0; i < colors.length; i++) { var path = new Path({ fillColor: colors[i] }); paths.push(path); } var count = 30; var group = new Group(paths); var headGroup; var eyePosition = new Point(); var eyeFollow = (Point.random() - 0.5); var blinkTime = 200; function createHead(vector, count) { var eyeVector = (eyePosition - eyeFollow); eyePosition -= eyeVector / 4; if (eyeVector.length < 0.00001) eyeFollow = (Point.random() - 0.5); if (headGroup) headGroup.remove(); var top = paths[0].lastSegment.point; var bottom = paths[paths.length - 1].firstSegment.point; var radius = (bottom - top).length / 2; var circle = new Path.Circle({ center: top + (bottom - top) / 2, radius: radius, fillColor: 'black' }); circle.scale(vector.length / 100, 1); circle.rotate(vector.angle, circle.center); innerCircle = circle.clone(); innerCircle.scale(0.5); innerCircle.fillColor = (count % blinkTime < 3) || (count % (blinkTime + 5) < 3) ? 'black' : 'white'; if (count % (blinkTime + 40) == 0) blinkTime = Math.round(Math.random() * 40) + 200; var eye = circle.clone(); eye.position += eyePosition * radius; eye.scale(0.15, innerCircle.position); eye.fillColor = 'black'; headGroup = new Group(circle, innerCircle, eye); } return function(vector, event) { var vector = (view.center - position) / 10; if (vector.length < 5) vector.length = 5; count += vector.length / 100; group.translate(vector); var rotated = vector.rotate(90); var middle = paths.length / 2; for (var j = 0; j < paths.length; j++) { var path = paths[j]; var nyanSwing = playing ? Math.sin(event.count / 2) * vector.length : 1; var unitLength = vector.length * (2 + Math.sin(event.count / 10)) / 2; var length = (j - middle) * unitLength + nyanSwing; var top = view.center + rotated.normalize(length); var bottom = view.center + rotated.normalize(length + unitLength); path.add(top); path.insert(0, bottom); if (path.segments.length > 200) { var index = Math.round(path.segments.length / 2); path.segments[index].remove(); path.segments[index - 1].remove(); } path.smooth(); } createHead(vector, event.count); if (mediaElement) mediaElement.setVolume(vector.length / 200); } } </script> <style> body { background: black; } </style> </head> <body> <audio id="nyan" src="http://dl.dropbox.com/u/31703/nyan.mp3" autoplay autobuffer preload=none loop style="display:none"></audio> <canvas id="canvas" resize hidpi="off"></canvas> </body> </html>