CSS - Можно ли анимировать clip на изображении, чтобы открывать квадранты по часовой стрелке?
У меня есть два круглых изображения. Верхнее изображение располагается абсолютно поверх нижнего изображения. Я показываю верхнее изображение с интервалом 25% с помощью клипа, и мне интересно, можно ли его анимировать, чтобы квадрант постепенно увеличивал угол, как часы.
В настоящее время у меня работает анимация, но она показывает только вертикальное направление, а не постепенное увеличение угла.
Я также открыт для других решений, не связанных с clipPath.
Update: Я также только что понял, что с помощью этого метода, который я использую, невозможно создать круг 3/4, хотя я полагаю, что мог бы просто добавить еще одно изображение с абсолютным положением и сделать одно из них 180 градусов по вертикали, а другое 180 градусов по горизонтали для этого.
.image-container {
position:relative;
height:180px;
width:180px;
border-radius:180px;
overflow:hidden;
}
.image-container img {
max-width:100%;
}
.image-container img.top-image {
position:absolute;
top:0;
left:0;
clip: rect(0, 90px, 90px, 0);
transform:rotate(90deg);
-webkit-transition: all 0.5s ease-out;
-moz-transition: all 0.5s ease-out;
transition: all 0.5s ease-out;
}
.image-container:hover img.top-image {
clip: rect(0, 180px, 90px, 0);
}
<div class="image-container">
<img src="https://e7.pngegg.com/pngimages/377/831/png-clipart-golden-circle-background-golden-circle-thumbnail.png"/>
<img class="top-image" src="https://www.pngjoy.com/pngm/380/18164680_circle-frame-vector-brown-round-frame-clip-art.png" />
</div>
Свободный перевод вопроса CSS - Possible to animate "clip" on an image to reveal quadrants clockwise? от участника @user13286.
Ответы (4 шт):
clip-path может это сделать:
.image-container {
height: 180px;
width: 180px;
display:grid;
border-radius:50%;
overflow:hidden;
}
.image-container img {
width: 100%;
display:block;
grid-area:1/1;
}
/* the 400% is an arbitrary big value*/
.image-container img.top-image {
clip-path:polygon(50% 0,400% 0,400% 50%,400% 50%,50% 50%);
transition: all 0.5s ease-out;
}
.image-container:hover img.top-image {
clip-path:polygon(50% 0,400% 0,400% 50%,50% 400%,50% 50%);
}
<div class="image-container">
<img src="https://e7.pngegg.com/pngimages/377/831/png-clipart-golden-circle-background-golden-circle-thumbnail.png" />
<img class="top-image" src="https://www.pngjoy.com/pngm/380/18164680_circle-frame-vector-brown-round-frame-clip-art.png" />
</div>
Чтобы понять, что происходит, добавьте box-shadow:
.image-container {
height: 180px;
width: 180px;
display:grid;
border-radius:50%;
}
.image-container img {
width: 100%;
display:block;
grid-area:1/1;
}
/* the 400% is an arbitrary big value*/
.image-container img.top-image {
clip-path:polygon(50% 0,400% 0,400% 50%,400% 50%,50% 50%);
box-shadow:0 0 0 1000px red;
transition: all 0.5s ease-out;
}
.image-container:hover img.top-image {
clip-path:polygon(50% 0,400% 0,400% 50%,50% 400%,50% 50%);
}
<div class="image-container">
<img src="https://e7.pngegg.com/pngimages/377/831/png-clipart-golden-circle-background-golden-circle-thumbnail.png" />
<img class="top-image" src="https://www.pngjoy.com/pngm/380/18164680_circle-frame-vector-brown-round-frame-clip-art.png" />
</div>
Свободный перевод ответа от участника @Temani Afif.
Если вам нужен «тикающий» эффект, такой как стрелка на аналоговых часах, вы можете использовать маску CSS с коническим градиентом, который постепенно откроет нижнее изображение.
Этот фрагмент создает анимацию CSS (используя JS, поскольку мне было лень вводить все это) с 60 точками анимации, каждый раз изменяя конический градиент на 6 градусов. Он добавляет анимацию к верхнему изображению при наведении курсора.
// create the 60 part animation
let keyframes = '@keyframes tickround {';
for (let i = 0; i <= 60; i++) {
keyframes += i * 100 / 60 + '% {-webkit-mask-image: conic-gradient(transparent ' + 6 * i + 'deg ' + 6 * (i + 1) + 'deg, black ' + 6 * (i + 1) + 'deg 360deg); mask-image: conic-gradient(transparent ' + 6 * i + 'deg ' + 6 * (i + 1) + 'deg, black ' + 6 * (i + 1) + 'deg 360deg);}';
}
keyframes += '}';
const newstyle = document.createElement('style');
newstyle.innerHTML = keyframes;
document.head.appendChild(newstyle);
.image-container {
position: relative;
height: 180px;
width: 180px;
border-radius: 180px;
overflow: hidden;
}
.image-container img {
max-width: 100%;
}
.image-container img.top-image {
position: absolute;
top: 0;
left: 0;
-webkit-mask-size: 100% 100%;
mask-size: 100% 100%;
-webkit-mask-repeat: no-repeat no-repeat;
mask-repeat: no-repeat no-repeat;
}
.image-container img.top-image:hover {
animation: tickround 60s linear infinite;
}
<div class="image-container">
<img src="https://e7.pngegg.com/pngimages/377/831/png-clipart-golden-circle-background-golden-circle-thumbnail.png" />
<img class="top-image" src="https://www.pngjoy.com/pngm/380/18164680_circle-frame-vector-brown-round-frame-clip-art.png" />
</div>
Свободный перевод ответа от участника @A Haworth.
Наложение на верхнюю картинку маски конического градиента - отличная идея, но анимировать его можно несколько по другому. Сами градиенты в css не поддаются анимации, но можно задать их отдельные свойства при помощи css-переменных и анимировать уже их
@property --value {
syntax: '<percentage>';
initial-value: 50%;
inherits: false;
}
.image-container {
display: inline-block;
position: relative;
height: 180px;
width: 180px;
border-radius: 180px;
overflow: hidden;
}
.image-container img {
max-width: 100%;
}
.image-container img.top-image {
position: absolute;
top: 0;
left: 0;
--value: 0%;
-webkit-mask: conic-gradient(black var(--value), transparent 0);
transition: --value 2s ease;
}
.image-container:nth-child(2) img.top-image{
transition: --value 2s steps(4);
}
.image-container img.top-image:hover {
--value: 100%;
}
<div class="image-container">
<img src="https://e7.pngegg.com/pngimages/377/831/png-clipart-golden-circle-background-golden-circle-thumbnail.png" />
<img class="top-image" src="https://www.pngjoy.com/pngm/380/18164680_circle-frame-vector-brown-round-frame-clip-art.png" />
</div>
<div class="image-container">
<img src="https://e7.pngegg.com/pngimages/377/831/png-clipart-golden-circle-background-golden-circle-thumbnail.png" />
<img class="top-image" src="https://www.pngjoy.com/pngm/380/18164680_circle-frame-vector-brown-round-frame-clip-art.png" />
</div>
добавил второй варант анимирования по четвертям (изначально вроде про него спрашивали)
Вариант с меньшими записями в таблице стилей. И без JavaScript.
Я решил анимировать CSS-переменные
Работает в основном в браузерах Chromium: https://caniuse.com/?search=%40property
.image-container {
position: relative;
display: block;
height: 180px;
width: 180px;
border-radius: 180px;
overflow: hidden;
}
.image-container img {
max-width: 100%;
}
.image-container img.top-image {
position: absolute;
top: 0;
left: 0;
-webkit-mask-size: 100% 100%;
mask-size: 100% 100%;
-webkit-mask-repeat: no-repeat no-repeat;
mask-repeat: no-repeat no-repeat;
--deg1: 0deg;
--deg2: 0deg;
--deg3: 0deg;
--deg4: 360deg;
-webkit-mask-image: conic-gradient(transparent var(--deg1) var(--deg2), black var(--deg3) var(--deg4));
mask-image: conic-gradient(transparent var(--deg1) var(--deg2), black var(--deg3) var(--deg4));
}
.image-container:hover img.top-image {
animation: tickround 60s steps(60) infinite;
}
@property --deg1 {
initial-value: 0deg;
inherits: false;
syntax: '<angle>';
}
@property --deg2 {
initial-value: 0deg;
inherits: false;
syntax: '<angle>';
}
@property --deg3 {
initial-value: 0deg;
inherits: false;
syntax: '<angle>';
}
@property --deg4 {
initial-value: 360deg;
inherits: false;
syntax: '<angle>';
}
@keyframes tickround {
0% {
--deg1: 0deg;
--deg2: 6deg;
--deg3: 6deg;
--deg4: 360deg;
}
100% {
--deg1: 360deg;
--deg2: 366deg;
--deg3: 366deg;
--deg4: 360deg;
}
}
<div class="image-container">
<img class="top-image" src="https://www.pngjoy.com/pngm/380/18164680_circle-frame-vector-brown-round-frame-clip-art.png" />
<img src="https://e7.pngegg.com/pngimages/377/831/png-clipart-golden-circle-background-golden-circle-thumbnail.png" />
</div>