使用Canvas实现画图程序。
本次更新主要实现了一下功能:
虚线实线的选择、辅助线、线条颜色选择、线条宽度选择
进一步整理了下代码,发现了不少很有用的写法,具体看下面。
效果截图:
源代码:
①HTML代码
<!docutype html>
<!--date 2014-12-28-->
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<style type="text/css">
canvas{
background-color: rgb(247, 247, 247);
margin-top: 10px;
}
</style>
</head>
<body>
<div class="controls">
线条类型<select id="lineTypeSelectBox">
<option value="solid">实线</option>
<option value="dashed">虚线</option>
</select>
线条颜色<select id="strokeColorSelectBox">
<option value="black">black</option>
<option value="red">red</option>
<option value="blue">blue</option>
</select>
线条宽度<select id="lineWidthSelectBox">
<option value="1">1</option>
<option value="2">2</option>
<option value="4">4</option>
</select>
网格线<input id="gridCheckBox" type="checkbox" checked="checked" >
坐标轴<input id="axesCheckBox" type="checkbox" checked="checked" >
辅助线<input id="guideWiresCheckBox" type="checkbox" checked="checked" >
<input type="button" value="清除画布" id="eraseAllButton">
</div>
<!--canvas默认大小300*150-->
<canvas id="canvas" width="800" height="500">
</canvas>
</body>
<!--导入绘制坐标、网格的js文件-->
<script type = "text/javascript" src ="mikuCanvasAxes.js"></script>
<!--导入绘制虚线的js文件-->
<script type = "text/javascript" src ="mikuCanvasLine.js"></script>
<!--导入主要绘图js文件-->
<!--
全局变量定义
函数:窗口坐标转换为Canvas坐标、保存\还原当前绘图表面数据、橡皮筋法相关函数、绘制辅助线相关函数、初始化函数
事件处理:鼠标down,move,up事件、按钮点击事件、单选框变化事件
-->
<script type = "text/javascript" src ="mikuCanvasPaintAppMain.js"></script>
</html>
②绘制坐标轴与网格
在第一篇里有,我没改动
http://blog.csdn.net/mikuscallion/article/details/43115917
③绘制虚线
//绘制虚线
//传入参数:上下文,起点,终点,虚线间隔
function drawDashedLine(context,x1,y1,x2,y2,dashLength){
//运用三元表达式实现默认参数
dashLength = dashLength===undefined ? 5 : dashLength;
//水平长度
var deltaX = x2 - x1;
//垂直长度
var deltaY = y2 - y1;
//虚线数量
var numDashed = Math.floor(
Math.sqrt(deltaX*deltaX+deltaY*deltaY)/dashLength
);
//开始绘制
context.beginPath();
for(var i=0; i<numDashed;i++){
//这种写法太强大了
//(deltaX/numDashed)是指虚线的长度
context[i%2===0 ? "moveTo":"lineTo"](x1+(deltaX/numDashed)*i,y1+(deltaY/numDashed)*i);
}
//要记得描线啊
context.stroke();
//结束绘制
context.closePath();
}
④主要绘图代码
//Vars--------------------------------------------------------
var canvas =document.getElementById("canvas"),
context =canvas.getContext("2d"),
//正在绘制的绘图表面变量
drawingSurfaceImageData,
//鼠标按下相关对象
mousedown = {},
//橡皮筋矩形对象
rubberbandRect = {},
//拖动标识变量
dragging = false;
//控件
//擦除画布的控制
var eraseAllButton = document.getElementById("eraseAllButton");
//坐标轴的控制
var axesCheckBox = document.getElementById("axesCheckBox");
//网格线的控制
var gridCheckBox = document.getElementById("gridCheckBox");
//辅助线的控制
var guideWiresCheckBox = document.getElementById("guideWiresCheckBox");
//线条颜色的控制
var strokeColorSelectBox =document.getElementById("strokeColorSelectBox");
//线条样式的控制
var lineTypeSelectBox = document.getElementById("lineTypeSelectBox");
//线条宽度的控制
var lineWidthSelectBox = document.getElementById("lineWidthSelectBox");
//Functions---------------------------------------------------
//将窗口坐标转换为Canvas坐标
//传入参数:窗口坐标(x,y)
function windowToCanvas(x,y){
//获取canvas元素的边距对象
var bbox = canvas.getBoundingClientRect();
//返回一个坐标对象
//类似json的一种写法
return {
x : x - bbox.left*(canvas.width/bbox.width),
y : y - bbox.top*(canvas.height/bbox.height)
};
}
//保存当前绘图表面数据
function saveDrawingSurface(){
//从上下文中获取绘图表面数据
drawingSurfaceImageData = context.getImageData(0,0,canvas.width,canvas.height);
}
//还原当前绘图表面
function restoreDrawingSurface(){
//将绘图表面数据还原给上下文
context.putImageData(drawingSurfaceImageData,0,0);
}
//橡皮筋相关函数
//更新橡皮筋矩形+对角线
//传入参数:坐标对象loc
function updateRubberband(loc){
updateRubberbandRectangle(loc);
drawRubberbandShape(loc);
}
//更新橡皮筋矩形
//传入参数:坐标对象loc
function updateRubberbandRectangle(loc){
//获得矩形的宽
rubberbandRect.width = Math.abs(loc.x - mousedown.x);
//获得矩形的高
rubberbandRect.height = Math.abs(loc.y - mousedown.y);
//获得矩形顶点的位置(left,top)
//如果鼠标按下的点(起点)在当前点的的左侧
//这里画一下图就懂了
if(loc.x > mousedown.x){
rubberbandRect.left = mousedown.x;
}else{
rubberbandRect.left = loc.x;
}
if(loc.y > mousedown.y){
rubberbandRect.top = mousedown.y;
}else{
rubberbandRect.top = loc.y;
}
}
//绘制橡皮筋矩形的对角线
//传入参数:坐标对象loc
function drawRubberbandShape(loc){
//获取当前线条类型
var lineType = lineTypeSelectBox.value;
//获取当前线条颜色
var lineColor = strokeColorSelectBox.value;
//获取当前线条宽度
var lineWidth = lineWidthSelectBox.value;
//有改变context画笔属性就要做画笔保护
context.save();
context.strokeStyle = lineColor;
context.lineWidth = lineWidth;
if(lineType === "solid"){
//alert("draw");
//注意重新开始路径
context.beginPath();
context.moveTo(mousedown.x,mousedown.y);
//这里可以更改成画虚线
context.lineTo(loc.x,loc.y);
context.stroke();
}else if(lineType === "dashed"){
drawDashedLine(context,mousedown.x,mousedown.y,loc.x,loc.y);
}
context.restore();
}
//绘制辅助用的线-------------------------
//绘制水平线
function drawHorizontalLine(y){
context.beginPath();
context.moveTo(0,y+0.5);
context.lineTo(context.canvas.width,y+0.5);
context.stroke();
}
//绘制垂直线
function drawVerticalLine(x){
context.beginPath();
context.moveTo(x+0.5,0);
context.lineTo(x+0.5,context.canvas.height);
context.stroke();
}
//绘制辅助用的线
function drawGuideWires(x,y){
//画笔保护
context.save();
context.strokeStyle = "red";
context.lineWidth = 0.5;
drawHorizontalLine(y);
drawVerticalLine(x);
context.restore();
}
//初始化函数
function initialization(){
//清除画布
context.clearRect(0,0,canvas.width,canvas.height);
//绘制网格与坐标的颜色是默认的
if(axesCheckBox.checked){
drawAxes(context,40);
}
if(gridCheckBox.checked){
drawGrid(context,10,10);
}
}
//Event Hander-----------------------------------------------------
canvas.onmousedown = function(e){
var loc =windowToCanvas(e.clientX,e.clientY);
e.preventDefault();
saveDrawingSurface();
mousedown.x = loc.x;
mousedown.y = loc.y;
dragging = true;
}
canvas.onmousemove = function(e){
var loc;
if(dragging){
e.preventDefault();
loc = windowToCanvas(e.clientX,e.clientY);
restoreDrawingSurface();
updateRubberband(loc);
}
if(dragging&&guideWiresCheckBox.checked){
drawGuideWires(loc.x,loc.y);
}
}
canvas.onmouseup = function(e){
loc = windowToCanvas(e.clientX,e.clientY);
restoreDrawingSurface();
updateRubberband(loc);
dragging = false;
}
//需要擦除的操作需要重新初始化
eraseAllButton.onclick = function(e){
context.clearRect(0,0,canvas.width,canvas.height);
initialization();
saveDrawingSurface();
}
axesCheckBox.onchange = function(e){
initialization();
}
gridCheckBox.onchange = function(e){
initialization();
}
//Mian----------------------------------------------
initialization();
Canvas---Canvas版画图、虚线、辅助线、线条颜色、线条宽度,整合加强版
原文:http://blog.csdn.net/mikuscallion/article/details/43154237