Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >js实现贝塞尔曲线,div也能如此丝滑?

js实现贝塞尔曲线,div也能如此丝滑?

作者头像
Snine
发布于 2023-01-07 01:25:03
发布于 2023-01-07 01:25:03
1.8K00
代码可运行
举报
文章被收录于专栏:前端开发笔录前端开发笔录
运行总次数:0
代码可运行

今天遇到朋友发来的一个ui图,询问我如何实现下图这样的效果【vue项目】,(听说是类似LED灯的展示效果),于是便有了今天的小demo,要实现一个类似下图的动效,上面的灯会一直重复滚动,但是这个并不是什么难点,主要在于如何实现这种平滑的曲线,日常我们的开发的div在我们的脑海中通常就是一个网格状,涉及到平滑曲线的往往是图表,于是我们需要找一个方案来完成这种布局(非真实ui图,是完成之后的效果)

分析

我们需要先简单分析一下这个ui,当我们拿到这个UI图的时候,脑海中的第一反应是,一个大的DIV中间套了很多的小的DIV,并且小的的上下位置出现了偏移,但是偏移多少目前我们不得而知,但是基础的布局方案已经完成。

第二步我们考虑球体的颜色,可以看到,轨道是一种颜色,需要一直移动的球体是另一种颜色,这个非常简单,我们定义两组数据,一组是轨道,一组是高亮的球,通过不段改变高亮的这组数据,即可响应式的完成灯的移动,第二点我们也解决了

第三点,初始的时候考虑的是y的坐标是0, 2, 4, 6, 8, 10 , 8, 6, 4 , 2 ..... ,但是很显然,这样的坐标出来的形状一定是一个折线图,而不是平滑的曲线,于是我们需要用到数学知识了:需要使用到圆的弧度的概念,在javascript中有两个方法**Math.sin()和Math.cos()**都是关于弧度的公式,关于这两个方法,我们下面再说。

实现

布局

实现这个的布局非常简单,外层一个大的div,内层很多小的span,通过flex一排即可到一排

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<template>
  <div class="container">
    <div class="content">
      <span class="circle" v-for="(item,index) in list" :key="index"></span>
    </div>
  </div>
</template>
如何计算y的偏移量

这一步是我们比较重要的一步,我们有一个400px容器,容器中放置了20个span,现在他们在一排,我们只需要给他动态绑定样式**transform: translateY(?px)**即可,重要的是我们如何计算这个的坐标,我们先来了解下两个方法的用处:

Math.sin() 和 Math.cos()

Math.sin(x)      x 的正玄值。返回值在 -1.0 到 1.0 之间;

Math.cos(x)    x 的余弦值。返回的是 -1.0 到 1.0 之间;

可以看到其分别是x点的正弦,这两个函数中的x指的是弧度而不是角度弧度的计算公式是:2π/360°

这里涉及到数学知识,我们先看看这张图

我们看我们关注的sin和cos

sin(∠A) = 对边比斜边(a / c) cos(∠A) = 临边比斜边 (b / c)

可大致了解一下即可,当然,我们今天所需要使用的和这个关系不大,这里只是帮大家回顾一下高中知识(手动狗头)。

好了这里直接推荐一个在线网站,图形计算器可以直接在线调试各种曲线

我们看看基础的正弦余弦曲线

正弦曲线
余弦曲线

我们知道圆周率(π), 1π=180°2π=360°,就是一周,所以我们只需要截图(0-2π)一个周期的曲线即可,后续不管要什么曲线,都在这个上面进行变换即可,通过上面对比,发现正弦曲线的起始点是(0,0),比余弦的(0,1)更好计算,我们就直接用正弦吧,那么我们列出已知条件:

  1. 在曲线中 y = cos(x)
  2. 在曲线中,曲线的宽度是
  3. 在曲线中,曲线的高度最高点到最低点是2
  4. 在我们的需求中,总宽度是400px
  5. 在我们需求中, 共有二十个圆圈,所以我们可以算出每个球的宽度平均是20px,所以坐标就是(index+1)*20 现在我们知道了很多信息,我们就可以计算出更多信息了
计算更多信息

我们知道曲线的宽度和我们的物理实际宽度就可以得出宽度比: 400 / 2π

这个时候我们需要通过这个比例计算出物理的x坐标对应的曲线中的x坐标,那么 物理宽度/x坐标 = 2π/曲线中x坐标

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/* 400 / x = 2π / y, 我们的x是已知的,等下自己可以拿,这样拿到了曲线中实际的x坐标 */
const z = 400 x / 400 * Math.PI*2

