6

CSS sin()/cos()等数学三角函数简介与应用

 1 year ago
source link: https://www.zhangxinxu.com/wordpress/2023/06/css-sin-cos-tan-function/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

CSS sin()/cos()等数学三角函数简介与应用

这篇文章发布于 2023年06月30日,星期五,00:23,归类于 CSS相关。 阅读 110 次, 今日 107 次 没有评论

by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=10901 鑫空间-鑫生活
本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。

三角封面

就在最新,所有现代浏览器均支持了 CSS 数学函数中的三角函数,包括下面这些:

  • sin()
  • cos()
  • tan()
  • asin()
  • acos()
  • atan()
  • atan2()

兼容性见下图,以sin()函数举例。

sin()函数兼容性

这7个三角函数中,有的函数根据角度返回对应的弧度值,有的是根据弧度值返回对应的角度值(以字母 a 打头的那几个函数)。

/* 正弦函数 */
width: calc(100px * sin(45deg));
/* 反正弦 */
transform: rotate(asin(-0.2));

首先,通过一个简单的案例,看看三角函数的渲染表现效果。

这个案例之前有专门撰文介绍通过,就是如何实现折线图,不过当时是使用JS实现的,这里会演示如何使用CSS数学函数实现,代码肯定比之前简介了很多。

二、位置与折线

需求如下,已知两个点的坐标,绘制这两个点,以及点与点之间的连接线。

效果先行

您可以狠狠地点击这里:CSS驱动的折线效果demo

效果如下GIF录屏示意,点击按钮,随机生成两个点,可以看到折线自动跟随了。

点和折线

其中,就用到了三角函数。

具体实现

具体实现如下,首先是HTML代码:

<div id="box" class="box">
    <i class="dot1"></i>
    <span class="line"></span>
    <i class="dot2"></i>
</div> 

外面是盒子元素,里面有两点一线。

为了方便绘制,我们可以把坐标位置值使用CSS变量的形式设置在外部容器元素上(CSS变量天然继承)。

JS的作用很简单,创建随机点坐标,用来示意效果,如下:

box.style.setProperty('--x1', Math.round(150 * Math.random()));    
box.style.setProperty('--y1', Math.round(150 * Math.random()));    
box.style.setProperty('--x2', 150 + Math.round(150 * Math.random()));    
box.style.setProperty('--y2', Math.round(150 * Math.random()));

重点是CSS部分,首先,折线的长度我们可以使用CSS数学函数 hypot() 实现,而折线旋转的角度我们可以使用反正切三角函数 atan() 计算得出,于是有如下所示的代码:

.box { 
    border: 1px solid #bbb;
    position: relative;
    /* 坐标加px单位 */
    --p1x: calc(var(--x1) * 1px);
    --p1y: calc(var(--y1) * 1px);
    --p2x: calc(var(--x2) * 1px);
    --p2y: calc(var(--y2) * 1px);
}
.box > i {
    position: absolute;
    width: 5px; height: 5px;
    border-radius: 100%;
    background-color: currentColor;    
}
.dot1,
.line {
    left: var(--p1x);
    top: var(--p1y);
}
.dot2 {
    left: var(--p2x);
    top: var(--p2y);
}
.line {
    position: absolute;
    border-top: 1px solid;
    /* 宽度 */
    width: hypot(var(--p2y) - var(--p1y), var(--p2x) - var(--p1x));
    transform-origin: left bottom;
    /* 旋转角度 */
    transform: rotate(atan((var(--y2) - var(--y1)) /  (var(--x2) - var(--x1))));
}

其他

hypot()数学函数,目前仅Safari浏览器支持,caniuse上目前的兼容性示意是有误的(见下图示意),根据我的测试,Firefox并不支持(或者不是这个语法),demo页面对此做了兜底兼容处理。

Firefox兼容性有误

三、环形布局

要说三角函数另外一个常见应用,一定是环形布局了。

类似钟表数字,3D旋转木马动画。

在过去,这些元素的定位只能是JS计算(或者SVG的<textPath>元素实现文字环绕),现在可以交给CSS。

1. 3D旋转木马

此效果在介绍CSS3 3D transform这篇文章时候的有示意。

其中,各个图片的分布定位是使用JS枚举计算得到的,现在,无需这么麻烦了。

