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}