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

devtools/2024/10/22 9:52:13/

文章目录

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

yma16-logo

⭐前言

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

canvas_11">⭐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.ppmy.cn/devtools/6908.html

相关文章

C++ 几句话彻底点通虚表

#include <iostream>using namespace std;class Base { public:virtual void show() // 声明虚函数{cout << "Base" << endl;} };class Derived : public Base { public:void show() override // 覆盖虚函数{cout << "Derived" &l…

如何理解数据库事务

事务的概念起源于数据库系统的设计和实现。在计算机科学领域中&#xff0c;数据库系统被广泛用于存储和管理大量的数据&#xff0c;而事务的概念则是为了解决多用户并发访问数据库时可能出现的一系列问题。 事务的概念最早由 IBM 的科学家 Edgar F. Codd 在 1970 年提出。Codd…

vue+Element-ui实现模板文件下载

最近实现一个功能&#xff0c;数据过多&#xff0c;录入系统的时候过慢&#xff0c;所以新增一个导入数据的功能。 导入数据的话&#xff0c;为了防止用户随意输入&#xff0c;或者不知道怎么输入&#xff0c;所以特完成模板下载功能。 通常情况下实现模板下载采用a标签即可实现…

mac jd-gui安装

在macOS上安装JD-GUI&#xff08;Java Decompiler GUI&#xff09;是一个简单的过程。JD-GUI是一个独立的图形化应用程序&#xff0c;你可以使用它来查看Java字节码对应的源代码。下面是安装步骤&#xff1a; 下载JD-GUI&#xff1a; 访问JD-GUI的官方网站&#xff08;http://j…

XiaodiSec day034 Learn Note 小迪渗透学习笔记

XiaodiSec day034 Learn Note 小迪渗透学习笔记 记录得比较凌乱&#xff0c;不尽详细 day34 黑盒审计和白盒审计 与 cms 相关 .net java php 代码审计 开始 黑盒&#xff1a;找文件上传的功能 个人用户中心是否存在文件上传功能后台管理系统是否存在文件上传功能字典目录…

深入理解人工智能:从基础到前沿/厾罗

导言&#xff1a; 随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;已经成为了一个家喻户晓的概念。无论是在电影中看到的智能机器人&#xff0c;还是我们日常生活中的智能助手&#xff0c;人工智能的应用已经无处不在。但人工智能究竟是什么&#xff1f;它如…

【数据结构】二叉爆炸

【数据结构】二叉爆炸 按照惯例整点抽象的&#xff0c;贴上这篇博客的名字由来&#xff1a; 言归正传&#xff0c;本篇博客介绍二叉树的构造方式、前中后序遍历、层序遍历以及代码随想录中二叉树章节的相关题目&#xff1a; 代码随想录 (programmercarl.com) 一、啥是二叉树 …

节点加密技术:保障数据传输安全的新利器

随着信息技术的快速发展&#xff0c;网络数据的安全传输问题日益凸显。节点加密技术作为一种新兴的加密手段&#xff0c;正逐渐成为保障数据传输安全的重要工具。本文将探讨节点加密技术的原理、应用及其优势&#xff0c;并分析其未来的发展趋势。 节点加密技术的原理 节点加密…