Canvas制作排序算法演示动画

tips: 形象化演示排序算法可以让初学者快速理解,比较好的例子:jun-lu的SortAnimate,旧金山大学的David Galles教授的算法演示课件。最近在看canvas,试着用js+canvas自己做了一个。

实现思路

  • 获取输入字符串
  • 存入数组S[]
  • 新建一个对象数组Rect[]{ x , y , target_x , target_y , text:S[i]}(注:x , y 是当前坐标,target_x , target_y 是目的坐标,text 记录字符)
  • 排序
  • 使用插入排序进行顺序排序,当数值有交换行为时, 用track_insert[]记录进行交换的元素在数组中的位置(方便在绘制动画时进行坐标定位)
  • 因为我用的是插入排序,属于arr[i]arr[i+1]进行交换,所以只需要记录i就可以。
  • 绘制
  • 图片绘制function Draw(){}
  • 图片坐标更新function Update(){}
  • 使用setInterval()定时调用Draw()Update()函数进行页面刷新

效果

初始界面

排序过程

gif演示

小结

做动画都是一个原理,不短刷新更新坐标,擦除,绘制,之前用opencv做的2d的小游戏也是同样的原理。

Source code

.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="Content-Type" content="text/html;charset=utf-8"><link rel="stylesheet" type="text/css" href="css/demo.css"/><script type="text/javascript"src="js/demo2.js"></script><title>Demo</title>
</head>
<body>  <div id="container"><div><p>Input String:<input  name="string" id="tin" type="text"/></p>                    </div><div><p> <input type="button" onclick="showDemo()"id="bin" value="Show"/></p><canvas id="mycanvas"  ></canvas></div></div>
</body>
</html>

.js

var S;
var Coordinate_y = 40;
var Rect = new Array();
var track_insert = new Array();
var cons = 0;
var cnt;function func() {
//获取字符串,存入数组S = document.getElementsByName("string")[0].value.split("");
//依据数组元素,完成对象数组for (var i = 0; i < S.length; i++) {var rect = {x: 30 * i,y: Coordinate_y,target_x: 30 * i,target_y: Coordinate_y,text: S[i]}Rect.push(rect);}insertSort(S);
}function insertSort(arr) {var i = 1,j, key, temp;for (; i < arr.length; i++) {j = i;key = arr[i];while (--j >= 0) {if (arr[j] > key) {arr[j + 1] = arr[j];arr[j] = key;
//当数据有交换时,记录下标track_insert.push(j);} else {break;}}}
}
//坐标更新
function update() {if (cons > track_insert.length) {return;}if (cons == 0) {cnt = track_insert[cons];Rect[cnt].target_x = Rect[cnt + 1].x;Rect[cnt + 1].target_x = Rect[cnt].x;cons += 1;console.log(cnt);}if (Rect[cnt].x == Rect[cnt].target_x) {if (cons == track_insert.length) {cons += 1;return;}var tem = Rect[cnt];Rect[cnt] = Rect[cnt + 1];Rect[cnt + 1] = tem;cnt = track_insert[cons];Rect[cnt].target_x = Rect[cnt + 1].x;Rect[cnt + 1].target_x = Rect[cnt].x;cons += 1;console.log(cnt);} else {Rect[cnt].x += 1;Rect[cnt + 1].x -= 1;}
}
//绘制图像
function draw(context) {context.clearRect(0, 0, context.canvas.width, context.canvas.height);for (var i = 0; i < Rect.length; i++) {if ((Rect[i].x - Rect[i].target_x) >= 2 || (Rect[i].x - Rect[i].target_x) < -2) {context.fillStyle = "yellow";context.fillRect(Rect[i].x, Rect[i].y, 25, 25);context.fillStyle = "blue";context.fillText(Rect[i].text, Rect[i].x + 10, Rect[i].y + 15);} else {context.strokeStyle = "blue";context.strokeRect(Rect[i].x, Rect[i].y, 25, 25);context.fillStyle = "blue";context.fillText(Rect[i].text, Rect[i].x + 10, Rect[i].y + 15);}}context.fillText("插入排序", 40, 80);
}
function showDemo() {func();var c = document.getElementById("mycanvas");c.width = 600;c.height = 300;var context = c.getContext("2d");
//40ms调用一次函数setInterval(function() {draw(context);update();}, 40);
}

.css

input#tin{margin-bottom: 5px;background-color: #fff;opacity:0.85;8width:20px;height:25px; border-width: 1;font-size: 17px; color: #000; font-weight: 500; border-radius: 5px;cursor:pointer; 
}
input#bin{background-color: gray;width:80; height:25; border-width: 2; font-size: 20px; color: #FFFFFF; font-weight: 500;cursor:pointer; border-radius: 5px;
}
canvas#mycanvas{border:1px solid;width: 600px;height: 300px;margin-top: 5px;border-radius: 5px;
}
div#container{margin-left: 70px;
}

