canva绘制(二次、三次)贝塞尔曲线并且图片在曲线上运动

news2024/11/16 22:21:22

下图为实现效果(图片在三次贝塞尔曲线中运动)
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    html,
    body,
    canvas {
      margin: 0;
      padding: 0;
      height: 100%;
      width: 100%;
    }
  </style>
</head>

<body>
  <canvas id="canvas" ></canvas>
</body>
<script>
  const canvas = document.getElementById('canvas')
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
  const ctx = canvas.getContext('2d');
  //起点
//   var [x1, y1] = [10, 10];
//   //小球起点
//   var [x, y] = [10, 10];
//   //控制点 如果是二次贝塞尔曲线用的控制点是cx,cy
// //   var [cx, cy] = [100, 0];
//   //终点
//   var [x2, y2] = [200, 200]
//  三次贝塞尔曲线用的控制点是cx1,cx2,cy1,cy2
//   var [cx1, cy1] = [100, 0];
//   var [cx2, cy2] = [100, 250]
var t = 0
// 由于本示例为三次贝尔赛曲线所以控制点有两个
  var pointarr = [
    {
      start:{x:10,y:10},//小球起点
      begin:{x:10,y:10},//起点      这两个的区别是小球的起点一直随着运动轨迹在发生变化
      control1:{x:100,y:0},  //控制点1       
      control2:{x:100,y:250},  //控制点2
      end:{x:200,y:200}  //终点
    }
  ]
  //画一条线
  function draw() {
    ctx.beginPath()
    
    // ctx.moveTo(10, 10)
    // 二次贝塞尔曲线的绘制   与上边的 ctx.moveTo()连用 ,三次的也是
    // ctx.quadraticCurveTo(cx, cy, x2, y2)
    // 三次贝尔赛曲线的绘制
    // ctx.bezierCurveTo(cx1, cy1, cx2, cy2, x2, y2)

    // 此次示例的是三次贝塞尔曲线
    ctx.moveTo(pointarr[0].begin.x, pointarr[0].begin.y);
    ctx.bezierCurveTo(pointarr[0].control1.x, pointarr[0].control1.y, pointarr[0].control2.x, pointarr[0].control2.y, pointarr[0].end.x, pointarr[0].end.y);

    ctx.stroke()
    ctx.closePath()
  }

  /*贝塞尔曲线上点位的控制*/
  function computedPosition() {

    // 二次贝塞尔曲线上运动轨迹的运算方式
    // x = Math.pow(1 - t, 2) * x1 + 2 * t * (1 - t) * cx + Math.pow(t, 2) * x2
    // y = Math.pow(1 - t, 2) * y1 + 2 * t * (1 - t) * cy + Math.pow(t, 2) * y2

    // 三次的贝塞尔曲线运动轨迹的计算方式
    // x = x1 * Math.pow((1 - t), 3) + 3 * cx1 * t * Math.pow((1 - t), 2) + 3 * cx2 * Math.pow(t, 2) * (1 - t) + x2 * Math.pow(t, 3)
    // y = y1 * Math.pow((1 - t), 3) + 3 * cy1 * t * Math.pow((1 - t), 2) + 3 * cy2 * Math.pow(t, 2) * (1 - t) + y2 * Math.pow(t, 3)
    // 根据开始到结束的大小判断,控制时间 
    if (pointarr[0].start.x > pointarr[0].end.x) {
        t = 0;
        pointarr[0].start.x = pointarr[0].begin.x;
        pointarr[0].start.y = pointarr[0].begin.y;
    }


    pointarr[0].start.x = pointarr[0].begin.x * Math.pow((1 - t), 3) + 3 * t * pointarr[0].control1.x * Math.pow((1 - t), 2) + 3 * pointarr[0].control2.x * Math.pow(t, 2) * (1 - t) + pointarr[0].end.x * Math.pow(t, 3);
    pointarr[0].start.y = pointarr[0].begin.y * Math.pow((1 - t), 3) + 3 * t * pointarr[0].control1.y * Math.pow((1 - t), 2) + 3 * pointarr[0].control2.y * Math.pow(t, 2) * (1 - t) + pointarr[0].end.y * Math.pow(t, 3);
    
  }

  function drawPoint() {
    computedPosition()
    // 下面四行为红色小球的运动轨迹但是需要加requestAnimationFrame(loopDraw)下面的代码cleaReact()
    // ctx.beginPath()
    // ctx.fillStyle = "red"
    // ctx.arc(pointarr[0].start.x, pointarr[0].start.y, 10, 0, 2 * Math.PI)
    // ctx.fill()

    let leftimgrun1 = new Image()
    leftimgrun1.src = './img/网络设备.png';
    leftimgrun1.onload = function () {
        ctx.clearRect(0, 0,pointarr[0].end.x+leftimgrun1.width,pointarr[0].end.y+leftimgrun1.width)

        ctx.drawImage(leftimgrun1,pointarr[0].start.x-15,pointarr[0].start.y-15, 25, 25)

    }

    
  }

  let loopDraw = () => {
    requestAnimationFrame(loopDraw);//这个是由浏览器调度的  而 setTimeout 只能设置一个固定的时间间隔,这个时间不一定和屏幕的刷新时间相同。
    // ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height)
    draw()
    drawPoint()
    t += 0.007//控制动画移动速度
  }
  loopDraw()//启动动画
