梦幻摩天轮——用CSS写一个元素发光以及圆盘旋转的效果

标题当然是我自创的啦,这个效果是我偶然做出来的,并没有人严肃地起过名字。那我为什么会偶然做出这个东西呢?

最近做一个PC端官网的项目,首页的banner迟迟没有定下来,感觉客户想搞个大文章。果然后来客户说了个“要会动的banner”?什么是会动的?banner图左边有一个大圆环,(圆环上有8个栏目,每个栏目有个小圆圈,下面是标题)所以我认为,会动是圆环会转动。然后我花了好几个小时,研究如何使用animation动画让圆环转动,而且不让里面的文字颠倒。

banner的截图,长这样——

简单介绍一下圆环转动的思路:这个思路不是我原创的,而是来自一本叫做《CSS揭秘》的书的最后一节。

这个圆环有个特点:里面的每个项目并不是单纯的一个圆,而是含有文字的,甚至文字和圆是在同一张切图上的,也就是说,这些子项目的中心点并不是圆心。让圆环转动不难,但是如果只是圆环在转动,文字会颠倒,所以文字需要做相反方向的转动。据我所知有两种实现方法。

第一种是我一开始使用的,很蠢,非常蠢——分别指定每个子项目的transform-origin为圆环的圆心位置(因为不同的对于不同的点来说,圆心的位置不一样,)让子项目绕着圆心转动,因为它们本身就在圆环上,所以绕圆心转动,就是沿着圆环转动,理想的情况下是刚好在圆上的。然后让子项目里再套一层子元素(图片是子元素的背景图),子元素旋转的方向相反,让文字不颠倒。这个方法很麻烦,需要一一指定转动的中心,而且指定的位置如果没那么准确,转的时候会脱离轨道,效果很尴尬。

第二种效果好多了,那就是,不让每个子项目自己绕着圆心转,而是就摆在圆环上,让圆环自己转动,子项目自然就被带动着转起来了。然后,找到每个子项目中的圆心位置,让子项目绕着自己的圆心做方向相反的转动,就保证了文字不颠倒。这样计算量小得多,也不容易出意外(因为每个子项目看起来差不多大,圆心的位置几乎是一样的,只需要设置一次就可以了)

代码是这样的——

        <!-- banner -->
		<div class="banner-box">
			<img src="img/banner_bg.png" class="index-img"/>
			<!-- 左边,圆环 -->
			<div class="left-box">
				<div class="circle-box">
					<div class="menu-box menu-box1">
						<a href="#" class="menu">创新成果</a>
					</div>
                    ...
					<!-- 这里一共8个子项目,每个子项目有两层,外层是div,class为menu-box,内层是a,class为menu --->
				</div>
				<!-- 中间的文字 -->
				<img src="img/gxdjlc.png" alt="高校对接流程" class="circle-title"/>
			</div>
			<!-- 右边不重要 -->
			<div class="right-box">
				<img/><img/>
			</div>
		</div>

 

/* 两个方向相反的旋转关键帧动画 */
@keyframes spin{
	to{transform: rotate(1turn);}
}

@keyframes spin-reverse{
	from{
		transform:rotate(1turn);
	}
}

/* 圆环 */
.banner-box .circle-box {
	width: 560px;
	height: 560px;
	transform-origin: center;
	background: url("../img/circle_bg.png");
    /* 圆环转动 */
	animation:spin 60s infinite linear;
}

/* banner里面的每一个子项目div */
.banner-box .circle-box .menu-box {
	position: absolute;
	animation: inherit;
	animation-name: spin-reverse;
	transform-origin: 50% 40px;
	/* 子元素转动,animation是继承了圆环的,但是指定了另一个动画名字,所以是倒着转的 */
	animation: inherit;
	animation-name: spin-reverse;
}

/* 每个子元素div的位置,menu-box1到menu-box8各不相同,这里省略了其他的 */
.banner-box .circle-box .menu-box1 {
	top: -39px;
	left: 218px;
}

