【注意,此章节完全是css的二次开发,理解难度极高,且极易出错,大家可以直接复制本文末尾的源码来跳过此章节】
本节课要承接上节课的内容,继续解决这个扇形统计图的 外层和内指针的角度动画问题:
我们上节课说后端会给一个 含有四个元素的列表来作为求出角度
这个复杂的计算我期望在 后端完成,最后给前端的时候 直接就是 现成的角度。这样我们便可以直接绕过复杂的js,而直接把数据给到 home_tj.html顶部的全局样式中 用{{ }} 来占位替换。
我们回到views.py中,先写好需要的统计数据
- 实际的数据 ,如:
2.计算百分比,我们可以用他们当前数量级的最大数作为分母,来求出百分比
刷新下页面就可以看到打印结果:
如图,已经成功计算出了角度。
3. 给到前端:
我修改了前端的展示数据样式,不显示百分比,而是实际数据。
注意,是分成了四个变量给过去,每个变量都有实际数据和百分比角度
4. 展示实际数据:
看看效果:
注意看到,他们的实际数据已经展示成功了,并且动画增长依旧给力。
5. 角度变量替换到顶部head中的loading- 各个里
其中2和6是一组,3和7是一组,4和8是一组,5和9是一组
(注意 loading-1 是初始不要碰不要改)
2345管着外圈角度, 6789管着内圈指针
但是实际测试角度和效果的时候,我又发现新的问题!
就是角度并不是那么简单的 显示的。
首先第一个问题
- 内圈指针角度(6、7、8、9) 原作者是分了俩段,即先一半时间到什么角度,全部时间到什么角度。
也就是loading-6 /7/8/9 这些50%的 部分全部删除 即可简单化!
改成后顺便带入我们的变量,6789如下:
然后是第二个 更复杂的问题:
就是外圈的度数,经过测试发现,并不是简单的根据度数增长。而是分为了左右俩部分。
看来是用 俩部分的圆弧 遮挡效果 实现的。
也就是说:loading-1 是控制所有圆环右侧半圆,而laoding-2/3/4/5分别控制左侧半圆。
但是原作者 却把loading-1给写死了180度 ,所以我先要在这里暗自抱怨一下了,这作者完成的手段属实不咋样。 我们的度数不够180的时候,依然会至少有180度在,作者的效果图中也很巧妙的没有截图低于180度的情况。
这里要额外说一下,所有的-webkit-transform: 都可以删掉,暂时不用。
(到这里不得不说,我们似乎掉进了一个巨大的深坑之中,原作者真的挺坑的。)
也就是说,整个圆弧是分为 左右俩部分来实现的,我仔细看了下css ,发现的确如此:
以上俩个图,可以不难的发现,作者把右侧部分写死在了公共部分,把左侧部分分别放进了 四段来实现可以定制。
那么我们目前的做法就是 要给右侧的公共部分调用删掉,也就是完全删掉loading-1,然后把右侧的调用也分别 放在 四组内,而且我们的后台过来的角度中,也要重新再传一份单独的,外圈右角度 和 外圈左角度。
也就是说 ,当总度数大于180度时候,右侧= 180,左侧= 度数-180
当度数小于 180度的时候,右侧 = 度数,左侧=0
说干就干,先删掉公共部分调用:
删除loading-1:
然后四段代码内加上right相关:
注意划红线的地方,千万千万别抄错!
但是我们目前还不知道调用哪部分,所以我们还要新建 四组专给右侧部分的loading
取名为 loading-2r /3r /4r/ 5r
注意调用代码 我再次进行了修改,修改如下:
千万千万别写错 调用!!!
然后是下面的 四个新的loading 2r/3r/4r/5r
图没截全,大家把5r也写上。
好了,现在我们要回到views.py中,再弄一套左右角度变量。
新变量为 tj_x.du_left 和 tj_x.du_right
在前端替换:
注意对照序号,变量名是从1 -4 ,而前端的loading-是从2 -5
好,重启服务,刷新页面。
效果如下:
可以看到,终于成功的实现了 这个东西。解决了原作者隐瞒的缺陷问题。
大家如果对CSS不熟悉,这种问题基本就是无解了。
好了,首页到此就暂时告一段落了。
最后附上 VIEWS函数源码 和 这个home_tj.html的源码。方便大家直接复制。
from django.shortcuts import render
from myapp.models import *
# Create your views here.
def home(request):
res = {}
res['user'] = request.user
res['big_statistics'] = list(DB_Statistics.objects.filter(tool_which='big').values())
data_tj = [79,1223,22,9] #这是四个维度的数据
data_b = [(i/(10**len(str(i))))*360 for i in data_tj]
res['tj_1'] = {"num":data_tj[0],'du':data_b[0],'du_left':data_b[0]-180 if data_b[0]>180 else 0,'du_right':180 if data_b[0]>180 else data_b[0]}
res['tj_2'] = {"num":data_tj[1],'du':data_b[1],'du_left':data_b[1]-180 if data_b[1]>180 else 0,'du_right':180 if data_b[1]>180 else data_b[1]}
res['tj_3'] = {"num":data_tj[2],'du':data_b[2],'du_left':data_b[2]-180 if data_b[2]>180 else 0,'du_right':180 if data_b[2]>180 else data_b[2]}
res['tj_4'] = {"num":data_tj[3],'du':data_b[3],'du_left':data_b[3]-180 if data_b[3]>180 else 0,'du_right':180 if data_b[3]>180 else data_b[3]}
return render(request,'home.html',res)
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="http://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<link href="http://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<style type="text/css">
.demo{
padding: 2.5em;
background: #fff;
}
.progress{
width: 100px;
height: 100px;
line-height: 150px;
background: none;
margin: 0 auto;
box-shadow: none;
position: relative;
overflow: visible;
}
.progress:after{
content: "";
width: 100%;
height: 100%;
border-radius: 50%;
border: 5px solid #fff;
position: absolute;
top: 0;
left: 0;
}
.progress > span{
width: 50%;
height: 100%;
overflow: hidden;
position: absolute;
top: 0;
z-index: 1;
}
.progress .progress-left{ left: 0; }
.progress .progress-bar{
width: 100%;
height: 100%;
background: none;
border-width: 5px;
border-style: solid;
position: absolute;
top: 0;
}
.progress .progress-left .progress-bar{
left: 100%;
border-top-right-radius: 80px;
border-bottom-right-radius: 80px;
border-left: 0;
-webkit-transform-origin: center left;
transform-origin: center left;
}
.progress .progress-right{ right: 0; }
.progress .progress-right .progress-bar{
left: -100%;
border-top-left-radius: 80px;
border-bottom-left-radius: 80px;
border-right: 0;
-webkit-transform-origin: center right;
transform-origin: center right;
}
.progress .inner-circle,
.progress .progress-value{
width: 60px;
height: 60px;
border-radius: 50%;
border: 5px solid #8e8e8e;
font-size: 18px;
font-weight: bold;
line-height: 50px;
text-align: center;
margin: auto;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index: 1;
}
.progress .inner-circle:after{
content: "";
width: 5px;
height: 30px;
background: #8e8e8e;
margin: 0 auto;
position: absolute;
top: -30px;
left: 0;
right: 0;
z-index: 2;
transition: all 10s linear 0s;
}
.progress.blue .progress-bar{ border-color: #049dff; }
.progress.blue .progress-value{ color: #049dff; }
.progress.blue .progress-left .progress-bar{ animation: loading-2 1.5s linear forwards 1.8s; }
.progress.blue .progress-right .progress-bar{ animation: loading-2r 1.8s linear forwards; }
.progress.blue .inner-circle{ animation: loading-6 3.8s ease forwards; }
.progress.yellow .progress-bar{ border-color: #fdba04; }
.progress.yellow .progress-value{ color: #fdba04; }
.progress.yellow .progress-left .progress-bar{ animation: loading-3 1s linear forwards 1.8s; }
.progress.yellow .progress-right .progress-bar{ animation: loading-3r 1.8s linear forwards; }
.progress.yellow .inner-circle{ animation: loading-7 3.8s ease forwards; }
.progress.pink .progress-bar{ border-color: #ed687c; }
.progress.pink .progress-value{ color: #ed687c; }
.progress.pink .progress-left .progress-bar{ animation: loading-4 0.4s linear forwards 1.8s; }
.progress.pink .progress-right .progress-bar{ animation: loading-4r 1.8s linear forwards; }
.progress.pink .inner-circle{ animation: loading-8 3.8s ease forwards; }
.progress.green .progress-bar{ border-color: #1abc9c; }
.progress.green .progress-value{ color: #1abc9c; }
.progress.green .progress-left .progress-bar{ animation: loading-5 1.2s linear forwards 1.8s; }
.progress.green .progress-right .progress-bar{ animation: loading-5r 1.8s linear forwards; }
.progress.green .inner-circle{ animation: loading-9 3.8s ease forwards; }
@keyframes loading-2r{
0%{
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100%{
-webkit-transform: rotate(90deg);
transform: rotate({{ tj_1.du_right }}deg);
}
}
@keyframes loading-2{
0%{
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100%{
-webkit-transform: rotate(90deg);
transform: rotate({{ tj_1.du_left }}deg);
}
}
@keyframes loading-3r{
0%{
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100%{
-webkit-transform: rotate(90deg);
transform: rotate({{ tj_2.du_right }}deg);
}
}
@keyframes loading-3{
0%{
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100%{
-webkit-transform: rotate(90deg);
transform: rotate({{ tj_2.du_left }}deg);
}
}
@keyframes loading-4r{
0%{
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100%{
-webkit-transform: rotate(36deg);
transform: rotate({{ tj_3.du_right }}deg);
}
}
@keyframes loading-4{
0%{
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100%{
-webkit-transform: rotate(36deg);
transform: rotate({{ tj_3.du_left }}deg);
}
}
@keyframes loading-5r{
0%{
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100%{
-webkit-transform: rotate(126deg);
transform: rotate({{ tj_4.du_right }}deg);
}
}
@keyframes loading-5{
0%{
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100%{
-webkit-transform: rotate(126deg);
transform: rotate({{ tj_4.du_left }}deg);
}
}
@keyframes loading-6{
0%{
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100%{
-webkit-transform: rotate({{ tj_1.du }}deg);
transform: rotate({{ tj_1.du }}deg);
}
}
@keyframes loading-7{
0%{
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100%{
-webkit-transform: rotate({{ tj_2.du }}deg);
transform: rotate({{ tj_2.du }}deg);
}
}
@keyframes loading-8{
0%{
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100%{
-webkit-transform: rotate({{ tj_3.du }}deg);
transform: rotate({{ tj_3.du }}deg);
}
}
@keyframes loading-9{
0%{
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100%{
-webkit-transform: rotate({{ tj_4.du }}deg);
transform: rotate({{ tj_4.du }}deg);
}
}
@media only screen and (max-width: 990px){
.progress{ margin-bottom: 20px; }
}
</style>
</head>
<body>
<div class="row" style=";margin-top: 100px">
<div class="col-md-2 col-sm-6" >
<div class="progress blue">
<span class="progress-left">
<span class="progress-bar"></span>
</span>
<span class="progress-right">
<span class="progress-bar"></span>
</span>
<div class="inner-circle"></div>
<div class="progress-value"><span>{{ tj_1.num }}</span></div>
</div>
<div style="text-align: center;margin-top: 5px">我是标题1 </div>
</div>
<div class="col-md-2 col-sm-6">
<div class="progress yellow">
<span class="progress-left">
<span class="progress-bar"></span>
</span>
<span class="progress-right">
<span class="progress-bar"></span>
</span>
<div class="inner-circle"></div>
<div class="progress-value"><span>{{ tj_2.num }}</span></div>
</div>
<div style="text-align: center;margin-top: 5px">我是标题2 </div>
</div>
<div class="col-md-2 col-sm-6">
<div class="progress pink">
<span class="progress-left">
<span class="progress-bar"></span>
</span>
<span class="progress-right">
<span class="progress-bar"></span>
</span>
<div class="inner-circle"></div>
<div class="progress-value"><span>{{ tj_3.num }}</span></div>
</div>
<div style="text-align: center;margin-top: 5px">我是标题3 </div>
</div>
<div class="col-md-2 col-sm-6">
<div class="progress green">
<span class="progress-left">
<span class="progress-bar"></span>
</span>
<span class="progress-right">
<span class="progress-bar"></span>
</span>
<div class="inner-circle"></div>
<div class="progress-value"><span>{{ tj_4.num }}</span></div>
</div>
<div style="text-align: center;margin-top: 5px">我是标题4 </div>
</div>
</div>
<script type="text/javascript">
$(document).ready(function(){
$('.progress-value > span').each(function(){
$(this).prop('Counter',0).animate({
Counter: $(this).text()
},{
duration: 3500,
easing: 'swing',
step: function (now){
$(this).text(Math.ceil(now));
}
});
});
});
</script>
</body>
</html>
本文使用 文章同步助手 同步