1 | <!DOCTYPE html>
|
---|
2 | <html>
|
---|
3 | <head>
|
---|
4 | <meta charset="UTF-8">
|
---|
5 | <title>Bouncing Balls</title>
|
---|
6 | <link rel="stylesheet" href="../css/style.css">
|
---|
7 | <script type="text/javascript" src="../../dist/paper.js"></script>
|
---|
8 | <script type="text/paperscript" canvas="canvas">
|
---|
9 | var Ball = function(point, vector) {
|
---|
10 | if (!vector || vector.isZero()) {
|
---|
11 | this.vector = Point.random() * 5;
|
---|
12 | } else {
|
---|
13 | this.vector = vector * 2;
|
---|
14 | }
|
---|
15 | this.point = point;
|
---|
16 | this.dampen = 0.4;
|
---|
17 | this.gravity = 3;
|
---|
18 | this.bounce = -0.6;
|
---|
19 |
|
---|
20 | var color = {
|
---|
21 | hue: Math.random() * 360,
|
---|
22 | saturation: 1,
|
---|
23 | brightness: 1
|
---|
24 | };
|
---|
25 | var gradient = new Gradient([color, 'black'], true);
|
---|
26 |
|
---|
27 | var radius = this.radius = 50 * Math.random() + 30;
|
---|
28 | // Wrap CompoundPath in a Group, since CompoundPaths directly
|
---|
29 | // applies the transformations to the content, just like Path.
|
---|
30 | var ball = new CompoundPath({
|
---|
31 | children: [
|
---|
32 | new Path.Circle({
|
---|
33 | radius: radius
|
---|
34 | }),
|
---|
35 | new Path.Circle({
|
---|
36 | center: radius / 8,
|
---|
37 | radius: radius / 3
|
---|
38 | })
|
---|
39 | ],
|
---|
40 | fillColor: new Color(gradient, 0, radius, radius / 8),
|
---|
41 | });
|
---|
42 |
|
---|
43 | this.item = new Group({
|
---|
44 | children: [ball],
|
---|
45 | transformContent: false,
|
---|
46 | position: this.point
|
---|
47 | });
|
---|
48 | }
|
---|
49 |
|
---|
50 | Ball.prototype.iterate = function() {
|
---|
51 | var size = view.size;
|
---|
52 | this.vector.y += this.gravity;
|
---|
53 | this.vector.x *= 0.99;
|
---|
54 | var pre = this.point + this.vector;
|
---|
55 | if (pre.x < this.radius || pre.x > size.width - this.radius)
|
---|
56 | this.vector.x *= -this.dampen;
|
---|
57 | if (pre.y < this.radius || pre.y > size.height - this.radius) {
|
---|
58 | if (Math.abs(this.vector.x) < 3)
|
---|
59 | this.vector = Point.random() * [150, 100] + [-75, 20];
|
---|
60 | this.vector.y *= this.bounce;
|
---|
61 | }
|
---|
62 |
|
---|
63 | var max = Point.max(this.radius, this.point + this.vector);
|
---|
64 | this.item.position = this.point = Point.min(max, size - this.radius);
|
---|
65 | this.item.rotate(this.vector.x);
|
---|
66 | };
|
---|
67 |
|
---|
68 |
|
---|
69 | var balls = [];
|
---|
70 | for (var i = 0; i < 10; i++) {
|
---|
71 | var position = Point.random() * view.size,
|
---|
72 | vector = (Point.random() - [0.5, 0]) * [50, 100],
|
---|
73 | ball = new Ball(position, vector);
|
---|
74 | balls.push(ball);
|
---|
75 | }
|
---|
76 |
|
---|
77 | var textItem = new PointText({
|
---|
78 | point: [20, 30],
|
---|
79 | fillColor: 'black',
|
---|
80 | content: 'Click, drag and release to add balls.'
|
---|
81 | });
|
---|
82 |
|
---|
83 | var lastDelta;
|
---|
84 | function onMouseDrag(event) {
|
---|
85 | lastDelta = event.delta;
|
---|
86 | }
|
---|
87 |
|
---|
88 | function onMouseUp(event) {
|
---|
89 | var ball = new Ball(event.point, lastDelta);
|
---|
90 | balls.push(ball);
|
---|
91 | lastDelta = null;
|
---|
92 | }
|
---|
93 |
|
---|
94 | function onFrame() {
|
---|
95 | for (var i = 0, l = balls.length; i < l; i++)
|
---|
96 | balls[i].iterate();
|
---|
97 | }
|
---|
98 | </script>
|
---|
99 | </head>
|
---|
100 | <body>
|
---|
101 | <canvas id="canvas" resize></canvas>
|
---|
102 | </body>
|
---|
103 | </html> |
---|