CSS 饼图动画从 40% 到 60%
CSS pie chart animation from 40% to 60%
我尝试在 CSS 中制作一个动态饼图,它工作得很好,除非我想从小于 50% 到大于 50% 设置动画,反之亦然。
这是一个代码笔(我没有找到如何在堆栈工具中使用 SCSS):http://codepen.io/mbrillaud/pen/NNgqYE
有什么技巧可以避免这种影响吗?
HTML
<div class="wrapper">
<div class="pie percent-10" id="pie"></div>
<div class="border"></div>
</div>
<div class="buttons">
<button data-value="10">10%</button>
<button data-value="20">20%</button>
<button data-value="30">30%</button>
<button data-value="40">40%</button>
<button data-value="50">50%</button>
<button data-value="60">60%</button>
<button data-value="70">70%</button>
<button data-value="80">80%</button>
<button data-value="90">90%</button>
<button data-value="100">100%</button>
</div>
CSS
@import 'compass';
body {
background-color: #2c333b;
}
.wrapper {
position: absolute;
top: 50%;
left: 50%;
width: 100px;
@include transform(translate(-50%, -50%));
.pie,
.border {
box-sizing: border-box;
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
border-radius: 50%;
}
.pie {
background-color: #FDDED9;
background-image: linear-gradient(to right, transparent 50%, #ff4081 0);
&::before {
content: '';
display: block;
top: 0;
left: 50%;
width: 50%;
margin-left: 50%;
height: 100%;
border-radius: 0 100% 100% 0 / 50%;
background-color: inherit;
transform-origin: left;
transition: transform .2s linear;
}
&.percent-10::before {
transform: rotate(.1turn);
}
&.percent-20::before {
transform: rotate(.2turn);
}
&.percent-30::before {
transform: rotate(.3turn);
}
&.percent-40::before {
transform: rotate(.4turn);
}
&.percent-50::before {
transform: rotate(.5turn);
}
&.percent-60::before {
transform: rotate(.1turn);
background-color: #ff4081;
}
&.percent-70::before {
transform: rotate(.2turn);
background-color: #ff4081;
}
&.percent-80::before {
transform: rotate(.3turn);
background-color: #ff4081;
}
&.percent-90::before {
transform: rotate(.4turn);
background-color: #ff4081;
}
&.percent-100::before {
transform: rotate(.5turn);
background-color: #ff4081;
}
}
.border {
border: 5px solid #FDDED9
}
}
JS
$(document).ready(function() {
var $pie = $('#pie'),
className;
$('button').on('click', function() {
className = $pie.attr('class').match(/percent[\w-]*\b/);
$pie
.removeClass(className[0])
.addClass('percent-' + $(this).data('value'));
});
});
您使用的方法非常适合静态饼图,但永远无法很好地在 50% 标记之间设置动画。我个人更喜欢走 SVG 路线。
Lea Verou 写了一篇关于如何处理这样的事情的好文章:
https://www.smashingmagazine.com/2015/07/designing-simple-pie-charts-with-css/
它基本上归结为创建一个 <circle>
应用一个与圆本身一样宽的 stroke
并使用 CSS 操纵 stroke-dasharray
属性。
HTML
<svg width="100" height="100" class="svg">
<circle r="50" cx="50" cy="50" class="circle"/>
<circle id="pie" r="22.5" cx="50" cy="50" class="circle percent-10"/>
</svg>
SCSS
// circumference = 2π * radius
// so in this case circumference = 2π × 22.5 ≈ 141):
$circumference: 141;
.svg {
/* Appearance */
transform: rotate(-90deg);
}
.circle {
/* Appearance */
fill: #fdded9;
}
#pie {
/* Appearance */
stroke: #ff4081;
stroke-dasharray: 0 $circumference;
stroke-width: 45;
transition: stroke-dasharray .2s linear;
&.percent-10 { stroke-dasharray: ($circumference * 0.1) $circumference; }
&.percent-20 { stroke-dasharray: ($circumference * 0.2) $circumference; }
&.percent-30 { stroke-dasharray: ($circumference * 0.3) $circumference; }
&.percent-40 { stroke-dasharray: ($circumference * 0.4) $circumference; }
&.percent-50 { stroke-dasharray: ($circumference * 0.5) $circumference; }
&.percent-60 { stroke-dasharray: ($circumference * 0.6) $circumference; }
&.percent-70 { stroke-dasharray: ($circumference * 0.7) $circumference; }
&.percent-80 { stroke-dasharray: ($circumference * 0.8) $circumference; }
&.percent-90 { stroke-dasharray: ($circumference * 0.9) $circumference; }
&.percent-100 { stroke-dasharray: ($circumference * 1) $circumference; }
}
我现在对您的代码唯一担心的是它的可扩展性不是很好。我认为基于 data-attribute
.
使用 JavaScript 动态设置 stroke-dasharray
可能是更好的方法
JavaScript
$('button').on('click', function(){
var CIRCUMFERENCE = 141,
percentage = Number($(this).data('value')),
factor = percentage / 100,
strokeDashArray = (CIRCUMFERENCE * factor) + ' ' + CIRCUMFERENCE);
$pie.css('stroke-dasharray', strokeDashArray;
});
这里有一个基于您的原始代码的 CodePen,因此您可以看到它的实际效果:
http://codepen.io/rvmook/pen/LNLGoE
我尝试在 CSS 中制作一个动态饼图,它工作得很好,除非我想从小于 50% 到大于 50% 设置动画,反之亦然。
这是一个代码笔(我没有找到如何在堆栈工具中使用 SCSS):http://codepen.io/mbrillaud/pen/NNgqYE
有什么技巧可以避免这种影响吗?
HTML
<div class="wrapper">
<div class="pie percent-10" id="pie"></div>
<div class="border"></div>
</div>
<div class="buttons">
<button data-value="10">10%</button>
<button data-value="20">20%</button>
<button data-value="30">30%</button>
<button data-value="40">40%</button>
<button data-value="50">50%</button>
<button data-value="60">60%</button>
<button data-value="70">70%</button>
<button data-value="80">80%</button>
<button data-value="90">90%</button>
<button data-value="100">100%</button>
</div>
CSS
@import 'compass';
body {
background-color: #2c333b;
}
.wrapper {
position: absolute;
top: 50%;
left: 50%;
width: 100px;
@include transform(translate(-50%, -50%));
.pie,
.border {
box-sizing: border-box;
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
border-radius: 50%;
}
.pie {
background-color: #FDDED9;
background-image: linear-gradient(to right, transparent 50%, #ff4081 0);
&::before {
content: '';
display: block;
top: 0;
left: 50%;
width: 50%;
margin-left: 50%;
height: 100%;
border-radius: 0 100% 100% 0 / 50%;
background-color: inherit;
transform-origin: left;
transition: transform .2s linear;
}
&.percent-10::before {
transform: rotate(.1turn);
}
&.percent-20::before {
transform: rotate(.2turn);
}
&.percent-30::before {
transform: rotate(.3turn);
}
&.percent-40::before {
transform: rotate(.4turn);
}
&.percent-50::before {
transform: rotate(.5turn);
}
&.percent-60::before {
transform: rotate(.1turn);
background-color: #ff4081;
}
&.percent-70::before {
transform: rotate(.2turn);
background-color: #ff4081;
}
&.percent-80::before {
transform: rotate(.3turn);
background-color: #ff4081;
}
&.percent-90::before {
transform: rotate(.4turn);
background-color: #ff4081;
}
&.percent-100::before {
transform: rotate(.5turn);
background-color: #ff4081;
}
}
.border {
border: 5px solid #FDDED9
}
}
JS
$(document).ready(function() {
var $pie = $('#pie'),
className;
$('button').on('click', function() {
className = $pie.attr('class').match(/percent[\w-]*\b/);
$pie
.removeClass(className[0])
.addClass('percent-' + $(this).data('value'));
});
});
您使用的方法非常适合静态饼图,但永远无法很好地在 50% 标记之间设置动画。我个人更喜欢走 SVG 路线。
Lea Verou 写了一篇关于如何处理这样的事情的好文章: https://www.smashingmagazine.com/2015/07/designing-simple-pie-charts-with-css/
它基本上归结为创建一个 <circle>
应用一个与圆本身一样宽的 stroke
并使用 CSS 操纵 stroke-dasharray
属性。
HTML
<svg width="100" height="100" class="svg">
<circle r="50" cx="50" cy="50" class="circle"/>
<circle id="pie" r="22.5" cx="50" cy="50" class="circle percent-10"/>
</svg>
SCSS
// circumference = 2π * radius
// so in this case circumference = 2π × 22.5 ≈ 141):
$circumference: 141;
.svg {
/* Appearance */
transform: rotate(-90deg);
}
.circle {
/* Appearance */
fill: #fdded9;
}
#pie {
/* Appearance */
stroke: #ff4081;
stroke-dasharray: 0 $circumference;
stroke-width: 45;
transition: stroke-dasharray .2s linear;
&.percent-10 { stroke-dasharray: ($circumference * 0.1) $circumference; }
&.percent-20 { stroke-dasharray: ($circumference * 0.2) $circumference; }
&.percent-30 { stroke-dasharray: ($circumference * 0.3) $circumference; }
&.percent-40 { stroke-dasharray: ($circumference * 0.4) $circumference; }
&.percent-50 { stroke-dasharray: ($circumference * 0.5) $circumference; }
&.percent-60 { stroke-dasharray: ($circumference * 0.6) $circumference; }
&.percent-70 { stroke-dasharray: ($circumference * 0.7) $circumference; }
&.percent-80 { stroke-dasharray: ($circumference * 0.8) $circumference; }
&.percent-90 { stroke-dasharray: ($circumference * 0.9) $circumference; }
&.percent-100 { stroke-dasharray: ($circumference * 1) $circumference; }
}
我现在对您的代码唯一担心的是它的可扩展性不是很好。我认为基于 data-attribute
.
stroke-dasharray
可能是更好的方法
JavaScript
$('button').on('click', function(){
var CIRCUMFERENCE = 141,
percentage = Number($(this).data('value')),
factor = percentage / 100,
strokeDashArray = (CIRCUMFERENCE * factor) + ' ' + CIRCUMFERENCE);
$pie.css('stroke-dasharray', strokeDashArray;
});
这里有一个基于您的原始代码的 CodePen,因此您可以看到它的实际效果: http://codepen.io/rvmook/pen/LNLGoE