使用 CSS/SASS 在圆形路径上旋转图像
Rotating images on a circular path using CSS/SASS
我发现 Hugo Giraudel's excellent tutorial on arranging images on a circle using SASS/CSS, and I am trying to take it another step further by animating the rotation of the circle of images. I have modified a codepen 显示了我得到的各种不满意的结果之一。 HTML 只是五个图像的无序列表:
<ul class='circle-container'>
<li class="city">
<a href='#'><img src='http://lorempixel.com/150/150/city'></a>
</li>
<li class="nature">
<a href='#'><img src='http://lorempixel.com/150/150/nature'></a>
</li>
<li class="abstract">
<a href='#'><img src='http://lorempixel.com/150/150/abstract'></a>
</li>
<li class="sports">
<a href='#'><img src='http://lorempixel.com/150/150/sports/'></a>
</li>
<li class="food">
<a href='#'><img src='http://lorempixel.com/150/150/food'></a>
</li>
</ul>
他的 SASS/CSS 加上我的一些小修改:
/**
* Mixin to put items on a circle
* [1] - Allows children to be absolutely positioned
* [2] - Allows the mixin to be used on a list
* [3] - In case box-sizing: border-box has been enabled
* [4] - Allows any type of direct children to be targeted
*/
@mixin putOnCircle(
$nb-items, //Number of items
$circle-size, //Parent size
$item-size, //Item size
$class-for-IE: false //Base class name, false means use of pseudo-selectors
) {
$item-size: 150px;
$nb-items: 5;
$circle-size: 550px;
$half-item: $item-size / 2;
$half-parent: $circle-size / 2;
position: relative; /* [1] */
width: $circle-size;
height: $circle-size;
padding: 0;
border-radius: 50%;
list-style: none; /* [2] */
@include box-sizing(content-box); /* [3] */
> * { /* [4] */
display: block;
position: absolute;
top: 50%;
left: 50%;
width: $item-size;
height: $item-size;
margin: -$half-item;
$angle: 360 / $nb-items;
$rot: 0;
@for $i from 1 to $nb-items+1 {
// If no support for IE8-
@if $class-for-IE == false {
&:nth-of-type(#{$i}) {
@include transform(rotate(#{$rot}deg) translate($half-parent) rotate(-#{$rot}deg));
}
}
// If support for IE8-
@else {
&.#{$class-for-IE}#{$i} {
// If CSS transforms are not supported
$mt: sin($rot * pi() / 180) * $half-parent - $half-item;
$ml: cos($rot * pi() / 180) * $half-parent - $half-item;
margin: $mt 0 0 $ml;
}
}
$rot: $rot + $angle;
}
}
}
.circle-container {
@include putOnCircle(8, 20em, 6em, false);
margin: 5em auto 0;
border: solid 5px tomato;
animation: rot 8s infinite linear;
-webkit-animation: rot 8s infinite linear;
-moz-animation: rot 8s infinite linear;
a {
display: block;
border-radius: 50%;
box-shadow: 0 0 0 5px tomato;
}
img {
display: block;
width: 100%;
border-radius: 50%;
@include filter(grayscale(100%));
&:hover {
@include filter(grayscale(0));
}
}
}
@keyframes rot {
from {
transform: rotate(0deg)
translate(-275px)
rotate(0deg);
-webkit-transform: rotate(0deg)
translate(-275px)
rotate(0deg);
}
to {
transform: rotate(360deg)
translate(-275px)
rotate(-360deg);
-webkit-transform: rotate(360deg)
translate(-275px)
rotate(-360deg);
}
}
@-webkit-keyframes rot {
from {
transform: rotate(0deg)
translate(-275px)
rotate(0deg);
-webkit-transform: rotate(0deg)
translate(-275px)
rotate(0deg);
}
to {
transform: rotate(360deg)
translate(-275px)
rotate(-360deg);
-webkit-transform: rotate(360deg)
translate(-275px)
rotate(-360deg);
}
}
.city,
.nature,
.abstract,
.sports,
.food {
/*animation: rot 8s infinite linear;
-webkit-animation: rot 8s infinite linear;
-moz-animation: rot 8s infinite linear;
*/
}
在上面的代码中(与 codepen 中的相同),图像保持在固定位置,但整个圆形容器旋转(旋转,真的)。
如果我删除 circle-container ul 上的动画:
.circle-container {
@include putOnCircle(8, 20em, 6em, false);
margin: 5em auto 0;
border: solid 5px tomato;
/* animation: rot 8s infinite linear;
-webkit-animation: rot 8s infinite linear;
-moz-animation: rot 8s infinite linear; */
...而是为列表项(或锚元素,或 imgs)设置动画:
.city,
.nature,
.abstract,
.sports,
.food {
animation: rot 8s infinite linear;
-webkit-animation: rot 8s infinite linear;
-moz-animation: rot 8s infinite linear;
}
然后我可以正确地围绕圆圈旋转(旋转)图像,但只能旋转一个图像。其他四个图像似乎排在它后面。我确信解决方案相当简单,但我已经尝试了我能想到的每一种排列方式,而且它已经让我困惑了很长时间,以至于我想我应该转向这里寻求建议。任何帮助将不胜感激!
当然可以为此编写更好的 mixin,但我只想为每个图像创建新的动画,以便开始和结束角度偏移。
@-webkit-keyframes city-rot {
from {
transform: rotate(45deg)
translate(-275px)
rotate(-45deg);
-webkit-transform: rotate(45deg)
translate(-275px)
rotate(-45deg);
}
to {
transform: rotate(405deg)
translate(-275px)
rotate(-405deg);
-webkit-transform: rotate(405deg)
translate(-275px)
rotate(-405deg);
}
}
.city {
animation: city-rot 8s infinite linear;
-webkit-animation: city-rot 8s infinite linear;
-moz-animation: city-rot 8s infinite linear;
}
解决这个问题的通常方法,不需要编写不同的动画,就是为每个动画使用不同的时间
.city {animation-delay: 0s; }
.nature {animation-delay: -1.6s; }
.abstract {animation-delay: -3.2s; }
.sports {animation-delay: -4.8s;}
.food {animation-delay: -6.4s;}
每次延迟是总动画时间除以元素数量再乘以元素位置
延迟是负的,所以一切从一开始就正常。
你应该使用 nth-child(n) 编写一个 mixin,但我对 SASS 的了解还不够。 (抱歉)
我发现 Hugo Giraudel's excellent tutorial on arranging images on a circle using SASS/CSS, and I am trying to take it another step further by animating the rotation of the circle of images. I have modified a codepen 显示了我得到的各种不满意的结果之一。 HTML 只是五个图像的无序列表:
<ul class='circle-container'>
<li class="city">
<a href='#'><img src='http://lorempixel.com/150/150/city'></a>
</li>
<li class="nature">
<a href='#'><img src='http://lorempixel.com/150/150/nature'></a>
</li>
<li class="abstract">
<a href='#'><img src='http://lorempixel.com/150/150/abstract'></a>
</li>
<li class="sports">
<a href='#'><img src='http://lorempixel.com/150/150/sports/'></a>
</li>
<li class="food">
<a href='#'><img src='http://lorempixel.com/150/150/food'></a>
</li>
</ul>
他的 SASS/CSS 加上我的一些小修改:
/**
* Mixin to put items on a circle
* [1] - Allows children to be absolutely positioned
* [2] - Allows the mixin to be used on a list
* [3] - In case box-sizing: border-box has been enabled
* [4] - Allows any type of direct children to be targeted
*/
@mixin putOnCircle(
$nb-items, //Number of items
$circle-size, //Parent size
$item-size, //Item size
$class-for-IE: false //Base class name, false means use of pseudo-selectors
) {
$item-size: 150px;
$nb-items: 5;
$circle-size: 550px;
$half-item: $item-size / 2;
$half-parent: $circle-size / 2;
position: relative; /* [1] */
width: $circle-size;
height: $circle-size;
padding: 0;
border-radius: 50%;
list-style: none; /* [2] */
@include box-sizing(content-box); /* [3] */
> * { /* [4] */
display: block;
position: absolute;
top: 50%;
left: 50%;
width: $item-size;
height: $item-size;
margin: -$half-item;
$angle: 360 / $nb-items;
$rot: 0;
@for $i from 1 to $nb-items+1 {
// If no support for IE8-
@if $class-for-IE == false {
&:nth-of-type(#{$i}) {
@include transform(rotate(#{$rot}deg) translate($half-parent) rotate(-#{$rot}deg));
}
}
// If support for IE8-
@else {
&.#{$class-for-IE}#{$i} {
// If CSS transforms are not supported
$mt: sin($rot * pi() / 180) * $half-parent - $half-item;
$ml: cos($rot * pi() / 180) * $half-parent - $half-item;
margin: $mt 0 0 $ml;
}
}
$rot: $rot + $angle;
}
}
}
.circle-container {
@include putOnCircle(8, 20em, 6em, false);
margin: 5em auto 0;
border: solid 5px tomato;
animation: rot 8s infinite linear;
-webkit-animation: rot 8s infinite linear;
-moz-animation: rot 8s infinite linear;
a {
display: block;
border-radius: 50%;
box-shadow: 0 0 0 5px tomato;
}
img {
display: block;
width: 100%;
border-radius: 50%;
@include filter(grayscale(100%));
&:hover {
@include filter(grayscale(0));
}
}
}
@keyframes rot {
from {
transform: rotate(0deg)
translate(-275px)
rotate(0deg);
-webkit-transform: rotate(0deg)
translate(-275px)
rotate(0deg);
}
to {
transform: rotate(360deg)
translate(-275px)
rotate(-360deg);
-webkit-transform: rotate(360deg)
translate(-275px)
rotate(-360deg);
}
}
@-webkit-keyframes rot {
from {
transform: rotate(0deg)
translate(-275px)
rotate(0deg);
-webkit-transform: rotate(0deg)
translate(-275px)
rotate(0deg);
}
to {
transform: rotate(360deg)
translate(-275px)
rotate(-360deg);
-webkit-transform: rotate(360deg)
translate(-275px)
rotate(-360deg);
}
}
.city,
.nature,
.abstract,
.sports,
.food {
/*animation: rot 8s infinite linear;
-webkit-animation: rot 8s infinite linear;
-moz-animation: rot 8s infinite linear;
*/
}
在上面的代码中(与 codepen 中的相同),图像保持在固定位置,但整个圆形容器旋转(旋转,真的)。
如果我删除 circle-container ul 上的动画:
.circle-container {
@include putOnCircle(8, 20em, 6em, false);
margin: 5em auto 0;
border: solid 5px tomato;
/* animation: rot 8s infinite linear;
-webkit-animation: rot 8s infinite linear;
-moz-animation: rot 8s infinite linear; */
...而是为列表项(或锚元素,或 imgs)设置动画:
.city,
.nature,
.abstract,
.sports,
.food {
animation: rot 8s infinite linear;
-webkit-animation: rot 8s infinite linear;
-moz-animation: rot 8s infinite linear;
}
然后我可以正确地围绕圆圈旋转(旋转)图像,但只能旋转一个图像。其他四个图像似乎排在它后面。我确信解决方案相当简单,但我已经尝试了我能想到的每一种排列方式,而且它已经让我困惑了很长时间,以至于我想我应该转向这里寻求建议。任何帮助将不胜感激!
当然可以为此编写更好的 mixin,但我只想为每个图像创建新的动画,以便开始和结束角度偏移。
@-webkit-keyframes city-rot {
from {
transform: rotate(45deg)
translate(-275px)
rotate(-45deg);
-webkit-transform: rotate(45deg)
translate(-275px)
rotate(-45deg);
}
to {
transform: rotate(405deg)
translate(-275px)
rotate(-405deg);
-webkit-transform: rotate(405deg)
translate(-275px)
rotate(-405deg);
}
}
.city {
animation: city-rot 8s infinite linear;
-webkit-animation: city-rot 8s infinite linear;
-moz-animation: city-rot 8s infinite linear;
}
解决这个问题的通常方法,不需要编写不同的动画,就是为每个动画使用不同的时间
.city {animation-delay: 0s; }
.nature {animation-delay: -1.6s; }
.abstract {animation-delay: -3.2s; }
.sports {animation-delay: -4.8s;}
.food {animation-delay: -6.4s;}
每次延迟是总动画时间除以元素数量再乘以元素位置
延迟是负的,所以一切从一开始就正常。
你应该使用 nth-child(n) 编写一个 mixin,但我对 SASS 的了解还不够。 (抱歉)