Web端视觉】如何用svg实现一个钟表动画呢?

2020-08-11 20:32发布

如何用svg实现一个钟表动画呢?我用canvas实现了一个钟表动画,但是用svg如何实现呢?

如何用svg实现一个钟表动画呢?我用canvas实现了一个钟表动画,但是用svg如何实现呢?

1条回答
我想吃肉
2楼 · 2020-08-12 09:00

基于SVG实现简单时钟效果

前端绘图

目前浏览器端绘制图形有2种主流方式:SVG和Canvas。相对于Canvas的更加底层的绘图API,SVG是一种声明式的,更可读、易于理解、方便交换。

提到前端绘图,事实上有多种技术可以选择,除了SVG和Canvas,还可以基于javascript操作普通DOM元素(虽然特别麻烦)、基于Actionscript的、基于后台开发语言绘制生成图片或某种数据格式传回前端的等等。

比较流行的可视化库ECharts,底层基于Canvas技术;D3.js 底层基于SVG。

SVG基础

SVG全称叫Scalable Vector Graphics,弹性矢量图形。这是一种基于XML语法声明的图形格式,主要优点是可任意缩放不变形,便于数据交换。

这里主要说明两个主要的语法:symbol和transform

symbol

symbol用于定义一个可被重复引用的图形符号,类似模板或类定义,可以用于定义非常复杂的组合图形。

   

定义了一个名为tick-small的图形,实际上就是竖直灰色线段 (110,12) - (110,10)

   

   

   

   

组合四个tick-small定义了 tick-small-1234,实现了钟表上1/2/3/4四个刻度的效果。

transform

transform用于对图形进行变换。常见的变换包括translate、scale、rotate、skew等。

translate(xval, yval) 将图形坐标系移动从默认的(0,0)移动到(xval, yval)。

scale(xscale, yscale) 将图形分别在两个方向进行缩放 如scale(2,2)表示拉长为2倍

rotate(deg, [x, y]) 将图形顺时针绕[x, y] 旋转deg度。一圈为360度。默认旋转中心为当前坐标系的原点。

skewX(deg) skewY(deg)是将图形X轴/Y轴倾向deg度。



实现原理

图形设计

简单时钟包括几个部分:时钟盘、刻度(0/3/6/9四个主刻度和另外48个次刻度)、指针(时针、分针和秒针)。

始终盘:用两个circle表示,内圆采用较深颜色填充,与时钟外部区别开来。两个圆形成一个轮廓效果

刻度:设计两个刻度线 tick和tick-small,组合四个tick-small形成1/2/3/4的分钟刻度 tick-small-1234。组合四个tick和四个tick-small-1234可形成0点到3点之间的刻度tick012。再组合四个tick012即得到完整的刻度。

   

   

 

 

 

 

 

 

 

 

 

 

指针设计较为简单,利用symbol定义0时刻的指针图形:

在不同的时刻 将这些指针旋转相应角度。

程序设计

编写一个函数render,展示任意时刻的时钟图形:

function render(){

  let now = new Date()

  let hour = now.getHours(), min = now.getMinutes(), sec = now.getSeconds();

  secLine.setAttribute("transform", "rotate("+(sec*6)+",110,110)")

  minLine.setAttribute("transform", "rotate("+(min*6+sec/10)+",110,110)")

  hourLine.setAttribute("transform", "rotate("+(hour*30+min/2)+",110,110)")

}

注意:时针的角度为(小时/12+分钟/12/60)*360;分针的角度为(分钟/60+秒/60/60)*360。加上次级指针的角度使得时针和分针的指向更加准确。

最后定时执行:

render()

setInterval(render, 1000)

为啥要执行一下render?可以避免看到00:00:00的初始时钟图形。


体会

之前有过一段用D3.js绘制关系图的工作。当时采用circle绘制节点,用line表示节点间的连线。但绘制的连线如果直接从节点的中心起止,并且在节点之后绘制,会显示在节点的上面,比较难看。当时的想法是每个角度自己去计算连线收尾点的位置(位置在节点的circle之外) 三角函数计算特别麻烦。如果用rotate就很简单了。

灵活运用symbol进行符号组合可以快速构建复杂图形。

准确理解和运用transform很重要。



