点击右上方红色按钮关注“web秀”,让你真正秀起来

前言

前段时间看抖音,有人用时间轮盘作为动态的桌面壁纸,感觉很好玩,于是突发奇想,可以用JS来实现这个功能。

来来来,先看看成果

JavaScript时间轮盘:JS元素圆形布局制作时间轮盘动画

这个效果实现起来其实只有1个难点(其他都不是事),难点就是:元素圆形布局。

效果示意图

居然是圆,那我们肯定要知道圆心,和半径了,这样才能确定一个圆。

JavaScript时间轮盘:JS元素圆形布局制作时间轮盘动画

先看看上面这个效果图

解析:

1、圆心:O点、半径r;

2、圆心角:∠BOM;

3、需要布局的元素:A、B、C、D、E、F、G、H绝对定位的DIV元素;

4、DIV绝对定位时的元素的坐标点,可以用left值 和 top值

根据上图,我们知道圆心坐标,半径r的值,那就很容易计算B元素的lef和top。

OK,有了这些信息,我们还需要一些数学知识,先来了解一波,然后再开始制作。

概念定义

JavaScript时间轮盘:JS元素圆形布局制作时间轮盘动画

1、弧度:弧度是角的度量单位。

弧长等于半径的弧,其所对的圆心角为1弧度。(即两条射线从圆心向圆周射出,形成一个夹角和夹角正对的一段弧。当这段弧长正好等于圆的半径时,两条射线的夹角的弧度为1)。

根据定义,一周的弧度数为2πr/r=2π,360°角=2π弧度,因此,1弧度约为57.3°,即57°17'44.806'',1°为π/180弧度,近似值为0.01745弧度,周角为2π弧度,平角(即180°角)为π弧度,直角为π/2弧度。

弧长=n2πr/360 (在这里n就是角度数,即圆心角n所对应的弧长。)

2、正弦值:弦值是在直角三角形中,对边的长比上斜边的长的值。

Math.sin(x) : x 必需。一个以弧度表示的角。将角度乘以 0.017453293 (2PI/360)即可转换为弧度。

3、余弦值:是指直角三角形锐角邻边与斜边的比值。

有了这些基础知识,我们就可以正式开始用代码实现元素圆形布局了。

JS如何实现元素圆形布局了???

圆心角∠BOM是多少度?上面的图形,就是一个圆平均分成了8分,所以每份角度是: 360°/8。

有了角度,和半径r,我们就知道了MB的长度,即可知道B元素top值:

对边(MB ) = Math.sin(X) 斜边(r) = Math.sin( (360/8) PI/180 )* r

同理,我们也就知道了OM,即可知道B元素的left值:

邻边(OM) = Math.COS(X索引) 200

索引即当前元素是第几个

JavaScript时间轮盘:JS元素圆形布局制作时间轮盘动画

JavaScript时间轮盘:JS元素圆形布局制作时间轮盘动画

这时候会发现,效果不尽人意,圆心和各个元素位置存在偏差。这个差距恰好是每个元素宽高的一半,所以我们进一步处理,同时,对js做一下简单的封装,供后续使用

JavaScript时间轮盘:JS元素圆形布局制作时间轮盘动画

JavaScript时间轮盘:JS元素圆形布局制作时间轮盘动画

调用上面方法即可

JavaScript时间轮盘:JS元素圆形布局制作时间轮盘动画

有了圆形布局,一切就很简单了。下面我们吧日期填充到元素上面即可,同时注意每个圆的半径,不然其重合。

下面用到了moment.js,没有了解过的,可以先了解一波《moment.js日期时间管理的常用方法详细教程》

年份轮盘

先收集今年后10年的年份数据,并把数字转换成大写。

