当前位置: 首页 > Web前端 > CSS

CSS3实现直方图的3D动画效果

时间:2023-03-30 13:38:37 CSS

首先我们来看一下要实现的效果:本文实现的动画效果源于一个小idea,来自另一个网站的一篇文章,描述了如何使用CSS、图像和JavaScript在网页中创建三维直方图。读完那篇文章后,我想接受挑战,尝试使用纯CSS实现同样的效果。一开始的难点是创建一个六边形的半透明立方体,后来的难点是如何创建一个完整的带有动画效果的3D直方图。接下来,让我们看看如何解决这些困难。让我们首先列出一些要实现的要求。我们实现的直方图应该是:背景无关(即直方图和背景互不影响)自适应(列数不会影响布局)可扩展(如矢量图一样)易于定制(颜色,大小和比例)规划是任何项目中最重要的部分之一。所以我们必须先制定一个计划。在实际编码之前,我通常会列出我将在项目中遇到的潜在挑战以及这些挑战的解决方案,然后重复这个过程,直到我得到一些看起来像执行策略的东西。以下是我为这个项目提出的挑战和解决方案的列表:挑战1-具有可扩展内核的列我们知道直方图是由6个面组成的三维图形。这个直方图的内核是垂直可扩展的,并且有一个隐藏它的选项所以,我们需要:一个生成直方图的三个边(后、下、左)的div一个生成直方图的其他三个边的div(front,top,right)一个div,生成核心圆柱体的三个面,和上面第二个div类似,但是它的z-index值小了一个div,作为容器,用来定位上面三个组件,并在右下角实现一个纯色背景的div和一个带有overflow:hidden的容器,用来在核心列高度为0时隐藏。一共有五个div。您可能想知道为什么我们需要两个容器?好吧,这是一个很难解释的问题,但我会尽力把它说清楚。我们需要每列至少一个容器(以保持前三个div到位),并且由于我们的列核心是可扩展的,所以我们使用百分比来操纵核心的高度,这要求容器的高度等于bar图形Y轴的高度。这看起来不错,但是,还有另一个问题,应该有一个隐藏移动内核的选项,这意味着它应该在“低于栏”并隐藏。你可能会说有一个解决方法——overflow:hidden,是的,但是它对这里的容器不起作用,因为它的高度会比实际的列高短,这就是我们添加另一个容器的原因。希望我说清楚了,让我们继续。挑战2——坐标轴坐标轴应该:是一个三维坐标轴,包含3个面(背景面、X轴面、Y轴面)以及面的个数和属性(宽、高等)背景独立自适应圆柱体外面有X轴和Y轴的文本标签所以,我们需要:一个无序列表X轴标签每个列表项有一个span元素每个列表项有一个列Y轴标签包含一个无序列表实现现在我们有了一个总体规划,让我们将其转化为代码。请注意,文章中的代码没有写浏览器前缀。实际工程中请不要遗漏。挑战1-具有可拉伸核心的柱子??

