这是一款纯 js 实现 360 度旋转预览图片特效。该 js 特效仅使用 120 行代码,即可实现通过滑块、或鼠标手动 360 度旋转图片,以及自动 360 度旋转图片的效果。
<div class="tabs">
<input type="radio" name="tabs" id="sol1" checked="checked"/>
<label for="sol1">Range</label>
<div class="tab">
<div class="frame" id="frame1"></div>
<input type="range" id="slider" min="0" max="34" step="1" value="0"/>
</div>
<input type="radio" name="tabs" id="sol2"/>
<label for="sol2">Drag / Swipel</label>
<div class="tab">
<div class="frame" id="frame2"></div>
</div>
<input type="radio" name="tabs" id="sol3">
<label for="sol3">Canvas</label>
<div class="tab">
<canvas class="frame" id="frame3"></canvas>
</div>
</div>
<div id="overlay">Loading...</div>
body {
margin: 0;
padding: 0;
font-size: .8em;
font-family: 'Open Sans', sans-serif;
overflow: hidden;
}
body .tabs {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 480px;
height: 351px;
}
body .tabs label {
cursor: pointer;
border-radius: 4px;
}
body .tabs input[name="tabs"] {
display: none;
}
body .tabs input[name="tabs"]:checked + label {
background: #44abda;
color: #fff;
}
body .tabs input[name="tabs"]:checked + label + .tab {
display: block;
}
body .tabs label {
display: inline-block;
width: 33.3333%;
float: left;
height: 24px;
line-height: 24px;
text-align: center;
}
body .tabs .tab {
display: none;
position: absolute;
width: 100%;
height: 327px;
top: 24px;
text-align: center;
}
body .tabs .tab .frame {
width: 100%;
height: 100%;
}
body .tabs .tab #slider {
width: calc(100% - 80px);
}
body #overlay {
position: absolute;
width: 100%;
height: calc(100% - 20px);
background: rgba(0, 0, 0, 0.3);
text-align: center;
color: #fff;
font-size: 1.1em;
padding-top: 20px;
}
let frame1 = document.getElementById('frame1'),
frame2 = document.getElementById('frame2'),
frame3 = document.getElementById('frame3'),
labels = document.querySelectorAll('label'),
ctx = frame3.getContext('2d'),
slider = document.getElementById('slider'),
frameWidth = 480,
frameHeight = 327,
activeFrame = 0,
frames = 34,
xStart = null,
s2Settings = {
sensitivity: 40
},
s3Settings = {
fps: 20,
reverse: false
},
now, delta, then = Date.now(),
interval = 1000 / s3Settings.fps,
runCanvas = false;
let gui = new dat.GUI(),
s2 = gui.addFolder('Drag / Swipe'),
s3 = gui.addFolder('Canvas');
s2.add(s2Settings, "sensitivity", 10, 80, 1);
s3.add(s3Settings, "fps", 1, 60, 1).onChange(() =gt; {interval = 1000 / s3Settings.fps;});
s3.add(s3Settings, "reverse");
s2.open();
s3.open();
let sprite = new Image();
sprite.onload = function() {
frame1.style.background = frame2.style.background = `url(${sprite.src})`;
document.getElementById('overlay').style.display = 'none';
solution1(); //input range
solution2(); // drag / swipe
solution3(); // canvas
labels.forEach(function(element) {
element.addEventListener('click', function() {
runCanvas = false;
if(this.getAttribute('for') == "sol3")
runCanvas = true;
});
});
};
sprite.src = 'https://serving.photos.photobox.com/\
55967562d176c08ff2d7e23195f94e704faa7feede75617ac5\
905d8dca9295f1a547077a.jpg';
function solution1() {
slider.addEventListener("input", function() {
activeFrame = parseInt(this.value);
frame1.style.backgroundPositionX = `-${activeFrame * frameWidth}px`;
});
}
function solution2() {
frame2.addEventListener('touchstart', (e) =gt; {
xStart = e.touches ? e.touches[0].clientX : e.clientX;
});
frame2.addEventListener('mousedown', (e) =gt; {
xStart = e.touches ? e.touches[0].clientX : e.clientX;
});
frame2.addEventListener('touchend', () =gt; { xStart = null; });
frame2.addEventListener('mouseup', () =gt; { xStart = null; });
frame2.addEventListener("mousemove", move);
frame2.addEventListener("touchmove", move);
}
function move(e) {
if(!xStart)
return;
let xEnd = e.touches ? e.touches[0].clientX : e.clientX;
if (xStart - xEnd gt; .5 * frameWidth / (10 + s2Settings.sensitivity)) {
activeFrame++;
if(activeFrame gt; frames)
activeFrame = 0;
frame2.style.backgroundPositionX = `${activeFrame * frameWidth}px`;
xStart = xEnd;
} else if(xEnd - xStart gt; .5 * frameWidth / (10 + s2Settings.sensitivity)) {
activeFrame--;
if(activeFrame lt; 0)
activeFrame = frames;
frame2.style.backgroundPositionX = `${activeFrame * frameWidth}px`;
xStart = xEnd;
}
}
function solution3() {
frame3.width = frameWidth;
frame3.height = frameHeight;
animate();
}
function animate() {
now = Date.now();
delta = now - then;
if(runCanvas && delta gt; interval) {
if(activeFrame gt; frames)
activeFrame = 0;
else if(activeFrame lt; 0)
activeFrame = frames;
ctx.drawImage(
sprite, activeFrame * frameWidth, 0, frameWidth, frameHeight,
0, 0, frameWidth, frameHeight
);
activeFrame += (s3Settings.reverse) ? -1 : 1;
then = now - (delta % interval);
}
window.requestAnimationFrame(animate);
}
Codepen 网址:https://codepen.io/_massimo/pen/zVYVNb
演示地址 | 下载地址 |
专业提供WordPress主题安装、深度汉化、加速优化等各类网站建设服务,详询在线客服!