webgl canvas系列——animation中基本旋转、平移、缩放(模拟冒泡排序过程)

文章目录

    • ⭐前言
    • ⭐canvas绘制图片
      • 💖状态保存和恢复
      • 💖移动、旋转、缩放、变形
        • 💖移动绘制一个渐变的box
        • 💖旋转
        • 💖缩放
    • ⭐模拟冒泡排序过程
    • ⭐结束

yma16-logo

⭐前言

大家好,我是yma16,本文分享webgl canvas系列——animation基本旋转、平移、缩放。
该系列往期文章
web canvas系列——快速入门上手绘制二维空间点、线、面
webgl canvas系列——快速加背景、抠图、加水印并下载图片

⭐canvas绘制图片

💖状态保存和恢复

方法作用
save()保存画布 (canvas) 的所有状态。
restore()save 和 restore 方法是用来保存和恢复 canvas 状态的,都没有参数。Canvas 的状态就是当前画面应用的所有样式和变形的一个快照。

💖移动、旋转、缩放、变形

方法作用
translate(x, y)在这里插入图片描述x *是左右偏移量,y 是上下偏移量
scale(x, y)scale方法可以缩放画布的水平和垂直的单位。两个参数都是实数,可以为负数,x 为水平缩放因子,y 为垂直缩放因子,如果比 1 小,会缩小图形,如果比 1 大会放大图形。默认值为 1,为实际大小
transform(a, b, c, d, e, f)将当前的变形矩阵乘上一个基于自身参数的矩阵

a c e b d f 0 0 1 (transform) \begin{matrix} a & c & e \\ b & d & f \\ 0 & 0 & 1 \end{matrix} \tag{transform} ab0cd0ef1(transform)

💖移动绘制一个渐变的box

使用translate移动
js代码快如下

function draw() {var ctx = document.getElementById("canvas").getContext("2d");const width=150const height=150for (var i = 0; i < 3; i++) {for (var j = 0; j < 3; j++) {ctx.save();ctx.fillStyle = "rgb(" + 51 * i + ", " + (255 - 51 * i) + ", 255)";ctx.translate(10+ j * (width+1), 10 + i * (height+1));ctx.fillRect(0, 0, width, height);ctx.restore();}}}

效果
translate

💖旋转

