При использовании transform rotate остановить смещение содержимого
Я использую transform: rotate();
чтобы повернуть содержимое в & Вне поля зрения, однако, каждый текст находится в другом положении, когда он появляется в поле зрения. Поэтому, когда вы нажимаете кнопку "Далее" в моей демонстрации, если вы посмотрите на границу, содержимое находится в разных позициях.
при нажатии следующей кнопки колесо вращается одинаково на 90 градусов, поэтому я ожидаю, что содержимое будет в том же положении при каждом вращении. Может кто-нибудь объяснить/решить, почему этого не происходит?
Я создал колесо для моего контента, и я стилизовал колесо, чтобы скрыть параметры, которые в настоящее время не видны;
// Page load transform start, setters
var degree = 0;
var itemStart = $('.wheel').find('.item-one').addClass('item-active');
var itemNext = $('.wheel').find('.item-four').addClass('item-prev');
// On click
$('.next').click(function() {
var wheel = $('.wheel');
// Increment rotation
degree += 90;
wheel.css({
WebkitTransform: 'rotate(' + degree + 'deg)'
});
// Update setter
itemStart = $('.wheel').find('.item-active');
itemNext = $('.wheel').find('.item-prev');
// Add Animation
$(itemStart).addClass('fadeOut');
$(itemNext).addClass('fadeIn');
//If were at the end
var getStartPrev = $(itemStart).prev();
var getNextPrev = $(itemNext).prev();
if (getStartPrev.length == 0) {
$(itemStart).removeClass('item-active');
$(itemNext).prev().addClass('item-prev');
$('.item-four').addClass('item-active').removeClass('item-prev');
} else {
$(itemStart).removeClass('item-active');
$(itemNext).removeClass('item-prev').addClass('item-active');
$(itemNext).prev().addClass('item-prev');
}
if (getNextPrev.length == 0) {
$('.item-four').addClass('item-prev');
}
// Remove Animation
setTimeout(function() {
$('.wheel').find('.item').removeClass('fadeIn fadeOut');
}, 400);
});
.wheel-wrp {
position: relative;
height: 700px;
width: 700px;
}
.wheel {
height: 700px;
width: 700px;
transition: 0.75s;
border-radius: 50%;
position: relative;
background: #fff;
left: -350px;
}
.item {
width: 250px;
position: absolute;
opacity: 0;
}
.item-active {
opacity: 1;
}
.item-one {
bottom: 300px;
left: 450px;
}
.item-two {
bottom: 20px;
left: 230px;
-webkit-transform: rotate(90deg);
-moz-transform: rotate(90deg);
transform: rotate(90deg);
}
.item-three {
bottom: 320px;
left: 0px;
-webkit-transform: rotate(180deg);
-moz-transform: rotate(180deg);
transform: rotate(180deg);
}
.item-four {
top: 20px;
left: 230px;
-webkit-transform: rotate(270deg);
-moz-transform: rotate(270deg);
transform: rotate(270deg);
}
.current-item {
bottom: 300px;
left: 450px;
}
.next-item {
top: 20px;
left: 230px;
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
transform: rotate(-90deg);
opacity: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="page">
<div class="wheel-wrp">
<div class="wheel">
<div class="item item-one">
<h4>Project 1 - beautifully crafted digital brand</h4>
<p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum..</p>
</div>
<div class="item item-two">
<h4>Project 2 - redefining technological boundaries</h4>
<p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum..</p>
</div>
<div class="item item-three">
<h4>Project 3 - Beauty in Design</h4>
<p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum..</p>
</div>
<div class="item item-four">
<h4>Project 4 - simply stunning </h4>
<p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum..</p>
</div>
</div>
</div>
</div>
<div class="next">Next</div>
пример демо - https://codepen.io/SamXronn/pen/opqWbq
4 ответов
вот мой пойти на это.
я установил начало преобразования элементов в левом верхнем углу (та же точка, что и для позиционирования)
использование transform
translateY
иtranslateX
, каждый деталь можно после этого поместить против колеса, независимо от их ширины и высотывам не нужен jQuery для анимации. Просто используйте его для переключения активного класса. Тот же результат достигается гораздо более плавно и с гораздо меньшим количеством кода с CSS3 анимация и "активный" класс.
let currentItem = 0
const $wheel = $('.wheel'),
$items = $wheel.find(".item")
$('.next').click(() => rotate(1));
$('.prev').click(() => rotate(-1));
const rotate = direction => {
currentItem -= direction
$wheel.css("transform",`rotate(${-currentItem*90}deg)`)
$items.removeClass("active")
.eq(currentItem%$items.length)
.addClass("active")
}
body {
background-color: #2c3e50;
}
button {
background: #2980b9;
padding: 15px 35px;
color: #fff;
float: left;
position: relative;
z-index: 9999;
cursor: pointer;
}
.wheel {
height: 700px;
width: 700px;
transition: transform 0.75s;
border-radius: 50%;
position: relative;
background: #fff;
}
.item {
width: 250px;
position: absolute;
opacity: 0.2;
transition: opacity 0.75s;
border: 1px solid #f00;
transform-origin: top left;
}
.item:nth-child(1) {
top: 50%;
left: 100%;
transform: translateY(-50%) translateX(-100%);
}
.item:nth-child(2) {
top: 100%;
left: 50%;
transform: rotate(90deg) translateY(-50%) translateX(-100%);
}
.item:nth-child(3) {
left: 0;
top: 50%;
transform: rotate(180deg) translateY(-50%) translateX(-100%);
}
.item:nth-child(4) {
top: 0;
left: 50%;
transform: rotate(270deg) translateY(-50%) translateX(-100%);
}
.item.active {
opacity: 1;
}
h4 {
margin: 0px 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<div id="page">
<div class="wheel">
<div class="item active">
<h4>Project 1 - beautifully crafted digital brand</h4>
<p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum..</p>
</div>
<div class="item">
<h4>Project 2 - redefining technological boundaries</h4>
<p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum..</p>
</div>
<div class="item">
<h4>Project 3 - Beauty in Design</h4>
<p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum..</p>
</div>
<div class="item">
<h4>Project 4 - simply stunning </h4>
<p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum..</p>
</div>
</div>
</div>
<button class="prev">Prev</button>
<button class="next">Next</button>
довольно сложным. Проблема заключается в сочетании вертикального центрирования для ваших divs имеют разные высоты, и ваше абсолютное позиционирование с px. И трансформация вращается, конечно
Я вышел с решением, используя типичный top:50; transform:-50%
вертикальный центрирующий Хак, адаптированный к различным вращениям div.
это позаботится о вертикальном выравнивании полностью предсказуемыми и вычисляемыми значениями. Горизонтальное выравнивание с другой стороны доказывает будьте хитрее, может быть, я что-то упускаю здесь, но я придумал решение для них с помощью магических чисел ( % , которые работают, хотя я не уверен почему)... Во всяком случае, вот фрагмент
// Page load transform start, setters
var degree = 0;
var itemStart = $('.wheel').find('.item-one').addClass('item-active');
var itemNext = $('.wheel').find('.item-four').addClass('item-prev');
// On click
$('.next').click( function() {
var wheel = $('.wheel');
// Increment rotation
degree += 90;
wheel.css({ WebkitTransform: 'rotate(' + degree + 'deg)'});
// Update setter
itemStart = $('.wheel').find('.item-active');
itemNext = $('.wheel').find('.item-prev');
// Add Animation
$(itemStart).addClass('fadeOut');
$(itemNext).addClass('fadeIn');
//If were at the end
var getStartPrev = $(itemStart).prev();
var getNextPrev = $(itemNext).prev();
if( getStartPrev.length == 0 ) {
$(itemStart).removeClass('item-active');
$(itemNext).prev().addClass('item-prev');
$('.item-four').addClass('item-active').removeClass('item-prev');
} else {
$(itemStart).removeClass('item-active');
$(itemNext).removeClass('item-prev').addClass('item-active');
$(itemNext).prev().addClass('item-prev');
}
if( getNextPrev.length == 0 ) {
$('.item-four').addClass('item-prev');
}
// Remove Animation
setTimeout(function(){
$('.wheel').find('.item').removeClass('fadeIn fadeOut');
}, 400);
});
body{
background-color: #2c3e50;
}
.next{
background: #2980b9;
padding: 15px 35px;
color: #fff;
float: left;
position: relative;
z-index: 9999;
cursor: pointer;
}
.wheel-wrp{
position: relative;
height: 700px;
width: 700px;
}
.wheel{
height: 700px;
width: 700px;
transition: 0.75s;
border-radius: 50%;
position: relative;
background: #fff;
left: -350px;
}
.item{
width: 250px;
position: absolute;
opacity: 0;
border: 1px solid red;
}
.item-active{
opacity: 1;
}
.item-one {
top: 50%;
transform: translateY(-50%);
left: 75%;
}
.item-two {
right: 50%;
top: 83%;
transform: translateX(50%) rotate(90deg);
}
.item-three {
top: 50%;
right: 75%;
transform: rotate(180deg) translateY(50%);
}
.item-four {
left: 50%;
bottom: 84%;
transform: translateX(-50%) rotate(270deg);
}
.current-item{
bottom: 300px;
left: 450px;
}
.next-item{
top: 20px;
left: 230px;
-webkit-transform:rotate(0deg);
-moz-transform:rotate(0deg);
transform:rotate(-90deg);
opacity: 0;
}
h4{
margin:0px 0px;
}
.fadeOut{
animation: menuFadeOut 350ms;
webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
.fadeIn{
animation: menuFadeIn 1500ms;
webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
@keyframes menuFadeOut {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
@keyframes menuFadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<div id="page">
<div class="wheel-wrp">
<div class="wheel">
<div class="item item-one">
<h4>Project 1 - beautifully crafted digital brand</h4>
<p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum..</p>
</div>
<div class="item item-two">
<h4>Project 2 - redefining technological boundaries</h4>
<p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum..</p>
</div>
<div class="item item-three">
<h4>Project 3 - Beauty in Design</h4>
<p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum..</p>
</div>
<div class="item item-four">
<h4>Project 4 - simply stunning </h4>
<p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum..</p>
</div>
</div>
</div>
</div>
<div class="next">Next</div>
единственные изменения в определении конкретных элементов, так что если вы хотите, чтобы проверить на перо для лучшей видимости, это часть, которую вы должны заменить:
.item-one {
top: 50%;
transform: translateY(-50%);
left: 75%;
}
.item-two {
right: 50%;
top: 83%;
transform: translateX(50%) rotate(90deg);
}
.item-three {
top: 50%;
right: 75%;
transform: rotate(180deg) translateY(50%);
}
.item-four {
left: 50%;
bottom: 84%;
transform: translateX(-50%) rotate(270deg);
}
надеюсь, что это поможет. И если каким-либо образом кому-то хочется объяснить + фиксация эти магические числа, которые были бы очень рады ;)
и это моя проба :) я удалил item-one two..
классы и используемые css nth-child
селекторы и подготовили Первоначальный макет колеса сначала с помощью CSS, используя transform-origin
к центру круга, а затем повернул само колесо. Возвращение в исходное положение было сложным, потому что оно анимировало обратное направление şn при вращении от 270deg до 0deg. Поэтому я добавил дополнительный класс, чтобы мгновенно перейти в исходное положение без анимации.
$(".next").on("click", function () {
var wheel = $(".wheel");
if (wheel.hasClass("rotate-1")) {
wheel.removeClass("rotate-1").addClass("rotate-2");
}
else if (wheel.hasClass("rotate-2")) {
wheel.removeClass("rotate-2").addClass("rotate-3");
}
else if (wheel.hasClass("rotate-3")) {
wheel.removeClass("rotate-3").addClass("rotate-4");
}
else if (wheel.hasClass("rotate-4")) {
wheel.removeClass("rotate-4").addClass("rotate-5").delay(1000).queue(function (next) {
$(this).addClass("rotate-1");
$(this).removeClass("rotate-5");
next();
});
}
});
.wheel {
border-radius: 50%;
background: rebeccapurple;
width: 700px;
height: 700px;
display: flex;
align-items: center;
justify-content: center;
position: relative;
transition: all 1s ease;
margin-left : -350px;
}
.item {
background:transparent;
color: white;
width: 250px;
margin-right: 10px;
margin-left: calc(50% - 135px);
position: absolute;
transform-origin: calc(-50% + 35px) 50%;
transition: all 1s ease;
}
.wheel.rotate-1 {
transform: rotateZ(0deg);
transition: all 0s ease;
}
.wheel.rotate-2 {
transform: rotateZ(90deg);
}
.wheel.rotate-3 {
transform: rotateZ(180deg);
}
.wheel.rotate-4 {
transform: rotateZ(270deg);
}
.wheel.rotate-5 {
transform: rotateZ(360deg);
}
.item:nth-child(1) {
transform: rotateZ(0deg);
}
.item:nth-child(2) {
transform: rotateZ(-90deg);
}
.item:nth-child(3) {
transform: rotateZ(-180deg);
}
.item:nth-child(4) {
transform: rotateZ(-270deg);
}
.wheel.rotate-1 .item {
opacity: 0;
}
.wheel.rotate-1 .item:nth-child(1) {
opacity: 1;
}
.wheel.rotate-2 .item {
opacity: 0;
}
.wheel.rotate-2 .item:nth-child(2) {
opacity: 1;
}
.wheel.rotate-3 .item {
opacity: 0;
}
.wheel.rotate-3 .item:nth-child(3) {
opacity: 1;
}
.wheel.rotate-4 .item {
opacity: 0;
}
.wheel.rotate-4 .item:nth-child(4) {
opacity: 1;
}
.wheel.rotate-5 .item {
opacity: 0;
}
.wheel.rotate-5 .item:nth-child(1) {
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="page">
<div class="wheel-wrp">
<div class="wheel rotate-1">
<div class="item">
<h4>Project 1 - beautifully crafted digital brand</h4>
<p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
laborum..
</p>
</div>
<div class="item">
<h4>Project 2 - redefining technological boundaries</h4>
<p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
laborum..
</p>
</div>
<div class="item">
<h4>Project 3 - Beauty in Design</h4>
<p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
laborum..
</p>
</div>
<div class="item">
<h4>Project 4 - simply stunning </h4>
<p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
laborum..
</p>
</div>
</div>
</div>
</div>
<div class="next">Next</div>
возможно, это не совсем правильное решение, но оно работает правильно.
Я изменил отображение собственность .item
поигрывать.
И сделал некоторые манипуляции с transform-origin
и положение элементов
body{
background-color: #2c3e50;
}
.next{
background: #2980b9;
padding: 15px 35px;
color: #fff;
float: left;
position: relative;
z-index: 9999;
cursor: pointer;
}
.wheel-wrp{
position: relative;
height: 700px;
width: 700px;
}
.wheel{
height: 700px;
width: 700px;
transition: 0.75s;
border-radius: 50%;
position: relative;
background: #fff;
left: -350px;
transform-origin: center;
}
.item{
width: 250px;
height: 100%;
flex-direction: column;
display: flex;
justify-content: center;
position: absolute;
opacity: 0;
border: 1px solid red;
transform-origin: center;
}
.item-active{
opacity: 1;
}
.item-one{
right: 0;
}
.item-two{
-webkit-transform: rotate(90deg);
-moz-transform: rotate(90deg);
transform: rotate(90deg);
bottom: 250px;
transform-origin: bottom left;
}
.item-three{
left: 0px;
-webkit-transform: rotate(180deg);
-moz-transform: rotate(180deg);
transform: rotate(180deg);
}
.item-four{
bottom: -250px;
transform-origin: top left;
-webkit-transform: rotate(270deg);
-moz-transform: rotate(270deg);
transform: rotate(270deg);
}
.current-item{
bottom: 300px;
left: 450px;
}
.next-item{
top: 20px;
left: 230px;
-webkit-transform:rotate(0deg);
-moz-transform:rotate(0deg);
transform:rotate(-90deg);
opacity: 0;
}
h4{
margin:0px 0px;
}
.fadeOut{
animation: menuFadeOut 350ms;
webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
.fadeIn{
animation: menuFadeIn 1500ms;
webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
@keyframes menuFadeOut {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
@keyframes menuFadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}