createYear(); function createYear() {  // 今年  var thisYear = moment().format('YYYY');  // 今年 + 10年  var futureYear = moment().add(10, 'Y').format('YYYY');   var yearlistText = function(list){  var list = list.map(item=>{  return albToCn(item+'');  })  // console.log(list);  list.forEach(item=>{  $('.year').append('
'+item+'

') }) circle('.year', 100) } // 递归来生成后10年的数组,如果大于截止年份,就调用yearlistText方法来,把数字转成大写,生成新的数组,并在year元素中append box元素,后再调用circle来让元素圆形布局 var yearlist = []; var createList = function(year) { if(year<=futureYear){ yearlist.push(year); year++; createList(year); } else { // console.log(yearlist); yearlistText(yearlist); } } createList(thisYear); } function albToCn(value) { var words = []; for(var i=0;i

JavaScript时间轮盘:JS元素圆形布局制作时间轮盘动画

这里把box的宽度调小,刚好只能装下一个文字的宽度,就可以使文字竖着。同时把box颜色去掉。最终样式和html主体元素

JavaScript时间轮盘:JS元素圆形布局制作时间轮盘动画

是不是同样很奇怪了,元素同样需要旋转一个角度,而这个角度刚好是每一个BOX对应的角度

在circle方法里面把每个box加上旋转

function circle(el, radius, cb) {  var el = $(el);  ...  ...  box.each(function(index, element){  $(this).css({  ...  'transform': 'rotate(-'+ avd * index +'deg)' // 这里注释去掉  });  });  ... }

JavaScript时间轮盘:JS元素圆形布局制作时间轮盘动画

这样就搞定了年份轮盘了。

月份、日期、小时轮盘

有了上面的经验,后面制作就更简单。对创建元素也进行一次封装。CN的定义主要是把数组转成中文汉字,很lou,大家可以用其他办法。

const CN = [{ value: 1, label: '一' },{ value: 2, label: '二' },{ value: 3, label: '三' },{ value: 4, label: '四' },{ value: 5, label: '五' },{ value: 6, label: '六' },{ value: 7, label: '七' },{ value: 8, label: '八' },{ value: 9, label: '九' },{ value: 10, label: '十' },{ value: 11, label: '十一' },{ value: 12, label: '十二' },{ value: 13, label: '十三' },{ value: 14, label: '十四' },{ value: 15, label: '十五' },{ value: 16, label: '十六' },{ value: 17, label: '十七' },{ value: 18, label: '十八' },{ value: 19, label: '十九' },{ value: 20, label: '二十' },{ value: 21, label: '二十一' },{ value: 22, label: '二十二' },{ value: 23, label: '二十三' },{ value: 24, label: '二十四' },{ value: 25, label: '二十五' },{ value: 26, label: '二十六' },{ value: 27, label: '二十七' },{ value: 28, label: '二十八' },{ value: 29, label: '二十九' },{ value: 30, label: '三十' },{ value: 31, label: '三十一' },{ value: 32, label: '三十二' },{ value: 33, label: '三十三' },{ value: 34, label: '三十四' },{ value: 35, label: '三十五' },{ value: 36, label: '三十六' },{ value: 37, label: '三十七' },{ value: 38, label: '三十八' },{ value: 39, label: '三十九' },{ value: 40, label: '四十' },{ value: 41, label: '四十一' },{ value: 42, label: '四十二' },{ value: 43, label: '四十三' },{ value: 44, label: '四十四' },{ value: 45, label: '四十五' },{ value: 46, label: '四十六' },{ value: 47, label: '四十七' },{ value: 48, label: '四十八' },{ value: 49, label: '四十九' },{ value: 50, label: '五十' },{ value: 51, label: '五十一' },{ value: 52, label: '五十二' },{ value: 53, label: '五十三' },{ value: 54, label: '五十四' },{ value: 55, label: '五十五' },{ value: 56, label: '五十六' },{ value: 57, label: '五十七' },{ value: 58, label: '五十八' },{ value: 59, label: '五十九' },{ value: 60, label: '六十' }]  var thisMonth = moment().format('MM'); createEle('.month', thisMonth, 12, 180);  var thisDays = moment().format('DD'); let maxDays = moment().month(moment().month()).endOf('month').format("DD"); createEle('.days', thisDays, maxDays, 230);  var thisHour = moment().format('HH'); createEle('.hours', thisHour, 24, 300);  /**  * el:盒子元素  * activeIndex: 当前时间(月、日、时、分、秒)  * length: 长度(12月、当前月多少天、24小时、60分、60秒)  * r: 半径  * cb: 回调函数 */ function createEle(el, activeIndex, length, r, cb) {  let list = CN.slice(0, length);  let thisIndex = 0;   list.forEach((item, index)=>{  if(item.value == activeIndex){  thisIndex = index;  }  })  var a = list.slice(0, thisIndex);  var b = list.slice(thisIndex);  console.log(b.concat(a));  b.concat(a).forEach(item=>{  $(el).append('
'+item.label+'

') }) circle(el, r, cb); }

秒轮盘动画

上面的回调一直没有用,其实主要就是用来整个轮盘旋转动画的。 从秒开始,每秒旋转一下每个轮盘对应每个元素的角度。

var thisSecond = moment().format('ss'); createEle('.second', thisSecond, 60, 450, (avd)=>{  setInterval(()=>{  let transform = $('.second').css('transform');  if(transform){  // 获取当前元素已经旋转的角度,然后加上每个元素应该分的角度  let rotate = getTranslate(transform, 'rotate');  $('.second').css({  'transform': 'rotate('+(rotate + avd)+'deg)',  'transition': 'all 1s linear'  })  }  }, 1000) });

下面方法,用来获取元素transform的值,可以定义参数,分别获取x、y、z以及rotate的值。

/**  * transform: 元素的transform(rotate(100deg))  * sty: 字符串,获取transform的对应的具体值(x、y、z以及rotate) */ function getTranslate(transform,sty){//获取transform值  var translates=transform.substring(7);  var result = translates.match(/(([^)]*))/);// 正则()内容  var matrix=result?result[1].split(','):translates.split(',');  if(sty=="x" || sty==undefined){  return matrix.length>6?parseFloat(matrix[12]):parseFloat(matrix[4]);  }else if(sty=="y"){  return matrix.length>6?parseFloat(matrix[13]):parseFloat(matrix[5]);  }else if(sty=="z"){  return matrix.length>6?parseFloat(matrix[14]):0;  }else if(sty=="rotate"){  return matrix.length>6?getRotate([parseFloat(matrix[0]),parseFloat(matrix[1]),parseFloat(matrix[4]),parseFloat(matrix[5])]):getRotate(matrix);  } } function getRotate(matrix){  var aa=Math.round(180*Math.asin(matrix[0])/ Math.PI);  var bb=Math.round(180*Math.acos(matrix[1])/ Math.PI);  var cc=Math.round(180*Math.asin(matrix[2])/ Math.PI);  var dd=Math.round(180*Math.acos(matrix[3])/ Math.PI);  var deg=0;  if(aa==bb||-aa==bb){  deg=dd;  }else if(-aa+bb==180){  deg=180+cc;  }else if(aa+bb==180){  deg=360-cc||360-dd;  }  return deg>=360?0:deg; }

这样一来,就有了轮盘转动效果

JavaScript时间轮盘:JS元素圆形布局制作时间轮盘动画

JavaScript时间轮盘:JS元素圆形布局制作时间轮盘动画

目前就实现了秒轮盘转动,如果想要其他都遵循时间,其实也不难,只需要从秒开始,到60,分就选中一次。分到60,小时就旋转一次。小时到24,日就旋转一次,一次类推。就是实现整个效果。

如果觉得代码样式不够美观,建议PC预览,或者点击文章最下方了解更多,样式或许会美观很多。

公告

喜欢小编的点击关注,了解更多知识!

源码地址,可以点击下方“了解更多”获取!

moment转换时间戳_酷炫时间轮盘:JS元素圆形布局制作时间轮盘动画效果相关推荐

  1. ae怎么做圆一圈圈扩散效果_轻备学院AE特效基础教程 - 如何制作一个带有动画效果村庄烟雾...

    熟练运用AE软件做几个偏技巧性并且可以举一反三的超简单小动画,教大家如何制作一个带有动画效果村庄烟雾,你学会了这些小动画,不仅可以熟练运用AE软件,还能对动画制作有深入的了解. 第一步:在AI中绘制插 ...

  2. wpsppt页面卷曲在哪里_2013版ppt怎么制作页面卷曲动画效果_博客

    2013 版 ppt 怎么制作页面卷曲动画效果 _ 博客 2013 版 ppt 怎么制作页面卷曲动画效果 在制作幻灯片的时候会用到不少切换动画效果, 但是怎么才能实现 ? 对于不常用 ppt 的朋友或 ...

  3. python可视化图表工具_酷炫的可视化图表工具来帮忙 深度评测五大Python数据可视化工具...

    原标题:酷炫的可视化图表工具来帮忙 深度评测五大Python数据可视化工具 不少Python用户的一大诉求是做出各种酷炫的可视化图表,而这就需要了解清楚工具特色,才好在制作不同类型图表顺利找到适合自己 ...

  4. file 选择的图片作为背景图片_酷炫!用Python把桌面变成实时更新的地球图片

    如何拥有够酷炫逼格够高的桌面?本文教你轻松定制自己的桌面背景 (建议带上耳机听一下地球的声音)最近疯狂迷恋地球卫星图和地球的卫星视频,看上面的视频简直极度舒适.不禁想把这种图片作为桌面背景图.这就产生 ...

  5. 可视化大屏设计尺寸_可视化大屏设计_酷炫不是最高效的大屏展示的唯一标准...

    目前市面上有众多做大屏的可视化BI工具,有的部分企业为了要实现其功能效果而令人感到枯燥乏味,或者是为了看上去绚丽多彩而显得极端复杂,从而实现对于相当复杂而又冗余数据的深入分析,让企业决策者难以理解数据 ...

  6. 乐高凯德机器人_酷炫到底!乐高EV3机器人+冰淇淋的高级玩法,你GET到了吗?...

    原标题:酷炫到底!乐高EV3机器人+冰淇淋的高级玩法,你GET到了吗? 你喜欢吃冰淇淋吗? 甜甜凉凉的冰淇淋圣代, 最适合炎热的夏天啦~ 我们"多才多艺"的EV3机器人, 也会做冰 ...

  7. html显示日期时间代码,JS全中文显示日期时间代码

    JS全中文显示日期时间代码_网页代码站(www.webdm.cn) function number(index1){ var numberstring="一二三四五六七八九十"; ...

  8. js svg语音波动动画_让动效更酷炫!4 个常见且常用的 SVG 交互动画方法

    本文介绍了 4 种常见的 SVG 交互动画方法,帮你了解 SVG 交互动画的原理和简单方法. 优秀的人机交互和舒适合理的动画,一直是 UX 设计师孜孜不倦追求的目标.但 UX 设计师每天都遇到能做出效 ...

  9. 生成有时间限制的二维码_微信公众号渠道二维码怎么制作?监测渠道效果的利器来了...

    每逢营销节点,各种渠道推广少不了,非常时刻需要能够统计不同渠道二维码的数据情况. 微信引流效果好不好怎么判断?新增人数为什么一团乱麻?粉丝又分别是从哪个渠道来的? 用渠道二维码就能搞定这些问题. 一. ...

最新文章

  1. 时间序列(三)滑动窗口
  2. 第十二周项目三-数组类运算的实现
  3. linux下的网络管理命令,常用linux网络管理命令(下)
  4. 【数据结构与算法】之深入解析“逆波兰表达式求值”的求解思路与算法示例
  5. 07-01-安装-Exchange Server 2019 on Win 2019 Core
  6. Pymetrics开源公平性感知机器学习算法Audit AI
  7. os是android5.0,Funtouch OS 2.1曝光 完美改Android5.0
  8. git+pylint实现python提交代码格式校验
  9. Linux性能监控与分析之--- CPU
  10. linux centos7 配置ftp,Linux Centos7配置ftp服务器
  11. Unix环境高级编程的学习环境的搭建
  12. 计算机硬件知识ppt课件,计算机硬件课件
  13. 世界十大垃圾邮件发送者出炉
  14. [源码解析] 模型并行分布式训练 Megatron (4) --- 如何设置各种并行
  15. oracle中update,insert,delete的高级用法
  16. Reasoning with Sarcasm by Reading In-between读书笔记
  17. Unity-数学3-数学符号
  18. 决策树回归:不掉包源码实现
  19. 今日总结:错误码配置,关于TXT文件下载问题
  20. 耶鲁大学《博弈论》课程——前言(以囚徒困境为引)

热门文章

  1. Jquery中用offset().top和offsetTop的比较
  2. 【python】pyhton中的and
  3. PHP函数func_get_args(),func_get_arg(),func_num_args()
  4. 允许我在这里吐槽一下某宝客的代码
  5. 利用.htaccess绑定域名到子目录
  6. 分享一篇SCCM软件更新的故障排除
  7. 我们应选择怎样的IT公司
  8. 拿什么拯救你,程序新丁?
  9. OpenCV-高斯低通高通滤波器(C++)
  10. 【软件测试】你的简历出现这些问题?没人要也是有原因的