50
??
我们再回顾一下每个元素的用途:bar-wrapper–当.bar-inner滑动时隐藏到柱子底部bar-container–作为.bar-foreground,.bar-inner,.bar-foreground定位的参考元素,并设置底角的背景色bar-background–生成三个条形图面(back,bottom,left)bar-inner-最重要的部分-柱状图的核心bar-foreground-生成条形图的其他三个边(front,top,right)首先,让我们为容器设置样式。/*Barwrapper容器-当核心低于条形高度时隐藏核心,必需*/.bar-wrapper{overflow:hidden;}/*Barcontainer-这个家伙是条形图的真正父级-child元素相对于它定位。*/.bar-container{位置:相对;顶部边距:2.5em;width:12.5em;}/*右下角的小块-确保当核心向下滑动时右下角被“切割”*/.bar-container:before{content:"";位置:绝对;z-指数:3;底部:0;右:0;宽度:0;高度:0;边框样式:实心;边框宽度:002.5em2.5em;border-color:transparenttransparentrgba(183,183,183,1);}请注意,我们将.bar-container的宽度设置为12.5em。这个数字是圆柱体前宽和右宽的总和——在我们的例子中是10+2.5=12.5。我们还使用border属性创建一个三角形并将其放置在.bar-container的右下角,以确保在垂直移动时核心的边被“切割”。我们使用:before伪类来生成这个元素。让我们设置.bar-background:/*back*/.bar-background{width:10em;高度:100%;位置:绝对;顶部:-2.5em;左:2.5em;z-index:1;}.bar-background:before,.bar-background:after{content:"";position:absolute;}/*bottomsurface*/.bar-background:before{bottom:-2.5em;右:1.25em;宽度:10em;高度:2.5em;transform:skew(-45deg);}/*leftback*/.bar-background:after{top:1.25em;右:10em;宽度:2.5em;高度:100%;/*仅倾斜Y轴*/transform:skew(0deg,-45deg);}如您所见,我们将.bar-background向上和向右移动了2.5em。当然,我们将左后背和底面倾斜45度。请注意,:after伪元素将第一个倾斜值设置为0deg,将第二个倾斜值设置为-45度,这仅倾斜元素的Y轴。接下来,在*/.bar-foreground{z-index:3;前面设置.bar-foreground:/*/*在.bar-background和.bar-inner之上*/}.bar-foreground,.bar-inner{position:absolute;宽度:10em;高度:100%;顶部:0;left:0;}.bar-foreground:before,.bar-foreground:after,.bar-inner:before,.bar-inner:after{content:"";position:absolute;}/*右前*/.bar-foreground:before,.bar-inner:before{top:-1.25em;右:-2.5em;宽度:2.5em;高度:100%;背景色:rgba(160,160,160,.27);transform:skew(0deg,-45deg);}/*front*/.bar-foreground:after,.bar-inner:after{top:-2.5em;右:-1.25em;宽度:100%;高度:2.5em;背景色:rgba(160,160,160,.2);transform:skew(-45deg);}这里没有什么新东西,所有的样式都和.bar-background一样,只是方向不同。其中,有些样式同时应用于.bar-foreground和.bar-inner元素,因为它们看起来完全一样。好了,我们继续设置内核的样式。.bar-inner{z-index:2;/*在.bar-background之上*/top:auto;/*重置顶部属性*/background-color:rgba(5,62,123,.6);高度:0;底部:-2.5em;颜色:透明;/*隐藏文本*/transition:height1slinear,bottom1slinear;}/*rightside*/.bar-inner:before{background-color:rgba(5,62,123,.6);}/*Above*/.bar-inner:after{background-color:rgba(47,83,122,.7);}好了,bar的样式设置好了,接下来我们看坐标轴。挑战2-坐标轴
  • 2011<--此处为直方图的HTML标记-->
  • 2012<--此处为直方图的HTML标记-->
  • 25%
  • 50%
  • 75%
  • 100%
  • 如您所见,我们在项目中使用无序列表和span元素来定位X轴和Y轴标签。/**坐标轴容器**/.graph-container{position:relative;显示:内联块;填充:0;列表样式:无;/*移除列表元素附带的小黑点*//*背景*/background-image:linear-gradient(left,rgba(255,255,255,.3)100%,transparent100%);背景重复:不重复;background-position:0-2.5em;}here一个小点,我们用线性渐变填充容器背景,然后抬高2.5em,为什么呢?因为轴的底部(我们将在下一个样式中设置)是2.5em高。并且轴倾斜了45度,所以右下角有一个空白区域。轴的X轴样式:/*X-axis*/.graph-container:before{position:absolute;内容:””;底部:0;左:-1.25em;/*倾斜会将它向左推,所以我们将它向相反的方向移动一点。*/宽度:100%;/*确保它和整个组件一样宽*/height:2.5em;背景色:rgba(183,183,183,1);变换:倾斜(-45deg);}我们让它倾斜45度,然后向左移动一点以确保它在正确的位置。轴的Y轴样式:/*Yaxis*/.graph-container:after{position:absolute;内容:””;顶部:1.25em;/*倾斜将它向上推,所以我们将它向下移动一点。*/左:0em;宽度:2.5em;背景色:rgba(28,29,30,.4);transform:skew(0deg,-45deg);}这里没什么特别的。也将元件倾斜45度并将其向下推一点以便正确定位。坐标轴的基本设置就是这些,接下来我们继续设置列表项中的样式:.graph-container>li{float:left;/*横向排列*/position:relative;}.graph-container>li:nth-last-child(2){margin-right:2.5em;}/*X轴的文本标签*/.graph-container>li>span{position:absolute;左:0;底部:-2em;宽度:80%;文本对齐:居中;字体大小:1.5em;color:rgba(200,200,200,.4);}这里有两点需要注意。首先,我们使用浮动来水平对齐条形图。一般来说,浮动应该非常小心地使用,它会导致布局问题,如高度崩溃。所以,这里可以尝试改成display:inline-block来实现。其次,我们在最后一个栏中添加一些右边距。这样我们就可以确保为轴的底部提供足够的空间,尝试将其移除,您就会明白我的意思。好的,我们差不多完成了。最后要做的是为Y轴添加文本标签。/*文本标记容器*/.graph-container>li:last-child{width:100%;位置:绝对;左:0;bottom:0;}/*Y轴文本标记列表*/.graph-marker-container>li{position:absolute;左:-2.5em;底部:0;宽度:100%;底部边距:2.5em;list-style:none;}/*Y轴线正常样式*/.graph-marker-container>li:before,.graph-marker-container>li:after{content:"";位置:绝对;边框样式:无无点缀;边框颜色:rgba(100,100,100,.15);边框宽度:00.15em;background:rgba(133,133,133,.15);}/*Y轴侧线*/.graph-marker-container>li:before{width:3.55em;高度:0;底部:-1.22em;左:-.55em;z-指数:2;transform:rotate(-45deg);}/*Y轴背景线*/.graph-marker-containerli:after{width:100%;底部:0;left:2.5em;}/*Y轴文本标签*/.graph-marker-containerspan{color:rgba(200,200,200,.4);位置:绝对;顶部:1em;左:-3.5em;宽度:3.5em;font-size:1.5em;}正如你所看到的,我们将文本标记容器的宽度设置为100%,让背景线覆盖对于整个坐标轴,使用虚线边框设置Y轴线的样式,定位span元素,使文本标签位于坐标轴外。使用:before和:after伪元素可以减少HTML代码量并保持页面整洁。至此,我们已经完成了条形图的所有样式设置,但是我们缺少一些重要的变量-大小、颜色和条形填充值!上面说了我们的图表是可以定制的,所以,我决定不把变量和其他代码混在一起,这样大家定制起来更方便。/****************Size******************//*graph的整体大小*/.graph-container,.bar-container{font-size:8px;}/*列的高度*/.bar-container,.graph-container:after,.graph-container>li:last-child{height:40em;}/******************间距******************//*列之间的间距*/.graph-容器>李。bar-container{margin-right:1.5em;}/*第一个bar的左边距*/.graph-container>li:first-child{margin-left:1.5em;}/*最后一个bar的右边距*/.graph-container>li:nth-last-child(2).bar-container{margin-right:1.5em;}/******************颜色******************//*bar的背景颜色*/.bar-background{background-color:rgba(160,160,160,.1);}/*bar的底部颜色*/.bar-background:before{background-color:rgba(160,160,160,.2);}/*bar的左侧背景颜色*/.bar-background:after{background-color:rgba(160,160,160,.05);}/*bar的正面颜色*/.bar-foreground{background-color:rgba(160,160,160,.1);}/*内部颜色*/.bar-inner,.bar-inner:before{background-color:rgba(5,62,123,.6);}.bar-inner:after{背景色:rgba(47,83,122,.7);}/****************************************内核高度********************************************/.graph-container>li:nth-child(1).bar-inner{高度:25%;底部:0;}.graph-container>li:nth-child(2).bar-inner{高度:50%;底部:0;}.graph-container>li:nth-child(3).bar-inner{高度:75%;底部:0;在下载的源代码中,你不会找到这部分代码,因为我在那里做了一些更有趣的事情——我使用单选按钮让你在不修改代码的情况下使用变量,但如果你只需要自定义一个静态图,那么就拿代码片段从上面,并根据自己的喜好对其进行自定义。总结让我们回顾一下本文中涉及的一些CSS规范/技术。transform:skew()和transform:rotate()用于对元素进行倾斜和旋转,两者结合使元素模拟产生三维效果。:before和:after伪元素保持HTML标记相对干净:nth-??last-child()和:not是特定于列表项的伪类,可以避免向HTML添加额外的类/id。linear-gradient和background-position可以一起使用来填充部分背景。rgba()可用于实现具有透明度的颜色。border属性可以创建一个三角形。最后,获取直方图的三维动画效果源码,可以: