您现在的位置是:首页 > 诗句大全

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

作者:付梓时间:2024-05-09 17:39:26分类:诗句大全

简介  文章浏览阅读8.6k次,点赞22次,收藏17次。大家好,我是yma16,本文分享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} ab0​cd0​ef1​(transform)

💖移动绘制一个渐变的box

使用translate移动
js代码快如下

function draw() {    var ctx = document.getElementById("canvas").getContext("2d");    const width=150    const height=150    for (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=100    const yRextY=100    const width=100    const height=100    ctx.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/2    const translateY=yRextY-height/4      // left rectangles, rotate from canvas origin    // blue rect    ctx.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 back    ctx.rotate((Math.PI / 180) * 45);    // red rect    ctx.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 = 100    const yRextY = 100    const width = 100    const height = 100    ctx.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 * height    const translateX = xRectX + width / 2    const translateY = yRextY + height / 2    // left rectangles, rotate from canvas origin    // blue rect    ctx.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 rect    ctx.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 horizontally    ctx.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');                // 最大高度 400        let 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

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

点击全文阅读

郑重声明:

本站所有活动均为互联网所得,如有侵权请联系本站删除处理

我来说两句