Трансформация картинок в кубе
Всем привет. Как сделать трансформацию картинок по граням куба? Чтобы они плавно перетекали от одной грани к другой?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Perspective</title>
<style>
body {
margin: 0 auto;
}
.cube-container {
height: 200px;
top: 50%;
left: 50%;
margin-left: -100px;
margin-top: -100px;
perspective: 600px;
perspective-origin: 50% 50%;
position: absolute;
width: 200px;
}
.cube {
height: 100%;
position: absolute;
transform: translateZ(100px);
transform-style: preserve-3d;
width: 100%;
animation: spin 5s linear infinite;
}
.side {
background: transparent;
border: 3px solid grey;
height: 196px;
position: absolute;
width: 196px;
overflow: hidden;
}
.front {
transform: translateZ(100px);
}
.back {
transform: rotateX(180deg) translateZ(100px);
}
.back .img-inner {
width: 100%;
height: 100%;
background-image: url(https://cdn.sportmaster.ru/upload/content/mediahab/prod/0c868511-3fc5-4da6-9092-56235985e840.jpg);
background-position: top;
background-size: 33%;
background-repeat: no-repeat;
}
.left {
transform: rotateY(-90deg) translateZ(100px);
}
.right {
transform: rotateY(90deg) translateZ(100px);
}
.top {
transform: rotateX(90deg) translateZ(100px);
}
.bottom {
transform: rotateX(-90deg) translateZ(100px);
}
.img-inner {
animation: marquee-vertical 5s linear infinite;
}
@keyframes marquee-vertical {
0% {
transform: translateY(0);
}
100% {
transform: translateY(-100%);
}
}
</style>
</head>
<body>
<div class="cube-container">
<div class="cube">
<figure class="side front"></figure>
<figure class="side back">
<div class="img-inner"></div>
<div class="img-inner"></div>
<div class="img-inner"></div>
</figure>
<figure class="side left"></figure>
<figure class="side right"></figure>
<figure class="side top"></figure>
<figure class="side bottom"></figure>
</div>
</div>
</body>
</html>
Ответы (3 шт):
Это довольно трудоёмкая задача. Вам необходимо каждой грани куба задать свойство overflow:hidden затем в каждую из этих граней поместить картинку, одинаковую или разные, но они все должны быть одинаковых размеров. Дальше все другие изображения кроме главного сместить относительно центра за областью видимости. Например, transform:translate(-100%, 0) или что-то в этой области. Дальше вешаете обработчик событий который отслеживает в какой именно части куба сейчас перебывает курсор. Два состояния: 1 - в которой был, 2 - в которой стал. И дальше идет синхронизация по времени с изменением для данных картинок положений transform... Что б обе картинки были как бы взаимозависимы.
Для простоты я б вам рекомендовал начать просто с двух плоскостей. Когда реализуете на 2 тогда и на 6 получиться... хотя по факту на меньше, если ваш куб не вертится.
эм... случаем не оно?
p.s. слушалка мыши только чтоб не гадать - какой ракурс нагляднее.
var cub = document.querySelector(".cube");
window.addEventListener("mousemove",
function (e) {
var leftCord = e.pageX;
var TopCord = e.pageY;
document.querySelector(".cube").style.cssText =
"transform: rotateY(" + (leftCord / 2.5) + "deg) rotateX(" + (TopCord / 2.5) + "deg);";
},
false
);
var posX, posY;
function positFingers(e) {
posX = e.pageX;
posY = e.pageY;
document.querySelector(".cube").style.cssText =
"-webkit-transform:rotateY(" + posX + "deg) rotateX(" + posY + "deg);";
}
window.addEventListener("touchmove", positFingers, false);
body {
margin: 0 auto;
}
.cube-container {
height: 225px;
top: 50%;
left: 50%;
margin-left: -100px;
margin-top: -100px;
perspective: 600px;
perspective-origin: 50% 50%;
position: absolute;
width: 225px;
}
.cube {
height: 100%;
position: absolute;
transform: translateZ(100px);
transform-style: preserve-3d;
width: 100%;
}
.side {
background: transparent;
border: 3px solid grey;
height: 196px;
position: absolute;
width: 196px;
overflow: hidden;
}
.front {
transform: translateZ(100px);
}
.back {
transform: rotateX(180deg) translateZ(100px);
}
:is(.back, .top, .bottom) .img-inner /*!!!!!!!!!!!*/
{
width: 100%;
height: 100%;
background-image: url(https://cdn.sportmaster.ru/upload/content/mediahab/prod/0c868511-3fc5-4da6-9092-56235985e840.jpg);
background-position: top;
background-size: 75%;
background-repeat: no-repeat;
}
.left {
transform: rotateY(-90deg) translateZ(100px);
}
.right {
transform: rotateY(90deg) translateZ(100px);
}
.top {
transform: rotateX(90deg) translateZ(100px);
}
.bottom {
transform: rotateX(-90deg) translateZ(100px);
}
.img-inner {
animation: marquee-vertical 5s linear infinite;
}
@keyframes marquee-vertical {
0% {
transform: translateY(0);
}
100% {
transform: translateY(-100%);
}
}
<div class="cube-container">
<div class="cube">
<figure class="side front"></figure>
<figure class="side back">
<div class="img-inner"></div>
<div class="img-inner"></div>
<div class="img-inner"></div>
</figure>
<figure class="side left"></figure>
<figure class="side right"></figure>
<figure class="side top">
<div class="img-inner"></div>
<div class="img-inner"></div>
<div class="img-inner"></div>
</figure>
<figure class="side bottom">
<div class="img-inner"></div>
<div class="img-inner"></div>
<div class="img-inner"></div>
</figure>
</div>
</div>
Придал анимацию каждой стороне с картинкой и рассчитал им animation-delay, а так же поставил transform: translateY(100%); для изначального состояния
back>.img-inner {
animation-delay: 1s;
}
.bottom>.img-inner {
animation-delay: 2s;
}
Для верхней стороны это 0s, для задней 1s, для нижней 2s
Анимация теперь идет от 100% до -400%
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Perspective</title>
<style>
body {
margin: 0 auto;
}
.cube-container {
height: 200px;
top: 50%;
left: 50%;
margin-left: -100px;
margin-top: -100px;
perspective: 600px;
perspective-origin: 50% 50%;
position: absolute;
width: 200px;
}
.cube {
height: 100%;
position: absolute;
transform: translateZ(100px);
transform-style: preserve-3d;
width: 100%;
animation: spin 2s linear infinite;
}
.side {
background: transparent;
border: 3px solid grey;
height: 196px;
position: absolute;
width: 196px;
overflow: hidden;
}
.front {
transform: translateZ(100px);
}
.back {
transform: rotateX(180deg) translateZ(100px);
}
.img-inner {
width: 100%;
height: 100%;
background-image: url(https://cdn.sportmaster.ru/upload/content/mediahab/prod/0c868511-3fc5-4da6-9092-56235985e840.jpg);
background-position: top;
background-size: 100%;
background-repeat: no-repeat;
}
.left {
transform: rotateY(-90deg) translateZ(100px);
}
.right {
transform: rotateY(90deg) translateZ(100px);
}
.top {
transform: rotateX(90deg) translateZ(100px);
}
.bottom {
transform: rotateX(-90deg) translateZ(100px);
}
.img-inner {
animation: marquee-vertical 4s linear infinite;
transform: translateY(100%);
}
.back>.img-inner {
animation-delay: 1s;
}
.bottom>.img-inner {
animation-delay: 2s;
}
@keyframes marquee-vertical {
0% {
transform: translateY(100%);
}
100% {
transform: translateY(-400%);
}
}
</style>
</head>
<body>
<div class="cube-container">
<div class="cube">
<figure class="side front"></figure>
<figure class="side back">
<div class="img-inner"></div>
</figure>
<figure class="side left"></figure>
<figure class="side right"></figure>
<figure class="side top">
<div class="img-inner"></div>
</figure>
<figure class="side bottom">
<div class="img-inner"></div>
</figure>
</div>
</div>
</body>
</html>