Guest User

Untitled

a guest
Aug 7th, 2019
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import React, { useEffect, useState, createRef } from 'react';
  2.  
  3. function TagSphere() {
  4.   const cloudSphere = createRef<any>();
  5.   const [clicked, setClicked] = useState(false);
  6.   const [lastX, setLastX] = useState(0);
  7.   const [lastY, setLastY] = useState(0);
  8.   const [looping, setLooping] = useState(false);
  9.  
  10.   const texts = [
  11.       'HTML5', 'Javascript', 'Scala', 'Kotlin', 'Erlang',
  12.       'CSS', 'Python', 'Java', 'PostgreSQL', 'MongoDB',
  13.       'Android', 'TensorFlow', 'Flask', 'React', 'Redis',
  14.       'NodeJS', 'OCaml', 'Redux', 'Rx',
  15.   ];
  16.   const counts = [1,2,4,5,4,2,1];
  17.   const options:any = {
  18.       tilt: Math.PI / 9,
  19.       initialVelocityX: 0.09,
  20.       initialVelocityY: 0.09,
  21.       initialRotationX: Math.PI * 0.14,
  22.       initialRotationZ: 0
  23.   };
  24.  
  25.   const π = Math.PI;
  26.   const {
  27.       width = 500,
  28.       height = 500,
  29.       radius = 150,
  30.       padding = 50,
  31.       fontSize = 22,
  32.       tilt = 0,
  33.       initialVelocityX = 0,
  34.       initialVelocityY = 0,
  35.       initialRotationX = 0,
  36.       initialRotationZ = 0,
  37.   } = options;
  38.  
  39.   let vx = initialVelocityX, vy = initialVelocityY;
  40.   let rx = initialRotationX, rz = initialRotationZ;
  41.  
  42.  
  43.  
  44.   function rot(x:number,y:number,t:number) {
  45.     return [x*Math.cos(t)-y*Math.sin(t), x*Math.sin(t)+y*Math.cos(t)];
  46.   }
  47.  
  48.   function renderSphere() {
  49.     ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
  50.  
  51.     let ix = 0, iz = 0, i = 1;
  52.  
  53.     for (const text of texts) {
  54.       const degZ = (π/(counts.length-1)) * iz;
  55.       const degX = (2*π/counts[iz]) * ix;
  56.  
  57.       let x = radius * Math.sin(degZ) * Math.cos(degX);
  58.       let y = radius * Math.sin(degZ) * Math.sin(degX);
  59.       let z = radius * Math.cos(degZ) + 8*(ix % 2) /* randomness */;
  60.  
  61.       [y,z] = rot(y, z, tilt);
  62.       [x,z] = rot(x, z, rz);
  63.       [x,y] = rot(x, y, rx);
  64.  
  65.       const alpha = 0.6 + 0.4 * (x/radius);
  66.       const size = fontSize + 2 + 5*(x/radius);
  67.       ctx.fillStyle = `rgba(255,255,255,${alpha})`;
  68.       ctx.font = `${size}px "Brandon Grotesque"`;
  69.       ctx.fillText(text, y + width/2, -z + height/2);
  70.  
  71.       ix--;
  72.       if (ix < 0) {
  73.         iz++;
  74.         ix = counts[iz] - 1;
  75.       }
  76.         i++;
  77.     }
  78.   }
  79.  
  80.   function rendererLoop() {
  81.     if (looping) window.requestAnimationFrame(rendererLoop);
  82.     renderSphere();
  83.  
  84.     if (vx > 0) vx = vx - 0.01;
  85.     if (vy > 0) vy = vy - 0.01;
  86.     if (vx < 0) vx = vx + 0.01;
  87.     if (vy > 0) vy = vy + 0.01;
  88.     if (vx === 0 && vy === 0) stopLoop();
  89.    
  90.     rz += vy * 0.01;
  91.     rx += vx * 0.01;
  92.   }
  93.  
  94.   function startLoop() {
  95.     setLooping(true);
  96.     window.requestAnimationFrame(rendererLoop);
  97.   }
  98.  
  99.   function stopLoop() {
  100.     setLooping(false);
  101.   }
  102.  
  103.   function selectTarget(event:any) {
  104.     setClicked(true);
  105.     setLastX(event.screenX);
  106.     setLastY(event.screenY);
  107.   }
  108.  
  109.   function calcMouseMoveDistance(event:any) {
  110.     console.log(clicked, looping);
  111.     if (!clicked) return;
  112.     setLastX(event.screenX);
  113.     setLastY(event.screentY);
  114.     let [dx, dy] = [event.screenX - lastX, event.screenY - lastY];
  115.  
  116.     rz += -dy * 0.01;
  117.     rx += dx * 0.01;
  118.  
  119.     vx = dx * 0.1;
  120.     vy = dy * 0.1;
  121.  
  122.     if (!looping) startLoop();
  123.   }
  124.  
  125.   function resetTarget(event:any) {
  126.     setClicked(false);
  127.   }
  128.  
  129.  
  130.   useEffect(() => {
  131.     let ctx = cloudSphere.current.getContext('2d');
  132.     ctx.textAlign = 'center';
  133.      
  134.     cloudSphere.current.width = width * 2;
  135.     cloudSphere.current.height = height * 2;
  136.     cloudSphere.current.style.width = `${width}px`;
  137.     cloudSphere.current.style.height = `${height}px`;
  138.     ctx.scale(2,2);
  139.    
  140.     startLoop();
  141.   }, [])
  142.  
  143.   return (
  144.     <div>
  145.       <canvas onMouseDown={selectTarget} onMouseMove={calcMouseMoveDistance} onMouseLeave={resetTarget} onMouseUp={resetTarget} ref={cloudSphere} width={300} height={300}></canvas>
  146.     </div>
  147.   );
  148. }
  149.  
  150. export default TagSphere;
Advertisement
Add Comment
Please, Sign In to add comment