</script>
</html>

二次贝塞尔曲线的绘制:

ctx.quadraticCurveTo(cx, cy, x2, y2)

三次贝尔赛曲线的绘制:

ctx.bezierCurveTo(cx1, cy1, cx2, cy2, x2, y2)

二次贝尔赛曲线的运动的x,y

x = Math.pow(1 - t, 2) * x1 + 2 * t * (1 - t) * cx + Math.pow(t, 2) * x2
y = Math.pow(1 - t, 2) * y1 + 2 * t * (1 - t) * cy + Math.pow(t, 2) * y2

三次贝尔赛曲线的运动的x,y

x = x1 * Math.pow((1 - t), 3) + 3 * cx1 * t * Math.pow((1 - t),2) + 3 * cx2 * Math.pow(t, 2) * (1 - t) + x2 * Math.pow(t, 3)
y = y1 * Math.pow((1 - t), 3) + 3 * cy1 * t * Math.pow((1 - t), 2) + 3 * cy2 * Math.pow(t, 2) * (1 - t) + y2 * Math.pow(t, 3)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/136638.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring之注解开发

目录 一&#xff1a;Bean基本注解开发 二&#xff1a;Bean依赖注入注解开发 三&#xff1a;非自定义Bean注解开发 四&#xff1a;Bean配置类的注解开发 五&#xff1a;Spring配置其他注解 六&#xff1a;Spring注解的解析原理 一&#xff1a;Bean基本注解开发 Spring除了…

【区块链】区块链技术学习总结

文章目录一、区块链技术简介1.1 区块链概念1.2 区块链应用1.2.1 区块链1.0技术&#xff1a;比特币1.2.2 区块链2.0技术&#xff1a;以太坊1.2.3 区块链3.0技术&#xff1a;价值互联网二、区块链1.0技术比特币2.1 比特币2.1.1 比特币概念2.1.2 比特币性质2.1.3 比特币解决的问题…

Springboot扩展点之BeanDefinitionRegistryPostProcessor

前言通过这篇文章来大家分享一下&#xff0c;另外一个Springboot的扩展点BeanDefinitionRegistryPostProcessor&#xff0c;一般称这类扩展点为容器级后置处理器&#xff0c;另外一类是Bean级的后置处理器&#xff1b;容器级的后置处理器会在Spring容器初始化后、刷新前这个时间…

第二章 chrony服务器

文章目录第二章 chrony服务器1.1安装与配置1.2同步网络时间服务器1.3 配置时间服务器1.4 chronyc 命令1.5常见时区课后练习第一题&#xff1a;第一台机器从阿里云同步时间&#xff0c;第二台机器从第一台机器同步时间第二题&#xff1a;第一台服务器使用系统时间作为第二台服务…

jetson nano GPIO控制说明

文章目录一.GPIO介绍二.安装GPIO库python库C库三.几种常用的通信协议UARTPWMI2CI2SSPI四.控制函数说明python&#xff08;[参考](https://pypi.org/project/Jetson.GPIO/)&#xff09;C五.例程一.GPIO介绍 GPIO&#xff08;General Purpose Input Output&#xff09;通用输入输…

干货 | Web自动化测试中显式等待与隐式等待该怎么用?

在实际工作中等待机制可以保证代码的稳定性&#xff0c;保证代码不会受网速、电脑性能等条件的约束。等待就是当运行代码时&#xff0c;如果页面的渲染速度跟不上代码的运行速度&#xff0c;就需要人为的去限制代码执行的速度。在做 Web 自动化时&#xff0c;一般要等待页面元素…

高压放大器在电子束增材制造聚焦消像散控制技术研究的应用

实验名称&#xff1a;高压放大器在电子束增材制造聚焦消像散控制技术研究的应用 研究方向&#xff1a;增材制造 实验目的&#xff1a; 电子束选区熔化技术&#xff0c;即电子束3D打印技术&#xff0c;属于金属增材制造的分支。该技术以电子束为热源&#xff0c;在计算机控制下以…

华为防火墙配置笔记

防火墙&#xff08;Firewall&#xff09;也称防护墙&#xff0c;是由Check Point创立者Gil Shwed于1993年发明并引入国际互联网&#xff08;US5606668&#xff08;A&#xff09;1993-12-15&#xff09;防火墙是位于内部网和外部网之间的屏障&#xff0c;它按照系统管理员预先定…

实战工作十年的Code Review方法论与实践总结

作为卓越工程文化的一部分&#xff0c;Code Review其实一直在进行中&#xff0c;只是各团队根据自身情况张驰有度&#xff0c;松紧可能也不一&#xff0c;这里简单梳理一下CR的方法和团队实践。 一、为什么要CR 提前发现缺陷 在CodeReview阶段发现的逻辑错误、业务理解偏差、…

CleanMyMac2023Mac下载排行最好的清理工具

CleanMyMac是Mac清理工具&#xff0c;具有很多功能。例如‬&#xff0c;删除大量不可见的缓存文件&#xff0c;可以批量删除未使用的DMG、不完整的下载以及其余的旧包。不过由于MAC系统不像windows那样会产生缓存或系统垃圾&#xff0c; 使用Win电脑很多人会下载各类系统优化软…

MQ面试题总结

✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏&#xff1a;Java面试题…

【流行框架】Zookeeper

&#x1f31f;个人博客&#xff1a;www.hellocode.top&#x1f31f; &#x1f31f;Java知识导航&#xff1a;Java-Navigate&#x1f31f; ⭐想获得更好的阅读体验请前往Java-Navigate &#x1f525;本文专栏&#xff1a;《流行框架》 &#x1f31e;如没有JavaWEB基础&#xff0…

Linux文件目录结构详解

Linux文件目录结构 Linux文件系统是采用级层式的树状目录结构&#xff0c;在此结构中的最上层是根目录“/”&#xff0c;然后在此目录下再创建其他的目录 Linux系统下一切硬件皆文件 具体的目录结构 /bin ->存放最经常使用的指令/sbin ->存放系统管理员使用的系统管理…

从Redis、HTTP协议,看Nett协议设计,我发现了个惊天大秘密

1. 协议的作用 TCP/IP 中消息传输基于流的方式&#xff0c;没有边界 协议的目的就是划定消息的边界&#xff0c;制定通信双方要共同遵守的通信规则 2. Redis 协议 如果我们要向 Redis 服务器发送一条 set name Nyima 的指令&#xff0c;需要遵守如下协议 // 该指令一共有3…

第一章 R语言介绍

1.为何使用R 与起源于贝尔实验室的S语言类似&#xff0c;R也是一种为统计计算和绘图而生的语言和环境&#xff0c;它是一套开源的数据分析解决方案&#xff0c;由一个庞大且活跃的全球性研究型社区维护。但是&#xff0c;市面上也有许多其他流行的统计和制图软件&#xff0c;如…

NLP自然语言处理NLTK常用英文功能汇总

自然语言处理 (NLP) 是一门研究如何让计算机程序理解人类语言的学科。NLTK (Natural Language Toolkit) 是一个 Python 包,可以用于 NLP 的应用开发。 很多数据都是非结构化的,而且包含可以被人类读懂的文本。在用编程方式分析这些数据之前,我们需要对它们进行预处理。在本…

Allegro174版本新功能介绍之背景颜色设置

Allegro174版本新功能介绍之背景颜色设置 Allegro升级到了174的时候,打开的时候默认是黑色的背景,如下图 选择界面 工作界面 和166以及172版本不一样,174支持切换成白色的背景,具体操作如下 选择setup

Java--基础语法

文章目录一、输出hello world二、示例说明三、基本语法三、标识符规则四、注释一、输出hello world public class Helloworld {/*第一个java程序*输出Hello world!!!*/public static void main(String[] args) {//输出Hello world!!!System.out.println("Hello world!!!&…

如何使用Git同时绑定Github以及Gitee

今天接到一项任务&#xff0c;是需要clone一个github上面的项目&#xff0c;正兴高采烈的git clone的时候&#xff0c;git bash框框报错&#xff0c;突然一想&#xff0c;我貌似一直用的Gitee,绑定的也是Gitee,并没有绑定Github,于是就有了这篇博客记录如何使用Git同时绑定Gite…

CTF压轴题解题思路和过程

前言 压轴题难度极大。我在这里详细的记录一下解题思路和过程 题目初探 拿到题目&#xff0c;为三个文件&#xff0c;其中mem_secret-963a4663.vmem为常见内存镜像文件&#xff0c;另外两个文件格式未知。 使用volatility进行分析无法识别profile。 接着分析分析Encryption.…