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& ...
随机推荐
- Laravel Homestead安装笔记
引言: 最近开始学习laravel框架,了解到有个laravel homestead的box,开发起来非常方便快捷,于是就准备开始配置homestead虚拟开发环境了 什么是Homestead 要想学 ...
- sql server 语句使用规范
Sql语句使用规范 规范内容以及注意事项: 1.查询时候使用top 10 /top 100 和where 字句控制每次执行SQL 返回的结果集合,在满足业务需求的同时返回最小的结果. 2.使用数据投影 ...
- pyhon 模块与库
引用“http://www.iplaypython.com/module/” 引用“http://codingnow.cn/language/265.html” Python模块是什么? 玩蛇网:一个 ...
- CodeForces 13E 分块
题目链接:http://codeforces.com/problemset/problem/13/E 题意:给定n个弹簧和每个弹簧初始的弹力a[].当球落在第i个位置.则球会被弹到i+a[i]的位置. ...
- 数据结构之KMP算法next数组
我们要找到一个短字符串(模式串)在另一个长字符串(原始串)中的起始位置,也就是模式匹配,最关键的是找到next数组.最简单的算法就是用双层循环来解决,但是这种算法效率低,kmp算法是针对模式串自身的特 ...
- 每日一问:面试结束时面试官问"你有什么问题需要问我呢",该如何回答?
面试结束时面试官问"你有什么问题需要问我呢",该如何回答?
- CodeForces 520B Two Buttons(用BFS)
Two Buttons time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...
- NOIP2014 uoj20解方程 数论(同余)
又是数论题 Q&A Q:你TM做数论上瘾了吗 A:没办法我数论太差了,得多练(shui)啊 题意 题目描述 已知多项式方程: a0+a1x+a2x^2+..+anx^n=0 求这个方程在[1, ...
- osg 示例程序解析之osgdelaunay
osg 示例程序解析之osgdelaunay 转自:http://lzchenheng.blog.163.com/blog/static/838335362010821103038928/ 本示例程序 ...
- STM32之GPIO操作
啊哈.没办法.外国人的芯片就喜欢用英文来命名,所以中文的:通用输入/输出 就用GPIO来代替..谁叫哥们都不是外国人呢.好啦.胡扯了一下,借用唐伯虎点秋香的话:小小书童,可笑可笑... 知道了GPI ...