这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » 扣丁学堂HTML5视频教程之HTML5+CSS33D雷达扫描动画及源码

共2条 1/1 1 跳转至

扣丁学堂HTML5视频教程之HTML5+CSS33D雷达扫描动画及源码

助工
2020-11-04 10:28:19     打赏

  在现如今,随着互联网技术飞速的发展和进步,比如HTML5+CSS3可以做出很炫酷的动画,今天扣丁学堂给大家介绍一下关于一款雷达动画更加让人震撼,它是基于HTML5和CSS3实现,它的一大特点是3D立体的视觉效果,鼠标点击雷达后将会展现一张3D立体地图,并且对地图上指定的几个地点进行坐标详细信息描述。下面我们一起来解析一下这款炫酷的HTML53D雷达动画的实现过程。

  HTML代码


  首先HTML代码非常简单,只需在页面上展示一个div容器即可。


  <divclass="radar"></div>


  CSS代码


  这里主要利用了CSS3的旋转等动画特性,看看以下的CSS代码,主要是完成所有的动画:


  @-webkit-keyframesflashing{


  0%,


  30%{


  -webkit-transform:scale(1);


  transform:scale(1);


  }


  70%,


  100%{


  -webkit-transform:scale(0);


  transform:scale(0);


  }


  }


  @keyframesflashing{


  0%,


  30%{


  -webkit-transform:scale(1);


  transform:scale(1);


  }


  70%,


  100%{


  -webkit-transform:scale(0);


  transform:scale(0);


  }


  }


  @-webkit-keyframespulsation{


  0%{


  -webkit-transform:scale(0);


  transform:scale(0);


  border-color:red;


  background-color:rgba(255,0,0,0.6);


  }


  80%,


  100%{


  -webkit-transform:scale(1);


  transform:scale(1);


  border-color:rgba(255,0,0,0.2);


  background-color:rgba(255,0,0,0.1);


  }


  }


  @keyframespulsation{


  0%{


  -webkit-transform:scale(0);


  transform:scale(0);


  border-color:red;


  background-color:rgba(255,0,0,0.6);


  }


  80%,


  100%{


  -webkit-transform:scale(1);


  transform:scale(1);


  border-color:rgba(255,0,0,0.2);


  background-color:rgba(255,0,0,0.1);


  }


  }


  @-webkit-keyframesrotation{


  from{


  -webkit-transform:rotate(0deg)translateZ(1px);


  transform:rotate(0deg)translateZ(1px);


  }


  to{


  -webkit-transform:rotate(360deg)translateZ(1px);


  transform:rotate(360deg)translateZ(1px);


  }


  }


  @keyframesrotation{


  from{


  -webkit-transform:rotate(0deg)translateZ(1px);


  transform:rotate(0deg)translateZ(1px);


  }


  to{


  -webkit-transform:rotate(360deg)translateZ(1px);


  transform:rotate(360deg)translateZ(1px);


  }


  }


  @-webkit-keyframesscale{


  from{


  -webkit-transform:scale(1);


  transform:scale(1);


  }


  to{


  -webkit-transform:scale(1.3);


  transform:scale(1.3);


  }


  }


  @keyframesscale{


  from{


  -webkit-transform:scale(1);


  transform:scale(1);


  }


  to{


  -webkit-transform:scale(1.3);


  transform:scale(1.3);


  }


  }


  @-webkit-keyframespolish{


  30%,


  100%{


  -webkit-transform:skewX(35deg)translateX(380%);


  transform:skewX(35deg)translateX(380%);


  }


  }


  @keyframespolish{


  30%,


  100%{


  -webkit-transform:skewX(35deg)translateX(380%);


  transform:skewX(35deg)translateX(380%);


  }


  }


  当然这个雷达光是有动画是不行的,还得有漂亮的外观,用以下CSS代码实现:


  .radar{


  height:40em;


  width:48em;


  position:relative;


  cursor:pointer;


  -webkit-perspective:62.5em;


  perspective:62.5em;


  }


  .radar.radar-map-container,


  .radar.risk-points,


  .radar.scanning-circlecanvas{


  left:0;


  top:0;


  position:absolute;


  }


  .radar.radar-map-container,


  .radar.radar-map,


  .radar.scanning-circle,


  .radar.risk-elements-group{


  -webkit-transition:opacity2.5sease-out,-webkit-transform2.5sease-out,-webkit-transform-origin;


  transition:opacity2.5sease-out,-webkit-transform2.5sease-out,-webkit-transform-origin;


  transition:transform2.5sease-out,opacity2.5sease-out,transform-origin;


  transition:transform2.5sease-out,opacity2.5sease-out,transform-origin,-webkit-transform2.5sease-out,-webkit-transform-origin;


  }


  .radar.radar-map-container,


  .radar.radar-map,


  .radar.scanning-circle{


  will-change:transform;


  }


  .radar.radar-map-container{


  width:400%;


  height:400%;


  left:-150%;


  top:-150%;


  -webkit-transform:scale(0.25);


  transform:scale(0.25);


  -webkit-transform-style:preserve-3d;


  transform-style:preserve-3d;


  }


  .radar.radar-map{


  color:rgba(19,182,206,0.4);


  background:url('http://i64.tinypic.com/5l17ut.jpg')center/containno-repeat;


  width:100%;


  height:100%;


  -webkit-transform-style:preserve-3d;


  transform-style:preserve-3d;


  }


  .radar.radar-map.roaming{


  -webkit-transition-duration:5s!important;


  transition-duration:5s!important;


  -webkit-transition-timing-function:ease-in-out;


  transition-timing-function:ease-in-out;


  -webkit-transition-delay:.5s;


  transition-delay:.5s;


  }


  .radar.radar-map.risk-elements-group{


  opacity:0;


  -webkit-transform-style:preserve-3d;


  transform-style:preserve-3d;


  }


  .radar.radar-map.risk-elements-group.red-flag,


  .radar.radar-map.risk-elements-group.info-panel,


  .radar.radar-map.risk-elements-group.dashed-circle{


  position:absolute;


  }


  .radar.radar-map.risk-elements-group.red-flag,


  .radar.radar-map.risk-elements-group.dashed-circle{


  visibility:hidden;


  }


  .radar.radar-map.risk-elements-group.red-flag,


  .radar.radar-map.risk-elements-group.info-panel{


  -webkit-transform-origin:bottom;


  transform-origin:bottom;


  -webkit-transform:rotateX(-70deg);


  transform:rotateX(-70deg);


  }


  .radar.radar-map.risk-elements-group.red-flag{


  width:0.5em;


  height:10em;


  background-color:white;


  -webkit-transform:rotateX(-70deg)rotateZ(-90deg);


  transform:rotateX(-70deg)rotateZ(-90deg);


  }


  .radar.radar-map.risk-elements-group.red-flag.stand-up{


  -webkit-transform:rotateX(-70deg);


  transform:rotateX(-70deg);


  visibility:visible;


  }


  .radar.radar-map.risk-elements-group.red-flag:before{


  content:attr(data-city);


  font-weight:bold;


  color:white;


  position:absolute;


  background-color:red;


  -webkit-clip-path:polygon(00,100%50%,0100%);


  -moz-clip-path:polygon(00,100%50%,0100%);


  clip-path:polygon(00,100%50%,0100%);


  width:4.782608695652174em;


  height:3.4782608695652173em;


  line-height:3.4782608695652173em;


  font-size:1.4375em;


  font-family:微软雅黑;


  letter-spacing:0.43478260869565216em;


  padding-left:0.5217391304347826em;


  -webkit-box-sizing:border-box;


  box-sizing:border-box;


  top:0.43478260869565216em;


  white-space:nowrap;


  }


  .radar.radar-map.risk-elements-group.red-flag:after{


  content:'';


  position:absolute;


  width:2.1875em;


  height:0.625em;


  border-radius:50%;


  background-color:inherit;


  top:calc(100%-0.625em);


  left:calc(50%-1.09375em);


  }


  .radar.radar-map.risk-elements-group.info-panel{


  -webkit-transform:rotateX(-70deg)translateY(-30%);


  transform:rotateX(-70deg)translateY(-30%);


  -webkit-filter:opacity(0);


  -moz-filter:opacity(0);


  filter:opacity(0);


  border:0.0625emsolid#DCDA6B;


  border-radius:0.25em;


  background-color:rgba(245,228,158,0.31);


  display:table;


  font-weight:bold;


  font-size:2.5em;


  text-shadow:0.025em0.025em0.05emblack;


  padding:0.2em0.3em;


  font-family:黑体;


  overflow:hidden;


  }


  .radar.radar-map.risk-elements-group.info-panel.showup{


  -webkit-filter:opacity(1);


  -moz-filter:opacity(1);


  filter:opacity(1);


  transition:-webkit-filter1slinear0.5s,-moz-filter1slinear0.5s,filter1slinear0.5s,opacity0.5slinear;


  }


  .radar.radar-map.risk-elements-group.info-panel.polish:after{


  -webkit-animation:polish5slinear11s;


  animation:polish5slinear11s;


  }


  .radar.radar-map.risk-elements-group.info-panel.info-title{


  background-image:-webkit-gradient(linear,lefttop,righttop,from(rgba(208,209,120,0.6)),to(rgba(223,226,183,0.05)));


  background-image:linear-gradient(toright,rgba(208,209,120,0.6),rgba(223,226,183,0.05));


  color:#FFE401;


  padding:00.275em;


  border-radius:inherit;


  }


  .radar.radar-map.risk-elements-group.info-panel.info-content{


  color:white;


  margin:0.25em;


  line-height:1.3em;


  }


  .radar.radar-map.risk-elements-group.info-panel:after{


  content:'';


  position:absolute;


  width:30%;


  height:100%;


  -webkit-transform:skewX(35deg)translateX(-160%);


  transform:skewX(35deg)translateX(-160%);


  top:0;


  background-image:-webkit-gradient(linear,lefttop,righttop,from(transparent),color-stop(rgba(255,255,255,0.3)),to(transparent));


  background-image:linear-gradient(toright,transparent,rgba(255,255,255,0.3),transparent);


  }


  .radar.radar-map.risk-elements-group.dashed-circle{


  width:7.5em;


  height:7.5em;


  border-radius:50%;


  background:center/containno-repeat;


  -webkit-animation:rotation5slinearinfinite;


  animation:rotation5slinearinfinite;


  -webkit-transition-property:visibility;


  transition-property:visibility;


  }


  .radar.radar-map.risk-elements-group.dashed-circle:after{


  content:'';


  border-radius:inherit;


  margin:auto;


  width:15%;


  height:15%;


  background-color:#E03636;


  -webkit-box-shadow:000.9375emblack;


  box-shadow:000.9375emblack;


  -webkit-animation:scale1slinearinfinitealternate;


  animation:scale1slinearinfinitealternate;


  position:absolute;


  left:0;


  right:0;


  top:0;


  bottom:0;


  }


  .radar.changing-number-container{


  position:absolute;


  right:12%;


  top:10%;


  bottom:0;


  margin:auto;


  }


  .radar.changing-number-container{


  display:table;


  color:#10ABE0;


  }


  .radar.changing-number-container:before,


  .radar.changing-number-container:after{


  display:inline-block;


  }


  .radar.changing-number-container:before{


  content:'';


  background:-webkit-gradient(linear,lefttop,leftbottom,color-stop(45%,transparent),color-stop(55%,currentColor),color-stop(55%,transparent))center/100%1em;


  background:linear-gradient(tobottom,transparent45%,currentColor55%,transparent55%)center/100%1em;


  width:1em;


  height:100%;


  margin-right:0.625em;


  }


  .radar.changing-number-container:after{


  font-size:0.75em;


  content:attr(data-number);


  width:1.3333333333333333em;


  line-height:1.3333333333333333em;


  word-break:break-all;


  letter-spacing:1.3333333333333333em;


  vertical-align:top;


  font-weight:bold;


  }


  .radar.risk-points{


  z-index:15;


  }


  .radar.risk-points.risk-point-group.risk-point{


  position:absolute;


  width:0.625em;


  height:0.625em;


  border-radius:50%;


  -webkit-filter:blur(2px);


  }


  .radar.risk-points.risk-point-group.risk-point:after{


  content:'';


  display:block;


  height:100%;


  border-radius:50%;


  will-change:transform;


  -webkit-transform:scale(0);


  transform:scale(0);


  }


  .radar.risk-points.risk-point-group.risk-point.type1:after{


  -webkit-box-shadow:000.3125em0.3125emwhiteinset,000.3125em0.5625emrgba


  (245,76,128,0.54),002.5625em1.5625emrgba(222,17,17,0.89);


  box-shadow:000.3125em0.3125emwhiteinset,000.3125em0.5625emrgba


  (245,76,128,0.54),002.5625em1.5625emrgba(222,17,17,0.89);


  }


  .radar.risk-points.risk-point-group.risk-point.type2:after{


  -webkit-box-shadow:000.3125em0.3125emwhiteinset,000.3125em0.5625em#15d8e8,002.5625em1.5625emrgba(44,218,226,0.89);


  box-shadow:000.3125em0.3125emwhiteinset,000.3125em0.5625em#15d8e8,002.5625em1.5625emrgba(44,218,226,0.89);


  }


  .radar.risk-points.risk-point-group.risk-point.critical{


  -webkit-transform:scale(1);


  transform:scale(1);


  }


  .radar.risk-points.risk-point-group.risk-point.ordinary{


  -webkit-transform:scale(0.4);


  transform:scale(0.4);


  }


  .radar.risk-points.risk-point-group.risk-point.pulsation{


  color:red;


  -webkit-filter:none;


  width:5em;


  height:5em;


  }


  .radar.risk-points.risk-point-group.risk-point.pulsation.pulse-circle{


  position:absolute;


  width:100%;


  height:100%;


  border-radius:50%;


  -webkit-box-sizing:border-box;


  box-sizing:border-box;


  border:0.1875emsolidcurrentColor;


  -webkit-animation:pulsation3slinear1;


  animation:pulsation3slinear1;


  }


  .radar.risk-points.risk-point-group.risk-point.pulsation.pulse-circle:nth-child(2){


  -webkit-animation-delay:.8s;


  animation-delay:.8s;


  }


  .radar.risk-points.risk-point-group.risk-point.pulsation.pulse-circle:nth-child(3){


  -webkit-animation-delay:1.6s;


  animation-delay:1.6s;


  }


  .radar.risk-points.risk-point-group.risk-point.pulsation:after{


  content:'';


  position:absolute;


  width:15%;


  height:15%;


  border-radius:50%;


  background-color:currentColor;


  left:0;


  right:0;


  top:0;


  bottom:0;


  margin:auto;


  }


  .radar.risk-points.risk-point-group.flashing.risk-point:after{


  -webkit-animation:flashing2slinear1;


  animation:flashing2slinear1;


  }


  .radar.scanning-circle{


  position:relative;


  height:100%;


  }


  .radar.scanning-circle.radar-scanner{


  width:40em;


  height:100%;


  margin:0auto;


  position:relative;


  z-index:10;


  -webkit-transform:rotate(125deg);


  transform:rotate(125deg);


  }


  .radar.scanning-circle.radar-scanner.inner-scanner,


  .radar.scanning-circle.radar-scanner.outer-scanner{


  width:100%;


  height:100%;


  }


  .radar.scanning-circle.radar-scanner.inner-scanner{


  display:none;


  position:absolute;


  -webkit-clip-path:inset(00050%);


  -webkit-filter:blur(30px);


  -webkit-animation:rotation30slinearinfinite;


  animation:rotation30slinearinfinite;


  }


  .radar.scanning-circle.radar-scanner.inner-scanner:after{


  content:'';


  -webkit-clip-path:inset(050%00);


  display:block;


  height:100%;


  background-color:rgba(19,182,206,0.3);


  -webkit-transform:rotate(30deg);


  transform:rotate(30deg);


  border-radius:50%;


  }


  .radar.scanning-circle.radar-scanner.outer-scanner{


  -webkit-clip-path:circle(20emat50%48%);


  -moz-clip-path:circle(20emat50%48%);


  clip-path:circle(20emat50%48%);


  -webkit-box-sizing:border-box;


  box-sizing:border-box;


  border:0solidwhite;


  border-top-width:5px;


  border-radius:50%;


  -webkit-box-shadow:0-0.1875em0.3125em#33C9E8,000.9375emwhite,00.3125em0.5em#38C1D2inset;


  box-shadow:0-0.1875em0.3125em#33C9E8,000.9375emwhite,00.3125em0.5em#38C1D2inset;


  will-change:transform;


  }


  .radar.scanning-circle.radar-scanner.outer-scanner.scanner-container{


  height:100%;


  position:relative;


  overflow:hidden;


  border-radius:50%;


  -webkit-transform:rotate(-35deg);


  transform:rotate(-35deg);


  }


  .radar.scanning-circle.radar-scanner.outer-scanner.scanner-container.umbrella,


  .radar.scanning-circle.radar-scanner.outer-scanner.scanner-container.color-sector{


  position:absolute;


  width:100%;


  height:100%;


  left:0;


  top:0;


  border-radius:inherit;


  }


  .radar.scanning-circle.radar-scanner.outer-scanner.scanner-container.umbrella{


  -webkit-clip-path:inset(0050%50%);


  -moz-clip-path:inset(0050%50%);


  clip-path:inset(0050%50%);


  overflow:hidden;


  -webkit-filter:blur(30px);


  -moz-filter:blur(30px);


  filter:blur(30px);


  }


  .radar.scanning-circle.radar-scanner.outer-scanner.scanner-container.umbrella.color-sector{


  -webkit-clip-path:inset(050%00);


  -moz-clip-path:inset(050%00);


  clip-path:inset(050%00);


  background-color:rgba(19,182,206,0.2);


  }


  .radar.scanning-circle.radar-scanner.outer-scanner.scanner-container.umbrella.color-sector:nth-child(1){


  -webkit-transform:rotate(60deg);


  transform:rotate(60deg);


  }


  .radar.scanning-circle.radar-scanner.outer-scanner.scanner-container.umbrella.color-sector:nth-child(2){


  -webkit-transform:rotate(54deg);


  transform:rotate(54deg);


  }


  .radar.scanning-circle.radar-scanner.outer-scanner.scanner-container.umbrella.color-sector:nth-child(3){


  -webkit-transform:rotate(48deg);


  transform:rotate(48deg);


  }


  .radar.scanning-circle.radar-scanner.outer-scanner.scanner-container.umbrella.color-sector:nth-child(4){


  -webkit-transform:rotate(42deg);


  transform:rotate(42deg);


  }


  .radar.scanning-circle.radar-scanner.outer-scanner.scanner-container.umbrella.color-sector:nth-child(5){


  -webkit-transform:rotate(36deg);


  transform:rotate(36deg);


  }


  .radar.scanning-circle.radar-scanner.outer-scanner.scanner-container.umbrella.color-sector:nth-child(6){


  -webkit-transform:rotate(30deg);


  transform:rotate(30deg);


  }


  .radar.scanning-circle.radar-scanner.outer-scanner.scanner-container.umbrella.color-sector:nth-child(7){


  -webkit-transform:rotate(24deg);


  transform:rotate(24deg);


  }


  .radar.scanning-circle.radar-scanner.outer-scanner.scanner-container.umbrella.color-sector:nth-child(8){


  -webkit-transform:rotate(18deg);


  transform:rotate(18deg);


  }


  .radar.scanning-circle.radar-scanner.outer-scanner.scanner-container.umbrella.color-sector:nth-child(9){


  -webkit-transform:rotate(12deg);


  transform:rotate(12deg);


  }


  .radar.scanning-circle.radar-scanner.outer-scanner.scanner-container.umbrella.color-sector:nth-child(10){


  -webkit-transform:rotate(6deg);


  transform:rotate(6deg);


  }


  .radar.scanning-circle.radar-scanner.outer-scanner.scanner-container.scanner-decoration{


  position:relative;


  height:100%;


  }


  .radar.scanning-circle.radar-scanner.outer-scanner.scanner-container.scanner-decoration.thin-border,


  .radar.scanning-circle.radar-scanner.outer-scanner.scanner-container.scanner-decoration.small-ellipse{


  -webkit-filter:blur(2px);


  margin-left:auto;


  margin-right:auto;


  }


  .radar.scanning-circle.radar-scanner.outer-scanner.scanner-container.scanner-decoration.thin-border{


  width:0.0625em;


  height:50%;


  background-color:rgba(65,191,226,0.5);


  }


  .radar.scanning-circle.radar-scanner.outer-scanner.scanner-container.scanner-decoration.small-ellipse{


  background-color:white;


  border-radius:50%;


  position:absolute;


  left:0;


  right:0;


  -webkit-transform:translateZ(0);


  transform:translateZ(0);


  }


  .radar.scanning-circle.radar-scanner.outer-scanner.scanner-container.scanner-decoration.small-ellipse:nth-child(2){


  width:0.9375em;


  height:0.1875em;


  top:3%;


  }


  .radar.scanning-circle.radar-scanner.outer-scanner.scanner-container.scanner-decoration.small-ellipse:nth-child(3){


  width:1.375em;


  height:0.25em;


  top:17%;


  }


  .radar.scanning-circle.radar-scanner.outer-scanner.scanner-container.scanner-decoration.small-ellipse:nth-child(4){


  width:1em;


  height:0.125em;


  top:33%;


  opacity:0.3;


  }


  .radar.scanning-circle.scanning-dashed-circle{


  -webkit-animation:rotation2.67slinearinfinite;


  animation:rotation2.67slinearinfinite;


  }


  .radar.scanning-circle.scanning-dashed-empty-circle{


  -webkit-animation:rotation1.67slinearinfinite;


  animation:rotation1.67slinearinfinite;


  }


  .radar.lying-down.radar-map-container,


  .radar.lying-down.radar-map,


  .radar.lying-down.scanning-circle,


  .radar.lying-down.risk-elements-group{


  -webkit-transition-duration:1s;


  transition-duration:1s;


  }


  .radar.lying-down.radar-map-container{


  -webkit-transform:scale(1);


  transform:scale(1);


  }


  .radar.lying-down.radar-map{


  -webkit-transform:translateZ(-125em)rotateX(70deg);


  transform:translateZ(-125em)rotateX(70deg);


  color:transparent;


  }


  .radar.lying-down.radar-map.risk-elements-group{


  opacity:1;


  }


  .radar.lying-down.radar-map.risk-elements-group.info-panel{


  opacity:.4;


  }


  .radar.lying-down.radar-map.risk-elements-group.red-flag{


  -webkit-transition:opacity0.5slinear,visibility,-webkit-transform.3slinear;


  transition:opacity0.5slinear,visibility,-webkit-transform.3slinear;


  transition:transform.3slinear,opacity0.5slinear,visibility;


  transition:transform.3slinear,opacity0.5slinear,visibility,-webkit-transform.3slinear;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(19).red-flag{


  -webkit-transition-delay:5.7s,0s,5.7s;


  transition-delay:5.7s,0s,5.7s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(19).dashed-circle{


  -webkit-transition-delay:5.7s;


  transition-delay:5.7s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(18).red-flag{


  -webkit-transition-delay:5.3999999999999995s,0s,5.3999999999999995s;


  transition-delay:5.3999999999999995s,0s,5.3999999999999995s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(18).dashed-circle{


  -webkit-transition-delay:5.3999999999999995s;


  transition-delay:5.3999999999999995s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(17).red-flag{


  -webkit-transition-delay:5.1s,0s,5.1s;


  transition-delay:5.1s,0s,5.1s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(17).dashed-circle{


  -webkit-transition-delay:5.1s;


  transition-delay:5.1s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(16).red-flag{


  -webkit-transition-delay:4.8s,0s,4.8s;


  transition-delay:4.8s,0s,4.8s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(16).dashed-circle{


  -webkit-transition-delay:4.8s;


  transition-delay:4.8s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(15).red-flag{


  -webkit-transition-delay:4.5s,0s,4.5s;


  transition-delay:4.5s,0s,4.5s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(15).dashed-circle{


  -webkit-transition-delay:4.5s;


  transition-delay:4.5s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(14).red-flag{


  -webkit-transition-delay:4.2s,0s,4.2s;


  transition-delay:4.2s,0s,4.2s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(14).dashed-circle{


  -webkit-transition-delay:4.2s;


  transition-delay:4.2s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(13).red-flag{


  -webkit-transition-delay:3.9s,0s,3.9s;


  transition-delay:3.9s,0s,3.9s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(13).dashed-circle{


  -webkit-transition-delay:3.9s;


  transition-delay:3.9s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(12).red-flag{


  -webkit-transition-delay:3.5999999999999996s,0s,3.5999999999999996s;


  transition-delay:3.5999999999999996s,0s,3.5999999999999996s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(12).dashed-circle{


  -webkit-transition-delay:3.5999999999999996s;


  transition-delay:3.5999999999999996s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(11).red-flag{


  -webkit-transition-delay:3.3s,0s,3.3s;


  transition-delay:3.3s,0s,3.3s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(11).dashed-circle{


  -webkit-transition-delay:3.3s;


  transition-delay:3.3s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(10).red-flag{


  -webkit-transition-delay:3s,0s,3s;


  transition-delay:3s,0s,3s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(10).dashed-circle{


  -webkit-transition-delay:3s;


  transition-delay:3s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(9).red-flag{


  -webkit-transition-delay:2.6999999999999997s,0s,2.6999999999999997s;


  transition-delay:2.6999999999999997s,0s,2.6999999999999997s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(9).dashed-circle{


  -webkit-transition-delay:2.6999999999999997s;


  transition-delay:2.6999999999999997s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(8).red-flag{


  -webkit-transition-delay:2.4s,0s,2.4s;


  transition-delay:2.4s,0s,2.4s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(8).dashed-circle{


  -webkit-transition-delay:2.4s;


  transition-delay:2.4s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(7).red-flag{


  -webkit-transition-delay:2.1s,0s,2.1s;


  transition-delay:2.1s,0s,2.1s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(7).dashed-circle{


  -webkit-transition-delay:2.1s;


  transition-delay:2.1s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(6).red-flag{


  -webkit-transition-delay:1.7999999999999998s,0s,1.7999999999999998s;


  transition-delay:1.7999999999999998s,0s,1.7999999999999998s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(6).dashed-circle{


  -webkit-transition-delay:1.7999999999999998s;


  transition-delay:1.7999999999999998s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(5).red-flag{


  -webkit-transition-delay:1.5s,0s,1.5s;


  transition-delay:1.5s,0s,1.5s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(5).dashed-circle{


  -webkit-transition-delay:1.5s;


  transition-delay:1.5s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(4).red-flag{


  -webkit-transition-delay:1.2s,0s,1.2s;


  transition-delay:1.2s,0s,1.2s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(4).dashed-circle{


  -webkit-transition-delay:1.2s;


  transition-delay:1.2s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(3).red-flag{


  -webkit-transition-delay:0.8999999999999999s,0s,0.8999999999999999s;


  transition-delay:0.8999999999999999s,0s,0.8999999999999999s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(3).dashed-circle{


  -webkit-transition-delay:0.8999999999999999s;


  transition-delay:0.8999999999999999s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(2).red-flag{


  -webkit-transition-delay:0.6s,0s,0.6s;


  transition-delay:0.6s,0s,0.6s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(2).dashed-circle{


  -webkit-transition-delay:0.6s;


  transition-delay:0.6s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(1).red-flag{


  -webkit-transition-delay:0.3s,0s,0.3s;


  transition-delay:0.3s,0s,0.3s;


  }


  .radar.lying-down.radar-map:not(.roaming).risk-elements-group:nth-child(1).dashed-circle{


  -webkit-transition-delay:0.3s;


  transition-delay:0.3s;


  }


  .radar.pause-animation.inner-scanner,


  .radar.pause-animation.scanning-dashed-circle,


  .radar.pause-animation.scanning-dashed-empty-circle{


  -webkit-animation-play-state:paused;


  animation-play-state:paused;


  }


  .radar.pause-animation.changing-number-container{


  display:none;


  }


  .radar.pause-animation.risk-points{


  display:none;


  }


  .radar.pause-animation.scanning-circle{


  -webkit-transform:scale(0);


  transform:scale(0);


  opacity:0;


  }


  html,


  body{


  width:100%;


  height:100%;


  }


  body{


  font-size:0.8em;


  margin:0;


  background-color:black;


  }


  .radar{


  left:0;


  right:0;


  top:0;


  bottom:0;


  margin:auto;


  }


  #radar-switch-btn{


  position:absolute;


  left:0;


  top:0;


  color:white;


  }


  @mediaonlyscreenand(max-device-width:667px)and(-webkit-min-device-pixel-ratio:2){


  .radar{


  overflow:hidden;


  }


  }


  JavaScript代码


  JS代码主要是实现向雷达div容器中注入其他元素以及3D地图中地点标注信息的切换展示,代码如下:


  functionRadar(radarContainer){


  radarContainer.innerHTML='


  \


  \


  \


  \


  \


  \


  \


  \


  \


  \


  \


  \


  \


  \


  \


  \


  \


  \


  \


  \


  ';


  this._container=radarContainer;


  this._containerWidth=this._container.offsetWidth;


  this._containerHeight=this._container.offsetHeight;


  this._centerX=this._containerWidth/2;


  this._centerY=this._containerHeight/2;


  //跟风险点"蒙版"有关的变量


  this._maskCtx=(function(cw,ch){


  varc=document.createElement('canvas');


  c.width=cw;


  c.height=ch;


  returnc.getContext('2d');


  })(this._containerWidth,this._containerHeight);


  this._maskSectorDegree=60;//雷达扇形所占角度


  this._maskStartDegree=0;//雷达扇形开始扫描的角度


  this._scanSpeed=2;//雷达扫描速度,单位为deg


  this._outerScanner=this._container.querySelector('.outer-scanner');//外层雷达扫描器


  this._riskPointsContainer=this._container.querySelector('.risk-points');


  this._allRiskPointsArr=[];//保存所有风险点的数组,改变雷达扫描速度时要用到这些信息


  this._tmpRiskPointsArr=[];//初始化时保存所有的风险点,雷达扫描过程中会遍历这个数组,并把当前扫描到的风险点从这个数组移动到保存风险点的对象中,雷达扫描玩一遍之后这个数组为空。这样做避免雷达扫描时重复遍历风险点,特别是当有很多风险点的时候


  this._riskPoints={};//以扫描角度为键值保存风险点信息


  this._riskElements=[];//与风险点相关的虚线圆圈、红旗、信息面面和位置信息


  this._curRoamingIndex=0;//当前漫游的风险点索引


  this._radarMap=this._container.querySelector('.radar-map');


  this._roamingDuration=0;//两个风险点之间漫游时长


  this._changingNumberContainer=this._container.querySelector('.changing-number-container');//不断变化的数字


  this._digits_base=Math.pow(10,Math.min(this._changingNumberContainer.dataset.number.length,16));//数字位数,最大为16


  this._mapTranslateZ=(function(container){//相机漫游时拉近的距离


  varfontSize=parseInt(getComputedStyle(container).fontSize);


  return300/16*fontSize;


  })(this._container);


  this._scaleFactor=this._radarMap.offsetWidth/this._containerWidth;//为了使地图拉近之后不失真而放大的倍数


  this._rotateX=70;//地图倒下旋转的角度


  }


  /*外部调用的方法*/


  Radar.prototype.init=function(options){


  /*


  options={


  scanSpeed:2//扫描的速度,单位为deg


  }


  */


  options.scanSpeed&&(this._scanSpeed=parseInt(options.scanSpeed));


  this._createCanvasElements();


  this._drawLineAndCircle();


  this._drawDashedCircle();


  this._drawDashedEmptyCircle();


  this._drawScannerSector();


  this._animate();


  this._initEvent();


  };


  //添加风险点


  Radar.prototype.addRiskPoints=function(points){


  if(!(pointsinstanceofArray)){


  points=[points];


  }


  points.forEach(this._addOneRiskPoint.bind(this));


  };


  //一次设置多个风险点


  Radar.prototype.setRiskPoints=function(points){


  this._removeAllRiskPoints();


  this.addRiskPoints(points);


  };


  //调整雷达扫描速度


  Radar.prototype.changeScanSpeed=function(perTimeDeg){


  perTimeDeg=parseInt(perTimeDeg);


  if(perTimeDeg==this._scanSpeed||360%perTimeDeg!=0){//每次旋转的角度必须是360的约数,否则可能会出现跳过风险点的情况


  return;


  }


  this._riskPoints={};


  this._tmpRiskPointsArr=this._allRiskPointsArr;


  this._scanSpeed=perTimeDeg;


  };


  //雷达状态切换


  Radar.prototype.roamingToggle=function(){


  this._container.classList.toggle('lying-down');


  if(this._isLyingDown()){


  //倒下之后停止动画绘制


  this._pauseAnimation();


  }else{


  this._radarMap.classList.remove('roaming');


  this._radarMap.style.removeProperty('transform');


  }


  };


  Radar.prototype.startRoaming=function(){


  this._container.classList.add('lying-down');


  this._pauseAnimation();


  };


  Radar.prototype.stopRoaming=function(){


  this._container.classList.remove('lying-down');


  this._radarMap.classList.remove('roaming');


  this._radarMap.style.removeProperty('transform');


  };


  /*私有方法*/


  Radar.prototype._addOneRiskPoint=function(options){


  /**


  options={


  type:'type1',//'type1'或者'type2',风险点的颜色是红色还是蓝色


  severity:'critical',//风险严重程度,'ordinary'表示普通,'critical'表示严重


  coords:[134.7728099,53.56097399999999],//城市的经纬度


  city:'北京',


  title:'大额预授权交易异常',


  total:3//风险卡的数量


  }


  **/


  //计算风险点屏幕坐标


  varpointCoords=this._geoCoordsToScreenCoords(options.coords),


  point_x=pointCoords[0],


  point_y=pointCoords[1];


  /*//计算风险点索引


  varriskPointIndex=this._calcRiskPointIndex(point_x,point_y);


  if(!this._riskPoints[riskPointIndex]){


  varriskPointGroup=document.createElement('div');//相同索引的风险点放在一组


  riskPointGroup.className='risk-point-group';


  this._riskPointsContainer.appendChild(riskPointGroup);


  this._riskPoints[riskPointIndex]=riskPointGroup;


  }*/


  //创建风险点元素


  varriskPoint=document.createElement('div');


  riskPoint.className='risk-point'+options.type+''+options.severity;


  if(options.type=='pulsation'){


  riskPoint.innerHTML='


  \


  \


  ';


  }


  //this._riskPoints[riskPointIndex].appendChild(riskPoint);


  //计算并设置风险点位置


  varpoint_left=point_x-riskPoint.offsetWidth/2,


  point_top=point_y-riskPoint.offsetHeight/2;


  riskPoint.style.cssText='left:'+point_left+'px;top:'+point_top+'px;';


  varriskPointItem={


  x:point_x,


  y:point_y,


  target:riskPoint


  };


  this._allRiskPointsArr.push(riskPointItem);


  this._tmpRiskPointsArr.push(riskPointItem);


  //创建跟风险点相关的红旗、虚线圆圈和信息面板


  varelements_group=document.createElement('div');


  elements_group.className='risk-elements-group';


  elements_group.innerHTML='


  \


  \


  \


  '+options.title+'


  \


  \


  \


  风险发生地:'+options.city+'\


  \


  \


  风险卡片:'+options.total+'\


  \


  \


  ';


  this._radarMap.appendChild(elements_group);


  vardashed_circle=elements_group.querySelector('.dashed-circle'),


  red_flag=elements_group.querySelector('.red-flag'),


  info_panel=elements_group.querySelector('.info-panel');


  dashed_circle.style.backgroundImage='url('+this._getDashedCircleBg(dashed_circle.offsetWidth)+')';


  //计算和设置圆圈、红旗、信息面板的位置


  vardashed_circle_left=point_x*this._scaleFactor-dashed_circle.offsetWidth/2,


  dashed_circle_top=point_y*this._scaleFactor-dashed_circle.offsetHeight/2,


  red_flag_left=point_x*this._scaleFactor-red_flag.offsetWidth/2,


  red_flag_top=point_y*this._scaleFactor-red_flag.offsetHeight,


  info_panel_left=point_x*this._scaleFactor-info_panel.offsetWidth/2,


  info_panel_top=point_y*this._scaleFactor-info_panel.offsetHeight;


  dashed_circle.style.left=dashed_circle_left+'px';


  dashed_circle.style.top=dashed_circle_top+'px';


  if(this._isLyingDown()){


  dashed_circle.style.visibility='visible';


  }


  red_flag.style.left=red_flag_left+'px';


  red_flag.style.top=red_flag_top+'px';


  info_panel.style.left=info_panel_left+'px';


  info_panel.style.top=info_panel_top+'px';


  //保存与风险点相关的元素


  this._riskElements.push({


  name:options.city,


  riskPoint:riskPoint,


  dashedCircle:dashed_circle,


  redFlag:red_flag,


  infoPanel:info_panel,


  translate:[(this._containerWidth*0.5-point_x)*this._scaleFactor,this._calcTYByTZ(this._mapTranslateZ,dashed_circle.offsetHeight/2)-point_y*this._scaleFactor],


  rotateY:(function(riskElements){


  //旋转的角度正负零交替


  varbase_deg=10,


  max_deviation_deg=5;


  varpn=(riskElements.length%2)*2-1;//positiveornegative


  varnew_base_deg=Math.ceil((riskElements.length+1)%3/2)*base_deg;//1010010100...


  returnpn*(new_base_deg+Math.round(Math.random()*max_deviation_deg));


  })(this._riskElements),


  transformOrigin:Math.round(point_x/this._containerWidth*100)+'%'


  });


  //旋转信息面板,使信息面板转到眼前时正对镜头


  varrotate_deg=this._riskElements[this._riskElements.length-1].rotateY;


  info_panel.style.transform=getComputedStyle(info_panel).transform+'rotateY('+(-rotate_deg)+'deg)';


  };


  //根据名称删除风险点


  Radar.prototype._removeRiskPointByName=function(name){


  for(vari=0,len=this._riskElements.length;i<len;i++){


  varcurRiskElement=this._riskElements[i];


  if(curRiskElement.name==name){


  varriskPointGroup=curRiskElement.riskPoint.parentElement,


  riskElementsGroup=curRiskElement.dashedCircle.parentElement;


  riskPointGroup.removeChild(curRiskElement.riskPoint);


  this._radarMap.removeChild(riskElementsGroup);


  this._riskElements.splice(i,1);


  returntrue;


  }


  }


  returnfalse;


  };


  //删除所有风险点


  Radar.prototype._removeAllRiskPoints=function(){


  vartotal=this._riskElements.length;


  this._radarMap.innerHTML='';


  this._riskPointsContainer.innerHTML='';


  this._riskPoints={};


  this._riskElements=[];


  returntotal;


  };


  //暂停动画


  Radar.prototype._pauseAnimation=function(){


  cancelAnimationFrame(this._requestId);


  this._container.classList.add('pause-animation');


  };


  //恢复动画


  Radar.prototype._resumeAnimation=function(){


  this._requestId=requestAnimationFrame(this._animate.bind(this));


  this._container.classList.remove('pause-animation');


  };


  //创建canvas标签


  Radar.prototype._createCanvasElements=function(){


  varscanningCircleElement=this._container.querySelector('.scanning-circle');


  //绘制雷达静止的线框和圆圈用到的canvas


  varcanvas=document.createElement('canvas');


  canvas.width=this._containerWidth;


  canvas.height=this._containerHeight;


  scanningCircleElement.appendChild(canvas);


  this._lineAndCircleCanvas=canvas;


  //绘制内部旋转的"虚线"圆圈用到的canvas


  this._dashedCircleCanvas=canvas.cloneNode(true);


  this._dashedCircleCanvas.className='scanning-dashed-circle';


  scanningCircleElement.appendChild(this._dashedCircleCanvas);


  //绘制内部旋转的"空心虚线"圆圈用到的canvas


  this._dashedEmptyCircleCanvas=canvas.cloneNode(true);


  this._dashedEmptyCircleCanvas.className='scanning-dashed-empty-circle';


  scanningCircleElement.appendChild(this._dashedEmptyCircleCanvas);


  };


  //地理坐标转换成屏幕坐标


  Radar.prototype._geoCoordsToScreenCoords=function(geoCoords){//geoCoords:经纬度数组


  varchina_geometry_bounds=[73.4994136,53.56097399999999,61.2733963,35.40335839999999];//西北的经纬度和经纬度跨度


  varpoint_x=Math.abs(geoCoords[0]-china_geometry_bounds[0])/china_geometry_bounds[2]*this._containerWidth,


  point_y=Math.abs(geoCoords[1]-china_geometry_bounds[1])/china_geometry_bounds[3]*this._containerHeight;


  return[point_x,point_y];


  };


  //计算风险点的索引(雷达扇形扫描到多少度时要显示这个风险点)


  Radar.prototype._calcRiskPointIndex=function(point_x,point_y){


  varpoint_offset_x=point_x-this._centerX,//与中心点的偏移


  point_offset_y=this._centerY-point_y,


  riskPointRadian=-Math.atan(point_offset_y/point_offset_x);//风险点在雷达扫描圆形的弧度


  if(point_offset_x<0){


  riskPointRadian-=Math.PI;


  }elseif(point_offset_y<0){


  riskPointRadian-=Math.PI*2;


  }


  varriskPointDeg=180/Math.PI*riskPointRadian;


  varriskPointIndex='_deg_'+riskPointDeg.toFixed();


  returnriskPointIndex;


  };


  //根据地图倒下之后translateZ的大小计算风险点应该拉近到相机前面的y值,使得风险点向镜头拉近后正好在屏幕正下方


  Radar.prototype._calcTYByTZ=function(tz,dashed_circle_r){


  varp=parseInt(getComputedStyle(this._container).perspective),//原始视角


  pr=(p-tz)/p,//应用translateZ后的视角比例


  point_screen_bottom_offset=dashed_circle_r/pr,//风险点漫游时要平移到的位置与屏幕底部的偏移量


  tr_o_offset_y=pr*(document.body.clientHeight-this._containerHeight/2-this._container.getBoundingClientRect().top-point_screen_bottom_offset);//最后相机要拉近到的y值与transformorigin中心点的偏移量


  returnthis._radarMap.offsetHeight/2+tr_o_offset_y;


  };


  /*Radar.prototype._calcTYByTZ=function(tz,dashed_circle_r){


  varp=parseInt(getComputedStyle(this._container).perspective),//原始视角


  pr=(p-tz)/p,//应用translateZ后的视角比例


  tmp_tr_o_offset_y=document.body.clientHeight-this._containerHeight/2-this._container.getBoundingClientRect().top;//最后相机要拉近到的y值与transformorigin中心点的偏移量


  vartr_o_offset_y=this._calcOffsetBeforeRotateX(tmp_tr_o_offset_y,this._rotateX,p-tz);


  returnthis._radarMap.offsetHeight/2+tr_o_offset_y*pr;


  };*/


  //根据绕x轴旋转之后风险点的位置计算旋转之前风险点要平移到的位置


  Radar.prototype._calcOffsetBeforeRotateX=function(newOffset,rotateX,oldPerspective){//计算不正确


  //(newOffset/cos(rotateX))/x=oldPerspective/(oldPerspective-x*sin(rotateX))


  varx1=newOffset/Math.cos(Math.PI/180*rotateX);


  returnoldPerspective*x1/(oldPerspective+x1*Math.sin(Math.PI/180*rotateX));


  };


  //动画


  Radar.prototype._animate=function(){


  this._rotateRiskPointMask();


  this._changeNumber();


  this._requestId=requestAnimationFrame(arguments.callee.bind(this));


  };


  //变化数字


  Radar.prototype._changeNumber=function(){


  var_assist_number=arguments.callee._assist_number||0;


  if(_assist_number%6==0){


  varnumber=Math.round(Math.random()*this._digits_base);


  this._changingNumberContainer.dataset.number=number;


  }


  arguments.callee._assist_number=(++_assist_number)%360;


  };


  //绘制雷达静止的线框和圆圈


  Radar.prototype._drawLineAndCircle=function(){


  varradius=this._containerHeight/2,


  ctx=this._lineAndCircleCanvas.getContext('2d');


  //最外层圆圈


  varlineWidth=5;


  ctx.lineWidth=lineWidth;


  ctx.strokeStyle='#0146C2';


  ctx.beginPath();


  ctx.arc(this._centerX,this._centerY,radius-lineWidth/2,0,Math.PI*2);


  ctx.closePath();


  ctx.stroke();


  //内部圆圈


  ctx.fillStyle='rgba(30,199,230,.5)';


  ctx.beginPath();


  ctx.arc(this._centerX,this._centerY,3,0,Math.PI*2);


  ctx.closePath();


  ctx.fill();


  vartotalCircle=8;


  ctx.lineWidth=0.5;


  ctx.strokeStyle='rgba(30,199,230,.5)';


  for(vari=0;i<totalCircle-1;i++){


  ctx.beginPath();


  ctx.arc(this._centerX,this._centerY,radius/totalCircle*(i+1),0,Math.PI*2);


  ctx.closePath();


  ctx.stroke();


  }


  //内部直线


  vartotalLines=14;


  ctx.save();


  ctx.lineWidth=0.3;


  ctx.translate(this._centerX,this._centerY);


  ctx.rotate(Math.PI/totalLines);


  for(vari=0;i<totalLines;i++){


  ctx.rotate(Math.PI*2/totalLines);


  ctx.beginPath();


  ctx.moveTo(0,0);


  ctx.lineTo(0,-radius+lineWidth);


  ctx.closePath();


  ctx.stroke();


  }


  ctx.restore();


  //内部虚线


  ctx.save();


  ctx.setLineDash([2,8]);


  ctx.translate(this._centerX,this._centerY);


  for(vari=0;i<totalLines/2;i++){


  ctx.rotate(Math.PI*4/totalLines);


  ctx.beginPath();


  ctx.moveTo(0,0);


  ctx.lineTo(0,-radius+lineWidth);


  ctx.closePath();


  ctx.stroke();


  }


  ctx.restore();


  };


  //绘制内部旋转的"虚线"圆圈


  Radar.prototype._drawDashedCircle=function(){


  varctx=this._dashedCircleCanvas.getContext('2d');


  ctx.clearRect(-this._centerX,-this._centerY,this._dashedCircleCanvas.width,this._dashedCircleCanvas.height);


  ctx.globalAlpha=0.8;


  ctx.lineWidth=5;


  ctx.translate(this._centerX,this._centerY);


  varradius=this._containerHeight/2/8*7-ctx.lineWidth/2;


  ctx.strokeStyle='#016FB7';


  ctx.beginPath();


  ctx.arc(0,0,radius,0,Math.PI/5);


  ctx.stroke();


  ctx.strokeStyle='#23B2D8';


  ctx.rotate(Math.PI/3);


  ctx.beginPath();


  ctx.arc(0,0,radius,0,Math.PI/6);


  ctx.stroke();


  ctx.strokeStyle='#80DEF9';


  ctx.rotate(Math.PI/3);


  ctx.beginPath();


  ctx.arc(0,0,radius,0,Math.PI/18);


  ctx.stroke();


  ctx.strokeStyle='#085BAF';


  ctx.rotate(Math.PI/4);


  ctx.beginPath();


  ctx.arc(0,0,radius,0,Math.PI/9);


  ctx.stroke();


  };


  //绘制内部旋转的空心虚线圆圈


  Radar.prototype._drawDashedEmptyCircle=function(){


  varctx=this._dashedEmptyCircleCanvas.getContext('2d');


  ctx.clearRect(-this._centerX,-this._centerY,this._dashedEmptyCircleCanvas.width,this._dashedEmptyCircleCanvas.height);


  ctx.strokeStyle='#5298D3';


  ctx.globalAlpha=0.3;


  ctx.translate(this._centerX,this._centerY);


  varradius=this._containerHeight/2/8*6,


  radiusDeviation=5,//空心虚线的高度


  innerRadius=radius-radiusDeviation;


  ctx.beginPath();


  ctx.arc(0,0,radius,0,Math.PI/5);


  ctx.arc(0,0,innerRadius,Math.PI/5,0,true);


  ctx.closePath();


  ctx.stroke();


  ctx.rotate(Math.PI/3);


  ctx.beginPath();


  ctx.arc(0,0,radius,0,Math.PI/6);


  ctx.arc(0,0,innerRadius,Math.PI/6,0,true);


  ctx.closePath();


  ctx.stroke();


  ctx.rotate(Math.PI/3);


  ctx.beginPath();


  ctx.arc(0,0,radius,0,Math.PI/18);


  ctx.arc(0,0,innerRadius,Math.PI/18,0,true);


  ctx.closePath();


  ctx.stroke();


  ctx.rotate(Math.PI/4);


  ctx.beginPath();


  ctx.arc(0,0,radius,0,Math.PI/9);


  ctx.arc(0,0,innerRadius,Math.PI/9,0,true);


  ctx.closePath();


  ctx.stroke();


  };


  //绘制雷达扫描锥形渐变扇形


  Radar.prototype._drawScannerSector=function(){


  //创建canvas元素


  varc=document.createElement('canvas');


  c.width=c.height=this._containerHeight;


  this._outerScanner.querySelector('.umbrella').appendChild(c);


  //绘制锥形渐变


  varctx=c.getContext('2d');


  varsectorCnt=10;//用10块扇形模拟锥形渐变


  varstartDeg=-90,endDeg;


  varsectorRadius=this._containerHeight/2;


  ctx.translate(sectorRadius,sectorRadius);


  ctx.fillStyle='rgba(19,182,206,0.2)';


  for(vari=0;i<sectorCnt;i++){


  endDeg=startDeg+this._maskSectorDegree-this._maskSectorDegree/sectorCnt*i;


  ctx.beginPath();


  ctx.moveTo(0,0);


  ctx.lineTo(0,sectorRadius);


  ctx.arc(0,0,sectorRadius,Math.PI/180*(startDeg-180),Math.PI/180*endDeg);


  ctx.closePath();


  ctx.fill();


  }


  };


  //旋转只显示风险点的区域


  Radar.prototype._rotateRiskPointMask=function(){


  functionangleToRadian(angle){


  returnMath.PI/180*angle;


  }


  this._maskStartDegree=this._maskStartDegree%360;


  this._maskCtx.beginPath();


  this._maskCtx.moveTo(this._centerX,this._centerY);


  this._maskCtx.arc(this._centerX,this._centerY,this._containerHeight/2,


  angleToRadian(this._maskStartDegree),angleToRadian


  (this._maskStartDegree+this._maskSectorDegree));


  this._maskCtx.lineTo(this._centerX,this._centerY);


  this._maskCtx.closePath();


  //控制风险点的显示


  varriskPointIndex='_deg_'+this._maskStartDegree;


  if(!this._riskPoints[riskPointIndex]&&this._tmpRiskPointsArr.length>0){


  //todo:这里先判断this._riskPoints[riskPointIndex]可能会出现不去处理this._tmpRiskPointsArr的情况,特别是当风险点在某一块区域很密集的时候,而且后面添加的风险点都会另开一组


  varthat=this;


  this._tmpRiskPointsArr.forEach(function(point){


  if(that._maskCtx.isPointInPath(point.x,point.y)){


  //把当前扫描到的风险点缓存起来


  if(!that._riskPoints[riskPointIndex]){


  varriskPointGroup=document.createElement('div');//相同索引的风险点放在一组


  riskPointGroup.className='risk-point-group';


  that._riskPointsContainer.appendChild(riskPointGroup);


  that._riskPoints[riskPointIndex]=riskPointGroup;


  }


  that._riskPoints[riskPointIndex].appendChild(point.target);


  point._willDelete=true;//将要删除的标记


  }


  });


  //遍历完之后删除已处理过的风险点


  this._tmpRiskPointsArr=this._tmpRiskPointsArr.filter(function(pointItem){


  varflag=!pointItem._willDelete;


  deletepointItem._willDelete;


  returnflag;


  });


  }


  this._riskPoints[riskPointIndex]&&this._riskPoints[riskPointIndex].classList.add('flashing');


  //旋转雷达扫描扇形


  this._outerScanner.style.transform='rotate('+this._maskStartDegree+'deg)translateZ(0)';


  this._maskStartDegree-=this._scanSpeed;


  };


  //绘制风险点旋转的虚线圆圈背景


  Radar.prototype._getDashedCircleBg=function(radius){


  varcenter_x=radius/2,


  center_y=radius/2;


  varc=document.createElement('canvas');


  c.width=radius;


  c.height=radius;


  varctx=c.getContext('2d');


  ctx.strokeStyle='#EAFF00';


  ctx.shadowColor='#EAFF00';


  ctx.shadowBlur=radius/25;


  代码中注释比较详细,有兴趣的同学可以自己进行研究下,HTML5和CSS3真是非常的强大,以上就是关于扣丁学堂HTML5视频教程之HTML5+CSS33D雷达扫描动画的详细介绍,最后想要工作不累就要不断的提升自己的技能,请关注扣丁学堂官网、微信等平台,扣丁学堂IT职业在线学习教育平台为您提供权威的HTML5培训视频教程系统,通过千锋扣丁学堂金牌讲师在线录制的第一套自适应HTML5在线视频课程系统,让你快速掌握HTML5从入门到精通开发实战技能。扣丁学堂H5技术交流群:751662650。



高工
2020-11-06 22:53:40     打赏
2楼

感谢分享


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]