这是我的问题: 我一直在努力做这个CSS立方体打开滚动。我做到了!以下是它的工作原理:https://codepen.io/vaninoo/pen/BmyYQd
我很开心。但在与朋友测试之后,似乎他们中的许多人想要“拖动”立方体以使其旋转。所以我决定添加这个功能。这是我最接近的:https://codepen.io/vaninoo/pen/jaEZBx
立方体可以在拖动时旋转,拖动后我可以通过滚动旋转它。但是:
以下是我可以在笔上找到的代码(“我最接近”):
// START OF UNSURE PART
$('document').ready(function() {
var lastScrollTop = 0;
$(window).scroll(function trucenscroll(event) {
var st = $(this).scrollTop();
var sl = $(this).scrollLeft();
if (st > lastScrollTop) {
//Le cube tourne
var p1,angle,i,tmp;
p1 = {'x': sl - p0.x, 'y': st - p0.y },
angle = {'x': -p1.y * unit, 'y': p1.x * unit};
for(i = 0; i < faces.length; i++)
{
tmp = 'rotateX(' + angle.x + 'deg)' + ' rotateY(' + angle.y + 'deg)' + styles[i];
faces[i].style.transform = p + tmp;
faces[i].style['-webkit-transform'] = p + tmp;
}
}
else if(st == lastScrollTop) {
//do nothing
//In IE this is an important condition because there seems to be some instances where the last scrollTop is equal to the new one
}
else {
var p1,angle,i,tmp;
p1 = {'x': sl - p0.x, 'y': st - p0.y },
angle = {'x': -p1.y * unit, 'y': p1.x * unit};
for(i = 0; i < faces.length; i++)
{
tmp = 'rotateX(' + angle.x + 'deg)' + ' rotateY(' + angle.y + 'deg)' + styles[i];
faces[i].style.transform = p + tmp;
faces[i].style['-webkit-transform'] = p + tmp;
}
}
lastScrollTop = st;
});
});
// END OF UNSURE PART
init();
//===========================================================
// onMouseMove
//===========================================================
function onMouseMove(e)
{
var p1,angle,i,tmp;
if (! dragging) return;
p1 = {'x': e.clientX - p0.x, 'y': e.clientY - p0.y },
angle = {'x': -p1.y * unit, 'y': p1.x * unit};
for(i = 0; i < faces.length; i++)
{
tmp = 'rotateX(' + angle.x + 'deg)' + ' rotateY(' + angle.y + 'deg)' + styles[i];
faces[i].style.transform = p + tmp;
faces[i].style['-webkit-transform'] = p + tmp;
}
}
//===========================================================
// onMouseDown
//===========================================================
function onMouseDown(e)
{
var element;
onMouseUp(); // disable if dragging
element = e.target;
//if (! element.classList.contains('face')) return false;
e.preventDefault();
window.p0 = { 'x': e.clientX, 'y': e.clientY };
dragging = true;
return false;
}
//===========================================================
// onMouseUp
//===========================================================
function onMouseUp(e)
{
var i,tmp,style;
if (! dragging) return;
dragging = false;
for ( i = 0; i < faces.length; i++)
{
style = faces[i].style;
tmp = style.transform || style['-webkit-transform'];
styles[i] = tmp.replace('perspective(32em) ', '');
}
}
//=====================================================================
// initializeCube
//=====================================================================
function initializeCube()
{
var i,tmp;
for (i = 0; i < faces.length; i++)
{
if (i < 4) tmp = 'rotateY(' + i*90 + 'deg)';
if (i >= 4) tmp = 'rotateX(' + Math.pow(-1, i) * 90 + 'deg)';
tmp += ' translateZ(' + side/2 + 'px)';
faces[i].style.transform = p + tmp;
faces[i].style['-webkit-transform'] = p + tmp;
styles.push(tmp);
}
}
//=====================================================================
// init
//=====================================================================
function init()
{
window.addEventListener('mousedown', onMouseDown, false);
window.addEventListener('mouseup', onMouseUp, false);
window.addEventListener('mousemove', onMouseMove, false);
window.faces = document.querySelectorAll('.face');
window.styles = new Array();
window.style = getComputedStyle(faces[0]);
window.factor = 3;
window.side = parseInt(style.width.split('px')[0], 10);
window.max_amount = factor * side;
window.unit = 360 / max_amount;
window.dragging = false;
window.scrolling = false;
window.p = 'perspective(32em)';
initializeCube();
}
body {
position: relative;
height:5000px;
}
.cube, .cube *
{
position: absolute;
top: 25vh;
left: 50%;
}
.cube
{
user-select: none;
cursor: move;
}
.cube div span
{
position: relative;
top: 60px;
left: -5px;
font-size: 8em;
}
.face
{
box-sizing: border-box;
border: solid 1px;
margin: -8em;
width: 16em;
height: 16em;
box-shadow: inset 0 0 15px rgba(0,0,255,0.6);
text-align: center;
/** backface-visibility: hidden; /**/
}
.face:nth-child(1) {
background: rgba(255, 0, 0, 0.2);
}
.face:nth-child(2) { background: rgba(255, 255, 0, 0.2); }
.face:nth-child(3) { background: rgba( 0, 255, 0, 0.2); }
.face:nth-child(4) { background: rgba( 0, 255, 255, 0.2); }
.face:nth-child(5) { background: rgba( 0, 0, 255, 0.2); }
.face:nth-child(6) { background: rgba(255, 0, 255, 0.2); }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body translate="no" onload="init()">
<div class='cube' id="cubo">
<div class='face'><span>1</span></div>
<div class='face'><span>2</span></div>
<div class='face'><span>3</span></div>
<div class='face'><span>4</span></div>
<div class='face'><span>5</span></div>
<div class='face'><span>6</span></div>
</div>
</body>
答案 0 :(得分:2)
我认为这应该是你想要的行为。您未能在代码中初始化p0
变量,因此当您尝试立即滚动而不单击它会导致错误。此外,您看到的跳转是因为在p0
函数中设置onMouseDown
后,您从未将其设置回初始状态(我刚设置为{x:0, y:0}
),因此滚动将基于您的鼠标设置的p0
值开始。
详细介绍。在$(document).ready()
中,我将p0变量的初始状态设置为window.p0={'x':0,'y':0}
。然后我还重置了onMouseUp
函数中的p0变量,以确保如果停止拖动并再次开始滚动,则会正确设置。
另外,我修改了滚动功能以包括存储立方体面的样式的状态。我相信,因为$(window).scroll
函数没有存储它正在应用的样式状态,所以拖动基本上“丢失”了立方体的最后状态,这导致了你注意到的跳跃。请注意,此更改可能会导致一些过载,因为它会不断附加到以快速速率应用于立方体面的样式。
// START OF UNSURE PART
$('document').ready(function() {
var lastScrollTop = 0;
//Set the initial state of window.p0 so that scrolling works without clicking
window.p0 = {
'x': 0,
'y': 0
};
$(window).scroll(function trucenscroll(event) {
var st = $(this).scrollTop();
var sl = $(this).scrollLeft();
if (st > lastScrollTop) {
//Le cube tourne
var p1, angle, i, tmp;
p1 = {
'x': sl - p0.x,
'y': st - p0.y
},
angle = {
'x': -p1.y * unit,
'y': p1.x * unit
};
for (i = 0; i < faces.length; i++) {
tmp = 'rotateX(' + angle.x + 'deg)' + ' rotateY(' + angle.y + 'deg)' + styles[i];
faces[i].style.transform = p + tmp;
faces[i].style['-webkit-transform'] = p + tmp;
//Save the state of the style of the cube faces. This ensures that if you switch to dragging, then there will be no jumps because all of the transforms will still be correctly applied.
style = faces[i].style;
var tmpStyle = style.transform || style['-webkit-transform'];
styles[i] = tmpStyle.replace('perspective(32em) ', '');
}
} else if (st == lastScrollTop) {
//do nothing
//In IE this is an important condition because there seems to be some instances where the last scrollTop is equal to the new one
} else {
var p1, angle, i, tmp;
p1 = {
'x': sl - p0.x,
'y': st - p0.y
},
angle = {
'x': -p1.y * unit,
'y': p1.x * unit
};
for (i = 0; i < faces.length; i++) {
tmp = 'rotateX(' + angle.x + 'deg)' + ' rotateY(' + angle.y + 'deg)' + styles[i];
faces[i].style.transform = p + tmp;
faces[i].style['-webkit-transform'] = p + tmp;
//Save the state of the style of the cube faces. This ensures that if you switch to dragging, then there will be no jumps because all of the transforms will still be correctly applied.
style = faces[i].style;
var tmpStyle = style.transform || style['-webkit-transform'];
styles[i] = tmpStyle.replace('perspective(32em) ', '');
}
}
lastScrollTop = st;
});
});
// END OF UNSURE PART
init();
//===========================================================
// onMouseMove
//===========================================================
function onMouseMove(e) {
var p1, angle, i, tmp;
if (!dragging) return;
p1 = {
'x': e.clientX - p0.x,
'y': e.clientY - p0.y
},
angle = {
'x': -p1.y * unit,
'y': p1.x * unit
};
for (i = 0; i < faces.length; i++) {
tmp = 'rotateX(' + angle.x + 'deg)' + ' rotateY(' + angle.y + 'deg)' + styles[i];
faces[i].style.transform = p + tmp;
faces[i].style['-webkit-transform'] = p + tmp;
}
}
//===========================================================
// onMouseDown
//===========================================================
function onMouseDown(e) {
var element;
onMouseUp(); // disable if dragging
element = e.target;
//if (! element.classList.contains('face')) return false;
e.preventDefault();
window.p0 = {
'x': e.clientX,
'y': e.clientY
};
dragging = true;
return false;
}
//===========================================================
// onMouseUp
//===========================================================
function onMouseUp(e) {
var i, tmp, style;
if (!dragging) return;
dragging = false;
//Save the state of the style of the cube faces. This ensures that if you switch to dragging, then there will be no jumps because all of the transforms will still be correctly applied.
for (i = 0; i < faces.length; i++) {
style = faces[i].style;
tmp = style.transform || style['-webkit-transform'];
styles[i] = tmp.replace('perspective(32em) ', '');
}
//Reset the window.p0 variable back for scrolling to work
window.p0 = {
'x': 0,
'y': 0
};
}
//=====================================================================
// initializeCube
//=====================================================================
function initializeCube() {
var i, tmp;
for (i = 0; i < faces.length; i++) {
if (i < 4) tmp = 'rotateY(' + i * 90 + 'deg)';
if (i >= 4) tmp = 'rotateX(' + Math.pow(-1, i) * 90 + 'deg)';
tmp += ' translateZ(' + side / 2 + 'px)';
faces[i].style.transform = p + tmp;
faces[i].style['-webkit-transform'] = p + tmp;
styles.push(tmp);
}
}
//=====================================================================
// init
//=====================================================================
function init() {
window.addEventListener('mousedown', onMouseDown, false);
window.addEventListener('mouseup', onMouseUp, false);
window.addEventListener('mousemove', onMouseMove, false);
window.faces = document.querySelectorAll('.face');
window.styles = new Array();
window.style = getComputedStyle(faces[0]);
window.factor = 3;
window.side = parseInt(style.width.split('px')[0], 10);
window.max_amount = factor * side;
window.unit = 360 / max_amount;
window.dragging = false;
window.scrolling = false;
window.p = 'perspective(32em)';
initializeCube();
}
body {
position: relative;
height: 5000px;
}
.cube,
.cube * {
position: absolute;
top: 25vh;
left: 50%;
}
.cube {
user-select: none;
cursor: move;
}
.cube div span {
position: relative;
top: 60px;
left: -5px;
font-size: 8em;
}
.face {
box-sizing: border-box;
border: solid 1px;
margin: -8em;
width: 16em;
height: 16em;
box-shadow: inset 0 0 15px rgba(0, 0, 255, 0.6);
text-align: center;
/** backface-visibility: hidden; /**/
}
.face:nth-child(1) {
background: rgba(255, 0, 0, 0.2);
}
.face:nth-child(2) {
background: rgba(255, 255, 0, 0.2);
}
.face:nth-child(3) {
background: rgba( 0, 255, 0, 0.2);
}
.face:nth-child(4) {
background: rgba( 0, 255, 255, 0.2);
}
.face:nth-child(5) {
background: rgba( 0, 0, 255, 0.2);
}
.face:nth-child(6) {
background: rgba(255, 0, 255, 0.2);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body translate="no" onload="init()">
<div class='cube' id="cubo">
<div class='face'><span>1</span></div>
<div class='face'><span>2</span></div>
<div class='face'><span>3</span></div>
<div class='face'><span>4</span></div>
<div class='face'><span>5</span></div>
<div class='face'><span>6</span></div>
</div>
</body>