<!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画流程图的更多相关文章

  1. canvas画流程图

    用canvas画流程图: 需求:最后一个圆圈无直线 遇到问题:需要画多个圆圈时,画布超出显示屏加滚动条,解决方法是<canvas>外层<div>的width=100%,且ove ...

  2. HTML5 Canvas 画虚线组件

    前段时间由于项目需要,用到了HTML5 Canvas画图,但是没有画虚线的方法,自己写了一个HTML5 画虚线的组件. dashedLine.js if (window.CanvasRendering ...

  3. HTML5 Canvas 画钟表

    画钟表是2D画图的老生常谈,我也不能免俗弄了一个.代码如下: <!DOCTYPE html> <html lang="utf-8"> <meta ht ...

  4. CSS3进度条 和 HTML5 Canvas画圆环

    看到一些高大上的进度条插件,然后想自己用CSS写.经过搜索资料之后,终于成功了.为了以后方便拿来用,或者复习.将代码贴出. HTML代码: 只需要两个div,外面的为一个有border的div id为 ...

  5. html5 canvas画饼

    1. [图片] lxdpie.jpg ​2. [文件] lqdpie.html ~ 801B     下载(7) <!DOCTYPE HTML PUBLIC "-//W3C//DTD ...

  6. html5 canvas画不出图像的原因

    很久没写博客了,今年过年的时候,家里出了意外,现在心里依然很难受.6月份之前一直忙着写毕业论文,答辩完6月初回公司继续上班,今天刚好周末有空,就写下之前碰到一个问题. 做一个图像查看器(基于Chrom ...

  7. HTML5 Canvas画数字时钟

    先不说废话,没代码算个蛋. 一些地方注释都写得比较清楚,不过这只是部分,因为只有秒针,但是时针,分针的逻辑都是一致的. 代码中有些坐标不知道为什么较不准,看看就好

  8. html5 canvas画进度条

    这个ie8的兼容是个问题,ie8 的innerHTML有问题啊,添加两个附件吧 <!DOCTYPE html> <html> <head> <meta cha ...

  9. html5 canvas 画hello ketty

    <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8& ...

随机推荐

  1. java -- getOutputStream() has already been called for

    原文:https://my.oschina.net/zhongwenhao/blog/209653 原因:既调用了response.getOutputStream(),又调用了response.get ...

  2. 【C#】MVC项目中搭建WebSocket服务器

    前言 因为项目需要,前端页面中需要不断向后台请求获取一个及一个以上的状态值.最初的方案是为每个状态值请求都建立一个定时器循环定时发起Ajax请求,结果显而 易见.在HTTP1.1协议中,同一客户端浏览 ...

  3. RSA的傻瓜原理

    设想一下,这种场景,你处在一个狭小的房间里,房间之中有一共有三个人,你是其中一个,你们之间被玻璃隔开,两两对视,现在给另外两个人起个名字叫小红.小明.你和他们通讯只能用写字板来展示给对方(简单起见,只 ...

  4. 参数max_allowed_packet

    通信信息包是发送至MySQL服务器的单个SQL语句,或发送至客户端的单一行. 当MySQL客户端或mysqld服务器收到大于max_allowed_packet字节的信息包时,将发出“信息包过大”错误 ...

  5. x64内核内存空间结构

    0x00 前言 本文主要是讨论Windows 7 x64下的内核虚拟地址空间的结构,可以利用WiinDBG调试的扩展命令"!CMKD.kvas"来显示x64下的内核虚拟地址空间的整 ...

  6. Linux第03天

    Linux 第03天 1.Linux帐号和ACL权限管理 1.帐号和用户组 1.1 用户标识符————UID(root为0 系统用户为1~499 普通用户为500~65535) 1.2 用户组标识符— ...

  7. shell example02

    输入值 //相加 add(){ echo "add two agrs..." echo "enter first one: " read arg1 echo & ...

  8. [spring源码学习]一、IOC简介

    一.程序实例 假设一个简单地实例,我们有一个人,人可能有姓名,年龄等属性,每天上下班的时候需要坐车,他可能做小轿车,suv等,这样一个场景.我们很容易想到如下代码: 1.人的对象类,包括两个属性,姓名 ...

  9. 水一道NOIP2002提高组的题【A003】

    [A003]均分纸牌[难度A]———————————————————————————————————————————————————— [题目要求] 有 N 堆纸牌,编号分别为 1,2,…, N.每堆 ...

  10. [转载]Grunt插件之LiveReload 实现页面自动刷新,所见即所得编辑

    配置文件下载  http://vdisk.weibo.com/s/DOlfks4wpIj LiveReload安装前的准备工作: 安装Node.js和Grunt,如果第一次接触,可以参考:Window ...