http://www.web008.net

美高梅手机版:用CSS和SVG制作饼图

用CSS和SVG制作饼图

2015/08/10 · CSS · SVG

初稿出处: Lea Verou   译文出处:lulux的博客   

在关系到CSS技艺时,未有人会比Lea Verou更执着、可是又丰硕聪明,努力去寻觅难点的种种施工方案。近些日子,Lea自身撰写、设计和出版了一本书——CSS Secrets,那本书那多少个有趣,包含一些CSS小手艺以至解除广大难题的技术。假诺您感觉温馨的CSS工夫还不易,看看那本书,你会吃惊的。在这里篇小说中,我们公布了书里的某些片段,那也被登载在Lea近些日子在SmashingConf New York的发言内容中——用CSS设计简约的饼图。注意,因为浏览器的支撑少数,有个别demo可能还是不能平常运作。——编辑

饼图,固然是最简易的独有三种颜色的样式,用Web本事创设也并不轻易,固然都以黄金年代对不足为道的音讯内容,从轻松的总结到进程条款的还有计时器。平日是使用外界图像编辑器来分别为多个值创立多少个图像来促成,或是使用大型的JavaScript框架来统筹更复杂的图片。

就算那么些事物并不像它早就看起来那么难以完结,可是也还没怎么直接并且轻便的办法。不过,今后早就有相当多更加好、更便于维护的点子来促成它。


基于转换的技术方案


以此方案从HTML的角度来讲是最佳的:它只须求三个成分,此外的都足以用伪成分、转换和CSS渐变完成。我们从上边那几个大概的因素开首:

<div class="pie"></div>

1
<div class="pie"></div>

明天,要是大家期望展现三个 伍分叁 比例的饼图。灵活性的主题素材大家前面再解决。我们先给成分增加样式,让它产生四个圆,也正是大家的背景:

美高梅手机版 1