转载于:https://www.cnblogs.com/coderleon/p/4784095.html

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

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

相关文章

oracle之单行函数2

--通用函数 --求公司员工的年薪 nvl 没有值代替 select employee_id,last_name,salary*12*(1nvl(commission_pct,0)) "annnal salary" from employees 运行结果 --输出department_id为空时候 没有部门 select last_name,nvl(to_char(department_id,99999),没有部门)…

linux vi命令 置顶,[置顶] Linux vi命令 创建文件

创建文件【vi】一、进入vi的命令vi filename :打开或新建文件&#xff0c;并将光标置于第一行首vi n filename &#xff1a;打开文件&#xff0c;并将光标置于第n行首vi filename &#xff1a;打开文件&#xff0c;并将光标置于最后一行首vi /pattern filename&#xff1a;打开…

Bootstrap中过渡效果(Transition)模态框插件的使用案例

通过使用模态框效果实现弹出框的登录效果&#xff1a; 效果图&#xff1a; <form id"formmodal" action"#"><h3>过渡效果&#xff08;Transition&#xff09;模态框插件的使用案例&#xff1a;</h3><!--按钮触发模态框--><but…

oracle之单行函数之课后练习

18. 打印出 "2009年10月14日 9:25:40" 格式的当前系统的日期和时间.select to_char(sysdate, YYYY"年"MM"月"DD"日" HH:MI:SS)from dual 注意: 使用双引号向日期中添加字符19. 格式化数字: 1234567.89 为 1,234,567.89select to_char(…

machine id linux,linux – 机器ID是uuid吗?

是的,现在.这在systemd手册中有所介绍. / etc / machine-id中的值最初不是有效的UUID,因为systemd人员最初没有编写用于生成版本4 UUID的正确代码.但此后已经修复.如果将许可证绑定到计算机ID,请注意它可以更改…> …如果有人删除/ etc / machine-id并在下次bootstrap中重新…

C++ 字符串指针与字符串数组

在做面试100题中第21题时&#xff0c;发现char *astr"abcdefghijk\0";和char astr[]{"abcdefghijk"};有点区别&#xff0c;以前一直以为是一样的&#xff0c;但是在该程序中采用字符串指针运行一直出错。后来在网上查查&#xff0c;果然发现大大的不同。 展…

oracle之单行函数之多表查询

--多表查询 select employees.employee_id,employees.department_id,departments.department_name from departments,employees where employees.department_iddepartments.department_id; 运行结果 --多表查询 其他情况 select e.employee_id,e.department_id,d.department…

hudson linux节点,在Linux下设置Hudson进行连续集成

在Linux下设置Hudson持续集成哈德森监督执行重复的工作&#xff0c;例如建立一个软件项目或由cron运行的工作。 本文介绍如何在Linux上进行设置。1准备1.创建目录结构如下&#xff1a;/var/hudson/|-[.ssh]|-[bin]| -[slave.jar]-[workspace]-[container]-[ci-tools]…

转: Jenkins+Gradle实现android开发持续集成、打包

http://my.oschina.net/uboluo/blog/157483 转载于:https://www.cnblogs.com/jhj117/p/4790079.html

VMware出现配置文件 .vmx 是由VMware产品创建,但该产品与此版 VMware workstation 不兼容,因此无法使用(VMware版本不兼容问题)

首先先修改.vmx文件 修改成你VM对应的版本号 然后修改.vmdk文件 同样修改成VM对应的版本号 接下来运行虚拟机会出现 不支持客户机操作系统"centos6-64", 请从"虚拟机设置"中"选项"选项卡上的"常规"页面选择一个客户机操作系统. 按照操…

parrot linux 安装grub,parrotsec 和 kali安装系统的时候出现“executing grub-install dummy”的解决方案...

在物理机的环境下安装系统出现点问题&#xff0c;弄了好一会才弄出解决方法1、parrot和kali安装的时候出现了无efi分区不能继续的问题&#xff0c;要知道我之前安装的时候一直都是\ ; 内存; \home三个分区搞定&#xff0c;然后我一直以为是我刻盘的问题&#xff0c;这里其实解决…

asp 下拉框二级联动

<script language "JavaScript"> //js开始 var aaa;//定义aaa变量 aaa0;//aaa赋0 bb new Array();//创建bb动态数组 <%count 0 定义bb数组下标变量 do while not rs.eof%>//循环所有记录 bb[<%count%>] new Array("<% trim(rs(&quo…

打不开磁盘“D:\CentOS7\CentOS7.vmdk”或它所依赖的某个快照磁盘。

这主要是非正常关闭虚拟机造成的&#xff0c;未能锁定文件 虚拟机为了防止有多虚拟机共用一个虚拟磁盘&#xff08;就是后 缀为.vmdk那个文件&#xff09;造成数据的丢失和性能的削弱&#xff0c;每次启动虚拟机时会给每个虚拟磁盘加一个磁盘锁&#xff08;也就是后缀为.lck的那…

qt c语言socket,c – Qt双向客户端服务器使用QTcpSocket和QTcpServer

默认情况下,QTcpSocket是异步的,因此当您调用connectToHost并在相同的上下文中写入时,将不会发送,因为套接字未连接.你应该改变你的“客户端”代码&#xff1a;void TopLevelComms::connect(){tcpSocket->connectToHost(hostAddress,QIODevice::ReadWrite);if(tcpSocket->…

【转】 代理模式

原文链接&#xff1a;http://layznet.iteye.com/blog/1182924一、代理概念 为某个对象提供一个代理&#xff0c;以控制对这个对象的访问。 代理类和委托类有共同的父类或父接口&#xff0c;这样在任何使用委托类对象的地方都可以用代理对象替代。代理类负责请求的预处理、过滤、…

oracle之单行函数之多表查询值之课后练习

26. 多表连接查询时, 若两个表有同名的列, 必须使用表的别名对列名进行引用, 否则出错!27. 查询出公司员工的 last_name, department_name, cityselect last_name, department_name, cityfrom departments d, employees e, locations lwhere d.department_id e.department_id …

行末没有空格c语言,新人提问:如何将输出时每行最后一个空格删除

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼如何将每行最后一个空格删除&#xff0c;使矩阵只有数字间有空格&#xff0c;没有多余空格&#xff1f;#include#includeint main(){int i,j,k,m,n,x,h,y;int a[15][15]{0};while(scanf("%d",&i)){k1;for(n1;n<i;…

Core Animation

关键字 1.Core Animation的核心类是CALayer,通过对其属性进行配置可以展现不同的外观&#xff0c;这些属性包括位置&#xff0c;尺寸&#xff0c;图片内容&#xff0c;背景色&#xff0c;边界&#xff0c;阴影&#xff0c;以及角半径。 CATextLayer *textLayer;textLayer [CAT…

oracle之单行函数之分组函数

--分组函数 select avg(salary),max(salary),min(salary),sum(salary) from employees 运行结果 --判断大小 select max(last_name),min(last_name),max(hire_date),min(hire_date) from employees 运行结果 --计数 select count(employee_id),count(last_name),count(hire_da…

LeetCode 98. Validate Binary Search Tree

原题链接在这里&#xff1a;https://leetcode.com/problems/validate-binary-search-tree/ 题目&#xff1a; Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as follows: The left subtree of a node contains only n…