前已经说过,本人是即将毕业的学生。前几天的HTML5实训学到了很多有趣的东西,其中CSS3做的东西很棒。由于时间关系,老师并没有讲解多少,只是做了几个简单的案例。其中有利用transform实现文字或图像的旋转,缩放,倾斜,移动这四种类型的变形处理;有使用transition功能通过将元素的某个属性从一个属性在指定的时间内平滑过渡到另一个属性值来实现动画;还有animations通过定义多个关键帧以及定义每个关键帧中元素的属性值来实现更为复杂的动画效果。
我自己还没有系统的学习CSS3,只是稍有了解。CSS3新增了很多美观的样式,不断丰富页面内容。我选择主攻前端正是因为喜欢将用户体验尽可能做到最佳,当然也少不了CSS3。今天先来分享一下两个使用CSS3做出的炫酷小动画吧,都是从老师那里学到的。
第一个先来大风车吧,说到大风车我第一时间想到了“大风车吱呀吱扭扭地转”这句词,嘿嘿。进入正题,首先将静态页面搭建起来,这个就比较简单啦。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>大风车</title>
<style type="text/css">
.wrap{
width: 400px;
height: 400px;
position: relative;
}
.wrap div{
width: 200px;
height: 200px;
position: absolute;
}
.box1{
background: linear-gradient(to top,#dc143c 50%,rgba(0,0,0,0) 50%);
top:100px;
border-radius: 0 0 100px 100px;
}
.box2{
background: linear-gradient(to bottom,#ff4500 50%,rgba(0,0,0,0) 50%);
top:100px;
right: 0;
border-radius: 100px 100px 0 0;
}
.box3{
background: linear-gradient(to right,#00ced1 50%,rgba(0,0,0,0) 50%);
left:100px;
border-radius:100px 0 0 100px;
}
.box4{
background: linear-gradient(to left,pink 50%,rgba(0,0,0,0) 50%);
left:100px;
bottom: 0;
border-radius:0 100px 100px 0;
}
.gunzi{
width: 10px;
height: 300px;
position: absolute;
top:208px;
left:204px;
background:black;
z-index: -1;
}
</style>
</head>
<body>
<div class="wrap">
<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>
<div class="box4"></div>
</div>
<div class="gunzi"></div>
</body>
</html>
先来看下效果,如下:
接下来在<style></style>标签中加入:
@keyframes rotate{
from{transform: rotate(0deg);}
to{transform: rotate(360deg);}
}
.wrap{
animation:rotate 2s linear infinite;
}
使用@keyframes规则定义关键帧创建动画。效果如下:
大风车到这里就结束啦,最后再来一个3D立方体。
<!DOCTYPE>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style>
body{-webkit-perspective:1500px;
}
.div{
-webkit-transform-style:preserve-3d;
width:200px;height:200px;
margin:100px auto;
position:relative;
-webkit-transition:-webkit-transform 2s ease 0s;
}
p{margin:0;
padding:0;width:200px;
height:200px;position:absolute;
opacity:0.5;}
p:nth-of-type(1){background-color:#00b38b;
-webkit-transform:translateZ(100px); opacity:1;
}
p:nth-of-type(2){background-color:#ff4500;
-webkit-transform:rotateX(90deg) translateZ(100px);
}
p:nth-of-type(3){background-color:honeydew;-webkit-transform:rotateX(90deg) translateZ(-100px)}
p:nth-of-type(4){background-color:red;-webkit-transform:rotateY(90deg) translateZ(100px)}
p:nth-of-type(5){background-color:#00bfff;-webkit-transform:rotateY(90deg) translateZ(-100px)}
p:nth-of-type(6){background-color:#ff1493;-webkit-transform:rotateY(90deg) translateZ(-100px)}
.div:hover{
-webkit-transform:rotateX(45deg) rotateY(45deg);
}
</style>
</head>
<body>
<div class="div">
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
</div>
</body>
</html>
上面使用了perspective 属性定义 3D元素距视图的距离。完成之后的效果如下:
以上就是今天的CSS3小动画全部源代码以及效果,刚刚接触,纯属娱乐,不喜勿喷,欢迎大家提出意见~
言:
这次项目用到了一些自定义的数据可视化组件,我把我做的部分抽出来几个典型做个汇总。
分为如下:
星球环绕旋转图
效果展示:
有些图片(例如上面这个 jpg 动图)太大,进行了一定程度的压缩,有点模糊(^_^)。
我的碎碎念(*^3^): 之所以出现两个版本的原因:本来用 svg 实现了一版,结果后来我这个星球的 svg 和同事的其他动画 svg 冲突了(?????????),发生了巨大改变,本身 svg 又臭又长,改的太累,干脆用 css3d 重新画一个了( ′▽`)。
步骤:
//举例一个星球的动画 <animateMotion dur="6s" begin="0" repeatCount="indefinite"> <mpath xlinkHref="#Path-12" /> //轨迹动画 </animateMotion> <animateTransform //自身动画,靠近我的时候星球变大,远离我时变小 id="first" attributeType="XML" attributeName="transform" type="scale" begin="0;second.end " from="1" to="0.512" dur="3s" fill="freeze" /> <animateTransform id="second" attributeType="XML" attributeName="transform" type="scale" begin="first.end" from="0.512" to="1" dur="3s" fill="freeze" /> 作者:溯朝 链接:https://juejin.im/post/5b690a66f265da0f820254bd 来源:掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
参考链接:https://www.jianshu.com/p/2b85973ad1ed
<!-- 轨道 --> <div class="orbit"> <!-- 行星 --> <div class="planet planet1"> <!-- <span class="name"></span> --> </div> <div class="planet planet2"> <!-- <span class="name"></span> --> </div> </div>
.orbit { //轨道旋转,公转 border: 5px solid red; transform-style: preserve-3d; padding: 65px; width: 500px; height: 500px; border-radius: 50%; animation: orbit-rotate 10s linear infinite; } .planet { //星球自转 width: 50px; height: 50px; background: url('../../img/ball1.png') no-repeat; background-size: 100% 100%; border-radius: 50%; animation: self-rotate 10s linear infinite; } // (1)rotateX 是为了让整个面倾斜,translateZ是为了防止椭圆(border)因为倾斜发生锯齿, // (2)停顿效果的产生,其实我是走了野路子的。五个球,根据360/5=72,写了五个不同的关于orbit的class, // 0 + 72,....360依次增加72,直到360,利用setimeout每隔4秒,按顺序切换一个class @keyframes orbit-rotate { 0% { transform: rotateX(70deg) rotateZ(0deg) translateZ(0); } 100% { transform: rotateX(70deg) rotateZ(-360deg) translateZ(0); } } @keyframes self-rotate { 0% { transform: rotateX(-90deg) rotateY(360deg) rotateZ(0deg); } 100% { transform: rotateX(-90deg) rotateY(0deg) rotateZ(0deg); } } .planet1 { //确定星球开始位置 position: absolute; top: 65px; right: 65px; } .planet2 { //确定星球开始位置 position: absolute; bottom: 65px; right: 65px; }
?───O(≧?≦)O────?可爱的分割线?───O(≧?≦)O────?
地图
我的碎碎念(*^3^): 奇葩的需求(?o?;;, 因为甲方认为百度地图等位置不准确,不准使用百度地图和高德地图的api,又不满意天地图的样式,所以我们采用的方案是ui画地图,导出svg,再让前端根据svg做各种效果展示。
步骤:
地图文件如下:index.js主文件包含悬浮事件,index.less样式文件,mapStyle.js存放背景地图,pathStyle.js数组格式存放代表地图上小块的路径
代码如下:
根据接口给的数据,按照五个色系分别给不同的path填充(fill)不同的颜色
const colorMap=[ 'rgba(89, 126, 247, 0.8)', 'rgba(0, 121, 254, 0.8)', 'rgba(0, 121, 254, 0.8)', 'rgba(38, 168, 254, 0.8)', 'rgba(192, 228, 253, 0.8)', ];
render 代码如下:
?───O(≧?≦)O────?可爱的分割线?───O(≧?≦)O────?
二维饼图(风车图)
效果展示:
我的碎碎念(*^3^):因为 echarts 的饼图都是一个参数纬度的饼图,而这次ui要求两个参数纬度的饼图,只能自己画了(′;ω;`)。因为之前用 canvas 画过饼图,本来以为还是简单的,结果甲方爸爸看了成果,说要加自定义悬浮事件(刚开始 prd 没有的),废了3天画了一个够用版的。
步骤:
option.push=[{ color: color[i], //饼图块颜色 radius: item.revenueTaxAvg, //饼图块半径 name: item.domainName, // 饼图块名称 angle: item.companyCnt, //饼图块角度 }];
进行碰撞检测,判断鼠标悬浮是落在哪个弧度的饼图块之间,如果不再饼图块里面悬浮样式消失。
数学里主要判断逻辑如下:
//使用勾股定理计算这个点与圆心之间的距离 distanceFromCenter=Math.sqrt(Math.pow(circle.x - clickX, 2) + Math.pow(circle.y - clickY, 2)) //α(弧度)=L (弧长)/ r(半径),但是弧长,我求不出来。 (点到圆心的直线的角度)的范围我主要使用sin(x),如下方法。 判断不同区间的sin(x)值大小,推断出悬浮区域所在的值是什么。
?───O(≧?≦)O────?可爱的分割线?───O(≧?≦)O────?
三棱锥
效果展示:
步骤:
主要原理:两个三角形 + 一个园=三棱锥
canvas.width=canvas.offsetWidth; //防止图片变形 canvas.height=canvas.offsetHeight; ctx.clearRect(0, 0, canvas.width, canvas.height); 清除画布 const { height }=canvas; // 计算等边三角形的高 //如下图,第一个三角形 A-B-C ctx.moveTo(100, 0); // 从A(100,0)开始 ctx.lineTo(0, height); // 从A(100,0)开始,画到B (0,height)结束 ctx.lineTo(144, height); // B(0,height)-C(144, height) //第二个三角形 A-C-D ctx.moveTo(100, 0); // 从A(100,0)开始 ctx.lineTo(143, height); // A-C ctx.lineTo(210, height); // C-D //第三个画圆 ctx.arc(100, 23 , 23, 0, Math.PI * 2, false); // 画圆 <canvas id={`pyramid${id}`} height={itemHeight} /> //计算itemHeight
对数增长--三棱锥高度(itemHeight)计算:
假设输入 data=[0, 1, 2, 3, 4, 5],x为其中任意值; maxHeight 为最大高度; 输出 itemHeight(0 <=itemHeight< maxHeight),成对数增长 //求最大值 const max=MAX(data) //排除 x===0 的情况 因为logmax(max)=1,且x > 0 由上图可得 0 < logmax(x)< 1 所以 0 < logmax(x) * maxHeight < maxHeight 可知 logmax(x) * maxHeight 成对数变化 又因为logmax(x)=loge(x) / loge(max) //写成代码为 const max=data.reduce((a, b)=> { return a > b ? a : b; }, 0); itemHeight=x===0 ? 0 : Math.log(x) / Math.log(max) * maxHeight
==/* 注意 */==
y 轴计算采用指数增长,因为任意 max 的 0 次方=1, 所以单独判断 i <=0的情况
i > 0 ? Math.round(max ** (i * 0.25)) : 0
长方体
效果展示:
步骤:
html
<div id="cube"> <figure class="front">1</figure> <figure class="back">2</figure> <figure class="right">3</figure> <figure class="left">4</figure> <figure class="top">5</figure> <figure class="bottom">6</figure> </div>
css
#box.show-front { transform: translateZ( -50px ) rotateY( 0deg ); } #box.show-back { transform: translateZ( -50px ) rotateX( -180deg ); } #box.show-right { transform: translateZ( -150px ) rotateY( -90deg ); } #box.show-left { transform: translateZ( -150px ) rotateY( 90deg ); } #box.show-top { transform: translateZ( -100px ) rotateX( -90deg ); } #box.show-bottom { transform: translateZ( -100px ) rotateX( 90deg ); }
增量增长--长方形高度(itemHeight)计算:
//求数据的和 const sum=data.reduce((a, b)=> { return a + b; }, 0); itemHeight=x <=min ? min : min + (max-min) * x /sum;
?───O(≧?≦)O────?可爱的分割线?───O(≧?≦)O────?
总结
我第一次写这么多字的总结技术的文章,排版有点乱,(╯°□°)╯︵ ┻━┻。大部分的内容其实很简单,用到的基本上是初中、高中里面最基础的数学(其实难了,我也不会了φ(??)。
厚着脸皮说,我可能文字功底不咋地,但是每个例子的中心思想应该都表达了。
最后的最后,看在我第一次写了这么多字的份上,给个赞呗(///▽///)。
者:lulu_up
转发链接:https://segmentfault.com/u/lulu_up
*请认真填写需求信息,我们会在24小时内与您取得联系。