聊聊Web中的度数单位

发布于 大漠

说到度数,你可能已经从生活中了解了很多关于他们相关的知识。在学校里学习几何课,做基本的木工活,进入外层空间或在图像编辑器中旋转一个元素等,都会有角度相关的身影。

在现实世界中,度数几乎是测量角度的单位。它在Web中同样是一个受欢迎的角色,也适用于我们将遇到的各种场景。幸运的是,在现实世界中的度数和虚拟世界中的度数有很多相似之处,所以在这篇文章中将来学习一些有关于度数相关的知识,然后深入了解一些细节。

那我们开始吧!

概述

在我们开始查看代码片段以及如何在HTML、CSS和JavaScript中使用度数单位之前,让我们花点时间来回忆一下什么是度数,并介绍一些关于度数的基本概念。首先,也是最重要的是:

你可能以前看过这样的一个图(一个圆)。它代表一个完整的旋转以及所有我们想要测量或指定的角度。需要记住的一个大细节是一个完整的旋转是由360度组成的。所有的角度都会在0360度之间:

这并不意味着你不能处理超出0360范围的度数值。负数和大于360度的值都是允许的。只是它们总是被归到0360度范围内。看看下面两个标准化下变体:

在第一个变体中,我们指定的值实际上是-90度。得到的角度路径是顺时针的,并停止在270度(360 - 90)位置处。在第二个变体中,我们指定的值是420度。这意味着我们要做完一个完整的旋转(360度),然后继续旋转60度。在大多数情况下,第一个变体的最终度数值是270度,第二个变体的最终度数值是60度。角度的值是否为负值,并无关紧要。为了得到0360之间的最终角度值,旋转的次数也不重要。同样,这只适用于大多数情况。在某些情况下,比如涉及到动画的情况下,我们采用最终角度度数值是非常重要的。我们稍后会谈到这个。

拓宽角度的视野

既然我们对角度的单位理论有了一定的了解,那么现在是时候现来深度的了解角度相关的知识。先来看看生活中有关于角度的例子在Web上的运用情况。

CSS中的旋转

角度最常用的用法之一就是在CSS中给旋转元素设置一个旋转角度(度数),依赖于CSS的transform属性中的rotate()函数,给这个rotate()函数传一个角度的值,让元素做相应的旋转。比如:

.rectangle {
    width: 200px;
    height: 100px;
    border: 10px solid #83B692;
    background-color: #BEE7B8;
    margin: 100px;

    transform: rotate(37deg);
}

rotate()函数设置了一个37度的值,告诉元素围绕旋转原点(当然,旋转原点是可以人为设置的,这里不做探讨,因为其超出了我们要讨论的范围)旋转37度。最终这个.rectangle元素旋转后的效果如下图所示:

看到这样的旋转结果,你是不是感到有点奇怪?37度旋转出来的效果应该像下面这样才对,是吧?

我们在浏览器中看到的效果几乎与此相反。原因是与Web上定义旋转的方向有关系。现实中,角度值是随着逆时针方向增加,前面的概述部分有提到过。在Web上,角度值却是随着顺时针方向增加

这似乎看上去有点奇怪,但事实就是这样,我们也无法改变。我们所要做的就是记住这样的差异性,并在实际使用的时候做相应的调整

有关于CSS中旋转运用到的角度值,介绍到这也就差不多了。但有一点需要记住,之前我们介绍过,如果角度值低于0或者大于360度最终都会规化到0360度范围内。大多数情况之下,负值和大于360度值都并不很重要。

下图很好的阐述了负值和大于360度值并不影响元素最终的旋转结果:

就上图的结果来看,.rectangle元素旋转37397757-323度,其最终的结果都是一样的。

只有当我们在做动画的时候,这个结果才不是一样的。在动画制作过程中,旋转角度的最终值和如何获得最终旋转的角度值都非常重要。这是制作动画的一个细节问题。对于负值,表示我们的元素是在做逆时针旋转,旋转到最终的角度值;大于360的度表示元素一直在旋转,直到最终的角度值。当我们真正的可视化实际发生的一切时,这样做的一切都变得有意义了。

下图的效果就是四个矩形旋转的另一个版本。从0度开始旋转,一直旋转到最终值(37397757-323度):

注意每个矩形是如何设置动画,如果你想更深入的了解这些细节,可以看上示例中的代码。

对于旋转37度的矩形动画没有什么特别之处,因为它是一个很正常的效果。对于旋转397度的矩形,它最终停止的点也是在37度的位置,只不过矩形做了一个完整(圆)的旋转之后,再继续旋转了37度(360 + 37度);757度的这个矩形同样的,动画最终停止的位置也是37度那,只不过他做了两圈旋转之后,再继续旋转了37度(360 + 360 + 37度);最后旋转-323度的矩形有点不一样,它是逆时针旋转,但最终动画停止位置也和其他矩形一样,是在37度位置处。所以,这四个矩形动画最终停止的位置是相同的,但动画如何到达停止处是完全不同的。

