Canvas:橡皮筋线条绘制

效果演示

实现要点

事件监听

【说明】:

在Canvas中检测鼠标事件是非常简单的,可以在canvas中添加一个事件监听器,当事件发生时,浏览器就会调用这个监听器。

我们可以使用绑定事件属性:

canvas.onmousedown = function(e)
{
//.....
}  

此外,也可以使用更为通用的addEventListener()方法来注册监听器:

canvas.addEventListener('mousedown',function(e){
//.....
})  

注意:使用onmouseXXX更为简单,但是addEventListener()可以向某个事件注册多个监听器。

鼠标坐标转换为canvas坐标

【说明】

  浏览器通过事件对象传递给监听器的鼠标坐标,是窗口坐标,而不是相对于canvas自身的坐标。大部分情况下,我们需要知道的是发生鼠标事件的点相对于canvas的位置,而不是在整个窗口中的坐标,所以必须进行坐标转换

【实例】:转换代码

    function windowToCanvas(x, y) {
var bbox = canvas.getBoundingClientRect();
return {
x: (x - bbox.left)*(canvas.width / bbox.width),
y: (y - bbox.top)*(canvas.height / bbox.height)
};
}

注意:为什么最后要乘(canvas.width / bbox.width),我们简单说明一下,canvas存在元素大小与绘图表面大小两套尺寸,我们的图像是显示在绘图表面上的,但是如果canvas元素大小较大的话,浏览器就会对绘图表面上的图像进行缩放以适应canvas元素大小,我们要避免这种缩放就要除去缩放比例

我们用element表示canvas元素,用canvas表示绘图表面,src表示绘制的内容,dest表示展示的内容

缩放规则为:dest.size = src.size * (element.size / canvas.size)

所以,src=dest.size*(canvas.size/element.size)

绘制表面的保存与恢复

【说明】:

  使用getImageData与putImageData方法来保存与恢复绘图环境的绘图表面数据。

【实例】:保存和恢复数据

    function saveDrawingSurface() {
drawingSurfaceImageData = context.getImageData(0, 0, canvas.width, canvas.height);
} function restoreDrawingSurface() {
context.putImageData(drawingSurfaceImageData, 0, 0);
}  

实现代码

<canvas id="canvas">
</canvas>
<script>
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var drawingSufraceData;
var mousedown ={};
var dragging = false; //绝对坐标转相对坐标
function windowToCanvas(x, y) {
var bbox = canvas.getBoundingClientRect();
return {
x: (x - bbox.left)* (canvas.width / bbox.width),
y: (y - bbox.top)* (canvas.height / bbox.height)
};
} //绘图表面的保存与恢复
function saveDrawingSurface()
{
drawingSufraceData = context.getImageData(0,0,canvas.width,canvas.height);
}
function restoreDrawingSurface()
{
context.putImageData(drawingSufraceData,0,0);
} function drawingLine(loc)
{
context.beginPath();
context.moveTo(mousedown.x,mousedown.y);
context.lineTo(loc.x,loc.y);
context.stroke()
} //鼠标按下
canvas.onmousedown = function (e) {
mousedown = windowToCanvas(e.x,e.y);
saveDrawingSurface();
dragging =true;
} //鼠标移动
canvas.onmousemove = function (e) {
var loc = windowToCanvas(e.x,e.y);
if(dragging)
{
restoreDrawingSurface();
drawingLine(loc);
}
}
//鼠标松开
canvas.onmouseup =function (e) {
dragging=false;
}
</script>