只要根据已知的角度,设置好对应的三角函数,偏移大小自动获得。

相关HTML代码和CSS code(仅展示核心部分):

<div id="container" class="container">
    <img src="1.jpg" class="piece" />
    <img src="2.jpg" class="piece" />
    <img src="3.jpg" class="piece" />
    <img src="4.jpg" class="piece" />
    <img src="5.jpg" class="piece" />
    <img src="6.jpg" class="piece" />
    <img src="7.jpg" class="piece" />
    <img src="8.jpg" class="piece" />
    <img src="9.jpg" class="piece" />
</div>
.container {
    --size: 128px;
    width: var(--size);
    height: 100px;
    transition: transform 1s;
    transform-style: preserve-3d; 
}

.piece {
    width: var(--size);
    position: absolute;
    // 40 是旋转角度,以此记住tan()函数算出偏移值
    --z: calc(40px + var(--size) / tan((40 / 180) * 3.14159));
    transform: rotateY(calc(40deg * var(--index))) translateZ(var(--z));
}
.piece:nth-child(1) { --index: 0; }
.piece:nth-child(2) { --index: 1; }
.piece:nth-child(3) { --index: 2; }
.piece:nth-child(4) { --index: 3; }
.piece:nth-child(5) { --index: 4; }
.piece:nth-child(6) { --index: 5; }
.piece:nth-child(7) { --index: 6; }
.piece:nth-child(8) { --index: 7; }
.piece:nth-child(9) { --index: 8; }

眼见为实,您可以狠狠地点击这里:CSS 三角函数与3D旋转木马效果demo

点击图片可以看到旋转效果。

旋转图片效果

2. CSS钟表

钟表上1-12折12个数字按照圆形等间距排布,也是CSS三角函数的典型应用。

直接看效果(原作者stoumann,有删改)。

钟表

眼见为实,您可以狠狠地点击这里:CSS绘制的钟表效果demo

其他实现细节不表,主要看下数字的排版定位。

.clock-face time {
  --x: calc(var(--radius) + (var(--radius) * cos(var(--index) * 30deg)));
  --y: calc(var(--radius) + (var(--radius) * sin(var(--index) * 30deg)));
  display: grid;
  place-content: center;
  height: 2em; width: 2em;
  position: absolute;
  left: var(--x);
  top: var(--y);
}

.clock-face time:nth-child(1) { --index: 9; }
.clock-face time:nth-child(2) { --index: 10; }
.clock-face time:nth-child(3) { --index: 11; }
.clock-face time:nth-child(4) { --index: 0; }
.clock-face time:nth-child(5) { --index: 1; }
.clock-face time:nth-child(6) { --index: 2; }
.clock-face time:nth-child(7) { --index: 3; }
.clock-face time:nth-child(8) { --index: 4; }
.clock-face time:nth-child(9) { --index: 5; }
.clock-face time:nth-child(10) { --index: 6; }
.clock-face time:nth-child(11) { --index: 7; }
.clock-face time:nth-child(12) { --index: 8; }

完整代码参见demo,不详细介绍。

四、结语与扯淡

虽然三角函数目前Chrome浏览器已经支持,但是其他数学函数,例如求平方根的sqrt()函数,幂指数的pow()函数,返回给定数字的幂的数学常数e的特殊指数函数exp(),返回数字对数的log()函数,绝对值abs()函数,取余数的rem()和mod()函数,四舍五入的round()函数,正负零判断的sign()的函数,目前都只有Safari浏览器支持,Safari 15.4+

感觉所有现代浏览器支持,还需要些时日。

这些CSS函数的出现,或者大规模应用都离不开CSS变量的支持,因此,会不断强化CSS变量的地位。

扯些什么呢,生活上,无非就是钓鱼,端午三天钓鱼,场场都还不错。

工作上,前天换了新工位,明天又有新团建,也没什么好讲的。

倒是7月份,计划来一趟自驾游,一路向南,自驾到厦门。

今年20天的年假已经用了一半了,正好半年过去,下半年还要省着点用。

为什么年假这么多?

一来工龄长,二来公司福利号,有赠送,三来绩效的奖励。

噢啦,就扯这么多吧,扯淡也是要看心情的。

苏檀儿

(本篇完)1f44d.svg 是不是学到了很多?可以分享到微信
1f44a.svg 有话要说?点击这里


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK