图片/图形

纯javascript实现360度旋转预览图片特效

阿里云


这是一款纯 js 实现 360 度旋转预览图片特效。该 js 特效仅使用 120 行代码,即可实现通过滑块、或鼠标手动 360 度旋转图片,以及自动 360 度旋转图片的效果。

HTML 结构

  1. <div class="tabs">
  2. <input type="radio" name="tabs" id="sol1" checked="checked"/>
  3. <label for="sol1">Range</label>
  4. <div class="tab">
  5. <div class="frame" id="frame1"></div>
  6. <input type="range" id="slider" min="0" max="34" step="1" value="0"/>
  7. </div>
  8. <input type="radio" name="tabs" id="sol2"/>
  9. <label for="sol2">Drag / Swipel</label>
  10. <div class="tab">
  11. <div class="frame" id="frame2"></div>
  12. </div>
  13. <input type="radio" name="tabs" id="sol3">
  14. <label for="sol3">Canvas</label>
  15. <div class="tab">
  16. <canvas class="frame" id="frame3"></canvas>
  17. </div>
  18. </div>
  19. <div id="overlay">Loading...</div>
也想出现在这里?联系我们
创客主机

CSS 样式

  1. body {
  2.   margin: 0;
  3.   padding: 0;
  4.   font-size: .8em;
  5.   font-family: 'Open Sans', sans-serif;
  6.   overflow: hidden;
  7. }
  8. body .tabs {
  9.   position: absolute;
  10.   left: 50%;
  11.   top: 50%;
  12.   transform: translate(-50%, -50%);
  13.   width: 480px;
  14.   height: 351px;
  15. }
  16. body .tabs label {
  17.   cursor: pointer;
  18.   border-radius: 4px;
  19. }
  20. body .tabs input[name="tabs"] {
  21.   display: none;
  22. }
  23. body .tabs input[name="tabs"]:checked + label {
  24.   background: #44abda;
  25.   color: #fff;
  26. }
  27. body .tabs input[name="tabs"]:checked + label + .tab {
  28.   display: block;
  29. }
  30. body .tabs label {
  31.   display: inline-block;
  32.   width: 33.3333%;
  33.   float: left;
  34.   height: 24px;
  35.   line-height: 24px;
  36.   text-align: center;
  37. }
  38. body .tabs .tab {
  39.   display: none;
  40.   position: absolute;
  41.   width: 100%;
  42.   height: 327px;
  43.   top: 24px;
  44.   text-align: center;
  45. }
  46. body .tabs .tab .frame {
  47.   width: 100%;
  48.   height: 100%;
  49. }
  50. body .tabs .tab #slider {
  51.   width: calc(100% - 80px);
  52. }
  53. body #overlay {
  54.   position: absolute;
  55.   width: 100%;
  56.   height: calc(100% - 20px);
  57.   background: rgba(0, 0, 0, 0.3);
  58.   text-align: center;
  59.   color: #fff;
  60.   font-size: 1.1em;
  61.   padding-top: 20px;
  62. }