作者:陈老师或波哥
来源:简书

相关问题推荐

  • 回答 4
    已采纳

    一:块元素块元素在很多浏览器中,都是显示占据一行,并且排斥其他元素和其他元素在同一行,在浏览器中,块元素出现的形状是矩形,并且盛放其他元素。例如有div,和h1~h6,p,hr,ol,ul。这些标签应该都不是很陌生,其中,和标签是块标签,并且独立占据一行...

  • 回答 4

    CSS3 过渡是元素从一种样式逐渐改变为另一种的效果。

  • 回答 9

    CSS和CSS3都是样式,CSS3是在CSS上新增了样式属性。 CSS3新增特性CSS3圆角边框:border-radius(解决了原有圆角边框需要截图的问题)CSS3文本阴影与盒阴影:text-shadow、box-shadow(可以用于实现标签边框或阴影)CSS3背景尺寸、背景切割和背景原点:backgr...

  • 回答 6

    相邻兄弟选择器、通用兄弟选择器、属性选择器、伪类选择器、伪元素选择器

  • 回答 9

           1.   !important    在属性后面写上这条样式,会覆盖掉页面上任何位置定义的元素的样式。  2.   行内样式,在style属性里面写的样式。  3.  id选择器  4. class选择器  5. 标签选择器    6. 通配符选择器*  7. 浏览器的自...

  • 回答 9

    ID选择器:#header {}类选择器:.header {}元素选择器:div {}子选择器:ul > li {}后代选择器:div p {}伪类选择器:a:hover {}属性选择器:input[type=text] {}

  • 回答 7

    a:link 没有访问之前a标签的样式a:visited 已访问a标签的样式a:hover a标签鼠标移上的样式a:actived a标签鼠标按下的样式input:focus input表单元素获取焦点input:blur input表单元素失去焦点

  • 回答 5

    是有一定难度的,自己平常要需要多加努力。因为你对计算机相关知识和概念都不太了解,在某些东西的接受可能相对会慢一些。

  • 回答 1

    从入门级选手到专业级选手都在做的——爬虫用 Python 写爬虫的教程网上一抓一大把,据我所知很多初学 Python 的人都是使用它编写爬虫程序。小到抓取一个小黄图网站,大到一个互联网公司的商业应用。通过 Python 入门爬虫比较简单易学,不需要在一开始掌握太多...

  • 回答 2

    想要自学前端,要先知道需要自学什么内容,然后给自己制定学习的计划,并且严格按照计划执行下去,切忌三天打鱼两天晒网,要耐得住寂寞坚持下去才行。可以按照下面的步骤去学习前端。第一阶段Html5+CSS3:主要学习HTML5基础、CSS基础、HTML5进阶、CSS3进阶、L...

  • 回答 1

    在《Web Content Accessibility Guidelines 1.0(Web内容可访问性指南)》里,对可访问性的描述是:Web内容对于残障用户的可阅读和可理解性。同时指南里还特别指明:提高可访问性也能让普通用户更容易理解Web内容。具体而言,要考虑以下两方面:无论用户是否...

  • 回答 2

    响应式布局可以为不同终端的用户提供更加舒适的界面和更好的用户体验。同一页面在不同大小和比例上看起来都应该是舒适的;同一页面在不同分辨率上看起来都应该是合理的;同一页面在不同操作方式(如鼠标和触屏)下,体验应该是统一的;同一页面在不同类型的设...

  • 回答 4

    经过前期的网站策划,确定网站主题和用户群、形象策划、制作抄规划等方面的内容之后,就要开始进行网页页面的布局了。首先是页面尺寸要紧跟时下流行的分辨率尺寸,因为页面尺寸和显示器大小及分辨率有关。其次是整体造型,一般可先画出网页的整百体设计,确定...

  • 回答 2

    GDB(GNU symbolic debugger)是一个功能很强大的调试器,它可以调试多种语言。有一点要说明的是,GDB是一个调试器,而不象VC一样是一个集成环境。你可以使用一些前端工具如XXGDB,DDD等。他 们都有图形化界面,因此使用更方便。...

  • 回答 1

    web的指向?你指的是?脚本中的this指向?还是其他什么?

没有解决我的问题,去提问