Привет! Я Мостафа, и это мой первый пост на DEV.
Здесь я хочу объяснить, как я создал это:
Прежде всего, мы используем хак checkbox, поэтому наше тело должно содержать checbox и label:
<input type="checkbox" name="play-checkbox" id="play-checkbox">
<label for="play-checkbox">
<div class="play">
</div>
</label>
Затем несколько основных стилей:
*,
*:after,
*::before {
padding: 0;
margin: 0;
box-sizing: border-box;
}
:root {
--primary-color: #242424;
--background-color: #01af5b;
}
body {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background-color: var(--background-color);
}
#play-checkbox {
display: none;
}
Наша цель — создать два треугольника, использовать их для создания еще одного треугольника и, наконец, превратить эти треугольники в две вертикальные полосы.
.play {
height: 22rem;
width: 22rem;
border: 1rem var(--primary-color) solid;
border-radius: 40rem;
overflow: hidden;
position: relative;
}
.play::before,
.play::after {
content: "";
position: absolute;
width: 10rem;
height: 5.8rem;
transition: all 400ms ease-out;
left: 6.7rem;
}
Весь элемент имеет ширину 20rem (2rem для границы), а игровой треугольник имеет высоту 10rem (в тригонометрической концепции). Здесь это означает, что он имеет ширину 10rem.
Для высоты мы используем математику:
height=10rem∗tan30°≃5.8rem
А left:6.7rem
центрирует его по горизонтали (снова используя тригонометрию :центры большого треугольника и круга должны совпадать).
Теперь большой треугольник имеет 10rem ширины и 11.6 rem высоты. Поэтому нам нужно 4,2 рема сверху и снизу, чтобы отцентрировать его.
Теперь мы используем линейный градиент, чтобы сделать два треугольника.
.play::before {
top: 4.2rem;
background-image: linear-gradient(
30deg,
var(--primary-color) 49%,
transparent 50%
);
}
.play::after {
top: 10rem;
background-image: linear-gradient(
-30deg,
transparent 49%,
var(--primary-color) 50%
);
}
Первая часть закончена. Просто помните: ::before
‘center:(top:7.1rem,left:11.7rem)
и ::after
‘center:(top:12.9rem,left:11.7rem)
.
Для следующей части мы должны сделать 3 вещи:
- Избавиться от фонового градиента
- Уменьшение ширины
- Поворот и перемещение псевдоэлементов в конечные позиции.
Давайте добавим наш код для взлома флажка:
#play-checkbox:checked + label .play::before {
/*
increase background size
transform:some rotation,translate and scale
*/
}
#play-checkbox:checked + label .play::after {
/*
increase background size
transform:some rotation,translate and scale
*/
}
Для фона мы просто увеличим размер фона со 100% до 400% (на самом деле достаточно 300%).
И трансформируем:
Представьте себе окончательную форму кнопки паузы, две полосы шириной 2,5rem и пространством между ними 5rem.
2.5/5.8=0.43 , поэтому масштабный коэффициент Y будет 0.43, а высота не изменится.
В конечном состоянии мы имеем :::before
‘s center:(top:10rem,left:6.25rem)
и ::after
‘s center:(top:10rem,left:13.75rem)
.
Таким образом, мы должны переместить ::before
на 5.45rem влево и 2.9rem вниз, а ::after
на 2.05rem вправо и 2.9rem вверх.
В CSS это означает:
{
transform: translate(-5.45rem, 2.9rem)
}
/* and */
{
transform: translate(2.05rem, -2.9rem)
}
Теперь мы можем завершить нашу работу:
Обратите внимание, что когда мы используем несколько функций преобразования, важен их порядок.
.play::before,
.play::after {
/* Don't forget this */
background-size: 100%;
}
#play-checkbox:checked + label .play::before {
background-size: 400%;
transform: translate(-5.45rem, 2.9rem) rotate(90deg) scaleY(0.43);
}
#play-checkbox:checked + label .play::after {
background-size: 400%;
transform: translate(2.05rem, -2.9rem) rotate(90deg) scaleY(0.43);
}
Теперь наша кнопка работает! Попробуйте увеличить длительность перехода, чтобы увидеть, что именно происходит.
Спасибо!