图1:第一步是先画叁个圆(或许能够说是展现0%比例的饼图卡塔 尔(阿拉伯语:قطر‎

CSS

.pie { width: 100px; height: 100px; border-radius: 50%; background: yellowgreen; }

1
2
3
4
5
.pie {
  width: 100px; height: 100px;
  border-radius: 50%;
  background: yellowgreen;
}

 

我们的饼图是海蓝(特指 yellowgreen 卡塔 尔(英语:State of Qatar)和藕荷色( #655 卡塔尔突显的比重。或许会在比例部分尝试利用 transform 中的 skew ,不过透过三回考试之后证明,那是叁个格外混乱的方案。因而,大家用那二种颜色为那些饼图的左右片段各自着色,然后对于大家想要的百分比,使用旋转的伪成分来兑现。

咱俩运用三个轻便的线性渐变,给右半部分着天蓝:

CSS

background-image: linear-gradient(to right, transparent 50%, #655 0);

1
background-image: linear-gradient(to right, transparent 50%, #655 0);

美高梅手机版 2

图2:用叁个简易的线性渐变给右半圆着紫色

如图2所示,那样就做到了。现在,大家能够世襲为伪成分增多样式,让它产生一个蒙版:

CSS

.pie::before { content: ''; display: block; margin-left: 50%; height: 100%; }

1
2
3
4
5
6
.pie::before {
  content: '';
  display: block;
  margin-left: 50%;
  height: 100%;
}

美高梅手机版 3

图3:虚线内的剧情表示伪成分将用作蒙版的区域

您可以在图3中看出我们的伪元素当前定位相对于我们的pie成分。前段时间,它还从未加多样式,也从不遮掩任何事物,只是多少个晶莹剔透的矩形。在开头增添样式以前,大家先来解析一下:

  • 因为大家盼望它覆盖圆的红铁锈棕部分,大家必要给它接受三个月光蓝的背景,使用 background-color: inherit 来制止重复定义,因为大家自然就可望它和父成分的背景颜色保持生龙活虎致。
  • 咱俩期望它绕着圆的中坚点旋转,中央点在伪成分的左侧,所以大家供给给它的 transform-origin ,应用一个0 二分之一 ,可能是直接一个 left 。
  • 咱俩不想要它是贰个矩形,因为它会超越饼图的边缘,所以大家要求给 .pie 应用 overflow: hidden ,只怕是二个体面的 border-radius 让它成为一个半圆。

总结,伪成分的CSS样式如下:

CSS

.pie::before { content: ''; display: block; margin-left: 50%; height: 100%; border-radius: 0 100% 100% 0 / 50%; background-color: inherit; transform-origin: left; }

1
2
3
4
5
6
7
8
9
.pie::before {
  content: '';
  display: block;
  margin-left: 50%;
  height: 100%;
  border-radius: 0 100% 100% 0 / 50%;
  background-color: inherit;
  transform-origin: left;
}

美高梅手机版 4

图4:加多体制之后的伪成分(这里用虚线表示卡塔 尔(英语:State of Qatar)

只顾:不要采用 class="crayon-syntax crayon-syntax-inline crayon-theme-github crayon-theme-github-inline crayon-font-monaco" style="font-size: 13px !important; line-height: 15px !important;font-size: 13px !important;"> class="crayon-pre crayon-code" style="font-size: 13px !important; line-height: 15px !important;font-size: 13px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;"> class="crayon-e">background class="crayon-sy">: class="crayon-i">inherit class="crayon-sy">; ,要用 id="crayon-5b8f6c8720464547585400" class="crayon-syntax crayon-syntax-inline crayon-theme-github crayon-theme-github-inline crayon-font-monaco" style="font-size: 13px !important; line-height: 15px !important;font-size: 13px !important;"> class="crayon-pre crayon-code" style="font-size: 13px !important; line-height: 15px !important;font-size: 13px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;"> class="crayon-e">background-color class="crayon-sy">: class="crayon-i">inherit ;,否则父成分背景图像上的渐变也会被持续

大家的饼图如今如图4所示。以后始于风趣起来了!大家得以起来旋转伪成分,给它应用叁个rotate() 调换。要来得 四分一 的百分比,大家能够给它三个 72deg ( 0.2 x 360 = 72 卡塔尔国,或 .2turn ,那几个可读性更加好。你能够在图5中来看不一致旋转角度值的结果。

美高梅手机版 5

图5:分别显示不相同比重的饼图,从左到右: 百分之十  ( 36deg 或 .1turn ), 六成  ( 72deg 或  .2turn ), 75%  ( 144deg  或 .4turn )

您或然会想我们早就成功了,不过它可没这么轻易。大家的饼图在展现050%的分寸的开始和结果时是未有此外难点的,可是只要大家要描绘二个十分之四 的转动(通过利用 .6turn 卡塔 尔(阿拉伯语:قطر‎,就能够发生如图6的情事。然则,别思念,我们能够解决这几个工作!

美高梅手机版 6

图6:对于超越二分一的比例,大家的饼图就跪了orz(这里的是十分六卡塔尔

风流倜傥经大家把 六分之三-百分之百 比例的图景作为独立的三个标题,大概会小心到能够接收在此之前的减轻方案的反相版本:从0.5turn旋转的黑褐伪成分。所以,对于二个60%的饼图,伪成分的CSS代码如下:

CSS

.pie::before { content: ''; display: block; margin-left: 50%; height: 100%; border-radius: 0 100% 100% 0 / 50%; background: #655; transform-origin: left; transform: rotate(.1turn); }

1
2
3
4
5
6
7
8
9
10
.pie::before {
  content: '';
  display: block;
  margin-left: 50%;
  height: 100%;
  border-radius: 0 100% 100% 0 / 50%;
  background: #655;
  transform-origin: left;
  transform: rotate(.1turn);
}

美高梅手机版 7

图7: 三成 饼图的不利展开药格局~

您能够在图7中看看结果。因为我们已经制定了二个得以描绘出任何百分比的措施,大家居然可认为饼图从0%100%增添动漫效用,创制出七个相映成趣的进度条:

CSS

@keyframes spin { to { transform: rotate(.5turn); } } @keyframes bg { 50% { background: #655; } } .pie::before { content: ''; display: block; margin-left: 50%; height: 100%; border-radius: 0 100% 100% 0 / 50%; background-color: inherit; transform-origin: left; animation: spin 3s linear infinite, bg 6s step-end infinite; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@keyframes spin {
  to { transform: rotate(.5turn); }
}
 
@keyframes bg {
  50% { background: #655; }
}
 
.pie::before {
  content: '';
  display: block;
  margin-left: 50%;
  height: 100%;
  border-radius: 0 100% 100% 0 / 50%;
  background-color: inherit;
  transform-origin: left;
  animation: spin 3s linear infinite,
             bg 6s step-end infinite;
}

 

See the Pen zGbNLJ by Airen (@airen) on CodePen.

突显未有毛病,但是大家假诺给多少个不等比例的静态饼图增加样式呢,最粗心浮气的用例是?在优异状态下,大家希望能够简轻松单地输入如下的剧情:

<div class="pie">20%</div> <div class="pie">60%</div>

1
2
<div class="pie">20%</div>
<div class="pie">60%</div>

接下来就能够获取三个饼图,二个代表20%,三个意味60%。首先,大家先斟酌一下怎样使用内联样式来达成,然后大家得以写叁个简约的台本来深入分析文本内容,对应地加上内联样式,並且要代码高雅、封装、可维护性,还应该有最注重的少数,可访问性。

运用内联样式调整饼图百分比的三个不方便是:用于安装百分比CSS代码是用伪成分完毕的。并且你也亮堂,大家无法给伪成分设置内联样式,所以大家需要更新。

瞩目:若是您想要使用的值是在有个别无需通过再一次的繁琐的构思的界定内的景况,你能够使用同风姿洒脱的本领,饱含透过它们一步一步调节和测量试验动漫的情事。看该本事的三个总结的事必躬亲。

 

See the Pen YXgNOK by Airen (@airen) on CodePen.

除恶务尽方案来自最非常小概的地点之风流罗曼蒂克。咱们将在利用大家早就介绍过的卡通片,然则它是搁浅状态的。大家不会让它像三个正常的动漫片那样运维,大家将应用负延迟来让它能够静态地暂停在有个别点。很古怪?二个负的animation-delay的值不仅仅在正规中是同意的,在相近那样的案例中也是相当好用:

负延迟是行得通的。和0s的推移相近,它意味着动漫将即时实施,不过是依据延迟的相对值来自动运转的,所以假诺动漫已经在钦点的日子早先就开首运营了,那它就能一直从active的光阴中途运维。 —CSS Animations Level 1

因为大家的卡通片是暂停的,它的第生龙活虎帧就是我们唯豆蔻梢头显示的那生机勃勃帧(通过大家的animation-delay概念卡塔 尔(英语:State of Qatar)。饼图上呈现的比例将会是大家的animation-delay的总时间。比方,当前的持续时间是6s,我们的 animation-delay 值为-1.2s则显示20%的比重。为了简化总结,大家设置叁个100s的持续时间。记住因为大家的动画是永远暂停的,我们给它钦赐的推移大小并不会有啥影响。

再有最终三个主题素材:动漫是赋给伪成分的,然而大家想要给.pie要素设置内联样式。因为<div>上并未动漫,大家得以给它设置animation-delay作为内联样式,然后给伪成分应用 animation-delay: inherit; 。简单来说,20%60%的饼图的HTML代码如下:

<div class="pie" style="animation-delay: -20s"></div> <div class="pie" style="animation-delay: -60s"></div>

1
2
<div class="pie" style="animation-delay: -20s"></div>
<div class="pie" style="animation-delay: -60s"></div>

正巧提出的那么些动漫的CSS代码如下(省略 .pie 准则,因为尚未变动卡塔尔:

CSS

@keyframes spin { to { transform: rotate(.5turn); } } @keyframes bg { 50% { background: #655; } } .pie::before { /* [Rest of styling stays the same] */ animation: spin 50s linear infinite, bg 100s step-end infinite; animation-play-state: paused; animation-delay: inherit; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@keyframes spin {
  to { transform: rotate(.5turn); }
}
 
@keyframes bg {
  50% { background: #655; }
}
 
.pie::before {
  /* [Rest of styling stays the same] */
  animation: spin 50s linear infinite, bg 100s step-end infinite;
  animation-play-state: paused;
  animation-delay: inherit;
}

那会儿,能够把HTML标签改成接收比例作为内容,和黄金年代起始期望的同样,然后经过一个大约的脚本为其添加animation-delay 内联样式。

JavaScript

$$('.pie').forEach(function(pie) { var p = parseFloat(pie.textContent); pie.style.animationDelay = '-' + p + 's'; });

1
2
3
4
$$('.pie').forEach(function(pie) {
  var p = parseFloat(pie.textContent);
  pie.style.animationDelay = '-' + p + 's';
});

美高梅手机版 8

图8:未有掩没文本前的图

  • 把饼图的height改变来 line-height (或加上三个和height值十一分的line-height,不过这值是毫无意义的双重代码,因为line-height会自动总括height的值)。
  • 透过相对定位给伪成分设置大小和职分,那样它不会把公文挤下去。
  • 累计 text-align: center; 让文本水平居中。

聊起底的代码如下:

CSS

.pie { position: relative; width: 100px; line-height: 100px; border-radius: 50%; background: yellowgreen; background-image: linear-gradient(to right, transparent 50%, #655 0); color: transparent; text-align: center; } @keyframes spin { to { transform: rotate(.5turn); } } @keyframes bg { 50% { background: #655; } } .pie::before { content: ''; position: absolute; top: 0; left: 50%; width: 50%; height: 100%; border-radius: 0 100% 100% 0 / 50%; background-color: inherit; transform-origin: left; animation: spin 50s linear infinite, bg 100s step-end infinite; animation-play-state: paused; animation-delay: inherit; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
.pie {
  position: relative;
  width: 100px;
  line-height: 100px;
  border-radius: 50%;
  background: yellowgreen;
  background-image: linear-gradient(to right, transparent 50%, #655 0);
  color: transparent;
  text-align: center;
}
 
@keyframes spin {
  to { transform: rotate(.5turn); }
}
@keyframes bg {
  50% { background: #655; }
}
 
.pie::before {
  content: '';
  position: absolute;
  top: 0; left: 50%;
  width: 50%; height: 100%;
  border-radius: 0 100% 100% 0 / 50%;
  background-color: inherit;
  transform-origin: left;
  animation: spin 50s linear infinite, bg 100s step-end infinite;
  animation-play-state: paused;
  animation-delay: inherit;
}

 

See the Pen qdvRMv by Airen (@airen) on CodePen.

The problem

饼图,四处可知,不过真正去落实,依然要下点武功的。
例如我们要创立二个速度提醒器,大概计时显示屏,平常涉及使用外界图像编辑器为饼图的多个值创制图像,或选拔js脚本设计尤为复杂的图纸。

今昔有其余越来越好的方法去达成。

依赖SVG的缓慢解决方案


SVG使得众多图纸职业变得特别简便易行,饼图也不例外。不过,用path渠道创立饼图,须求复杂的数学总计,我们得以行使一些小手艺来代表。

大家从四个圆开端:

<svg width="100" height="100"> <circle r="30" cx="50" cy="50" /> </svg>

1
2
3
<svg width="100" height="100">
<circle r="30" cx="50" cy="50" />
</svg>

前几日,给它应用有的幼功的样式:

CSS

circle { fill: yellowgreen; stroke: #655; stroke-width: 30; }

1
2
3
4
5
circle {
  fill: yellowgreen;
  stroke: #655;
  stroke-width: 30;
}

静心:你大概清楚,那个CSS属性也足以视作SVG元素的习性使用,要是把可移植性考虑在内的话那也许挺实惠的。

美高梅手机版 9

图9:从三个煤黑的SVG圆形,带二个胖胖的#655描边发轫

你能够在图9中看出我们绘制的加了描边的圆。SVG描边不唯有strokestroke-width属性。还应该有许多不是特意流行的描边相关的性质能够用来对描边举办微调。在那之中二个是stroke-dasharray,用于成立虚线描边。举例,大家得以选择如下:

CSS

stroke-dasharray: 20 10;

1
stroke-dasharray: 20 10;

美高梅手机版 10

图10:三个精练的虚线描边,通过stroke-dasharray性格创建

那行代码的野趣是大家的虚线是20的尺寸加上10的边距,如图10所示。在这里间,你大概会好奇那么些SVG描边属性和饼图毕竟有啥样关联吧。若是我们给描边应用一个值为0的虚线宽度,和一个大于或等于大家日前圆的周长的边距,它大概就清楚一些了(总括周长: C = 2πr , 所以在这里间  C = 2π × 30 ≈ 189 卡塔 尔(英语:State of Qatar):

CSS

stroke-dasharray: 0 189;

1
stroke-dasharray: 0 189;

美高梅手机版 11

图11:不同stroke-dasharray值对应的功效;从左到右: 0 189; 40 189; 95 189; 150 189 

如图1第11中学的第壹个圆所示,它的描边的都被移除了,只剩余八个暗黄的圆。但是,当我们起头增大第壹个值的时候,有趣的事情时有产生了(图11卡塔 尔(阿拉伯语:قطر‎:因为边距太长,大家就从不虚线描边了,独有叁个描边覆盖了大家钦定的圆的周长的比例。

你恐怕已经起来弄驾驭了那是怎么回事:假诺大家把圆的半径减小到自然水平,它恐怕就能够全盘被它的描边覆盖,最终收获的是一个可怜相同于饼图的事物。例如,你能够在图1第22中学看出:当给圆应用一个25的半径和多个50stroke-width,像上边包车型客车功效:

美高梅手机版 12

图12:大家的SVG图像开首像三个饼图了O(∩_∩)O

铭记:SVG描边总是相对于成分边缘四分之二在内八分之四在外的(居中的卡塔 尔(英语:State of Qatar)。以后应有能够操纵这一表现。

<svg width="100" height="100"> <circle r="25" cx="50" cy="50" /> </svg> circle { fill: yellowgreen; stroke: #655; stroke-width: 50; stroke-dasharray: 60 158; /* 2π × 25 ≈ 158 */ }

1
2
3
4
5
6
7
8
9
10
<svg width="100" height="100">
  <circle r="25" cx="50" cy="50" />
</svg>
 
circle {
  fill: yellowgreen;
  stroke: #655;
  stroke-width: 50;
  stroke-dasharray: 60 158; /* 2π × 25 ≈ 158 */
}

前段时间,把它成为大家在上一个缓慢解决方案中成立的饼图的表率是特别轻巧的:我们只须要在描边上面增加一个更加大的深蓝圆形,然后逆时针转动90°,那样它的源点就在最上端中间。因为<svg>要素也是HTML成分,大家能够给它助长样式:

CSS

svg { transform: rotate(-90deg); background: yellowgreen; border-radius: 50%; }

1
2
3
4
5
svg {
  transform: rotate(-90deg);
  background: yellowgreen;
  border-radius: 50%;
}

美高梅手机版 13

图13:最后的SVG饼图

您能够在图第13中学观望最终结果。这种手艺能够让饼图更便于实现从0%100%变动的动画。大家只供给创建叁个CSS动漫,让stroke-dasharray从 0 158 变成 158 158 :

CSS

@keyframes fillup { to { stroke-dasharray: 158 158; } } circle { fill: yellowgreen; stroke: #655; stroke-width: 50; stroke-dasharray: 0 158; animation: fillup 5s linear infinite; }

1
2
3
4
5
6
7
8
9
10
11
@keyframes fillup {
  to { stroke-dasharray: 158 158; }
}
 
circle {
  fill: yellowgreen;
  stroke: #655;
  stroke-width: 50;
  stroke-dasharray: 0 158;
  animation: fillup 5s linear infinite;
}

作为二个非常的改过,大家得以在圆上钦赐一个一定半径,使其周长Infiniti贴近100,那样我们得以用百分比钦赐stroke-dasharray的长度,而不必要做总结。因为周长是2πr,大家的半径则是100 ÷ 2π ≈ 15.915494309,约等于16。大家还足以用viewBox特点钦定SVG的尺寸,能够让它自动调解为容器的轻重缓急,不要采纳widthheight属性。

经过上述调治,图13的饼图的HTML标签如下:

<svg viewBox="0 0 32 32"> <circle r="16" cx="16" cy="16" /> </svg>

1
2
3
<svg viewBox="0 0 32 32">
  <circle r="16" cx="16" cy="16" />
</svg>

CSS如下:

CSS

svg { width: 100px; height: 100px; transform: rotate(-90deg); background: yellowgreen; border-radius: 50%; } circle { fill: yellowgreen; stroke: #655; stroke-width: 32; stroke-dasharray: 38 100; /* for 38% */ }

1
2
3
4
5
6
7
8
9
10
11
12
13
svg {
  width: 100px; height: 100px;
  transform: rotate(-90deg);
  background: yellowgreen;
  border-radius: 50%;
}
 
circle {
  fill: yellowgreen;
  stroke: #655;
  stroke-width: 32;
  stroke-dasharray: 38 100; /* for 38% */
}

只顾现行反革命比例已经得以很平价地转移了。当然,纵然已经简化了标签,大家还是不想在绘制各样饼图的时候都再也一遍全数这个SVG标签。那是时候拿出JavaScript来帮大家生龙活虎把了。大家写一个回顾的台本,让大家的HTML标签直接省略地那样写:

<div class="pie">20%</div> <div class="pie">60%</div>

1
2
<div class="pie">20%</div>
<div class="pie">60%</div>

接下来在种种.pie要素里边增添三个内联SVG,满含全部需求的成分和个性。它还恐怕会增加叁个<title>要素,为了增添可访问性,那样荧屏阅读器顾客还足以知晓当前的饼图表示的百分比。最终的剧本如下:

JavaScript

$$('.pie').forEach(function(pie) { var p = parseFloat(pie.textContent); var NS = ""; var svg = document.createElementNS(NS, "svg"); var circle = document.createElementNS(NS, "circle"); var title = document.createElementNS(NS, "title"); circle.setAttribute("r", 16); circle.setAttribute("cx", 16); circle.setAttribute("cy", 16); circle.setAttribute("stroke-dasharray", p + " 100"); svg.setAttribute("viewBox", "0 0 32 32"); title.textContent = pie.textContent; pie.textContent = ''; svg.appendChild(title); svg.appendChild(circle); pie.appendChild(svg); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$$('.pie').forEach(function(pie) {
  var p = parseFloat(pie.textContent);
  var NS = "http://www.w3.org/2000/svg";
  var svg = document.createElementNS(NS, "svg");
  var circle = document.createElementNS(NS, "circle");
  var title = document.createElementNS(NS, "title");
  circle.setAttribute("r", 16);
  circle.setAttribute("cx", 16);
  circle.setAttribute("cy", 16);
  circle.setAttribute("stroke-dasharray", p + " 100");
  svg.setAttribute("viewBox", "0 0 32 32");
  title.textContent = pie.textContent;
  pie.textContent = '';
  svg.appendChild(title);
  svg.appendChild(circle);
  pie.appendChild(svg);
});

正是它了!你大概会感觉CSS方法比较好,因为它的代码比较轻巧并且更可靠。不过,SVG方法相比较纯CSS方案可能有一定的优势的:

  • 可以特别轻巧地丰裕第二种颜色:只供给丰裕另叁个描边圆,然后利用stroke-dashoffset安装它的描边属性。然后,将它的描边长度增添到下方的圆的描边长度上。假使是前边那二个CSS的方案,你要哪些给饼图增添第三种颜色吗?
  • 咱俩无需寻思打字与印刷的难题,因为SVG成分就像<img>要素同样,被默以为是内容的风度翩翩部分,打印完全未有毛病。第大器晚成种方案决定于背景,所以不会被打字与印刷。
  • 小编们能够选用内联样式退换颜色,也正是说大家能够通过脚本就直接改造颜色(如,依照顾客输入改造颜色卡塔尔国。第生龙活虎种方案依赖于伪元素,除了通过接二连三,它并未有其它方法能够增加内联样式,那特别不便利。

See the Pen oXVBar by Airen (@airen) on CodePen.

transform solution

先是,我们来画八个圆:

<pre>
.pie {
width: 100 px;
height: 100 px;
border-radius: 50 %;
background: yellowgreen;
}
</pre>

美高梅手机版 14

既是是饼图,举个例子双色饼图,就须求另大器晚成种颜色来展现速度,再画一个半圆:

能够用渐变来做:

background-image: linear-gradient(to right, transparent 50%, #655 0);

美高梅手机版 15

我们还亟需创立二个遮罩层:虚线部分。

<pre>
.pie::before {
content: '';
display: block;
margin-left: 50%;
height: 100%;
border-radius: 0 100% 100% 0 / 50%;
background-color: inherit;
transform-origin: left;
}
</pre>

创设好了,不过有几点要潜心的地点:

  • 因为大家想让那么些层盖住肉色的某些,所以大家得以给它加个铁黄的背景,也足以用
    <pre>
    background-color: inherit;
    </pre>来幸免重新证明。

  • 旋转的中央点是圆心,我们能够如此表明:
    <pre>
    transform-origin: left;
    //或者
    transform-origin: 0 50%;
    </pre>

  • 我们创造遮罩层的目标是盖住棕褐的那某个,它需假使个半圆,不过大家现在写的是个矩形,所感觉了制止侧漏,大家用border-radius 让它也改成半圆:

<pre>
border-radius: 0 100% 100% 0 / 50%;
</pre>

遮罩层也就就绪了,现在给叁个转悠角度省视:

<pre>
.pie::before {
content: '';
display: block;
margin-left: 50%;
height: 100%;
border-radius: 0 100% 100% 0 / 50%;
background: #655;
transform-origin: left;
transform: rotate(.1turn);
}
</pre>

美高梅手机版 16

旋转36度

现行反革命加点动漫让它动起来:

<pre>
@keyframes spin {
to {
transform: rotate(.5turn)
}
}

@keyframes bg {
50% {
background: #655
}
}

.pie::before {
content: '';
display: block;
margin-left: 50%;
height: 100%;
border-radius: 0 100% 100% 0/50%;
background-color: inherit;
transform-origin: left;
animation: spin 3s linear infinite,bg 6s step-end infinite
}

</pre>

点击查阅:
http://dabblet.com/gist/722909b9808c14eb7300

于今先是步好了,更进一层,动脑,假使大家在html中定义百分数,就会显得相应的比重,那简直是不能更加好了。
就疑似这么定义:
<pre>
<div class="pie">20%</div>
<div class="pie">60%</div>
</pre>

美高梅手机版 17

就如这么

二个出示75%,另三个出示四分三 .

首先,我们探求能或不可能用行内样式,然后用豆蔻梢头段脚本去剖析。

回头想生龙活虎想:大家是要调节伪成分的转动度数来显示百分比的,那难点来了(开采机技能哪家强。。XD卡塔尔,大家万般无奈直接给伪成分增多行内样式...怎么做吧?

The solution comes from one of the most unlikely places.

我们刚刚定义了动漫,未来它该停停了。

我们将选择animation的delay 来兑现,与常规的选拔不相同的是,大家将应用负数 让它停在大家定义的地点。很吸引是或不是,animation-delay 的参数为负数,那是不相符标准的,可是在有个别景况下,它是很有用的,看描述:

“A negative delay is valid. Similar to a delay of 0s, it means that the ani-mation executes immediately, but is automatically progressed by the ab-solute value of the delay, as if the animation had started the specifiedtime in the past, and so it appears to start partway through its activeduration.”
— CSS Animations Level 1 (w3.org/TR/css-animations/#animation-delay)

因为动漫被定义为pause 的时候,只会显示第大器晚成帧。

那会儿,展现在饼图上的百分比正是大家定义的延迟时间占总体动漫时间的比例。

诸如,大家的动漫片持续时间是6s, 延迟时间是-1.2s, 就能够显得 五分之三 ;
为了看起来方便,大家定义整个动漫的持续时间为100s。

因为动漫是有序的,所以设置多大的推迟是不会有此外影响的。

事例走起:

<pre>
<div class="pie" style="animation-delay: -20s"></div>
<div class="pie" style="animation-delay: -60s"></div>
</pre>

CSS 规则:
<pre>
@keyframes spin {
to {
transform: rotate(.5turn);
}
}

@keyframes bg {
50% {
background: #655;
}
}

.pie::before {
/* [Rest of styling stays the same] */
animation: spin 50s linear infinite,
bg 100s step-end infinite;
animation-play-state: paused;
animation-delay: inherit;
}
</pre>

<pre>
$$('.pie').forEach(function(pie) {
var p = pie.textContent;
pie.style.animationDelay = '-' + parseFloat(p) + 's';
});
</pre>

美高梅手机版 18

大家几天前不想看看这么些比重,如何是好呢?

<pre>
color: transparent;
</pre>

如此那般字体就看不到了,可是照旧是可以选大壮打字与印刷的。
此外,我们得以让这几个百分比居中,制止它被入选时,出今后其他地点。

几点注意的地点:

  • 为了完毕垂直居中,大家能够:

<pre>
height:100px;
line-height:100px;
</pre>

唯独如此的代码是双重的,只写line-height 就好。

Convert height to line-height (or add a line-height equal to the height, but that’s pointless code duplication, because line- height would set the computed height to that as well ).

  • 给伪成分 相对定位,防止字飞出去。
  • text-align:center; 实现程度居中。

末尾的代码是那般的:

<pre>

.pie {
opacity: 1;
width: 100px;
height: 100px;
border-radius: 50%;
background-color: yellowgreen;
background-image: linear-gradient(to right ,transparent 50% , #655 0);
}

@keyframes spin {
to {
transform: rotate(.5turn);
}
}

@keyframes bg {
50% {
background: #655;
}
}

.pie::before {
/* [Rest of styling stays the same] */
animation: spin 50s linear infinite,
bg 100s step-end infinite;
animation-play-state: paused;
animation-delay: inherit;
}
</pre>

在线查看:http://scaukk.github.io/css/static_pie_chart.html

理所当然,还是能够用svg 实现,篇幅有限,这里就背着了。


题外话:

那是张鑫旭 从前做的 摊鸡蛋饼 动漫 XD
http://www.zhangxinxu.com/wordpress/2014/04/css3-pie-loading-waiting-animation/

既然 饼图小编都写好了,干脆写点动漫,也摊个鸡蛋饼。
原理大约,风野趣的能够看看。
访谈地址:

http://scaukk.github.io/css/pie.html


正文内容差不离就那样多,接待调换,接待举报,如有错误,还请修改,谢谢阅读。

郑重声明:本文版权归美高梅163888所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。