Canvas:橡皮筋线条绘制的更多相关文章

  1. HTML5 Canvas ( 线段的绘制 ) beginPath, moveTo, strokeStyle, stroke

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. 8-2 canvas专题-线条样式

    8-2 canvas专题-线条样式 学习要点 对第五章知识进行简单的回顾和总结 进一步讲解canvas绘图相关的知识点 第八章内容介绍 在第八章中我们将对以前的知识进行简单的回顾,着重对canvas绘 ...

  3. canvas教程(三) 绘制曲线

    经过 canvas 教程(二) 绘制直线 我们知道了 canvas 的直线是怎么绘制的 而本次是给大家带来曲线相关的绘制 绘制圆形 在 canvas 中我们可以使用 arc 方法画一个圆 contex ...

  4. Quartz2D简介及基本线条绘制

    * Quartz2D简介 1.什么是Quartz2D? 他是一个二维的绘图引擎,同时支持iOS和Mac系统 2.Quartz2D能完成的工作 画基本线条,绘制文字,图片,截图,自定义UIView. 3 ...

  5. -_-#【Canvas】导出在<canvas>元素上绘制的图像

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  6. canvas设置线条样式

    canvas设置线条样式 合法属性和方法 lineWidth = value 设置线宽 lineCap = type 设置线端点样式 lineJoin = type 设置线交合处样式 setLineD ...

  7. Canvas 中drawImage 绘制不出图片

    在使用Canvas的drawImage绘制图片时,却发现绘制不出图片,原因是图片是异步加载,图片加载完再绘制. //html <img src="1.png" /> & ...

  8. canvas教程(二) 绘制直线

    经过 canvas 教程(一) 简介 我们知道了 canvas 的一些基本情况 而本次是给大家带来直线的绘制 canvas 中,基本图形有两种,一种是直线,还有一种是曲线 但是无论是直线还是曲线,我们 ...

  9. Android中使用Canvas和Paint绘制一个安卓机器人

    场景 在Android中画笔使用Paint类,画布使用Canvas类来表示. 绘图的基本步骤 首先编写一个继承自View的自定义View类,然后重写其onDraw方法,最后把自定义的view添加到ac ...

随机推荐

  1. 使用Navicat连接阿里云服务器上的MySQL数据库

    1.首先打开Navicat,文件>新建连接> 2,两张连接方法 1>常规中输入数据库的主机名,端口,用户名,密码 这种直接连就可以了 第2种方法: 常规中输入数据库的信息,主机名用l ...

  2. ffmpeg 日志系统av_log()

    一般使用Error, Warning, Debug3个级别即可(见下面的颜色).AV_LOG_QUIET 核心函数只有一个:av_log().使用av_log()在控制台输出日志的效果如下图所示. a ...

  3. Oracle启动中,startup nomount、 startup mount 有什么差别?

    Oracle启动中,startup nomount. startup mount 有什么差别? 解答: startup nomount:启动实例,读取参数文件,分配内存空间,启动后台进程,打开跟踪文件 ...

  4. smartJS 0.1 API 讲解 - FlowController

    本篇介绍0.1版中最后一个特性,FlowController:同时也对第一版总结一下,因为近两年全部都是在搞前端,都是做一些js框架类的东西,也做了不少有意思的功能,做smartjs对我来说一个是对自 ...

  5. 【watcher】 #02 c# 中实现时间戳等,日期数字及大概率绝对随机数 实现

    在Wacher的项目中,用到了很多时间记录的地方,为了将来能够和在线数据打通,我们使用了时间戳来记录时间信息 由于c# 没有现成的方法,所以我们重新写了一个Helper类来帮助我们使用这些公共函数 同 ...

  6. Toxophily-数论以及二分三分

    G - Toxophily Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submi ...

  7. 面试之Java持久层(十)

    91,什么是ORM?         对象关系映射(Object-Relational Mapping,简称ORM)是一种为了解决程序的面向对象模型与数据库的关系模型互不匹配问题的技术: 简单的说,O ...

  8. .Net framework 的浏览器定义文件

    .net framework4.5.1之前的版本有一个非常愚蠢的设定, 它为每个浏览器设置了一个浏览器定义文件, 通过正则表达式来匹配浏览器的userAgent, 然后来定义一些功能集. 这种做法有一 ...

  9. 使用NSKeyedArichiver进行归档、NSKeyedUnarchiver进行解档

    一.使用archiveRootObject进行简单的归档 使用NSKeyedArichiver进行归档.NSKeyedUnarchiver进行接档,这种方式会在写入.读出数据之前对数据进行序列化.反序 ...

  10. MySQL Connector/C++ C++连接mysql

    MySQL :: MySQL Connector/C++ Developer Guide :: 1 Introduction to Connector/C++ https://dev.mysql.co ...