Прошло много времени с тех пор, как я возвращался к проверке знаний CSS, и так получилось, что крайний срок написания статьи был в конце месяца...
Все статьи были размещены на SF ранее, и это впервые для Nuggets.
Поэтому на этот раз я решил подробно обобщить знания, связанные с анимацией CSS3, потому что раньше использовал только некоторые свойства и не вдавался в подробности.
Когда я сам писал эту статью, я чувствовал, что с помощью CSS действительно можно добиться множества крутых эффектов.
Завершение демонстрации этой статьи также проверило множество соответствующих знаний и узнало из содержания некоторых статей. Но несмотря ни на что, как новичок во фронтенде, я всегда расту благодаря постоянному обучению. Это предложение написано здесь, и я чувствую себя более непринужденно. (побег......
Окончательный адрес демонстрационного эффекта
Ниже я объясню шаг за шагом, как с помощью чистого CSS добиться эффекта вращающейся карусели кубика Рубика.
В общем случае нам необходимо реализовать следующие две основные функции:
-
Постройте куб, который может вращаться
-
Пусть куб имеет характеристики базовой карусели
Но прежде чем выполнить два вышеуказанных пункта, нам нужно понять или ознакомиться с базовыми знаниями CSS3, чтобы реализовать его функции:
-
transition
-
transform
-
perspective
-
preserve-3d
-
animation
свойство перехода --- эффект перехода
transition: property duration timing-fucntion delay;
Это свойство должно быть вам знакомо, и я не буду много говорить, просто перечислю все его подсвойства.
Свойства перехода --- Длительность перехода --- Функция перехода (кривая) --- Задержка перехода
transition-timing-function: linear|ease|ease-in|ease-out|ease-in-out; 原生具有的基本过渡函数
свойство преобразования --- 2D или 3D преобразование элемента
Он имеет несколько часто используемых методов преобразования: масштабировать, масштабировать, переводить, переводить, вращать, поворачивать, поворачивать, поворачивать и так далее.
transform-origin: x-axis y-axis z-axis; 设置旋转元素的基点位置
transform-style: preserve-3d; 让转换的子元素保留3D转换(与perspective搭配使用)
свойство перспективы --- позволить элементу достичь эффекта 3D-перспективы
perspective: 1000px;
它有两种写法
transform: perspective(1000px);
Это свойство придает объекту эффект стереоскопической 3D перспективы.Чем больше значение, тем дальше находится объект от объекта на экране, который видят наши глаза в это время.Наоборот, чем меньше его значение, тем ближе он в нашей перспективе, то есть в большем размере, отображаемом на экране. Он используется вместе с save-3d для создания сценической перспективы родительского элемента, которому необходимо достичь 3D-эффектов, чтобы его дочерние элементы могли достичь истинного 3D-преобразования.
Подробное объяснение трансформации (Чжан Синьсюй)
Для достижения базового куба необходимо объединить три вышеуказанных атрибута.
Cube
<div class="cube-wrap">
<div class="cube">
<div class="cube-face front"><img src="1.jpg"></div>
<div class="cube-face back"><img src="2.jpg"></div>
<div class="cube-face left"><img src="3.jpg"></div>
<div class="cube-face right"><img src="4.jpg"></div>
<div class="cube-face top"><img src="5.jpg"></div>
<div class="cube-face bottom"><img src="6.jpg"></div>
</div>
</div>
Важные стили CSS
.cube-wrap{
width: 300px;
height: 300px;
perspective: 1000px;
position: relative;
}
.cube-wrap .cube{
width: 100%;
height: 100%;
position: absolute;
transform-style: preserve-3d;
transition: all .5s ease;
}
.cube-wrap .cube .cube-face{
width: 100%;
height: 100%;
position: absolute;
overflow: hidden;
opacity: 0.9;
border: 1px solid #ccc;
}
.cube-wrap .cube .cube-face img{
width: 100%;
height: 100%;
}
.cube-face.front{
transform: translateZ(150px);
}
.cube-face.back{
transform: rotateX(180deg) translateZ(150px);
}
.cube-face.left{
transform: rotateY(-90deg) translateZ(150px);
}
.cube-face.right{
transform: rotateY(90deg) translateZ(150px);
}
.cube-face.top{
transform: rotateX(90deg) translateZ(150px);
}
.cube-face.bottom{
transform: rotateX(-90deg) translateZ(150px);
}
Здесь мы используем перспективу и save-3d для родительского элемента, после чего вступает в силу эффект 3D-преобразования дочернего элемента.
Итак, дело в том, как приведенный выше код соединяется в полный куб? При внимательном рассмотрении в инструментах разработчика браузера нетрудно обнаружить, что элемент с именем класса куб расположен сбоку посередине куба. Итак, у нас есть представление о том, как построить каждую сторону куба с помощью кода.
Прежде всего, должно быть ясно, что направление осей x, y и z пространственной декартовой системы координат устанавливается во время преобразования, связанного с преобразованием.
То есть, принимая экран компьютера за плоскость, горизонтальное направление — это ось x, вертикальное направление — ось y, а вертикальное направление — ось z.
Итак, как построить шесть граней куба, становится очень просто, начальное положение грани куба находится посередине, а длина всего куба составляет 300 пикселей, поэтомуtranslateZ(150px)
Это положительно. Чтобы построить заднюю часть, вам сначала нужно развернуть начальную поверхность на 180 градусов против часовой стрелки, в это время передняя часть указывает на заднюю часть, поэтому просто повторите.translateZ(150px)
Вот и все. Чтобы построить левую сторону, вам нужно повернуть вокруг оси YrotateY(-90deg)
, а соответствующая правая частьrotateY(90deg)
, а затем продолжитьtranslateZ(150px)
Перевод оставшихся двух граней можно сделать по соответствующей логике. Следует отметить, что при вращении грани вокруг оси вращение против часовой стрелки является положительным, а вращение по часовой стрелке - отрицательным.
свойство анимации
Это свойство, безусловно, самое важное в анимации CSS3, и каждое из его подсвойств заслуживает более пристального внимания.
animation: name duration timing-function delay iteration-count direction fill-mode play-state;
animation-delay: 1s; 设置为负值时让动画马上开始, 并且跳过1秒前的动画
animation-direction: normal|reverse|alternate|alternate-reverse; 定义是否循环交替反向播放动画
alternate 动画在奇数次(1、3、5...)正向播放, 在偶数次(2、4、6...)反向播放
alternate-reverse 动画在奇数次(1、3、5...)反向播放, 在偶数次(2、4、6...)正向播放
animation-fill-mode: none|forwards|backwards|both; 规定当动画不播放时, 要应用到元素的样式
forwards 动画结束后停留在最后一帧
backwards 在animation-delay期间启动动画的第一帧属性
both 同时实现forwards与backwards的效果
animation-play-state: paused|running; 控制动画暂停或运行。
@keyframes 设置动画关键帧, 在这里我们用from...to或者百分比来实现自定义的动画
Подробное объяснение анимации
Далее добавляем анимацию анимации к уже построенному кубу:
.cube-wrap .cube{
......
animation: spin 10s linear infinite;
}
@keyframes spin {
from {
transform: rotateX(45deg) rotateY(45deg);
}
to {
transform: rotateX(405deg) rotateY(765deg);
}
}
Carousel
Теперь, когда мы реализовали эффект куба, который может свободно вращаться, нам нужно выполнить основные функции карусели.
-
Переключатель левой и правой кнопки
-
Нижняя кнопка переключения
Прежде чем реализовать эти две функции, нам нужно понять два мощных тега HTML, которые работают вместе для достижения эффекта щелчка и переключения в карусели. Это метка и метка ввода, давайте рассмотрим их основное использование.
<input type="radio" id="1">
<label for="1" ></label> 点击label标签, id为1的input标签被选中
Здесь тег for в теге label связан с идентификатором во входном теге, а когда тип во входном теге — радио, это эффект поля выбора, который имеет проверенный атрибут (для достижения эффекта радио, вам нужно установить name= "xxx" , имя должно быть таким же в это время, этот эффект будет использоваться ниже)
Теперь давайте начнем реализовывать конкретный эффект.
<div class="container">
<div class="cube-wrap">
<input type="radio" name="cuber" class="controller" id="1" checked="true">
<input type="radio" name="cuber" class="controller" id="2">
<input type="radio" name="cuber" class="controller" id="3">
<input type="radio" name="cuber" class="controller" id="4">
<input type="radio" name="cuber" class="controller" id="5">
<input type="radio" name="cuber" class="controller" id="6">
<div class="cube">
......
</div>
<div class="cube_left">
<label for="6" class="cube_action"></label>
<label for="1" class="cube_action"></label>
<label for="2" class="cube_action"></label>
<label for="3" class="cube_action"></label>
<label for="4" class="cube_action"></label>
<label for="5" class="cube_action"></label>
</div>
<div class="cube_right">
<label for="2" class="cube_action"></label>
<label for="3" class="cube_action"></label>
<label for="4" class="cube_action"></label>
<label for="5" class="cube_action"></label>
<label for="6" class="cube_action"></label>
<label for="1" class="cube_action"></label>
</div>
<div class="indicators">
<label for="1" class="indicator"></label>
<label for="2" class="indicator"></label>
<label for="3" class="indicator"></label>
<label for="4" class="indicator"></label>
<label for="5" class="indicator"></label>
<label for="6" class="indicator"></label>
</div>
</div>
</div>
Сначала реализуйте левый, правый и нижний стили CSS.
.cube_left .cube_action{
left: -75px;
top: 50%;
transform: translateY(-50%);
}
.cube_right .cube_action{
right: -75px;
top: 50%;
transform: translateY(-50%);
}
.cube_action{
background-color: #fafafa;
border-radius: 50%;
cursor: pointer;
display: none;
width: 40px;
height: 40px;
opacity: 0.15;
position: absolute;
transition: opacity 0.5s ease;
z-index: 5;
}
.cube_action:hover{
opacity: 1;
}
.cube_action::before{
border-bottom: 4px solid #111;
border-right: 4px solid #111;
content: '';
display: block;
height: 25%;
left: 50%;
position: absolute;
top: 50%;
width: 25%;
transform: translate(-70%, -50%) rotate(-45deg);
}
.cube_left .cube_action::before{
transform: translate(-40%, -50%) rotate(135deg);
}
.indicators{
position: absolute;
left: 0;
right: 0;
bottom: -80px;
padding: 20px;
text-align: center;
opacity:0;
transition: opacity .3s;
}
.container:hover .indicators{
opacity: 1;
}
.indicators .indicator{
background-color: #fafafa;
border-radius: 50%;
cursor: pointer;
display: inline-block;
width: 14px;
height: 14px;
margin: 6px;
opacity: .15;
}
.controller{
display: none;
}
После написания приведенного выше кода мы не можем увидеть желаемые результаты, потому что всем им нужны события наведения для срабатывания.
Теперь давайте стилизуем самый внешний контейнер и определим анимацию входа.
.container{
width: 600px;
height: 600px;
position: absolute;
top: 50%;
left: 50%;
margin-top: -300px;
margin-left: -300px;
transition: all .5s ease;
transform: scale(0.25);
}
.container:hover {
transform: scale(1);
}
.container:hover .cube-wrap .cube{
animation: entrance .5s ease ;
}
@keyframes entrance {
from {
transform: rotateX(-225deg) rotateY(-225deg);
}
}
При перемещении мыши внутрь куба анимация сменяется вращением с входом.
Итак, снова возникает вопрос: как CSS реализует карусельные изображения с переключением по щелчку?
Принцип очень прост, на самом деле, он сочетается с меткой метки и меткой ввода, упомянутыми выше, для достижения потрясающих результатов.
.controller:nth-of-type(1):checked ~ .cube{
transform: translateZ(-150px);
}
.controller:nth-of-type(2):checked ~ .cube{
transform: translateZ(-150px) rotateX(-180deg) ;
}
.controller:nth-of-type(3):checked ~ .cube{
transform: translateZ(-150px) rotateY(90deg) ;
}
.controller:nth-of-type(4):checked ~ .cube{
transform: translateZ(-150px) rotateY(-90deg) ;
}
.controller:nth-of-type(5):checked ~ .cube{
transform: translateZ(-150px) rotateX(-90deg) ;
}
.controller:nth-of-type(6):checked ~ .cube{
transform: translateZ(-150px) rotateX(90deg) ;
}
Независимо от того, нажимаем ли мы левую и правую кнопки или нижнюю кнопку, мы активируем атрибут for тега label, чтобы связать проверенный атрибут в соответствующем теге ввода.
Что касается того, как инвертировать соответствующую сторону на сторону, обращенную к экрану, просто поменяйте местами символы при преобразовании каждой стороны строительного куба.
Стоит отметить, что селектор CSS, который мы здесь используем, также является навыком.:nth-of-type(n)
Выбрана n-я метка того же типа,~
Выбор символа — это метка в родственном элементе.
Тщательно понять разницу между nth-child и nth-of-type
Теперь давайте вернемся и рассмотрим структуру HTML в начале. соответствующее преобразование 3D. Но почему порядок чисел в метке метки на левой и правой кнопках выглядит неправильно?
Сам долго тут раздумывал, и много сил ушло на то, чтобы разобраться в оригинале.cube_left
или.cube_right
Соответствующие 6 этикеток перекрываются, и все ониdisplay:none
, это очень интересно, давайте посмотрим на следующий код.
.container:hover .controller:nth-of-type(1):checked ~ .cube_left .cube_action:nth-of-type(1),
.container:hover .controller:nth-of-type(1):checked ~ .cube_right .cube_action:nth-of-type(1){
display: block;
}
.container:hover .controller:nth-of-type(2):checked ~ .cube_left .cube_action:nth-of-type(2),
.container:hover .controller:nth-of-type(2):checked ~ .cube_right .cube_action:nth-of-type(2){
display: block;
}
......
......
......
.container:hover .controller:nth-of-type(6):checked ~ .cube_left .cube_action:nth-of-type(6),
.container:hover .controller:nth-of-type(6):checked ~ .cube_right .cube_action:nth-of-type(6){
display: block;
}
Теперь у нас по умолчанию выбран первый элемент в контроллере, то есть его проверенное свойство имеет значение true. Таким образом, первая в метке метка в левой и правой кнопках отображается какdisplay:block
, если мы сейчас нажмем кнопку слева, мы хотим, чтобы нижняя часть куба отображалась на передней части экрана, поэтому для параметра должно быть установлено значение 6. Если вы нажмете кнопку справа, для метки первой метки должно быть установлено значение 2. Следуя этой логике, мы также понимаем, почему.cube_left
или.cube_right
Атрибут for не соответствует порядку.
До сих пор мы объясняли основное содержание и знания, необходимые для реализации вращающейся карусели кубика Рубика, а остальное — некоторые фрагментированные стили CSS для завершения интерфейса, которые здесь не будут показаны. После написания этой статьи я действительно чувствую, что хорошо знаком со знанием CSS... Но главная сила фронтенда - это JavaScript, и мне нужно продолжить изучение знаний JS в мае...
PS: ссылка на содержание этой статьи
Подробное объяснение трансформации (Чжан Синьсюй)