有个曲线中的对应x坐标,通过公式我们就可以拿到其曲线中实际y坐标了

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/* 这样就拿到了曲线中的y坐标 */
y = Math.sin(z)

拿到了曲线中的y坐标,那么们又知道,曲线中的总高是2,通过xy的坐标对比,我们可以计算出我们所需的真实的y

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/* 真实宽度400/曲线宽度2π = 真实高度y/曲线中的y 通过对比得到真实的y点 */
Y = Math.sin(z) * 400 / Math.PI * 2 / 2

然后通过这样的一个计算公式把这个y值赋值给我们的y点就可以得到这样的曲线

完善剩余

看起来有点意思了,这就是一个完整的2π,或者我们理解为就是曲线的一个周期,但是很明显曲线的度数不对,我们如何调整呢,回到刚刚的那个网站之中,我们要想曲线更加平滑,只需要对sin()除以/x即可,x最大线越平,我们到刚刚的网站去自己调试到自己理想的高度,

我们调试发现除以4就得到了差不多我们想要的曲线,所以我们只需要在上面的基础上/4就得到了我们真正想要的y。

此时我们的曲线就已经完成了,所以其实是不是就是我们的高中数学知识呢

完成跑马灯制作

前面的曲线画完,后面就已经不难了,我们只需要定义一段高亮的下标数组,我们写一个方法,创建一个自己想要高亮几个就生成0-x的数组

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
createActiveIndex(len = 6){
  return Array.from({length:len}, (v,k) => k)
},

然后在给span动态绑定一个背景颜色。当index属于高亮的时候就给高亮的颜色,不是则反之,然后我们写一个定时器一直修改这个高亮的数组即可,每次让其里面所有元素加1,就可以让他一直跑下去了,当然边界的时候我们需要对他进行归0

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
changeIndex(){
   this.activeIndex = this.activeIndex.map( item => item === this.list.length - 1 ? 0 : item + 1)
},

最后我们启动即可,就实现了我们开头想要的效果。

至此这个需求算是完成了,这只是一个小的场景通过这样的方式我们可以绘制出更多好玩的东西,你可以改变各种参数对齐进行调整修改,看看是不是你想要的效果

贝塞尔曲线

我们知道,前端的动画经常出现一个名词贝塞尔曲线,就是动画的执行过程,我们刚刚的曲线其实就是同理,如果此时我们需要去手动书写一个贝塞尔曲线我们应该怎么做呢,刚刚我们知道,我们容器的总宽度是400,曲线的周长是2π,比例就是400/2π,同理,当我们换算成时间的时候,假如动画是1秒。那么我们需要60帧,一帧动画的时间就是1000/60=16.7ms,我们通过2π/60就知道我们每一帧动画在什么位置了,当我们手写贝塞尔曲线的时候,利用差不多的公式一样可以完成。

简单封装一下方法

看起来似乎很复杂,但是实际上我们所需要的其实只是利用真实的x点,拿到对应曲线求出我们y的坐标,所以我们需要的参数有,我们真实场景的总宽,总宽之中的个数,我们所需要的曲线的倍率,三个参数即可,我们尽量分开步骤写,这样你看会理解的更清楚

js中π就是Math.PI

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function getCoordinate(width, count,  mag = 1){
      /* 通过总宽和个数计算出一个单个的宽 */
      const singleWidth = width / count
      /* 通过物理宽度/曲线周长计算出比率 */
      const ratio = 400 / Math.PI*2
      /* 上面实例代码我们是动态一次计算一个,而现在是方法,我们应该一次去拿到所有,所以我们返回一个数组对象记录xy */
      let result = new Array(count).fill({})
      /* 遍历总长度的dom个数,在数组中填充宽高 */
      result = result.map( (item,index) => {
          /* x的坐标 */
          const x = (index + 1) * singleWidth
          /* 定义变量z计算曲线中x的坐标 */
          const z = x / width * Math.PI*2
          /* 计算出真实的y的坐标 */
          let y = Math.sin(z) / 4  * 400 / Math.PI * 2 / 2    
          /* y还需要通过倍率改变曲线,得到最终我们想要的y */
          y = y / mag
          /* 写入数组对象中 */
          return {x, y}
      })
      return result;
    } 

如果后期你也有这种需求,可以在上面的基础上进行修改,基础的算法已经写出来了,如果您有疑问,欢迎讨论

在线体验

最终版本在此体验,

