animation2code benchmark
For best compatibility, please view this dashboard in a Chrome browser.
← back

rendered animation

Gotta catch 'em all!

1'use strict';
2
3//          * * * * * * * * * * * * *
4//          * *      WARNING      * *
5//          * * * * * * * * * * * * *
6// I wrote this alongside someone who happened to be:
7//
8//   a) Eager and ambitious at the beginning of their
9//      Programmer's Journey, and:
10//   b) Really keen on Pokémon.
11//
12// It was fun *training*, but the code's *evolution*
13// left it smelling somewhat like *Weezing* (these
14// are Pokemon things iirc, C_y I'm not hip anymore).
15//
16// Enter at your own risk, enjoy, catch 'em all :)
17// - rileyjshaw
18
19var colors = ['#f10d00', // Standard ball
20'#a63deb', // Master ball
21'#5baeff', // Great ball
22'#00874b', // Safari ball
23'#505301'];
24
25// Editable.
26var d = 72; // Diameter.
27var w = 8; // Inner line width.
28var T = 120; // Period, in frames @ 60fps.
29
30// Computed.
31var r = d / 2; // Radius.
32var r2_max = r / 5; // Max radius of the mid-section.
33var l = r * 2 + w; // Canvas side length.
34
35// Constants.
36var abs = Math.abs,
37    pi = Math.PI;
38
39var C_y = 4 / 3; // Simplified from 4/3*tan(θ/4)), since θ=π.
40var _document = document,
41    body = _document.body;
42
43
44var bag = document.createElement('div');
45Object.assign(bag.style, {
46  left: '50%',
47  position: 'absolute',
48  top: '50%',
49  transform: 'translate3d(-50%, -50%, 0)'
50});
51
52var team = colors.map(pokeball);
53team.forEach(function (ball) {
54  return bag.appendChild(ball.canvas);
55});
56body.style.background = '#de73cd';
57body.appendChild(bag);
58
59!function loop(t) {
60  team.forEach(function (_ref, i, _ref2) {
61    var step = _ref.step;
62    var length = _ref2.length;
63    return step((t + i * T / length) % T);
64  });
65  requestAnimationFrame(loop.bind(this, t + 1));
66}(0);
67
68function pokeball(top) {
69  // Constants.
70  var canvas = document.createElement('canvas');
71  var ctx = canvas.getContext('2d');
72
73  // Prepare the canvas and clip it to a circle.
74  canvas.width = canvas.height = l;
75  Object.assign(canvas.style, {
76    background: '#f0f0f0',
77    border: w / 2 + 'px solid #f8f8f8',
78    borderRadius: '50%',
79    boxShadow: '2px 4px rgba(34, 34, 36, 0.2)',
80    height: l / 2 + 'px',
81    margin: w + 'px',
82    width: l / 2 + 'px'
83  });
84  ctx.translate(w / 2, w / 2);
85  ctx.beginPath();
86  ctx.lineWidth = w;
87  ctx.arc(r, r, r, 0, 2 * pi);
88  ctx.stroke();
89  ctx.clip();
90
91  ctx.strokeStyle = '#222224';
92  function step(t) {
93    // t:     0 -------- T/2 -------- T
94    // frame: 0 --------- T --------- 0
95    // y:     bottom --- top --- bottom
96    //     where bottom: 1 - C_y, top: C_y
97    var frame = 2 * (T / 2 - abs(T / 2 - t));
98    var y = 1 - C_y + frame / T * (2 * C_y - 1);
99
100    ctx.clearRect(0, 0, d, d);
101    ctx.lineWidth = w;
102
103    // Draw a "circle".
104    ctx.beginPath();
105    ctx.fillStyle = top;
106    ctx.moveTo(-w / 2, r);
107    ctx.bezierCurveTo(-w / 2, y * d, d + w, y * d, d + w, r);
108    ctx.stroke();
109    //ctx.arc(r, r, r, 0, pi, true);
110    ctx.lineTo(d, 0);
111    ctx.lineTo(0, 0);
112    ctx.fill();
113    ctx.closePath();
114
115    // Draw the center circle.
116    var c = d * y / C_y + r2_max * C_y;
117    var r2 = r2_max * (1 - abs(1 / 2 - y) / 3);
118    var r3 = r2 / 3 * 2;
119
120    ctx.beginPath();
121    ctx.lineWidth /= 2;
122    ctx.fillStyle = '#f0f0f0';
123    ctx.arc(r, c, r2, 0, 2 * pi);
124    ctx.fill();
125    ctx.stroke();
126    ctx.closePath();
127
128    ctx.beginPath();
129    ctx.lineWidth /= 2;
130    ctx.arc(r, c, r3, 0, 2 * pi);
131    ctx.stroke();
132    ctx.closePath();
133  };
134  return { canvas: canvas, step: step };
135}