基于D3.js实现时钟效果


Posted in Javascript onJuly 17, 2018

今天做了一个小时钟动画,因为学习canvas也做过一个时钟,所以想着可不可以使用d3来做个时钟动画。

主要利用的还是饼图这个布局,添加了一个圆形颜色渐变的效果。

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>时钟</title>
</head>
<body>
 
 <script type="text/javascript" src='../../../js/d3.js'></script>
 <script type="text/javascript">
 
 var width = 500,
 height = 500;
 var svg = d3.select('body').append("svg").attr("width", width).attr("height", height);
 var innerRadius = 190, //圆的内半径、外半径
 outerRadius = 200; 
 var arc = d3.svg.arc() //弧生成器
 .innerRadius(innerRadius) //设置内半径、0则为实心圆
 .outerRadius(outerRadius); //设置外半径
 
 //下面的数组的作用是这样的:
 //首先我的圆的颜色渐变的,而我的渐变方法是将圆切割成很多份,每份是渐变过程中的一个颜色。
 //当切割的份数多的时候就是看起来像渐变的一样。 
 //下面的时针、分针、秒针也会在指着不同的角度的时候同时改变自身的颜色。
 //当然也看到了其他的圆渐变的方法,你可以自己搜索。
 var sum = 1000; //sum代表圆被分成了多少份。 
 var num = new Array(); 
 for (var i = 0; i < sum; i++) {
 num.push(1);
 }
 var linear = d3.scale.linear() //通过线性比例尺来计算插值。
 .domain([0, sum])
 .range([0, 1])
 var arcs = svg.selectAll("g")
 .data(d3.layout.pie()(num)) //绑定转换后的数据piedata
 .enter()
 .append("g")
 .attr("transform", "translate(" + (width / 2) + "," + (height / 2) + ")");
 
 var color = d3.scale.category10()
 var a = d3.rgb(0, 255, 255); //红色 设置渐变颜色的起始
 var b = d3.rgb(255, 255, 0); //绿色
 var c = d3.rgb(255, 0, 0);
 var compute = d3.interpolate(a, b); //他的值是介于0-1的
 
 
 arcs.append("path")
 .attr('fill', function(d, i) {
 return compute(linear(i)); //通过上面的linear比例函数看i当前是在多少。当然也可以直接(1/sum*i)
 })
 .attr('stroke-width', "0")
 .attr("d", function(d) {
 return arc(d); //使用弧生成器
 });
 
 //下面是给将圆给分成了60等份
 var num2 = new Array();
 for (var i = 0; i < 60; i++) num2.push(i);
 var ticks = svg.append('g').selectAll('g')
 .data(num2)
 .enter()
 .append('g')
 .attr("transform", "translate(" + (width / 2) + "," + (height / 2) + ")")
 ;
 
 ticks.append("line")
   .attr("x1", 1)
   .attr("x1", 0)
   .attr("x2", function(d,i){
    return i%15==0?10:6; //添加圆内的刻度线 根据是不是3、6、9、12来判断是否加长
   })
   .attr("y2", 0)
   .attr('transform',function(d,i){
    
    return "rotate(" + (6*i -90) + ")" 
      + "translate(" + (innerRadius-10) +")";
   })
   .style('stroke',function(d,i){
    return compute(i/60);
   })
   .style('stroke-width',5); 
 
 ticks.append("text")
 .attr('transform', function(d, i) {
 var angle = (Math.PI * 2) / 60 * i - Math.PI;
 return "translate(" + (Math.sin(angle) * (innerRadius - 20) ) + "," + (Math.cos(angle) * (innerRadius - 20) )+ ")";
 })
 .attr("x", 8)
 .attr("dy", ".35em")
 .style('font-size', function(d, i) {
 if (i % 15 == 0)
  return "2em"
 })
 .style("text-anchor", function(d) {
 return i > 29 ? "end" : null;
 })
 .text(function(d, i) {
 return !(i % 5) ? (60 - i) / 5 : null;
 });
 
 var arc2 = d3.svg.arc().innerRadius(0).outerRadius(10);
 
 svg.selectAll('g')
 .data(d3.layout.pie()(num))
 .enter()
 .append('g')
 arcs.append("path")
 .attr('fill', function(d, i) {
 return compute(linear(i))
 })
 .attr("d", function(d, i) {
 return arc2(d);
 });
 
 var SecondsLine = svg.append('g').append('line')
 .attr("x1", width / 2)
 .attr("y1", height / 2)
 .style('stroke-width', 1)
 
 
 var MinutesLine = svg.append('g').append('line')
 .attr('x1', width / 2)
 .attr('y1', height / 2)
 .style('stroke-width', 3)
 
 var HoursLine = svg.append('g').append('line')
 .attr('x1', width / 2)
 .attr('y1', height / 2)
 .style('stroke-width', 5);
 
 var str=[1];
 var updatetimetext=svg.append('g')
 .selectAll('.timetext').data(str)
 .enter()
 .append('text')
 .attr('class', 'timetext')
 .text(function(d, i) {
  return d;
 })
 .attr('transform', function(d, i) {
  return "translate(" + (width / 2) + "," + (height - 20) + ")"
 })
 .style('text-anchor', "middle")
 .style('font-size', "2em");
 function chuli() {
 var d = new Date();
 var dm = d.getTime() % 1000;
 var h = (d.getHours() >= 12 ? d.getHours() - 12 : d.getHours());
 var m = d.getMinutes();
 var s = d.getSeconds();
 var angle = (Math.PI * 2) / 60 * (60 - s) + Math.PI;
 var angle2 = (Math.PI * 2) / (60 * 60) * ((60 * 60 - m * 60-s)) + Math.PI;
 var angle3 = (Math.PI * 2) / (12 * 60 * 60) * (12 * 60 * 60 - h * 60 * 60 - m * 60 - s) + Math.PI;
 SecondsLine.attr('x2', function(d, i) {
  return width / 2 + (innerRadius - 30) * Math.sin(angle);
 })
 .attr('y2', function(d, i) {
  return height / 2 + (innerRadius - 30) * Math.cos(angle);
 })
 .style('stroke', compute((s / 60)));
 
 MinutesLine.attr('x2', function(d, i) {
  return width / 2 + (innerRadius - 50) * Math.sin(angle2);
 })
 .attr('y2', function(d, i) {
  return height / 2 + (innerRadius - 50) * Math.cos(angle2);
 })
 .style('stroke', compute((m / 60)));
 
 HoursLine.attr('x2', function(d, i) {
  return width / 2 + (innerRadius - 80) * Math.sin(angle3);
 })
 .attr('y2', function(d, i) {
  return height / 2 + (innerRadius - 80) * Math.cos(angle3);
 })
 .style('stroke', compute((h / 12)));
 
 str.pop();    //删除上一个文本
 str.push(d.getHours()+":"+(m<10?"0"+m:m)+":"+(s<10?"0"+s:s)); //存入新的时间并且一位数时补0
 updatetimetext.data(str).text(function(d){return d;}) //更新时间
  
 
 
 setTimeout(chuli, 1000 - dm);//获取当前的毫秒,用1000减去,则是到下一秒的毫秒时间。
 }
 chuli();
 
 </script>
</body>
</html>

效果图:

基于D3.js实现时钟效果

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
使用IE的地址栏来辅助调试Web页脚本
Mar 08 Javascript
向fckeditor编辑器插入指定代码的方法
May 25 Javascript
初学Javascript的一些总结
Nov 03 Javascript
js实现双向链表互联网机顶盒实战应用实现
Oct 28 Javascript
深入理解JavaScript系列(9) 根本没有“JSON对象”这回事!
Jan 15 Javascript
JS实现点击图片在当前页面放大并可关闭的漂亮效果
Oct 18 Javascript
js(jQuery)获取时间的方法及常用时间类搜集
Oct 23 Javascript
动态加载jQuery的方法
Jun 16 Javascript
微信小程序如何获取用户信息
Jan 26 Javascript
jQuery使用动画队列自定义动画操作示例
Jun 16 jQuery
微信小程序 image组件遇到的问题
May 28 Javascript
layer.msg()去掉默认时间,实现手动关闭的方法
Sep 12 Javascript
vue生成token并保存到本地存储中
Jul 17 #Javascript
vue脚手架搭建项目的兼容性配置详解
Jul 17 #Javascript
使用svg实现动态时钟效果
Jul 17 #Javascript
详解.vue文件中style标签的几个标识符
Jul 17 #Javascript
webstrom Debug 调试vue项目的方法步骤
Jul 17 #Javascript
vue实现未登录跳转到登录页面的方法
Jul 17 #Javascript
打通前后端构建一个Vue+Express的开发环境
Jul 17 #Javascript
You might like
色色整理的PHP面试题集锦
2012/03/08 PHP
php中unlink()、mkdir()、rmdir()等方法的使用介绍
2012/12/21 PHP
php的mail函数发送UTF-8编码中文邮件时标题乱码的解决办法
2015/10/20 PHP
PHP实现导出excel数据的类库用法示例
2016/10/15 PHP
PHP接口继承及接口多继承原理与实现方法详解
2017/10/18 PHP
checkbox 复选框不能为空
2009/07/11 Javascript
用Javascript 获取页面元素的位置的代码
2009/09/25 Javascript
HTML中setCapture、releaseCapture 使用方法浅析
2016/09/25 Javascript
jQuery给指定的table动态添加删除行的操作方法
2016/10/12 Javascript
利用JS实现简单的日期选择插件
2017/01/23 Javascript
BootStrap table删除指定行的注意事项(笔记整理)
2017/02/05 Javascript
利用HBuilder打包前端开发webapp为apk的方法
2017/11/13 Javascript
js实现鼠标单击Tab表单切换效果
2018/05/16 Javascript
jQuery实现获取form表单内容及绑定数据到form表单操作分析
2018/07/03 jQuery
对angularjs框架下controller间的传值方法详解
2018/10/08 Javascript
Vue项目安装插件并保存
2019/01/28 Javascript
对Python通过pypyodbc访问Access数据库的方法详解
2018/10/27 Python
JupyterNotebook设置Python环境的方法步骤
2019/12/03 Python
Python使用指定字符长度切分数据示例
2019/12/05 Python
Python csv文件记录流程代码解析
2020/07/16 Python
数据库什么时候应该被重组
2012/11/02 面试题
后勤人员自我鉴定
2013/10/20 职场文书
红领巾心向党广播稿
2014/01/19 职场文书
抗洪救灾先进集体事迹材料
2014/05/26 职场文书
服装设计师求职信
2014/06/04 职场文书
竞选学委演讲稿
2014/09/13 职场文书
三严三实对照检查材料
2014/09/22 职场文书
党员批评与自我批评范文
2014/09/23 职场文书
工程承包协议书
2014/10/20 职场文书
幼儿园中班个人总结
2015/02/28 职场文书
党支部季度考核意见
2015/06/02 职场文书
超级礼物观后感
2015/06/15 职场文书
MySQL快速插入一亿测试数据
2021/06/23 MySQL
Win11怎么启动任务管理器?Win11启动任务管理器的几种方法
2021/11/23 数码科技
Vue的生命周期一起来看看
2022/02/24 Vue.js
漫画《催眠麦克风-Dawn Of Divisions》第二卷PV公开
2022/04/05 日漫