当前位置: 首页 > news >正文

【Canvas入门】从零开始在Canvas上绘制简单的动画

这篇文章是观看HTML5 Canvas Tutorials for Beginners教程做的记录,所以代码和最后的效果比较相似,教程的内容主要关于这四个部分:

  1. 创建并设置尺寸
  2. 添加元素
  3. 让元素动起来
  4. 与元素交互

设置Canvas的大小

获取到canvas并设置尺寸为当前窗口的大小:

var canvas = document.getElementById(canvas_id);
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

获取到二维的Context并赋值给变量c,后面对canvas的操作主要都是通过c进行的:

var c = canvas.getContext("2d")

填充矩形

在(x,y)坐标处,填充一个宽为width,高为height的矩形:

c.fillRect(x, y, width, height)

设定填充矩形的颜色:

c.fillStyle = "green";         // 填充的颜色为绿色
c.fillRect(100, 100, 100, 100) // 在(100,100)坐标处填充一个边长为100的正方形

绘制线段

c.beginPath();               // 开始绘制路径
c.moveTo(100, 200);          // 相当于笔尖在空中移动到(x,y)坐标的位置,也就是
c.lineTo(200, 300);          // 让笔尖从之前的坐标到现在的坐标(200,300)画一条线段
c.strokeStyle = "#4455ff";   // 设置线条的颜色
c.stroke();                  // 渲染到Canvas上

绘制圆形

,以(x,y)为圆心,radius为半径画圆,startAngle, endAngle分别为起点角度和终点角度(弧度制),最后一个参数是可选的counterclockwise,true为逆时针,false顺时针,默认为false:

arc(x, y, radius, startAngle, endAngle)
arc(x, y, radius, startAngle, endAngle, counterclockwise)

在 (100, 100) 处画一个半径为30,顺时针的圆:

c.beginPath();
c.arc(100, 100, 30, 0, 2 * Math.PI, false);
c.strokeStyle = "#00ff00";
c.stroke();

使用for循环生成随机位置的圆形

Math.random() 生成0-1之间的随机数,所以要乘上宽度和高度来让它的随机范围扩大到整个屏幕,也就是得到了很多个随机的坐标。

for (var i = 0; i < 100; i++) {var x = Math.random() * window.innerWidth;var y = Math.random() * window.innerHeight;var r = Math.random() * 100;                // 半径也随机生成,范围在0-100c.beginPath();c.arc(x, y, r, 0, 2 * Math.PI);c.strokeStyle = "#0fff00";c.stroke();
}

这样就生成了100个位置随机,大小随机的圆形。

加入动画

定义一个函数 animate() 并在内部调用,这样就得到了一个一直重复运行的函数,可以在这个函数里面更新元素的状态。
设置初始坐标为 (200, 200),x方向的速度 v x v_x vx为2,y方向的速度 v y v_y vy为0,在每一次刷新的时候使用速度来更新位置。
我们知道匀速运动时 x = v t x=vt x=vt,所以可以通过速度改变位移。还可以通过加速度 a a a来改变速度 v v v,在Canvas中实现变速运动。

var x = 200, y = 200;
var vx = 2, vy = 0;
function animate() {requestAnimationFrame(animate);c.clearRect(0, 0, window.innerWidth, window.innerHeight); // 清除掉前一帧绘制的内容,否则会不断的重叠c.beginPath();c.arc(x, y, 30, 0, 2 * Math.PI);c.stroke();x += vx;y += vy;
}
animate();

更多会动的圆

定义一个类,用来画一个圆心在 (200, 200) 处,半径为30的圆:

