<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<!------ Include the above in your HEAD tag ---------->
<!DOCTYPE html><html class=''>
<head><script src='//production-assets.codepen.io/assets/editor/live/console_runner-079c09a0e3b9ff743e39ee2d5637b9216b3545af0de366d4b9aad9dc87e26bfd.js'></script><script src='//production-assets.codepen.io/assets/editor/live/events_runner-73716630c22bbc8cff4bd0f07b135f00a0bdc5d14629260c3ec49e5606f98fdd.js'></script><script src='//production-assets.codepen.io/assets/editor/live/css_live_reload_init-2c0dc5167d60a5af3ee189d570b1835129687ea2a61bee3513dee3a50c115a77.js'></script><meta charset='UTF-8'><meta name="robots" content="noindex"><link rel="shortcut icon" type="image/x-icon" href="//production-assets.codepen.io/assets/favicon/favicon-8ea04875e70c4b0bb41da869e81236e54394d63638a1ef12fa558a4a835f1164.ico" /><link rel="mask-icon" type="" href="//production-assets.codepen.io/assets/favicon/logo-pin-f2d2b6d2c61838f7e76325261b7195c27224080bc099486ddd6dccb469b8e8e6.svg" color="#111" /><link rel="canonical" href="https://codepen.io/therne/pen/VbWowZ?depth=everything&order=popularity&page=80&q=redux&show_forks=false" />
<style class="cp-pen-styles"></style></head><body>
<canvas id="canvas"></canvas>
<script src='//production-assets.codepen.io/assets/common/stopExecutionOnTimeout-b2a7b3fe212eaa732349046d8416e00a9dec26eb7fd347590fbced3ab38af52e.js'></script>
<script >const canvas = document.getElementById('canvas');
const texts = [
'HTML5', 'Javascript', 'Scala', 'Kotlin', 'Erlang',
'CSS', 'Python', 'Java', 'PostgreSQL', 'MongoDB',
'Android', 'TensorFlow', 'Flask', 'React', 'Redis',
'NodeJS', 'OCaml', 'Redux', 'Rx',
];
const counts = [1,2,4,5,4,2,1];
const options = {
tilt: Math.PI / 9,
initialVelocityX: 0.09,
initialVelocityY: 0.09,
initialRotationX: Math.PI * 0.14,
initialRotationZ: 0
};
wordSphere(canvas, texts, counts, options);
/**
* WordSphere
* Written by Hyojun Kim in 2017. Licensed in MIT.
*/
function wordSphere(canvas, texts, counts, options) {
const π = Math.PI; // happy math!
const {
width = 500,
height = 500,
radius = 150,
padding = 50,
fontSize = 22,
tilt = 0,
initialVelocityX = 0,
initialVelocityY = 0,
initialRotationX = 0,
initialRotationZ = 0,
} = options;
let vx = initialVelocityX, vy = initialVelocityY;
let rx = initialRotationX, rz = initialRotationZ;
// canvas setup
let ctx = canvas.getContext('2d');
ctx.textAlign = 'center';
// Hi-DPI support
canvas.width = width * 2;
canvas.height = height * 2;
canvas.style.width = `${width}px`;
canvas.style.height = `${height}px`;
ctx.scale(2,2);
// scrolling
let clicked = false, lastX, lastY;
canvas.addEventListener('mousedown', event => {
clicked = true;
lastX = event.screenX;
lastY = event.screenY;
});
canvas.addEventListener('mousemove', event => {
if (!clicked) return;
[dx, dy] = [event.screenX - lastX, event.screenY - lastY];
[lastX, lastY] = [event.screenX, event.screenY];
// rotation update
rz += -dy * 0.01;
rx += dx * 0.01;
// velocity update
vx = dx * 0.1;
vy = dy * 0.1;
if (!looping) startLoop();
});
canvas.addEventListener('mouseup', e => clicked = false);
canvas.addEventListener('mouseleave', e => clicked = false);
function rot(x,y,t) {
return [x*Math.cos(t)-y*Math.sin(t), x*Math.sin(t)+y*Math.cos(t)];
}
function render() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
let ix = 0, iz = 0, i = 1;
for (const text of texts) {
const degZ = (π/(counts.length-1)) * iz;
const degX = (2*π/counts[iz]) * ix;
let x = radius * Math.sin(degZ) * Math.cos(degX);
let y = radius * Math.sin(degZ) * Math.sin(degX);
let z = radius * Math.cos(degZ) + 8*(ix % 2) /* randomness */;
// camera transform
[y,z] = rot(y, z, tilt);
[x,z] = rot(x, z, rz);
[x,y] = rot(x, y, rx);
// convert to cartesian and then draw.
const alpha = 0.6 + 0.4 * (x/radius);
const size = fontSize + 2 + 5*(x/radius);
ctx.fillStyle = `rgba(0,0,0,${alpha})`;
ctx.font = `${size}px "Helvetica Neue", sans-serif`;
ctx.fillText(text, y + width/2, -z + height/2);
ix--;
if (ix < 0) {
iz++;
ix = counts[iz] - 1;
}
i++;
}
}
// renderer
let looping = false;
function rendererLoop() {
if (looping) window.requestAnimationFrame(rendererLoop);
render();
// deacceleration - dirty code xD
if (vx > 0) vx = vx - 0.01;
if (vy > 0) vy = vy - 0.01;
if (vx < 0) vx = vx + 0.01;
if (vy > 0) vy = vy + 0.01;
if (vx == 0 && vy == 0) stopLoop();
rz += vy * 0.01;
rx += vx * 0.01;
}
function startLoop() {
looping = true;
window.requestAnimationFrame(rendererLoop);
}
function stopLoop() {
looping = false;
}
startLoop();
}
//# sourceURL=pen.js
</script>
</body></html>