Advertisement
Guest User

Untitled

a guest
Aug 19th, 2019
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import React, { useEffect, createRef } from 'react';
  2. // ПОПРОБОВАТЬ ЧЕРЕЗ КЛАССОВЫЙ КОМПОНЕНТ РЕАЛИЗОВАТЬ СФЕРУ
  3. function TagSphere() {
  4.   const cloudSphere = createRef<any>();
  5.   const texts = [
  6.     'HTML5', 'CSS3', 'Javascript', 'Typescript', 'Babel', 'Vue', 'Vuex', 'Vuetify', 'VueRouter', 'React', 'Redux', 'ReactRouter', 'Laravel', 'BEM', 'NPM', 'Webpack', 'Git', 'Bootstrap', 'Gulp', 'Pug',
  7.   ];
  8.   const counts = [1,2,4,5,4,2,1];
  9.   const options = {
  10.     tilt: Math.PI / 9,
  11.     initialVelocityX: 0.09,
  12.     initialVelocityY: 0.09,
  13.     initialRotationX: Math.PI * 0.14,
  14.     initialRotationZ: 0
  15.   };
  16.  
  17.   function wordSphere(canvas:any, texts:string[], counts:number[], options: any) {
  18.     const π = Math.PI;
  19.     const {
  20.       width = 600,
  21.       height = 600,
  22.       radius = 230,
  23.       fontSize = 26,
  24.       tilt = 0,
  25.       initialVelocityX = 0,
  26.       initialVelocityY = 0,
  27.       initialRotationX = 0,
  28.       initialRotationZ = 0,
  29.     } = options;
  30.    
  31.     let vx = initialVelocityX, vy = initialVelocityY;
  32.     let rx = initialRotationX, rz = initialRotationZ;
  33.    
  34.     let ctx = canvas.getContext('2d');
  35.    
  36.     canvas.width = width * 2;
  37.     canvas.height = height * 2;
  38.     canvas.style.width = `${width}px`;
  39.     canvas.style.height = `${height}px`;
  40.     ctx.scale(2,2);
  41.  
  42.     let clicked = false, lastX:number, lastY:number;
  43.     canvas.addEventListener('mousedown', (event:any) => {
  44.       clicked = true;
  45.       lastX = event.screenX;
  46.       lastY = event.screenY;
  47.     });
  48.     canvas.addEventListener('mousemove', (event:any) => {
  49.       if (!clicked) return;
  50.       let [dx, dy] = [event.screenX - lastX, event.screenY - lastY];
  51.       [lastX, lastY] = [event.screenX, event.screenY];
  52.  
  53.       rz += -dy * 0.01;
  54.       rx += dx * 0.01;
  55.  
  56.       vx = dx * 0.1;
  57.       vy = dy * 0.1;
  58.  
  59.       if (!looping) startLoop();
  60.     });
  61.     canvas.addEventListener('mouseup', (e:any) => clicked = false);
  62.     canvas.addEventListener('mouseleave', (e:any) => clicked = false);
  63.    
  64.     function rot(x:number,y:number,t:number) {
  65.       return [x*Math.cos(t)-y*Math.sin(t), x*Math.sin(t)+y*Math.cos(t)];
  66.     }
  67.  
  68.     function render() {
  69.       ctx.clearRect(0, 0, canvas.width, canvas.height);
  70.       ctx.textAlign = 'center';
  71.  
  72.       let ix = 0, iz = 0;
  73.       for (const text of texts) {
  74.         const degZ = (π/(counts.length-1)) * iz;
  75.         const degX = (2*π/counts[iz]) * ix;
  76.  
  77.         let x = radius * Math.sin(degZ) * Math.cos(degX);
  78.         let y = radius * Math.sin(degZ) * Math.sin(degX);
  79.         let z = radius * Math.cos(degZ) + 8*(ix % 2);
  80.  
  81.         [y,z] = rot(y, z, tilt);
  82.         [x,z] = rot(x, z, rz);
  83.         [x,y] = rot(x, y, rx);
  84.  
  85.         const alpha = 0.6 + 0.4 * (x/radius);
  86.         const size = fontSize + 2 + 5*(x/radius);
  87.         ctx.fillStyle = `rgba(8,253,216,${alpha})`;
  88.         ctx.font = `${size}px "Brandon Grotesque"`;
  89.         ctx.fillText(text, y + width/2, -z + height/2);
  90.  
  91.         ix--;
  92.         if (ix < 0) {
  93.           iz++;
  94.           ix = counts[iz] - 1;
  95.         }
  96.       }
  97.     }
  98.  
  99.     let looping = false;
  100.     function rendererLoop() {
  101.       if (looping) window.requestAnimationFrame(rendererLoop);
  102.       render();
  103.      
  104.       if (vx > 0) vx = vx - 0.01;
  105.       if (vy > 0) vy = vy - 0.01;
  106.       if (vx < 0) vx = vx + 0.01;
  107.       if (vy > 0) vy = vy + 0.01;
  108.       if (vx === 0 && vy === 0) stopLoop();
  109.      
  110.       rz += vy * 0.01;
  111.       rx += vx * 0.01;
  112.     }
  113.  
  114.     function startLoop() {
  115.       looping = true;
  116.       window.requestAnimationFrame(rendererLoop);
  117.     }
  118.  
  119.     function stopLoop() {
  120.       looping = false;
  121.     }
  122.     startLoop();
  123.   }
  124.  
  125.   useEffect(() => {
  126.     const canvas = cloudSphere.current;
  127.     wordSphere(canvas, texts, counts, options);
  128.   });
  129.  
  130.  
  131.   return (
  132.     <canvas ref={cloudSphere} width={300} height={300}></canvas>
  133.   );
  134. }
  135.  
  136. export default TagSphere;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement