基于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 相关文章推荐
jQuery checkbox全选/取消全选实现代码
Nov 14 Javascript
基于JQuery的密码强度验证代码
Mar 01 Javascript
深入理解JavaScript系列(9) 根本没有“JSON对象”这回事!
Jan 15 Javascript
MooBox 基于Mootools的对话框插件
Jan 20 Javascript
Node.js编写爬虫的基本思路及抓取百度图片的实例分享
Mar 12 Javascript
json传值以及ajax接收详解
May 24 Javascript
javaScript动态添加Li元素的实例
Feb 24 Javascript
基于javascript的拖拽类封装详解
Apr 19 Javascript
layui自定义插件citySelect实现省市区三级联动选择
Jul 26 Javascript
Node.JS枚举统计当前文件夹和子目录下所有代码文件行数
Aug 23 Javascript
Vue优化:常见会导致内存泄漏问题及优化详解
Aug 04 Javascript
区分vue-router的hash和history模式
Oct 03 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
Apache2 httpd.conf 中文版
2006/11/17 PHP
phpword插件导出word文件时中文乱码问题处理方案
2014/08/19 PHP
jQuery+PHP发布的内容进行无刷新分页(Fckeditor)
2015/10/22 PHP
php用户登录之cookie信息安全分析
2016/05/13 PHP
PHP chr()函数讲解
2019/02/11 PHP
window.onbeforeunload方法在IE下无法正常工作的解决办法
2010/01/23 Javascript
jquery插件制作教程 txtHover
2012/08/17 Javascript
event对象获取方法总结在google浏览器下测试
2013/11/03 Javascript
javascript内存管理详细解析
2013/11/11 Javascript
jquery实现可旋转可拖拽的文字效果代码
2016/01/27 Javascript
jQuery实现百度登录框的动态切换效果
2017/04/21 jQuery
AngularJS使用ng-repeat遍历二维数组元素的方法详解
2017/11/11 Javascript
详解VueJs中的V-bind指令
2018/05/03 Javascript
Vue 按键修饰符处理事件的方法
2018/05/04 Javascript
nodejs使用async模块同步执行的方法
2019/03/02 NodeJs
js实现查询商品案例
2020/07/22 Javascript
VUE实现吸底按钮
2021/03/04 Vue.js
[02:34]DOTA2亚洲邀请赛 BG战队出场宣传片
2015/03/09 DOTA
[02:30]辉夜杯主赛事第二日胜者组半决赛 CDEC.Y赛后采访
2015/12/26 DOTA
[06:14]《辉夜杯》外卡赛附加赛 4支战队巡礼
2015/10/23 DOTA
python命令行参数解析OptionParser类用法实例
2014/10/09 Python
Python实现的朴素贝叶斯分类器示例
2018/01/06 Python
解读python如何实现决策树算法
2018/10/11 Python
使用python根据端口号关闭进程的方法
2018/11/06 Python
解决新django中的path不能使用正则表达式的问题
2018/12/18 Python
Python数据可视化库seaborn的使用总结
2019/01/15 Python
python Django 反向访问器的外键冲突解决
2020/05/20 Python
使用keras根据层名称来初始化网络
2020/05/21 Python
python变量的作用域是什么
2020/05/26 Python
Python Dataframe常见索引方式详解
2020/05/27 Python
HTML5新增加标签和功能概述
2016/09/05 HTML / CSS
白宫黑市官网:White House Black Market
2016/11/17 全球购物
Notino瑞典:购买香水和美容产品
2019/07/26 全球购物
公安局班子个人对照检查材料思想汇报
2014/10/09 职场文书
行政复议决定书
2015/06/24 职场文书
MySQL 如何分析查询性能
2021/05/12 MySQL