先移动原点再旋转
旋转一个正方形

  function draw() {const ctx = document.getElementById("canvas").getContext("2d");const xRectX=100const yRextY=100const width=100const height=100ctx.fillStyle = "rgba(0, 0, 200, 0.5)";ctx.beginPath();ctx.arc(xRectX, yRextY, 10, 0, Math.PI * 2, true); // 旋转中心ctx.fill();ctx.restore();// ctx.save();const translateX=xRectX+width/2const translateY=yRextY-height/4// left rectangles, rotate from canvas origin// blue rectctx.fillStyle = "#0095DD";ctx.fillRect(xRectX, yRextY, width, height);ctx.fillStyle = "rgba(255, 0, 200, 0.5)";ctx.beginPath();ctx.arc(translateX, translateY, 10, 0, Math.PI * 2, true); // 旋转中心ctx.fill();ctx.translate(translateX, translateY); // translate backctx.rotate((Math.PI / 180) * 45);// red rectctx.fillStyle = "rgba(255,0,0,.2)";ctx.fillRect(0, 0, width, height);ctx.restore();}

旋转效果
蓝色的圆点移动到红色的点之后再旋转45°
rotate
移动中心 再旋转

function draw() {const ctx = document.getElementById("canvas").getContext("2d");const xRectX = 100const yRextY = 100const width = 100const height = 100ctx.fillStyle = "rgba(0, 0, 200, 0.5)";ctx.beginPath();ctx.arc(xRectX, yRextY, 10, 0, Math.PI * 2, true); // 旋转中心ctx.fill();ctx.restore();// ctx.save();// x = x + 0.5 * width// y = y + 0.5 * heightconst translateX = xRectX + width / 2const translateY = yRextY + height / 2// left rectangles, rotate from canvas origin// blue rectctx.fillStyle = "#0095DD";ctx.fillRect(xRectX, yRextY, width, height);ctx.translate(translateX, translateY);ctx.rotate((Math.PI / 180) * 45);ctx.translate(-translateX, -translateY);// ctx.translate(translateX, translateY); // translate back// red rectctx.fillStyle = "rgba(255,0,0,.2)";ctx.fillRect(xRectX, xRectX, width, height);ctx.fillStyle = "rgba(255, 0, 200, 0.5)";ctx.beginPath();ctx.arc(translateX, translateY, 10, 0, Math.PI * 2, true); // 旋转中心ctx.fill();}

效果(红点为旋转中心)
rate_center

💖缩放

缩放文字

function draw() {var ctx = document.getElementById("canvas").getContext("2d");// mirror horizontallyctx.scale(2, 2);ctx.font = "48px serif";ctx.fillStyle = "rgba(0, 0, 200, 0.5)";ctx.fillText("csdn yma16", 0, 120);}

scale

⭐模拟冒泡排序过程

冒泡排序(Bubble Sort)
是一种计算机科学领域的较简单的排序算法。
它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行,直到没有相邻元素需要交换,也就是说该元素列已经排序完成。

vue3页面简单使用canvas模拟冒泡排序的效果

<script lang="js" setup>
import { reactive, onMounted } from 'vue';
const state = reactive({value: '[100,20,69,16,55,33]',title: '冒泡排序可视化',visualSortArray: []
})function bubbleSort(arr) {// 冒泡排序算法,对数组进行排序,同时记录每一步操作,保存在一个数组中function sort() {// virtualArr 用来存放 每一个步内容的数组const virtualArr = [arr.slice()];console.log('virtualArr', virtualArr)const max = arr.length;for (let i = 0; i < max; i++) {let done = true;for (let j = 0; j < max - i; j++) {if (arr[j] > arr[j + 1]) {let temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;done = false;virtualArr.push(arr.slice());}};if (done) {break;};}return virtualArr;}// 绘画,调用一次就画出一步的图像 function darw(arr, count) {const canvas = document.getElementById('myCanvas');const ctx = canvas.getContext('2d');// 最大高度 400let maxHeight = canvas.height;// 每个长方形的宽度let width = 20;// 每个长方形之间的间隔let space = 100;const total = arr.reduce((p, c) => p + c, 0)// 清空画布ctx.clearRect(0, 0, canvas.width, canvas.height);// 设置字体ctx.font = "18px serif";// 在页面上,画出一步的内容for (let i = 0; i < arr.length; i++) {ctx.fillStyle = '#61C5FE';const x= i * (width + space)const y= maxHeight - arr[i]const height=Math.round((arr[i] / total)*100  + 100)ctx.fillRect(x, y, width, height);console.log('x',x)console.log('y',y)console.log('width',width)console.log('height',height)ctx.fillStyle = '#240be4';// 标题文字ctx.fillText(arr[i], x, y);ctx.restore();}ctx.fillText(`${count}趟排序`, 200, 100);ctx.fillStyle = "rgba(0, 66, 200, 0.5)";ctx.beginPath();ctx.lineTo(0, 400);ctx.lineTo(800, 400);ctx.stroke()}// 动画 function animation() {// 调用sort 方法,返回包括每一步内容的数组var virtualArr = sort();var interval = 500;// 遍历得到的数组,每隔500ms,调用darw 方法,画出一步内容virtualArr.forEach((item, index) => {setTimeout(() => darw(item, index + 1), index * interval);});state.visualSortArray = virtualArr}animation();
}const sortBtn = () => {const arr = state.value.replace('[', '').replace(']', '').split(',').map(n => +n)console.log('arr', arr)bubbleSort(arr);
}onMounted(()=>{sortBtn()
})</script>
<template><div><div style="display:flex;"><a-card :title="state.title" style="min-width: 800px"><div class="input-box"><div><a-input v-model:value="state.value" placeholder="请输入数组" clearable></a-input></div><div style="margin-left:50px"><a-button type="primary" @click="sortBtn">开始排序</a-button></div></div><div class="container-sort"><div style="text-align: right;margin-right: 20px;"><div v-for="(item, index) in state.visualSortArray" :key="index"><div>第 {{ index + 1 }} 躺排序:  {{ item.toString() }}</div></div></div><canvas id="myCanvas" width="800" height="400"> </canvas></div></a-card></div></div>
</template><style lang="less">
.input-box {display: flex;margin-bottom: 10px;
}.container-sort {height: 800px;border: 1px solid #dcdcdc;
}.box {margin: 10px;.bar {width: 10px;background: #1677ff;border-radius: 2px;}.num {font-size: 18px;}
}
</style>

效果
sort
inscode代码块

⭐结束

本文分享到这结束,如有错误或者不足之处欢迎指出!
light

👍 点赞,是我创作的动力!
⭐️ 收藏,是我努力的方向!
✏️ 评论,是我进步的财富!
💖 最后,感谢你的阅读!

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

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

相关文章

企业常用Linux正则表达式与三剑客/企业生产环境及知识/企业中远程连接ssh工具(为什么连接有时慢?)

企业高薪思维: 1.学习去抓重点有价值知识 2.猛劲学&#xff0c;使劲学&#xff08;能否给别人将会&#xff0c;讲明白&#xff0c;写明白&#xff0c;练习明白&#xff09;&#xff0c;在学习过程中你觉得学会了60-80%&#xff0c;其实你只会了40-50%&#xff0c;你要讲明白会操…

构建云原生湖仓:Apache Iceberg与Amoro的结合实践

随着大数据技术的快速发展&#xff0c;企业对数据的处理和分析需求日益增长。传统的数据仓库已逐渐无法满足现代业务对数据多样性和实时性的要求&#xff0c;这促使了数据湖和数据仓库的融合&#xff0c;即湖仓一体架构的诞生。在云原生技术的推动下&#xff0c;构建云原生湖仓…

AWD线下攻防万字最完整战术(记第一届“长城杯”半决赛战术)

目录 准备阶段 1.登录比赛平台&#xff08;获取资产&#xff09; 查看账号账号修改 服务器SSH口令mysqlWEB服务口令(后台密码)数据库后台管理员密码 账号用户检查 2.dump源码&#xff08;方便应急响应恢复靶机&#xff09; 网站源码备份 压缩文件解压文件备份到服务器本地上传…

【原创】springboot+mysql疫苗预约管理系统设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

Linux部署Coturn以及关于打洞的思考

目录 Coturn介绍部署架构图 2.1 局域网——无NAT映射 2.2 NAT网Corturn安装步骤验证 4.1 局域网——无NAT映射 4.2 NAT网 4.2.1 Cywin安装步骤 4.2.2 Coturn安装步骤 4.2.3 验证引言 下文部署架构图为Corturn为解决互联网NAT环境下“找朋友”的部署架构,也是Coturn发挥其价值…

玩转 AIGC!使用 SD-WebUI 实现从文本到图像转换

节前&#xff0c;我们组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、参加社招和校招面试的同学&#xff0c;针对算法岗技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备、面试常考点分享等热门话题进行了深入的讨论。 基于大家…

javaScript常用知识点

1. this指向问题 在绝大多数情况下&#xff0c;函数的调用方式决定了this的值。this不能在执行期间被赋值&#xff0c;并且在每次函数被调用时this的值也可能会不同。 this指向的对象称为函数的上下文对象context&#xff1b;this的指向取决于函数被调用方式this的指向不是函数…

【更新】cyのMemo(20240422~)

序言 胡哥首马在淮安325完赛&#xff0c;他的本硕都在淮安度过&#xff0c;七年的跑步生涯画上句号&#xff0c;真的是很圆满。七年&#xff0c;从180斤瘦到120斤&#xff0c;历经种种&#xff0c;胡哥理解的跑步&#xff0c;不是快&#xff0c;而是稳&#xff0c;他在比赛中从…

力扣HOT100 - 226. 翻转二叉树

解题思路&#xff1a; class Solution {public TreeNode invertTree(TreeNode root) {if (root null) return null;TreeNode left invertTree(root.left);TreeNode right invertTree(root.right);root.left right;root.right left;return root;} }

《ElementUI 基础知识》png 图片扩展 icon用法

前言 UI 设计给的切图是 .png 格式。但想与 Element UI icon 用法类似&#xff0c;方案如下。 实现 步骤一 准备图片 步骤二 新建文件&#xff0c;可使用 CSS 预处理语言 styl 或 scss。 stylus 方式 文件 icon.styl /* 定义一个混合 */ cfgIcon(w, h) {display: inlin…

如何判别三角形和求10 个整数中最大值?

分享每日小题&#xff0c;不断进步&#xff0c;今天的你也要加油哦&#xff01;接下来请看题------> 一、已知三条边a&#xff0c;b&#xff0c;c能否构成三角形&#xff0c;如果能构成三角形&#xff0c;判断三角形的类型&#xff08;等边三角形、等腰三角形或普通三角形 …

DAPP的商业模型创新: 探索可持续盈利路径

去中心化应用&#xff08;Decentralized Applications&#xff0c;DAPPs&#xff09;作为区块链技术的重要应用之一&#xff0c;在近年来蓬勃发展。然而&#xff0c;随着市场竞争的加剧和用户需求的不断变化&#xff0c;DAPP开发者们面临着寻找可持续盈利路径的挑战。本文将探讨…

注意libaudioProcess.so和libdevice.a是不一样的,一个是动态链接,一个是静态

libaudioProcess.so是动态链接&#xff0c;修改需要改根文件系统&#xff0c;需要bsp重新配置 libdevice.a是静态链接&#xff0c;直接替换就行 动态链接文件修改 然后执行fw_update.sh

最优控制理论笔记 - 03无约束条件下的泛函极值问题

一、始端时刻t0和终端时刻tf时刻都给定的泛函极值问题 其中式子2.8为欧拉方程&#xff0c;式子2.9为横截条件。 上述推导的重要作用在于将求泛函的极值问题转化为求解欧拉方程在满足边界条件和横截条件下的定解问题。 1. 固定始端和终端 2. 自由始端和自由终端 3. 自由始端和…

一文读懂链游!探索链游的前世今生,区块链与游戏结合的新兴趋势

区块链技术的崛起给游戏行业带来了前所未有的变革&#xff0c;而链游&#xff08;Blockchain Games&#xff09;正是这一变革的产物。本文将带您一览链游的前世今生&#xff0c;探索区块链与游戏结合的新兴趋势。 1. 链游的起源 链游&#xff0c;顾名思义&#xff0c;是指利用…

恶心透了的小日子,害人终害己,国货呼吁关注抵制日本核废水排放

​|日本排放核废水 日本政府决定将福岛第一核电站的核污染水经过处理后排放入海&#xff0c;这一决定引发了多方面的担忧和反对&#xff0c;特别是在周边国家&#xff0c;包括中国和韩国。关于日本排放核污染水这一新闻事件&#xff0c;我们必须首先认识到&#xff0c;核能利用…

【MySQL 数据宝典】【磁盘结构】- 002 数据字典

一、数据字典 ( Data Dictionary ) 1.1 背景介绍 我们平时使用 INSERT 语句向表中插入的那些记录称之为用户数据&#xff0c;MySQL只是作为一个软件来为我们来保管这 些数据&#xff0c;提供方便的增删改查接口而已。但是每当我们向一个表中插入一条记录的时候&#xff0c;MyS…

前端学习之DOM编程案例:点名案例和秒表案例

点名 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>点名案例</title><style>*{margin: 0;padding: 0;}</style> </head> <body><div id"container">…

H5 台球猜位置小游戏

刷到抖音有人这样玩&#xff0c;就写了一个这样的小游戏练习一下H5的知识点。 小游戏预览 w(&#xff9f;Д&#xff9f;)w 不开挂越急越完成不了&#xff0c;&#x1f47f;确认15次也没全对… 知识点 获取坐标位置的DOM元素&#xff0c;感觉应该是新的吧&#xff0c;以前的…

使用Python进行容器编排Docker Compose与Kubernetes的比较

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 随着容器化技术的普及&#xff0c;容器编排成为了管理和部署容器化应用程序的重要环节。在容…