Advertisement
Guest User

Untitled

a guest
May 12th, 2019
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.61 KB | None | 0 0
  1. function skillsCloud(element, entries)
  2. {
  3. const settings =
  4. {
  5. entries: entries,
  6. width: '100%',
  7. height: '100%',
  8. radius: '75%',
  9. radiusMin: 75,
  10. bgDraw: false,
  11. bgColor: 'transparent',
  12. opacityOver: 1.00,
  13. opacityOut: 0.4,
  14. opacitySpeed: 10,
  15. fov: 800,
  16. speed: 0.5,
  17. fontFamily: 'latoReg, Arial, sans-serif',
  18. fontSize: '15px',
  19. fontColor: '#fff',
  20. fontWeight: 'normal',
  21. fontStyle: 'normal',
  22. fontStretch: 'normal',
  23. fontToUpperCase: false
  24. };
  25.  
  26. let entryHolder = [];
  27.  
  28. let radius;
  29. let diameter;
  30.  
  31. let mouseReact = true;
  32. let mousePos = {x: 0, y: 0};
  33.  
  34. let center2D;
  35. let center3D = {x: 0, y: 0, z: 0};
  36.  
  37. let speed = {x: 0, y: 0};
  38.  
  39. let position = {sx: 0, cx: 0, sy: 0, cy: 0};
  40.  
  41. let MATHPI180 = Math.PI / 180;
  42.  
  43. let svg;
  44. let svgNS = 'http://www.w3.org/2000/svg';
  45.  
  46. let bg;
  47.  
  48. function init()
  49. {
  50.  
  51. svg = document.createElementNS(svgNS, 'svg');
  52. svg.addEventListener('mousemove', mouseMoveHandler);
  53.  
  54. element.appendChild(svg);
  55.  
  56. if (settings.bgDraw)
  57. {
  58.  
  59. bg = document.createElementNS(svgNS, 'rect');
  60. bg.setAttribute('x', 0);
  61. bg.setAttribute('y', 0);
  62. bg.setAttribute('fill', settings.bgColor);
  63.  
  64. svg.appendChild(bg);
  65.  
  66. }
  67.  
  68. addEntries();
  69. reInit();
  70. animloop();
  71.  
  72. window.addEventListener('resize', resizeHandler);
  73.  
  74. };
  75.  
  76. function reInit()
  77. {
  78.  
  79. const windowWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
  80. const windowHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
  81.  
  82. let svgWidth = windowWidth;
  83. let svgHeight = windowHeight;
  84.  
  85. if (settings.width.toString().indexOf('%') > 0 || settings.height.toString().indexOf('%') > 0 )
  86. {
  87. svgWidth = Math.round(element.offsetWidth / 100 * parseInt(settings.width));
  88. svgHeight = Math.round(svgWidth / 100 * parseInt(settings.height));
  89.  
  90. }
  91. else
  92. {
  93. svgWidth = parseInt(settings.width);
  94. svgHeight = parseInt(settings.height);
  95.  
  96. }
  97.  
  98. if (windowWidth <= svgWidth)
  99. {
  100. svgWidth = windowWidth;
  101. }
  102.  
  103. if (windowHeight <= svgHeight)
  104. {
  105. svgHeight = windowHeight;
  106. }
  107.  
  108. center2D = {x: svgWidth / 2, y: svgHeight / 2};
  109.  
  110. speed.x = settings.speed / center2D.x;
  111. speed.y = settings.speed / center2D.y;
  112.  
  113. if (svgWidth >= svgHeight)
  114. {
  115. diameter = svgHeight / 100 * parseInt(settings.radius);
  116. }
  117. else
  118. {
  119. diameter = svgWidth / 100 * parseInt(settings.radius);
  120. }
  121.  
  122. if (diameter < 1)
  123. {
  124. diameter = 1;
  125. }
  126.  
  127. radius = diameter / 2;
  128.  
  129. if (radius < settings.radiusMin)
  130. {
  131. radius = settings.radiusMin;
  132. diameter = radius * 2;
  133.  
  134. }
  135.  
  136. svg.setAttribute('width', svgWidth);
  137. svg.setAttribute('height', svgHeight);
  138.  
  139. if (settings.bgDraw)
  140. {
  141. bg.setAttribute('width', svgWidth);
  142. bg.setAttribute('height', svgHeight);
  143.  
  144. }
  145.  
  146. setEntryPositions(radius);
  147. };
  148.  
  149. function setEntryPositions(radius)
  150. {
  151. for (let i = 0, l = entryHolder.length; i < l; i++)
  152. {
  153. setEntryPosition(entryHolder[i], radius);
  154. }
  155.  
  156. };
  157.  
  158. function setEntryPosition(entry, radius)
  159. {
  160. const dx = entry.vectorPosition.x - center3D.x;
  161. const dy = entry.vectorPosition.y - center3D.y;
  162. const dz = entry.vectorPosition.z - center3D.z;
  163.  
  164. const length = Math.sqrt( dx * dx + dy * dy + dz * dz );
  165.  
  166. entry.vectorPosition.x /= length;
  167. entry.vectorPosition.y /= length;
  168. entry.vectorPosition.z /= length;
  169.  
  170. entry.vectorPosition.x *= radius;
  171. entry.vectorPosition.y *= radius;
  172. entry.vectorPosition.z *= radius;
  173.  
  174. };
  175.  
  176. function addEntry(index, entryObj, x, y, z)
  177. {
  178. let entry = {};
  179.  
  180. entry.element = document.createElementNS(svgNS, 'text');
  181. entry.element.setAttribute('x', 0);
  182. entry.element.setAttribute('y', 0);
  183.  
  184. entry.element.setAttribute('fill', settings.fontColor);
  185. entry.element.setAttribute('font-family', settings.fontFamily);
  186. entry.element.setAttribute('font-size', settings.fontSize);
  187. entry.element.setAttribute('font-weight', settings.fontWeight);
  188. entry.element.setAttribute('font-style', settings.fontStyle);
  189. entry.element.setAttribute('font-stretch', settings.fontStretch);
  190.  
  191. entry.element.setAttribute('text-anchor', 'middle' );
  192. entry.element.textContent = settings.fontToUpperCase ? entryObj.label.toUpperCase() : entryObj.label;
  193.  
  194. entry.link = document.createElementNS(svgNS, 'a');
  195.  
  196. entry.link.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', entryObj.url);
  197. entry.link.setAttribute('target', entryObj.target);
  198.  
  199. entry.link.addEventListener('mouseover', mouseOverHandler, true );
  200. entry.link.addEventListener('mouseout', mouseOutHandler, true );
  201.  
  202. entry.link.appendChild(entry.element);
  203.  
  204. entry.index = index;
  205. entry.mouseOver = false;
  206.  
  207. entry.vectorPosition = {x:x, y:y, z:z};
  208. entry.vector2D = {x:0, y:0};
  209.  
  210. svg.appendChild(entry.link);
  211.  
  212. return entry;
  213. };
  214.  
  215. function addEntries()
  216. {
  217. for (let i = 1, l = settings.entries.length + 1; i < l; i++)
  218. {
  219. const phi = Math.acos(-1 + ( 2 * i - 1 ) / l);
  220. const theta = Math.sqrt(l * Math.PI ) * phi;
  221.  
  222. const x = Math.cos(theta) * Math.sin(phi);
  223. const y = Math.sin(theta) * Math.sin(phi);
  224. const z = Math.cos(phi);
  225.  
  226. const entry = addEntry(i - 1, settings.entries[i - 1], x, y, z);
  227.  
  228. entryHolder.push( entry );
  229. }
  230. };
  231.  
  232. function getEntryByElement(element)
  233. {
  234. for (let i = 0, l = entryHolder.length; i < l; i++)
  235. {
  236. const entry = entryHolder[i];
  237.  
  238. if (entry.element.getAttribute('x') === element.getAttribute('x') && entry.element.getAttribute('y') === element.getAttribute('y'))
  239. {
  240. return entry;
  241. }
  242. }
  243.  
  244. return;
  245. };
  246.  
  247. function highlightEntry(element)
  248. {
  249. const entry = getEntryByElement(element);
  250.  
  251. for (let i = 0, l = entryHolder.length; i < l; i++)
  252. {
  253. let e = entryHolder[ i ];
  254. e.mouseOver = (e.index === entry.index);
  255. }
  256. };
  257.  
  258. function render()
  259. {
  260. const fx = speed.x * mousePos.x - settings.speed;
  261. const fy = settings.speed - speed.y * mousePos.y;
  262.  
  263. const angleX = fx * MATHPI180;
  264. const angleY = fy * MATHPI180;
  265.  
  266. position.sx = Math.sin(angleX);
  267. position.cx = Math.cos(angleX);
  268. position.sy = Math.sin(angleY);
  269. position.cy = Math.cos(angleY);
  270.  
  271. for (let i = 0, l = entryHolder.length; i < l; i++)
  272. {
  273. let entry = entryHolder[i];
  274.  
  275. if (mouseReact)
  276. {
  277. const rx = entry.vectorPosition.x;
  278. const rz = entry.vectorPosition.y * position.sy + entry.vectorPosition.z * position.cy;
  279.  
  280. entry.vectorPosition.x = rx * position.cx + rz * position.sx;
  281. entry.vectorPosition.y = entry.vectorPosition.y * position.cy + entry.vectorPosition.z * -position.sy;
  282. entry.vectorPosition.z = rx * -position.sx + rz * position.cx;
  283.  
  284. }
  285.  
  286. const scale = settings.fov / (settings.fov + entry.vectorPosition.z);
  287.  
  288. entry.vector2D.x = entry.vectorPosition.x * scale + center2D.x;
  289. entry.vector2D.y = entry.vectorPosition.y * scale + center2D.y;
  290.  
  291. entry.element.setAttribute('x', entry.vector2D.x);
  292. entry.element.setAttribute('y', entry.vector2D.y);
  293.  
  294. let opacity;
  295.  
  296. if (mouseReact)
  297. {
  298. opacity = (radius - entry.vectorPosition.z) / diameter;
  299.  
  300. if (opacity < settings.opacityOut)
  301. {
  302. opacity = settings.opacityOut;
  303. }
  304.  
  305. }
  306. else
  307. {
  308. opacity = parseFloat(entry.element.getAttribute('opacity'));
  309.  
  310. const opacityValue = (entry.mouseOver) ? settings.opacityOver : settings.opacityOut;
  311. opacity += (opacityValue - opacity) / settings.opacitySpeed;
  312. }
  313.  
  314. entry.element.setAttribute('opacity', opacity);
  315. }
  316.  
  317. entryHolder = entryHolder.sort(function(a, b)
  318. {
  319. return (b.vectorPosition.z - a.vectorPosition.z);
  320. });
  321. };
  322.  
  323. window.requestAnimFrame = (function()
  324. {
  325. return window.requestAnimationFrame ||
  326. window.webkitRequestAnimationFrame ||
  327. window.mozRequestAnimationFrame ||
  328. function(callback)
  329. {
  330. window.setTimeout(callback, 1000 / 60);
  331. };
  332. })();
  333.  
  334. function animloop()
  335. {
  336. requestAnimFrame(animloop);
  337. render();
  338. };
  339.  
  340. function mouseOverHandler(event)
  341. {
  342. mouseReact = false;
  343. highlightEntry(event.target);
  344. };
  345.  
  346. function mouseOutHandler(event)
  347. {
  348. mouseReact = true;
  349. };
  350.  
  351. function mouseMoveHandler(event)
  352. {
  353. mousePos = getMousePos(svg, event);
  354. };
  355.  
  356. function getMousePos(svg, event)
  357. {
  358. const rect = svg.getBoundingClientRect();
  359.  
  360. const pos =
  361. {
  362. x: event.clientX - rect.left,
  363. y: event.clientY - rect.top
  364. };
  365.  
  366. return pos;
  367. };
  368.  
  369. function resizeHandler(event)
  370. {
  371. reInit();
  372. };
  373.  
  374. init();
  375. };
  376.  
  377. window.skillsCloud = skillsCloud
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement