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),没有部门)…

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

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

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…

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

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

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

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

【转】 代理模式

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

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…

RocketMQ初步应用架构理论

RocketMQ初步应用架构理论 写给RocketMQ架构应用入门&#xff0c;内容涉及它的设计机理以及推到出来的应用注意事项&#xff0c;入门人员请看。 稍微涉及技术细节&#xff0c;留以我设计中间件时参考&#xff0c;将来整理深度文档时会抽取走&#xff0c;入门人员可以无视。 以下…

oracle之单行函数之子查询

--睡得工资比abel高 select last_name,salary from employees where salary>(select salary from employees where last_nameAbel)运行结果 --返回job_id 与141号员工相同 salary比143号多 select last_name,job_id,salary from employees where job_id(select job_id from…

android模拟gps定位软件,gps定位模拟器下载最新版

卫星地图导航&#xff0c;从此出门想去哪里去哪里&#xff0c;再也不用因为不知道路线而烦忧&#xff01;它还能实时定位&#xff0c;快速找人、找车&#xff01;推荐&#xff01;使用前提&#xff1a;1、定位模拟器是基于Xposed安卓框架下的插件&#xff0c;因此安装定位模拟器…

oracle之创建和管理表

create table emp2 AS Select employee_id,last_name name,hire_date,salary from employees select * from emp2 --创建表 --白手起家 /* create table emp1(id number(10),name varchar(20),salary number(10,2),hire_date date ) */

LocalBroadcastManager 的使用

一、使用本地广播发送一条广播&#xff08;本例为自己发送自己接收&#xff0c;本地广播也可以是其他应用接收&#xff09;然后接收到广播时回调Receiver类中的回调方法onReceive&#xff08;&#xff09;在此方法中自定义发出通知 代码 1 package com.qf.broadcastreceiver06;…

android xml正方形,使用Android Constraintlayout创建一排均匀分布的正方形

我正在努力创建一个由均匀分布的正方形链组成的布局&#xff0c;这些正方形可以填充可用空间。使用Android Constraintlayout创建一排均匀分布的正方形我到底想要的布局&#xff0c;看起来像这样&#xff1a;的想法是&#xff0c;与不同的宽高比手机这个正方形成长一点点地使用…

oracle之数据处理

--创建表 create table emp3 as select employee_id,last_name,hire_date,salary from employees--查询表 select * from emp3--插入表 insert into emp3 values(1001,AA,sysdate,10000) 运行结果 插入对应三项 --空值用null代替 --复制表 insert into emp3(last_name,employe…

HDU 4635(强连通分量分解

题目:给出一个有向图,要求添加最多的边数,使得图仍然不强连通. 思路:首先这个图在添加边之后肯定变成了两个强连通分量,现在就看怎么分.然后我们可以注意到,原图进行强连通分量分解之后必然存在一些分量的出度或入度为0,最小的分量肯定在这些分量之中.那么找出这个分量就可以得…

Android方法的概括,android中的Filter接口简介

一、结构public abstract class Filter extends Objectjava.lang.Objectandroid.widget.Filter二、概述过滤器通过过滤模式来约束数据&#xff0c;通常由实现了Filterable接口的子类来生成。 过滤操作是通过调用filter(CharSequence)或者filter(CharSequence, android.widget.F…

android webview 长按菜单拦截,javascript-在Android上长按时禁用上下文菜单

javascript-在Android上长按时禁用上下文菜单我想禁用长按(触摸并按住)Web应用程序中的图像后出现的上下文菜单。 我见过关于如何做到这一点的不同想法&#xff0c;但似乎没有一个对我有用。有没有办法通过HTML / CSS / Javascript在Android上执行此操作&#xff1f;12个解决方…

oracle之数据处理之约束1

--创建表 create table emp4( id number(10) constraint emp2_id_nn not null, name varchar2(20) not null, salaty number(10,2) )--查询表 select *from emp4--插入 insert into emp4 values(1001,geyao,2000) 运行结果 --创建表 create table emp5( --列级约束 id numbe…