html5 canvas画流程图

<!DOCTYPE html>
<html> <head>
<meta charset="utf-8" />
<title></title>
</head> <body>
<canvas id="myCanvas" width="1200" height="800" style="border: solid 1px;"></canvas>
<script type="text/javascript" src="js/arrow.js"></script>
<script type="text/javascript" src="js/step.js" ></script>
<script type="text/javascript" src="js/flow.js"></script>
</body> </html>
//
// arrow.js
// <箭头对象>
//
// Created by DurantSimpson on 2016-12-08.
// Copyright 2016 DurantSimpson. All rights reserved.
// /**
*
* @param {Object} x1起始点横坐标
* @param {Object} y1起始点纵坐标
* @param {Object} x2结束点横坐标
* @param {Object} y2结束点纵坐标
*/
function Arrow(x1, y1, x2, y2) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.tmpX1 = null;
this.tmpY1 = null;
this.tmpX2 = null;
this.tmpY2 = null;
this.color = "black"; } Arrow.prototype.setColor = function(color) {
this.color=color;
} /**
*
* @param {Object} x1起始点横坐标
* @param {Object} y1起始点纵坐标
* @param {Object} x2结束点横坐标
* @param {Object} y2结束点纵坐标
*/
Arrow.prototype.setP = function(x1, y1, x2, y2) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
} /**
* 第一个拐点
*/
Arrow.prototype.setP1 = function(tmpX1,tmpY1) {
this.tmpX1=tmpX1;
this.tmpY1=tmpY1;
} /**
* 第二个拐点
*/
Arrow.prototype.setP2 = function(tmpX2,tmpY2) {
this.tmpX2=tmpX2;
this.tmpY2=tmpY2;
} Arrow.prototype.drawBottomToTop = function(ctx) {
if (this.x1 != this.x2) {
this.setP1(this.x1,(this.y1+this.y2)/2);
this.setP2(this.x2,(this.y1+this.y2)/2);
this.draw(ctx);
}else{
this.draw(ctx);
}
} Arrow.prototype.drawLeftOrRightToTop = function(ctx) {
this.setP1(this.x2,this.y1);
this.draw(ctx);
} Arrow.prototype.drawLeftToRightOrRightToLeft = function(ctx) {
if (this.y1 != this.y2) {
this.setP1((this.x1+this.x2)/2,this.y1);
this.setP2((this.x1+this.x2)/2,this.y2);
this.draw(ctx);
}else{
this.draw(ctx);
}
} Arrow.prototype.draw = function(ctx) {
// arbitrary styling
ctx.strokeStyle = this.color;
ctx.fillStyle = this.color;
// draw the line
ctx.beginPath();
ctx.moveTo(this.x1, this.y1);
if(this.tmpX1 != null && this.tmpY1 != null && this.tmpX2 != null && this.tmpY2 != null) {
ctx.lineTo(this.tmpX1, this.tmpY1);
ctx.closePath();
ctx.stroke();
ctx.beginPath();
ctx.moveTo(this.tmpX1, this.tmpY1)
ctx.lineTo(this.tmpX2, this.tmpY2);
ctx.closePath();
ctx.stroke();
ctx.beginPath();
ctx.moveTo(this.tmpX2, this.tmpY2);
ctx.lineTo(this.x2, this.y2);
ctx.closePath();
ctx.stroke();
var endRadians = Math.atan((this.y2 - this.tmpY2) / (this.x2 - this.tmpX2));
endRadians += ((this.x2 >= this.tmpX2) ? 90 : -90) * Math.PI / 180;
this.drawArrowhead(ctx, this.x2, this.y2, endRadians);
} else if(this.tmpX1 != null && this.tmpY1 != null && this.tmpX2 == null && this.tmpY2 == null) {
ctx.lineTo(this.tmpX1, this.tmpY1);
ctx.closePath();
ctx.stroke();
ctx.beginPath();
ctx.moveTo(this.tmpX1, this.tmpY1)
ctx.lineTo(this.x2, this.y2);
ctx.closePath();
ctx.stroke();
var endRadians = Math.atan((this.y2 - this.tmpY1) / (this.x2 - this.tmpX1));
endRadians += ((this.x2 >= this.tmpX1) ? 90 : -90) * Math.PI / 180;
this.drawArrowhead(ctx, this.x2, this.y2, endRadians);
}else if(this.tmpX1 == null && this.tmpY1 == null && this.tmpX2 == null && this.tmpY2 == null){
ctx.lineTo(this.x2, this.y2);
ctx.closePath();
ctx.stroke();
var endRadians = Math.atan((this.y2 - this.y1) / (this.x2 - this.x1));
endRadians += ((this.x2 >= this.x1) ? 90 : -90) * Math.PI / 180;
this.drawArrowhead(ctx, this.x2, this.y2, endRadians);
}
} /**
* 画箭头
*/
Arrow.prototype.drawArrowhead = function(ctx, x, y, radians) {
ctx.save();
ctx.beginPath();
ctx.translate(x, y);
ctx.rotate(radians);
ctx.moveTo(0, 0);
ctx.lineTo(5, 10);
ctx.lineTo(-5, 10);
ctx.closePath();
ctx.restore();
ctx.fill();
}
//
// step.js
// <流程图对象>
//
// Created by DurantSimpson on 2016-12-08.
// Copyright 2016 DurantSimpson. All rights reserved.
//
function drawRoundRect(x, y, w, h) {
var r = h / 2;
cxt.beginPath();
cxt.moveTo(x + r, y);
cxt.arcTo(x + w, y, x + w, y + h, r);
cxt.arcTo(x + w, y + h, x, y + h, r);
cxt.arcTo(x, y + h, x, y, r);
cxt.arcTo(x, y, x + w, y, r);
cxt.closePath();
cxt.stroke();
} function drawRhombus(x, y, l) {
cxt.beginPath();
cxt.moveTo(x, y + l);
cxt.lineTo(x - l * 2, y);
cxt.lineTo(x, y - l);
cxt.lineTo(x + l * 2, y);
cxt.closePath();
cxt.stroke();
} /**
* 圆角矩形开始对象
* @param {Object} x
* @param {Object} y
*/
function Start(x, y) {
this.h = 50;
this.w = 2 * this.h;
this.x = x;
this.y = y;
drawRoundRect(x - this.w / 2, y - this.h / 2, this.w, this.h);
} /**
* 矩形步骤对象
* @param {Object} x
* @param {Object} y
*/
function Step(x, y) {
this.flag = "step";
this.h = 50;
this.w = 2 * this.h;
this.x = x;
this.y = y;
cxt.strokeRect(x - this.w / 2, y - this.h / 2, this.w, this.h);
} /**
* 菱形条件对象
* @param {Object} x
* @param {Object} y
*/
function Condition(x, y) {
this.flag = "condition";
this.l = 30;
this.x = x;
this.y = y;
drawRhombus(x, y, this.l);
} Start.prototype.drawBottomToTop = function(obj) {
if(obj.flag == "step") {
var arrow = new Arrow(this.x, this.y + this.h / 2, obj.x, obj.y - obj.h / 2);
arrow.drawBottomToTop(cxt);
} else if(obj.flag == "condition") {
var arrow = new Arrow(this.x, this.y + this.h / 2, obj.x, obj.y - obj.l);
arrow.drawBottomToTop(cxt);
}
} Step.prototype.drawBottomToTop = function(obj) {
if(obj.flag == "step") {
var arrow = new Arrow(this.x, this.y + this.h / 2, obj.x, obj.y - obj.h / 2);
arrow.drawBottomToTop(cxt);
} else if(obj.flag == "condition") {
var arrow = new Arrow(this.x, this.y + this.h / 2, obj.x, obj.y - obj.l);
arrow.drawBottomToTop(cxt);
}
} Condition.prototype.drawBottomToTop = function(obj) {
if(obj.flag == "step") {
var arrow = new Arrow(this.x, this.y + this.l, obj.x, obj.y - obj.h / 2);
arrow.drawBottomToTop(cxt);
} else if(obj.flag == "condition") {
var arrow = new Arrow(this.x, this.y + this.l, obj.x, obj.y - obj.l);
arrow.drawBottomToTop(cxt);
}
} Condition.prototype.drawRightToTop = function(obj) {
if(obj.flag == "step") {
var arrow = new Arrow(this.x + this.l * 2, this.y, obj.x, obj.y - obj.h / 2);
arrow.drawLeftOrRightToTop(cxt);
} else if(obj.flag == "condition") {
var arrow = new Arrow(this.x + this.l * 2, this.y, obj.x, obj.y - obj.l);
arrow.drawLeftOrRightToTop(cxt);
}
} Condition.prototype.drawLeftToTop = function(obj) {
if(obj.flag == "step") {
var arrow = new Arrow(this.x - this.l * 2, this.y, obj.x, obj.y - obj.h / 2);
arrow.drawLeftOrRightToTop(cxt);
} else if(obj.flag == "condition") {
var arrow = new Arrow(this.x - this.l * 2, this.y, obj.x, obj.y - obj.l);
arrow.drawLeftOrRightToTop(cxt);
}
} Condition.prototype.drawRightToLeft = function(obj) {
if(obj.flag == "step") {
var arrow = new Arrow(this.x + this.l * 2, this.y, obj.x - this.w / 2, obj.y);
arrow.drawLeftToRightOrRightToLeft(cxt);
} else if(obj.flag == "condition") {
var arrow = new Arrow(this.x + this.l * 2, this.y, obj.x - this.l * 2, obj.y);
arrow.drawLeftToRightOrRightToLeft(cxt);
}
} Condition.prototype.drawLeftToRight = function(obj) {
if(obj.flag == "step") {
var arrow = new Arrow(this.x - this.l * 2, this.y, obj.x + this.w / 2, obj.y);
arrow.drawLeftToRightOrRightToLeft(cxt);
} else if(obj.flag == "condition") {
var arrow = new Arrow(this.x - this.l * 2, this.y, obj.x + this.l * 2, obj.y);
arrow.drawLeftToRightOrRightToLeft(cxt);
}
}
//
// flow.js
// <主要逻辑>
//
// Created by DurantSimpson on 2016-12-08.
// Copyright 2016 DurantSimpson. All rights reserved.
//
var canvas = document.getElementById("myCanvas");
var cxt = canvas.getContext('2d'); var start = new Start(600,25);//新建开始对象
var step1 = new Step(600,105);//新建第一个步骤 start.drawBottomToTop(step1); //画箭头(从开始对象指向第一个步骤) var condition1 = new Condition(300, 200);//新建第一个条件对象
var condition2 = new Condition(450, 200);
var condition3 = new Condition(600, 200);
var condition4 = new Condition(750, 200);
var condition5 = new Condition(900, 200); step1.drawBottomToTop(condition1);//画箭头(从第一个步骤指向第一个条件)
step1.drawBottomToTop(condition2);
step1.drawBottomToTop(condition3);
step1.drawBottomToTop(condition4);
step1.drawBottomToTop(condition5); var step2 = new Step(450,295);
var step3 = new Step(750,295); condition1.drawBottomToTop(step2);
condition2.drawBottomToTop(step2);
condition3.drawBottomToTop(step2);
condition4.drawBottomToTop(step3);
condition5.drawBottomToTop(step3); var condition6 = new Condition(300, 400);
var condition7 = new Condition(450, 400);
var condition8 = new Condition(750, 400);
var condition9 = new Condition(900, 400);
var condition10 = new Condition(450, 500);
var condition11 = new Condition(900, 500);
var condition12 = new Condition(450, 600);
var condition13 = new Condition(900, 600); step2.drawBottomToTop(condition6);
step3.drawBottomToTop(condition9); var step4 = new Step(300,725);
var step5 = new Step(450,725);
var step6 = new Step(600,725);
var step7 = new Step(750,725);
var step8 = new Step(900,725); condition6.drawBottomToTop(step4);
condition6.drawRightToLeft(condition7);
condition7.drawRightToTop(step6);
condition7.drawBottomToTop(condition10);
condition8.drawBottomToTop(step7);
condition9.drawLeftToRight(condition8);
condition9.drawBottomToTop(condition11);
condition10.drawBottomToTop(condition12);
condition11.drawBottomToTop(condition13);
condition12.drawBottomToTop(step5);
condition13.drawBottomToTop(step8); /*canvas.onclick = function(e) { //给canvas添加点击事件
e = e || event; //获取事件对象
//获取事件在canvas中发生的位置
var x = e.clientX - canvas.offsetLeft;
var y = e.clientY - canvas.offsetTop;
//如果事件位置在矩形区域中
alert('x:' + x + "y:" + y);
if(x>=rect.x&&x<=rect.x+rect.w&&y>=rect.y&&y<=rect.y+rect.h){
alert('clicked')
}
}*/
html5 canvas画流程图的更多相关文章
- canvas画流程图
用canvas画流程图: 需求:最后一个圆圈无直线 遇到问题:需要画多个圆圈时,画布超出显示屏加滚动条,解决方法是<canvas>外层<div>的width=100%,且ove ...
- HTML5 Canvas 画虚线组件
前段时间由于项目需要,用到了HTML5 Canvas画图,但是没有画虚线的方法,自己写了一个HTML5 画虚线的组件. dashedLine.js if (window.CanvasRendering ...
- HTML5 Canvas 画钟表
画钟表是2D画图的老生常谈,我也不能免俗弄了一个.代码如下: <!DOCTYPE html> <html lang="utf-8"> <meta ht ...
- CSS3进度条 和 HTML5 Canvas画圆环
看到一些高大上的进度条插件,然后想自己用CSS写.经过搜索资料之后,终于成功了.为了以后方便拿来用,或者复习.将代码贴出. HTML代码: 只需要两个div,外面的为一个有border的div id为 ...
- html5 canvas画饼
1. [图片] lxdpie.jpg 2. [文件] lqdpie.html ~ 801B 下载(7) <!DOCTYPE HTML PUBLIC "-//W3C//DTD ...
- html5 canvas画不出图像的原因
很久没写博客了,今年过年的时候,家里出了意外,现在心里依然很难受.6月份之前一直忙着写毕业论文,答辩完6月初回公司继续上班,今天刚好周末有空,就写下之前碰到一个问题. 做一个图像查看器(基于Chrom ...
- HTML5 Canvas画数字时钟
先不说废话,没代码算个蛋. 一些地方注释都写得比较清楚,不过这只是部分,因为只有秒针,但是时针,分针的逻辑都是一致的. 代码中有些坐标不知道为什么较不准,看看就好
- html5 canvas画进度条
这个ie8的兼容是个问题,ie8 的innerHTML有问题啊,添加两个附件吧 <!DOCTYPE html> <html> <head> <meta cha ...
- html5 canvas 画hello ketty
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8& ...
随机推荐
- SQL入门语句之ORDER BY 和GROUP BY
一.SQL入门语句之ORDER BY ORDER BY 是用来基于一个或多个列按升序或降序顺序排列数据 1.从数据库表获取全部数据按字段A的升序排列 select *from table_name o ...
- poj 3280 Cheapest Palindrome
链接:http://poj.org/problem?id=3280 思路:题目给出n种m个字符,每个字符都有对应的添加和删除的代价,求出构成最小回文串的代价 dp[i][j]代表区间i到区间j成为回文 ...
- python初学杂记
python常用命令: 1.python 或者 python3 打开交互式python解释器 2.python hello.py 通过命令提示符运行python脚本 交互式python解释器常用 ...
- windows批处理语法
写批处理文件,除了了解基本语法外,你还需要熟悉常用的windows命令,那就先看看这篇文章:windows常用命令 #重要说明 文件及目录路径:要使用反斜杠'\',不要使用正斜杠'/' 如:del d ...
- C#自定义工业控件开发
由于工作需要,调研过一段时间的工业控制方面的“组态软件”(SCADA)的开发,组态软件常用于自动化工业控制领域,其中包括实时数据采集.数据储存.设备控制和数据展现等功能.其中工控组件的界面展现的实现类 ...
- Redis到底该如何利用(二)?
上一篇文章里我简述了使用Keys作为Redis搜索的方式,确实感受到了社区的力量,写文章好处多.首先谢谢各位前辈的指导,我知道了拿Redis作为搜索是个错误的方向.本来这篇文章我觉得确实没必要发了,但 ...
- HTML5和CSS3新特性一览
HTML5 1.HTML5 新元素 HTML5提供了新的元素来创建更好的页面结构: 标签 描述 <article> 定义页面独立的内容区域. <aside> 定义页面的侧边栏内 ...
- C#delegate委托
类似函数,却没有语句体. using System; using System.Collections.Generic; using System.Linq; using System.Text; u ...
- Linux Tomcat 开机自启动的方法
修改Tomcat/bin/startup.sh 为: export JAVA_HOME=/usr/java/j2sdk1.4.2_08 export CLASSPATH=$CLASSPATH:$JAV ...
- onDestroy 和 onBackPressed、onfinish 的区别
在android 开发中, 我容易不区分 onDestroy .onBackpress.onFinish. 其实,可以这样理解: (1)onDestory 的使用,是销毁了activity的实例在内存 ...