码上掘金体验地址

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023 年 01 月,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
区块链DApp的开发技术方案
DApp(去中心化应用)的开发技术方案是一个多层级、涉及区块链、智能合约、前端和去中心化存储的综合架构。下面将详细阐述其关键技术组件和最佳实践。
数字孪生开发者
2025/05/21
900
区块链DApp的开发技术方案
go-ethereum v1.15.10发布!解决死锁BUG,主网同步Electra与Pectra分叉,性能再升级!
以太坊官方客户端go-ethereum(Geth)迎来了重要版本更新——v1.15.10!本次更新重点修复了日志索引器的死锁问题,并完成了主网灯塔链轻客户端对Electra分叉的配置,补上了上一个版本遗留的关键环节。同时,它也为即将到来的Pectra分叉做好完备准备。除此之外,随着默认区块燃气上限提升至3600万,本次版本在性能和稳定性方面实现了多重提升。
福大大架构师每日一题
2025/04/30
760
go-ethereum v1.15.10发布!解决死锁BUG,主网同步Electra与Pectra分叉,性能再升级!
geth v1.15.9重磅发布!Prague主网升级倒计时,5月7日这些EIP将改变以太坊
以太坊核心客户端Geth迎来v1.15.9版本更新!本次升级不仅为即将到来的Prague硬分叉铺平道路,还包含多项性能优化和关键修复。Prague分叉已确定于北京时间2025年5月7日18:05:11(区块时间戳1746612311)启动,10项重要EIP将正式生效。本文将为你深度解析更新内容,助你提前做好准备!
福大大架构师每日一题
2025/04/23
1430
geth v1.15.9重磅发布!Prague主网升级倒计时,5月7日这些EIP将改变以太坊
go-ethereum v1.15.8紧急更新!存档节点安全升级,开发者必看十大亮点解析​
Go-Ethereum v1.15.8 是继v1.15.7后的又一关键补丁版本,聚焦数据库安全、交易池优化与网络稳定性三大方向,为开发者与节点运营者提供更可靠的运行环境!
福大大架构师每日一题
2025/04/13
680
go-ethereum v1.15.8紧急更新!存档节点安全升级,开发者必看十大亮点解析​
geth v1.15.7重磅发布:修复关键漏洞,存档节点安全再升级!
以太坊核心开发团队近日发布了go-ethereum (Geth) v1.15.7版本,这是一个以紧急修复和性能优化为主的更新。本次更新重点解决了存档节点数据库可能崩溃的严重问题,同时优化了交易池逻辑和内存管理,为开发者和节点运营者提供了更稳定的运行环境。
福大大架构师每日一题
2025/04/02
1420
geth v1.15.7重磅发布:修复关键漏洞,存档节点安全再升级!
​【刘文彬】以太坊RPC机制与API实例
原文链接:醒者呆的博客园,https://www.cnblogs.com/Evsward/p/eth-rpc.html
圆方圆学院
2018/12/24
1.9K0
把700元的单片机改造成以太坊节点, 9步get起新技能!
智能合约,是指完全按照编程方式运行的应用程序,它排除了任何停机、审查、欺诈或第三方干扰的可能性。
区块链大本营
2019/12/03
1.3K0
以太坊介绍和使用
以太坊是一个能够在区块链上实现智能合约、开源的底层系统。换言之,以太坊是可编程的区块链,它并不是给用户一系列预先设定好的操作(例如比特币交易),而是允许用户按照自己的意愿创建复杂的操作。这样一来,以太坊是就可以作为多种类型去中心化区块链应用的平台,这些应用比如包括之前很火的各种代币但并不仅限于此,我们可以做很多除了代币之外的东西,比如你可以输出一行代表自己不是外行身份的hello world,或者在上面做一个简单的计算器,总之你可以在上面实现你想要的任何功能。
fnatic
2022/07/15
37.4K0
第三课 以太坊术语说明及开发者资源列表
也称钱包,提供账户管理、挖矿、转账、智能合约的部署和执行等等功能,以太坊节点利用以太坊客户端接入到以太坊网络。 现在以太坊客户端主要有:Wallent/ist , Geth, Parity, Harmony,
辉哥
2018/08/10
7900
第三课 以太坊术语说明及开发者资源列表
以太坊数据存证性能与膨胀率测试
我们基于区块链在企业中的应用最广泛的就是“存证”功能需求,这是利用了区块链不可篡改和数据共享的特点,存证的业务数据一方面可以保证留痕和追溯,另一方面也实现了多个节点(如果部署在不同企业和部门)之间的数据共享。如果要实现存证,我们最关心并不是图灵完备,也不是去中心化,而是 存证的性能(也就是TPS)和数据膨胀率(也就是存1M的业务数据,单个节点要消耗多少M的磁盘空间)。
深蓝studyzy
2023/09/15
3140
以太坊数据存证性能与膨胀率测试
Bitcoin Core v29.0震撼发布!全新功能优化、性能提升与安全升级全方位解析
大家期待已久的 Bitcoin Core v29.0 现已正式发布!此次新版不仅带来了全新的功能改进和重要的性能优化,还修复了多项关键漏洞,提升了整体的安全性和使用体验。无论你是比特币节点运营者,还是区块链爱好者,升级 Bitcoin Core 到 v29.0 都将为你带来更稳定高效的网络环境。下面,我们为大家详细解读本次升级的亮点内容。
福大大架构师每日一题
2025/04/21
1050
Bitcoin Core v29.0震撼发布!全新功能优化、性能提升与安全升级全方位解析
部署自己的 Ethereum 浏览器
Blockscout 允许用户搜索交易、查看账户和余额、验证和与智能合约互动,并查看和与以太坊网络上的应用程序进行交互,包括许多分叉、侧链、L2 和测试网。
孟斯特
2024/11/06
3754
部署自己的 Ethereum 浏览器
以太坊客户端Geth命令用法-参数详解
Geth在以太坊智能合约开发中最常用的工具(必备开发工具),一个多用途的命令行工具。 熟悉Geth可以让我们有更好的效率,大家可收藏起来作为Geth命令用法手册。 本文主要是对geth help的翻译,基于最新的geth 1.7.3-stable版本。 如果你还不知道geth是什么,请先阅读入门篇:以太坊是什么。 以下开始正文。 命令用法 geth [选项] 命令 [命令选项] [参数…] 版本: 1.7.3-stable 命令: account 管理账户 attach 启动交互式JavaSc
Tiny熊
2018/06/21
2.4K0
搭建以太坊智能合约测试环境
早就想学习区块链相关技术了,可惜因为懒惰一直没有付诸实践,最近随着诸如 God.Game,Fomo3D 等区块链游戏接连暴出安全漏洞,让我对智能合约的兴趣愈发强烈起来,于是利用周末搭建以太坊智能合约测试环境,原想应该很简单,实际却花了不少精力,记录一下以飨读者。
LA0WAN9
2021/12/14
9190
搭建以太坊智能合约测试环境
Geth GraphQL使用说明
Geth V1.9.x增加了GraphQL的支持,开发者可以在经典的JSON RPC API和GraphQL API之间根据自己的去中心化应用具体需求进行选择。本文将介绍Geth 1.9新增GraphQL API的原因,并介绍其使用方法。
用户1408045
2019/10/10
1.8K0
Geth GraphQL使用说明
Solidity、Geth、EVM 三者之间的关系
在以太坊开发生态系统中,Solidity 版本、Geth 版本 和 EVM(Ethereum Virtual Machine)版本 之间有密切的关系。理解它们的关系对于智能合约开发、部署和执行至关重要。以下是对这些版本关系的详细介绍:
孟斯特
2024/10/12
2720
Solidity、Geth、EVM 三者之间的关系
金钱难寐,大盗独行——以太坊 JSON-RPC 接口多种盗币手法大揭秘
2010年,Laszlo 使用 10000 个比特币购买了两张价值25美元的披萨被认为是比特币在现实世界中的第一笔交易。
Seebug漏洞平台
2018/08/16
1.3K0
金钱难寐,大盗独行——以太坊 JSON-RPC 接口多种盗币手法大揭秘
以太坊私有链搭建_以太坊节点减少
下载地址:https://geth.ethereum.org/downloads/,下载之后是个 .exe文件,然后安装就好了,安装之后把geth的安装目录加入到系统环境变量的path里。验证是否安装成功,打开cmd窗口,输入 geth version 如果出来下面的内容,表示安装好了。(如果不加任何任何参数直接运行 geth ,会自动连接到以太坊公网,此时会开始同步区块)
全栈程序员站长
2022/11/09
1.5K0
探索查看以太坊交易池的方法
以太坊主网的内存池(称为交易池或 txpool)是动态内存中的区域,在那有待处理的交易驻留在其中,之后它们会被静态地包含在一个块中。
Tiny熊
2022/11/07
2.1K0
探索查看以太坊交易池的方法
搭建以太坊私有链
区块链技术正在逐渐走向成熟,以太坊作为区块链领域的重要代表被广泛应用于智能合约、去中心化应用等领域,然而公有链上的交易需要消耗大量的手续费,且数据的公开性也限制了其在某些场景下的应用。因此搭建以太坊私有链成为了一种更加灵活、高效、安全的解决方案,本文将介绍如何搭建以太坊私有链帮助读者更好地理解和应用区块链技术
Al1ex
2023/09/07
1.6K1
搭建以太坊私有链
推荐阅读
相关推荐
区块链DApp的开发技术方案
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验