class Circle{constructor(x, y) { // 在 constructor 中完成一些值的初始化this.x = x;this.y = y;}draw() {c.beginPath();c.arc(this.x, this.y, 30, 0, 2 * Math.PI); c.stroke();}
}
var circle = new Circle(200, 200);
// 当调用 new Circle(200, 200); 时,会将类的参数列表传入constructor()的参数列表,并执行constructor()
circle.draw()

接下来把更新 (x, y) 坐标的部分写成Circle类的update()函数,并把 draw() 方法也包含进来:

class Circle{constructor(x, y, vx, vy, radius) {this.x = x;this.y = y;this.vx = vx;this.vy = vy;this.radius = radius;}draw() { // 根据 x,y 坐标,半径 radius 画一个圆c.beginPath();c.arc(this.x, this.y, this.radius, 0, 2 * Math.PI);c.stroke();}update() { // 更新 x,y 坐标, 将越界时反弹, 更新后绘制圆形if (this.x - this.radius < 0 || this.x + this.radius > window.innerWidth)  this.vx = -this.vx;if (this.y - this.radius < 0 || this.y + this.radius > window.innerHeight) this.vy = -this.vy;this.x += this.vx;this.y += this.vy;this.draw();}}var circle = new Circle(200, 200, 2, 2, 30);function animate() {requestAnimationFrame(animate);c.clearRect(0, 0, window.innerWidth, window.innerHeight);circle.update(); // 这边只需要一次次的调用 update() 即可}

有了Circle类,就可以方便的创建很多个Circle对象,并更新它们的位置。

var circleArray = [];
for (var i = 0; i < 50; i++) {var x = Math.random() * window.innerWidth;var y = Math.random() * window.innerHeight;var vx = (Math.random() - 0.5) * 3;var vy = (Math.random() - 0.5) * 3;var radius = Math.random() * 100;circleArray.push(new Circle(x, y, vx, vy, radius))
}function animate() {requestAnimationFrame(animate);c.clearRect(0, 0, WIDTH, HEIGHT);for (var i = 0; i < circleArray.length; i++) {circleArray[i].update();}
}
animate();

与鼠标交互

给移动的小球增加与鼠标交互的动画,当鼠标靠近时增大小球的半径,当鼠标远离时,再让它缩小,需要监听mousemove事件,并更新mouse.x和mouse.y的值:

window.addEventListener('mousemove', function (event) {mouse.x = event.clientX;mouse.y = event.clientY;
})

然后在update()里面:

if (Math.sqrt((this.x - mouse.x) ** 2 + (this.y - mouse.y) ** 2) < 100) {if (this.radius < maxRadius)this.radius += 1;} else if (this.radius > minRadius) {this.radius -= 1;}

为了方便使用,可以提前设定好最小半径和最大半径:

const maxRadius = 40, minRadius = 2;

适配不同尺寸的屏幕

当窗口大小发生变化时,会触发resize事件,可以通过监听这个事件,来重新初始化Canvas中的小球。

window.addEventListener('resize', function (event) {init();
})

如果小球的数量是固定的,那么较小的屏幕上会太密集,而较大的屏幕上看起来又会太稀疏,所以可以根据屏幕的大小来设置小球的个数,我这里的做法是将窗口的面积除以5000并向下取整来计算出小球的个数:

var circleArray = [];
function init() {canvas.width = window.innerWidth;canvas.height = window.innerHeight;var ballNumber = Math.floor((window.innerWidth * window.innerHeight) / 5000);circleArray = [];for (var i = 0; i < ballNumber; i++) {var x = Math.random() * window.innerWidth;var y = Math.random() * window.innerHeight;var vx = (Math.random() - 0.5) * 3;var vy = (Math.random() - 0.5) * 3;var radius = Math.random() * minRadius + 1;//Math.random() * 20;circleArray.push(new Circle(x, y, vx, vy, radius))}
}

为了让小球更好看一些,可以为它们填充不同的颜色:

const colorArray = ["#AFD3E2", "#F2B6A0", "#FC4F00", "#FFEEB3", "#A5C0DD", "#FF6969", "#ECC9EE", "#00FFCA"];

constructor() 中设置当前这个小球的填充颜色:

this.color = colorArray[Math.floor(Math.random() * colorArray.length)]

在填充之前设定一下颜色:

c.fillStyle = this.color;

到这里,这个简单的项目就结束了,各个颜色的小球会按照随机的速度飘动,鼠标附近的小球会逐渐变大:
请添加图片描述

相关文章:

【Canvas入门】从零开始在Canvas上绘制简单的动画

这篇文章是观看HTML5 Canvas Tutorials for Beginners教程做的记录&#xff0c;所以代码和最后的效果比较相似&#xff0c;教程的内容主要关于这四个部分&#xff1a; 创建并设置尺寸添加元素让元素动起来与元素交互 设置Canvas的大小 获取到canvas并设置尺寸为当前窗口的大…...

【技术整合】各技术解决方案与对应解决的问题

文章目录 基本实现性能安全 本文将框架分为三大类&#xff1a; 基本实现&#xff1a;包括某个供能或者提供web、移动端、桌面端、或者上述端上的某种功能性能&#xff1a;提升高可用、高并发的框架安全&#xff1a;包括网络安全、权限与容灾等 基本实现 .NET CORE、.NET web基…...

公网远程访问公司内网象过河ERP系统「内网穿透」

文章目录 概述1.查看象过河服务端端口2.内网穿透3. 异地公网连接4. 固定公网地址4.1 保留一个固定TCP地址4.2 配置固定TCP地址 5. 使用固定地址连接 概述 ERP系统对于企业来说重要性不言而喻&#xff0c;不管是财务、生产、销售还是采购&#xff0c;都需要用到ERP系统来协助。…...

Win11的两个实用技巧系列之修改c盘大小方法、功能快捷键大全

Win11 c盘无法更改大小什么原因?Win11修改c盘大小方法 有不少朋友反应Win11 c盘无法更改大小是怎么回事&#xff1f;本文就为大家带来了详细的更改方法&#xff0c;需要的朋友一起看看吧 Win11 c卷无法更改大小什么原因&#xff1f;有用户电脑的系统盘空间太小了&#xff0c;…...

离散数学下--- 代数系统

代数系统 定义&#xff1a; 代数系统是用代数运算构造数学模型的方法。 • 通过构造手段生成&#xff0c;所以也称代数结构 • 代数运算&#xff1a;在集合上建立满足一定规则的运算系统 &#xff08;一&#xff09;二元运算 二元运算的定义 二元运算需要满足的两个条件&a…...

java基础入门-04

Java基础入门-04 11、集合&学生管理系统11.1.ArrayList集合和数组的优势对比&#xff1a;11.1.1 ArrayList类概述11.1.2 ArrayList类常用方法11.1.2.1 构造方法11.1.2.2 成员方法11.1.2.3 示例代码 11.1.3 ArrayList存储字符串并遍历11.1.3.1 案例需求11.1.3.2 代码实现 11…...

《面试1v1》java反射

我是 javapub&#xff0c;一名 Markdown 程序员从&#x1f468;‍&#x1f4bb;&#xff0c;八股文种子选手。 面试官&#xff1a; 你好&#xff0c;请问你对 Java 反射有了解吗&#xff1f; 候选人&#xff1a; 是的&#xff0c;我了解一些。 面试官&#xff1a; 那你能简单…...

【C语言】struct结构体

文章目录 一. 结构体简述二. 结构体的声明和定义1、简单地声明一个结构体和定义结构体变量2、声明结构体的同时也定义结构体变量3、匿名结构体4、配合typedef&#xff0c;声明结构体的同时为结构体取别名5、在声明匿名结构体时&#xff0c;使用typedef给这个匿名结构体取别名 三…...

Docker代码环境打包

1. 介绍 Docker是一种开源的容器化平台&#xff0c;它可以在操作系统级别运行应用程序。通过将应用程序及其依赖项封装成一个可移植的容器&#xff0c;Docker使得应用程序可以在任何环境中轻松部署、运行和管理。使用Docker&#xff0c;开发人员可以避免在不同环境中出现的配置…...

现代CMake高级教程 - 第 6 章:输出与变量

双笙子佯谬老师的【公开课】现代CMake高级教程课程笔记 第 6 章&#xff1a;输出与变量 在运行 cmake -B build 时&#xff0c;打印字符串&#xff08;用于调试&#xff09; message("Hello world!")❯ cmake --build buildHello world! -- Configuring done -- G…...

windows/linux文件传输

windows系统下文件传输-FTP python安装pyftpdlib模块 pip install pyftpdlib 这里可能会出现报错&#xff0c;自己看着更换源解决 然后运行python&#xff0c;在2121端口监听 python -m pyftpdlib 然后我们可以使用windows命令行进行操作&#xff0c;自己可以去看下相关文…...

Anoconda安装笔记+win10 更改中文用户名为英文

win10 更改中文用户名为英文 ① WinR打开命令窗口&#xff0c;输入regedit 打开注册表&#xff0c; 手动找到 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\ProfileList 在这个目录下面有几个S-1-5-的项&#xff0c;挨个检查每一项&#xff0c; 找到“…...

Java Web应用开发 ——作业七

一.单项选择题&#xff08;共7题,28.7分&#xff09; 1 Servlet程序的入口点是&#xff08; &#xff09;。 A、 init&#xff08;&#xff09; B、 main&#xff08;&#xff09; C、 service&#xff08;&#xff09; D、 doGet&#xff08;&#xff09; 正确答案&#…...

echo,date,bc命令详解

文章目录 echo&#xff0c;date&#xff0c;bc命令详解echo(输出文本)date(显示日期的命令)date命令的--date选项date命令 bc(高精度计算器) echo&#xff0c;date&#xff0c;bc命令详解 echo(输出文本) echo命令是一个常用的Shell命令&#xff0c;用于在终端上输出文本。它…...

【Java笔试强训 29】

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 一、选择题 二、编程题 &#x1f525;求正数数…...

如何在微服务下保证事务的一致性

随着业务的快速发展、业务复杂度越来越高&#xff0c;传统单体应用逐渐暴露出了一些问题&#xff0c;例如开发效率低、可维护性差、架构扩展性差、部署不灵活、健壮性差等等。而微服务架构是将单个服务拆分成一系列小服务&#xff0c;且这些小服务都拥有独立的进程&#xff0c;…...

华为OD机试 - 新学校选址(Python)

题目描述 为了解新学期学生暴涨的问题,小乐村要建立所新学校, 考虑到学生上学安全问题,需要所有学生家到学校的距离最短。 假设学校和所有学生家都走在一条直线之上,请问学校建立在什么位置, 能使得到学校到各个学生家的距离和最短。 输入描述 第一行: 整数 n 取值范围 [1…...

thinkphp6结合layui增删改查综合案列

文章目录 技术栈实现代码实现数据库 本案例适合新手&#xff0c;特别是杠刚入门thinkphp和layui&#xff0c;但又不是特别熟悉这类 主要实现登录退出功能&#xff0c;用户模块的增删改查功能&#xff0c;分页功能是layui表单自带功能 效果图 左侧的菜单栏我没有写对应的页面&am…...

PostgreSQL数据库以任意时间间隔聚合查询group by

文章目录 业务场景以固定时间&#xff08;年/月/日/时/分/秒&#xff09;聚合to_char聚合date_trunc聚合 以任意时间聚合date_bin聚合实际应用 业务场景 我们做的是交通信控平台&#xff0c;需要根据实时采集到的交通大数据&#xff0c;计算出一些指标&#xff0c;存储到数据库…...

sql注入(二)盲注,二次注入,宽字节注入

目录 目录 一、布尔盲注 1.判断库名的长度 2.判断数据库名 2.1判断数据库名首字符 2.2 判断数据库名的其余字符 二、时间盲注&#xff1a; 1.判断库名的长度 2.判断库名&#xff1a; 3.判断表名payload&#xff1a; 4.爆出列名 5.爆数据 三、二次注入 1.原理&#…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

管理学院权限管理系统开发总结

文章目录 &#x1f393; 管理学院权限管理系统开发总结 - 现代化Web应用实践之路&#x1f4dd; 项目概述&#x1f3d7;️ 技术架构设计后端技术栈前端技术栈 &#x1f4a1; 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 &#x1f5c4;️ 数据库设…...