/* 每个里面的a的大小和背景图 */
.banner-box .circle-box .menu-box1 .menu {
	width: 125px;
	height: 131px;
	background: url("../img/banner_menu1.png");
}

/* 圆盘悬浮时暂停动画,设置动画播放状态为暂停 */
.banner-box .circle-box:hover .menu-box {
    animation-play-state: paused; 
}

结果我满头大汗做出来给客户看了以后,客户居然说“不是要转动的。是像某某项目一样有发光、发散的效果。转动先留着。如果领导想不开,可能会想让圆环转起来”。所以重点并不是圆环转动,而是小圆发光。于是我接着去做小圆发光的事情……

为了防止给HTML代码“添乱”,我这里借用了伪元素,大部分元素都有两个伪元素,分别叫before和after。这样,看似一个元素,其实就有两个跟它站在一起的"分身“。思路是这样的(这个思路也不是我原创的,我在看黑马程序员老师讲CSS3的时候看到的):因为发光的时候光线会随着时间变淡,所以应该是透明度降低;而且光线应该是渐渐走出我们的视野,所以应该是变透明的同时放大了;而且发光的时候看起来是一闪一闪的,所以必须有两个光圈同时在动,而且节奏不一致。

更进一步说,两个光圈同时在动,但节奏不同,说明它们用的是同一个动画但有不同的延时,而这两个光圈,可以使用绝对定位、背景透明但有白色边框的伪元素来做。用js给子元素做了轮流闪烁的效果。另外,为了在鼠标悬浮时吸引用户的注意,我让鼠标悬浮的项目加上动画,并且次数为无数次。

/* 用伪元素做两个白色小圆环,初始状态下透明度为0,看不见 */
.banner-box .circle-box .menu::before,
.banner-box .circle-box .menu::after {
	content: '';
	position: absolute;
	top: 0;
	left: 50%;
	margin-left: -39.5px;
	width: 80px;
	height: 80px;
	box-sizing: border-box;
	border: 2px solid #fff;
	border-radius: 50%;
	transform-origin: center;
	opacity: 0;
}

/* 发光动画,在动的时候,透明度变淡,同时光圈变大 */
@keyframes shining {
	from {
		opacity: 1;
		transform: scale(1);
	}
	to {
		opacity: 0;
		transform: scale(1.8);
	}
}

/* 悬浮和active闪烁*/
.banner-box .circle-box .menu.active::before,
.banner-box .circle-box .menu:hover::before {
	/* 加上发光动画 */
	animation: shining 3s infinite linear;
}

/* after的动画有延时 */
.banner-box .circle-box .menu.active::after,
.banner-box .circle-box .menu:hover::after {
	animation: shining 3s infinite 1.5s linear;
}

/* 如果是加上了active,那么就只动一次 */
.banner-box .circle-box .menu.active::after,
.banner-box .circle-box .menu.active::before {
	animation-iteration-count: 1;
}
// 让元素自己闪的动画
// 现在闪烁的元素索引
let activeIndex = 0;
let links = $('.circle-box .menu');
// 先让第一个元素闪烁
links.eq(0).addClass('active')
/* 让里面的链接自动按顺序闪烁 */
window.setInterval(function() {
	activeIndex++;
	// 只有当前的元素有active类
	links.removeClass('active')
	links.eq(activeIndex % 8).addClass('active')
}, 4500) //闪烁一次时间是4.5秒

效果是这样的——

我不知道怎么截gif,所以就随手灵魂截图截了几张给大家看看,子项目的位置在变,说明有在旋转,而且有的子项目外面有半透明圆圈。

整体来说,这是一个不太难,但是又比较有趣的一个效果,莫名地有一种摩天轮的感觉。如果有小伙伴在学习CSS3动画,可以来了解一下,练习一下。好啦,这一个效果讲完了。我是南宫,我的愿望是——好好学习,好好生活,早日找到好工作!

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值