javascript

  1. let frame1 = document.getElementById('frame1'),
  2.     frame2 = document.getElementById('frame2'),
  3.     frame3 = document.getElementById('frame3'),
  4.     labels = document.querySelectorAll('label'),
  5.     ctx = frame3.getContext('2d'),
  6.     slider = document.getElementById('slider'),
  7.     frameWidth = 480,
  8.     frameHeight = 327,
  9.     activeFrame = 0,
  10.     frames = 34,
  11.     xStart = null,
  12.     s2Settings = {
  13.         sensitivity: 40
  14.     },
  15.     s3Settings = {
  16.         fps: 20,
  17.         reverse: false
  18.     },
  19.     now, delta, then = Date.now(),
  20.     interval = 1000 / s3Settings.fps,    
  21.     runCanvas = false;
  22.  
  23. let gui = new dat.GUI(),
  24.     s2 = gui.addFolder('Drag / Swipe'),
  25.     s3 = gui.addFolder('Canvas');
  26.  
  27. s2.add(s2Settings, "sensitivity", 10, 80, 1);
  28. s3.add(s3Settings, "fps", 1, 60, 1).onChange(() =gt; {interval = 1000 / s3Settings.fps;});
  29. s3.add(s3Settings, "reverse");
  30.  
  31. s2.open();
  32. s3.open();
  33.  
  34. let sprite = new Image();
  35. sprite.onload = function() {
  36.     frame1.style.background = frame2.style.background = `url(${sprite.src})`;
  37.     document.getElementById('overlay').style.display = 'none';
  38.  
  39.     solution1(); //input range
  40.     solution2(); // drag / swipe
  41.     solution3(); // canvas
  42.  
  43.     labels.forEach(function(element) {
  44.       element.addEventListener('click', function() {
  45.           runCanvas = false;
  46.           if(this.getAttribute('for') == "sol3")
  47.               runCanvas = true;
  48.       });
  49.     });
  50. };
  51. sprite.src = 'https://serving.photos.photobox.com/\
  52. 55967562d176c08ff2d7e23195f94e704faa7feede75617ac5\
  53. 905d8dca9295f1a547077a.jpg';
  54.  
  55. function solution1() {    
  56.     slider.addEventListener("input", function() {
  57.         activeFrame = parseInt(this.value);
  58.         frame1.style.backgroundPositionX = `-${activeFrame * frameWidth}px`;
  59.     });
  60. }
  61.  
  62. function solution2() {
  63.     frame2.addEventListener('touchstart', (e) =gt; {
  64.         xStart = e.touches ? e.touches[0].clientX : e.clientX;
  65.     });
  66.     frame2.addEventListener('mousedown', (e) =gt; {
  67.         xStart = e.touches ? e.touches[0].clientX : e.clientX;
  68.     });
  69.     frame2.addEventListener('touchend', () =gt; { xStart = null; });
  70.     frame2.addEventListener('mouseup', () =gt; { xStart = null; });
  71.     frame2.addEventListener("mousemove", move);
  72.     frame2.addEventListener("touchmove", move);
  73. }
  74.  
  75. function move(e) {
  76.     if(!xStart)
  77.         return;
  78.  
  79.     let xEnd = e.touches ? e.touches[0].clientX : e.clientX;
  80.     if (xStart - xEnd gt; .5 * frameWidth / (10 + s2Settings.sensitivity)) {
  81.         activeFrame++;
  82.         if(activeFrame gt; frames)
  83.             activeFrame = 0;
  84.         frame2.style.backgroundPositionX = `${activeFrame * frameWidth}px`;
  85.         xStart = xEnd;
  86.     } else if(xEnd - xStart gt; .5 * frameWidth / (10 + s2Settings.sensitivity)) {
  87.         activeFrame--;
  88.         if(activeFrame lt; 0)
  89.             activeFrame = frames;
  90.         frame2.style.backgroundPositionX = `${activeFrame * frameWidth}px`;
  91.         xStart = xEnd;
  92.     }
  93. }
  94.  
  95. function solution3() {
  96.     frame3.width = frameWidth;
  97.     frame3.height = frameHeight;
  98.     animate();
  99. }
  100.  
  101. function animate() { 
  102.     now = Date.now();
  103.     delta = now - then;
  104.  
  105.     if(runCanvas && delta gt; interval) {
  106.         if(activeFrame gt; frames)
  107.             activeFrame = 0;
  108.         else if(activeFrame lt; 0)
  109.             activeFrame = frames;
  110.  
  111.         ctx.drawImage(
  112.             sprite, activeFrame * frameWidth, 0, frameWidth, frameHeight, 
  113.             0, 0, frameWidth, frameHeight
  114.         );
  115.  
  116.         activeFrame += (s3Settings.reverse) ? -1 : 1;
  117.         then = now - (delta % interval);
  118.     }
  119.     window.requestAnimationFrame(animate);
  120. }

Codepen 网址:https://codepen.io/_massimo/pen/zVYVNb

纯 javascript 实现 360 度旋转预览图片特效

已有 495 人购买
  • prtf
查看演示升级 VIP立刻购买

演示地址 下载地址
收藏
(0)

发表回复

热销模板

Ashade - 作品展示摄影相册WordPress汉化主题
LensNews

本站承接 WordPress / PbootCMS / DedeCMS 等
系统建站、仿站、开发、定制等业务!