从代码中不难发现,动画的持续时间都是8sanimation-duration: 8s),这意味着四个矩形完成动画的时间都是8s。那么问题来了,四个矩形旋转的角度不同(前提也提到过了,有的旋转一圈多,有的旋转两圈多),但动画持续时间都相同(都是8s),而且他们要到达的目的地都是相同的(都是37度位置处),这样一来就会造成矩形旋转快慢的不同。正如在示例中看到的效果一样。

上面我们主要讨论了CSS中旋转的角度是如何工作的,特别是在动画的中旋转角度值和平时有何不同的细节。接下来我们换过另一个话题继续聊Web中的度数(角度值)。

CSS中的渐变

CSS中还会使用到角度的另外一个典型属性是linear-gradient。在CSS的linear-gradient属性中,除了像left top这样的关键词之外,还可以使用角度值:

background: linear-gradient(45deg, #f36, #389);

这里的45deg指的是渐变的角度。前面详细的介绍了CSS中transform中的rotate()函数,他也会用到角度值。很多同学可能会误以为渐变中的角度和旋转的角度应该是同一回事。事实上,他们还是不一样的,如果你使用过Photoshop这样的软件,你可能会找到一定的答案:

从上图可以看出来,渐变的角度与旋转的角度完全不是一回事。线性渐变的这个角度以圆心为起点的发散方向。下面来聊聊渐变中的角度。

先来看一张图:

C点渐变容器中心点(也就是元素中心点),A是通过C点垂直线与通过C点渐变线的夹角,这个称为渐变角度(比如前面说的45deg)。

可以通过下面两种方法来定义这个角度:

  • 使用关键词:to topto bottomto leftto rightto top rightto top leftto bottom rightto bottom left
  • 使用带单位数字定义角度,比如45deg1turn等 (有关于degturn的关系,我们后续会说到)

如果省略角度值的设置,那默认是to bottom(对应180deg或者.5turn):

在上面的示例中,渐变角度是没有设置,whitered渐变色从topbottom渐变,它和使用to bottom关键词得到的效果是一样的,如下所示:

除了使用这些关键词之外,还可以使用明确的角度值,比如45deg,而且更建议你使用角度值来替代关键词。下图能帮助我们看看渐变角度动态变化时,渐变线是怎么移动的:

回顾一下渐变角度:

  • 角度是渐变线与渐变容器中心点向上垂直线之间的夹角
  • 0deg的意思就是to top
  • 角度的默认值(也就是角度没有设置),它的值是to bottom,也和180deg相同
  • 顶角关键词和渐变容器尺寸有关

渐变角度只是CSS线性渐变知识点的一小部分,如果你想了解CSS线性渐变更深入的知识,建议你花点时间阅读这篇文章:《你真的理解CSS的linear-gradient》。同时也推荐大家阅读@张鑫旭老师的《深入理解CSS3 gradient斜向线性渐变》一文。

Canvas中的角度

大家都知道,canvas可以用来帮助我们绘制一些几何图形,也可以帮助我们做很多CSS之类无法做到的事情。在canvas的部分API中也会使用到角度,比如使用arc()arcTo()绘制圆和圆弧以及Canvas中的rotate()方法。

在Canvas中,角度的测量和我们常见的角度测量是有所差异的,其差异如下图所示:

然而,在Canvas中,角度并不是我们通常意义上所了解的角度,而是用弧度来表示的。比如,一个圆是360度,那么用弧度来表示的,其对应的就是弧度,即以圆心为坐标原点,开始计算开始弧度与终止弧度。顺时针还是逆时针就是画线的方向(或者旋转方向),比如像下图这样:

对于很多Web开发者而言,大家更为熟知的是度数来表达角度,所以说,要在canvas中使用度数,那还需要做一步转化过程,把度数转换成弧度。不过有关于度数转弧度,我们在后面会简单的介绍。

使用HSL指定颜色

在CSS中,我们有多种指定颜色的方式,最为经典的是十六进制和RGB格式。除此之外,我们还可以使用另一种指定颜色的格式,即**HSL。其中HSL**分别是色相(Hue),饱和度(Saturation)和亮度(Lightness)三个单词的首字母。

对于**HSL**相关的细节已经超出这篇文章的有关范围,但维基百科上的HSLHSV文章很好地解释了它的工作原理和目的。我们所知道的是,在Web中可以通过hslhsla函数来指定HSL格式中的任何颜色,这两个数都类似,唯一的区别是hsla增加了对透明度的支持。比如,我们可以像下面这样使用hsla来指定颜色:

background-color: hsla(54, 100%, 62%, 1);

上面使用hsla指定了background-color的值,上面的代码hsla(54, 100%, 62%, 1)是一个黄橙色。

此时,你可能会感到纳闷。我们在这篇文章中要聊的是Web中的角度相关的话题,那我们怎么又聊Web中的颜色呢?换句话说,HSL格式指定颜色与使用度数有何关系?如果你真的是这么想的,那表示你是对的,就应该这么的问。HSL颜色(以及hsla函数的扩展)是由四个值组成:色相,饱和度,亮度和透明度。

HSL中的H,也就是颜色的色相,它指定色相的方式是以度数为单位的,这些度数映射到色盘上的颜色,比如像下图这样:

在我们这个示例中,指定的颜色的色相值是54度。对应到色盘上的位置,就是我们看到的黄橙色。在实际使用的时候,如果一时无法确定角度值对应色盘上的颜色,我们可以借助浏览器开发者工具来帮助我们,比如像下面这样:

JavaScript中的度数

在JavaScript中有一个Math对象:

而在Math对象中有一些方法是用来进行三角函数反三角函数运算的,比如大家常见的三角函数:正弦函数(sin())余弦函数(cos()正切函数(tan();与其对应的反三角函数是反正弦函数(arcsin()反余弦函数(arccos()反正切函数(arctan。这些函数对应到Math的即是:

  • 正弦函数:Math.sin返回一个 -11 之间的数值,表示给定角度(单位:弧度)的正弦值
  • 余弦函数:Math.cos返回一个 -11 之间的数值,表示角度(单位:弧度)的余弦值
  • 正切函数:Math.tan回一个数值,表示一个角的正切值
  • 反正弦函数:Math.asin接受 -11 之间的数值作为参数,返回一个介于 -.5π.5π 弧度的数值。如果接受的参数值超出范围,则返回 NaN
  • 反余弦函数:Math.acos-11 的一个数为参数,返回一个 0PI (弧度)的数值。如果传入的参数值超出了限定的范围,将返回 NaN
  • 反正切函数:Math.atanMath.atan2。其中Math.atan返回一个 -.5π.5π 弧度之间的数值;Math.atan2方法返回一个 -PIPI 之间的数值,表示点 (x, y) 对应的偏移角度。这是一个逆时针角度,以弧度为单位,正X轴和点 (x, y) 与原点连线 之间。注意此函数接受的参数:先传递 y 坐标,然后是 x 坐标

有关于JavaScript中的Math对象更详细的介绍,可以查阅MDN上的文档

当然,我们这里并不是来讨论Math对象的,但话又说回来,Math对象中的一些函数调用的或返回的值类似canvas中的角度,是一个弧度值。如果有需要,我们可以将两者进行转换。

弧度值和度数值之间的转换

在前面,我们在CSS中大部分情况使用的是角度值都是用度数(deg)来做为单位值,事实上也可以像在JavaScript中使用弧度rad做为单位值。

正如大家所了解的一样。一个完整的圆的弧度是,所以2π rad = 360°1 π rad = 180°1°= π/180 rad1 rad = 180°/π(约57.29577951°)。以度数表示的角度,把数字乘以π/180便转换成弧度;以弧度表示的角度,乘以180/π便转换成度数。

rad = (π / 180) * deg

同样的:

deg = (rad * 180) / π

平时我们常看到的各种弧度如下:

上面简单的介绍了度数和弧度之间的关系。其实在JavaScript中我们可以很容易实现度数和弧度之间的换数:

rad = (Math.PI * deg) / 180

同样的:

deg = (rad * 180) / Math.PI

为了方便计算和使用,可以将其封装成JavaScript函数:

function getRads (degrees) {
    return (Math.PI * degrees) / 180;
}

function getDegrees (rads) {
    return (rads * 180) / Math.PI;
}

比如我们要将30deg转换成rad,可以直接使用:

getRads(30); // 0.5235987755982988rad
getDegrees(0.7853981633974483); // 45deg

下图展示了常见的角度和弧度之间的换算:

总结

在现实世界中测量单位通常不会进入到我们的数字世界之中。度数只是这些测量方法中的其中之一。在这篇文章中,咱们也只是涉及其中的冰山一解,即Web中有关于度数的使用。简单的了解到,在Web中,我们可以在元素的旋转,指定颜色的色相,线性渐变中的角度,Canvas中绘制图形等都会用到度数(或弧度)。而这些度数我们都是在0360度之间,当然也可以超出这个范围。另外,在Web中的度数和弧度之间,是可以进行转换的。

参考文档

  • Understanding Degrees on the Web
  • Canvas学习绘制圆和圆弧
  • JavaScript的Math对象
  • On Switching from HEX & RGB to HSLjordan retro 11 mens footlocker