一.原理

当鼠标点击并移动在画布canvas中时,会显示放大后的图片一角。移除canvas,鼠标松开或是鼠标离开点击那块范围时,则不会显示。
这个原理是:把这个图片放在离屏canvas上,而可视画布canvas放着这个图片的缩小版,填充画布。
当鼠标点击这个可视画布canvas中图像的位置,我们可以根据这个位置获取离屏画布canvas中图像上的位置(这个位置是=可视画布中图像的位置*图片与可视画布canvas的倍数),此时裁剪离屏canvas中的图像,显示在可视窗口中。
二.知识点
1.图片的加载:
var img=new Image();
img.src = "timg.jpg";
img.οnlοad=function (){
context.drawImage( image , 0 , 0 );
}
2. 鼠标与canvas的交互:
 ①.鼠标点击canvas.onmousedown = function(e){e.preventDefault();}
 ②鼠标移动: 当鼠标移动到某对象范围的上方时触发的事件 
canvas.onmousemove = function(e){e.preventDefault();}
 ③鼠标按下后,松开时激发的事件
canvas.onmouseup = function(e){e.preventDefault();}
 ④当鼠标离开某对象范围时触发的事件
canvas.onmouseout = function(e){e.preventDefault();}
 e.preventDefault();//禁止默认的响应事件
3.获取在canvas里的点坐标
getBoundingClientRect()用于获取某个元素相对于视窗的位置集合。集合中有top, right, bottom, left等属性。
 function detect(event){
var x=event.clientX-canvas.getBoundingClientRect().left;
var y=event.clientY-canvas.getBoundingClientRect().top;
}
4.创建一个新的变量,用来判断鼠标是否处于点击的状态
var isMouseDown = false;
5.需要一个离屏画布canvas(离屏是用户不可见的),用来做放大镜的作用
<canvas id="offCanvas" style="display: none">您的浏览器尚不支持canvas</canvas>
这个canvas画布承载这是图像的大小

6.创建一个变量,用来放大的倍数,用来计算图片与可视画布canvas的倍数

var scale;

在这里我们不考虑不规则图像的倍数多样性问题,简单点,让图形的大小等于可视画布canvas的大小整数倍。

三.代码

<!DOCTYPE html>
<html>
<head lang="en"><meta charset="UTF-8"><title></title><style type="text/css">body{background: black;}#canvas{display:block;margin:0 auto;border:1px solid #aaa;}</style>
</head>
<body><canvas id="canvas">您的浏览器尚不支持canvas</canvas><canvas id="offCanvas" style="display: none">您的浏览器尚不支持canvas</canvas><script>var canvas = document.getElementById("canvas");var context = canvas.getContext("2d");var offCanvas = document.getElementById("offCanvas");var offContext = offCanvas.getContext("2d");var image = new Image();var isMouseDown = false;//用来判断鼠标是否处于点击的状态var scale;window.onload = function(){canvas.width = 1024;canvas.height = 750;image.src = "img-lg.jpg";image.onload = function(){offCanvas.width = image.width;offCanvas.height = image.height;//在这里我们不考虑不规则图像的倍数问题,简单点,让图形的大小等于可视画布canvas的大小3倍scale = offCanvas.width / canvas.width;context.drawImage( image , 0 , 0 , canvas.width , canvas.height );//这边放着图像的缩放版,刚刚好填充可视窗口offContext.drawImage( image , 0 , 0 );//offContext的大小应该跟图像的大小}}//1.鼠标点击canvas.onmousedown = function(e){e.preventDefault();//禁止默认的响应事件point = windowToCanvas( e.clientX , e.clientY );//坐标点console.log( point.x , point.y );isMouseDown = true;drawCanvasWithMagnifier( true , point );}//3.1鼠标移动: 当鼠标移动到某对象范围的上方时触发的事件 canvas.onmousemove = function(e){e.preventDefault();//禁止默认的响应事件if( isMouseDown == true ){point = windowToCanvas( e.clientX , e.clientY );console.log( point.x , point.y );drawCanvasWithMagnifier( true , point );}}//3.2鼠标按下后,松开时激发的事件canvas.onmouseup = function(e){e.preventDefault();//禁止默认的响应事件isMouseDown = false;drawCanvasWithMagnifier( false );}//3.3当鼠标离开某对象范围时触发的事件canvas.onmouseout = function(e){e.preventDefault();isMouseDown = false;drawCanvasWithMagnifier( false );}//4放大镜绘制//参数:isShowMagnifier是否要显示放大镜  //point要放大镜时,显示在哪里坐标function drawCanvasWithMagnifier( isShowMagnifier , point ){context.clearRect( 0 , 0 , canvas.width , canvas.height );context.drawImage( image , 0 , 0 , canvas.width , canvas.height );if( isShowMagnifier == true ){drawMagnifier( point );}}//5.要放大镜时,显示在哪里坐标function drawMagnifier( point ){var mr = 200;//设置半径值//离屏画布canvas中图像上的位置imageLG_cx,imageLG_cy=可视画布中图像的位置*图片与可视画布canvas的倍数var imageLG_cx = point.x * scale;var imageLG_cy = point.y * scale;var sx = imageLG_cx - mr;var sy = imageLG_cy - mr;var dx = point.x - mr;var dy = point.y - mr;context.save();context.lineWidth = 10.0context.strokeStyle = "#069"context.beginPath();context.arc( point.x , point.y , mr , 0 , Math.PI*2 , false );context.stroke();context.clip();context.drawImage( offCanvas , sx , sy , 2*mr , 2*mr , dx , dy , 2*mr , 2*mr );context.restore();}//2.获取在canvas里的点坐标//canvas在屏幕在的坐标,getBoundingClientRect()用于获取某个元素相对于视窗的位置集合。//集合中有top, right, bottom, left等属性。function windowToCanvas( x , y ){var bbox = canvas.getBoundingClientRect();return {x:x-bbox.left , y:y-bbox.top};}</script>
</body>
</html>

四.放大镜可以用五角星形

代码跟之前差不多,只要修改

//5.要放大镜时,显示在哪里坐标function drawMagnifier( point ){context.save();var mr = 200;//设置半径值//离屏画布canvas中图像上的位置imageLG_cx,imageLG_cy=可视画布中图像的位置*图片与可视画布canvas的倍数var imageLG_cx = point.x * scale;var imageLG_cy = point.y * scale;var sx = imageLG_cx - mr;var sy = imageLG_cy - mr;var dx = point.x - mr;var dy = point.y - mr;context.save();context.lineWidth = 10.0;context.translate(point.x ,point.y);context.scale(mr,mr);starPath(context);context.fillStyle="#fff";context.fill();context.restore();context.clip();context.drawImage( offCanvas , sx , sy , 2*mr , 2*mr , dx , dy , 2*mr , 2*mr );context.restore();}//五角星function starPath(ctx){//参数:canvas的内容传递,小圆半径,大圆半径,原点坐标的转移位置x,y,旋转的角度ctx.beginPath();for(var i=0;i<5;i++){ctx.lineTo(Math.cos(2*(18+i*72)*Math.PI / 360),-Math.sin(2*(18+i*72)*Math.PI / 360));ctx.lineTo(Math.cos(2*(54+i*72)*Math.PI / 360)*0.5,-Math.sin(2*(54+i*72)*Math.PI / 360)*0.5);}context.closePath();}

五.不足

如果是用户上传图像,这时图像大小就不确定,倍数得情况就多样性了,而此项目并没有考虑这些而是简单化了,事先就把图像大小设计成可视画布canvas的整数倍(3倍),。

欢迎大家一起讨论,解决这些不足,使其项目更加完整。

canvas系列-图片处理(五)放大镜相关推荐

  1. 【微信小程序-原生开发】实用教程20 - 生成海报(实战范例为生成活动海报,内含生成指定页面的小程序二维码,保存图片到手机,canvas 系列教程)

    可在系列教程的基础上继续开发,也可以单独使用 [微信小程序-原生开发]系列教程 效果预览 代码实现 点击触发生成海报 在活动详情页,指定点击某图标/按钮,触发跳转到生成海报的页面 pages\comp ...

  2. 前端画圆弧html弧线的像素,[js高手之路] html5 canvas系列教程 - arc绘制曲线图形(曲线,弧线,圆形)...

    arc:画弧度 cxt.arc( x, y, 半径, 开始角度,结束角度,是否逆时针 ); x, y: 为弧度的中心横坐标和纵坐标,如果这是画一个圆.那么x,y就是圆的圆心. 开始角度与结束角度都是以 ...

  3. keras系列︱Application中五款已训练模型、VGG16框架(Sequential式、Model式)解读(二)...

    引自:http://blog.csdn.net/sinat_26917383/article/details/72859145 中文文档:http://keras-cn.readthedocs.io/ ...

  4. canvas离屏技术与放大镜实现

    教程所示图片使用的是 github 仓库图片,网速过慢的朋友请移步>>> (原文)canvas 离屏技术与放大镜实现. 更多讨论或者错误提交,也请移步. 利用 canvas 除了可以 ...

  5. html5游戏制作入门系列教程(五)

    我们继续这一系列文章,使用HTML5的canvas组件进行游戏开发.今天,这是相当完整的游戏例子 – 它会回顾经典的旧电脑游戏 – 坦克大战.我会教你使用阵列地图并教你如何检测活动对象(坦克)与环境( ...

  6. keras系列︱Application中五款已训练模型、VGG16框架(Sequential式、Model式)解读(二)

    不得不说,这深度学习框架更新太快了尤其到了Keras2.0版本,快到Keras中文版好多都是错的,快到官方文档也有旧的没更新,前路坑太多. 到发文为止,已经有theano/tensorflow/CNT ...

  7. 【canvas系列】用canvas实现一个colorpicker(类似PS的颜色选择器)

    每个浏览器都有自己的特点,比如今天要做的colorpicker就是,一千个浏览器,一千个哈姆雷特,一千个colorpicker.今天canvas系列就用canvas做一个colorpicker. ** ...

  8. HTML弧度文本,[js高手之路] html5 canvas系列教程 - 文本样式(strokeText,fillText,measureText,textAlign,textBaseline)...

    canvas提供两种输出文本的方式: strokeText:描边文本 fillText:填充文本 fillStyle配合fillText使用,strokeStyle配合strokeText使用 str ...

  9. 从0开始canvas系列一 --- canvas画布

    从0开始canvas系列 从0开始canvas系列一 - canvas画布 从0开始canvas系列二 - 文本和图像 从0开始canvas系列三 - 图像像素级操作 从0开始canvas系列四 - ...

最新文章

  1. pip install 默认安装路径修改
  2. android 自动休眠时间设置在哪里,Android休眠设置时间
  3. 蚂蚁科技 Service Mesh 落地实践与挑战
  4. Python Django知识体系
  5. 主域控宕机无法恢复后,如何配置辅助域控继续工作
  6. 如何在C#里实现端口监视呢?
  7. termux配置python安装kali_安卓安装kali linux之Termux
  8. 【2017年第3期】大数据服务三农的初步分析与探索
  9. Java:源文件名、公共类名、main()方法之间关系
  10. htop的VIRT是什么
  11. 纽约客封面故事:欢迎来到「黑暗工厂」,这里是由机器统治的世界
  12. 软件体系结构期末复习题
  13. linux下caffe安装过程原理,caffe安装过程详解linux版本
  14. windows下Middlebury离线工具使用(补充)
  15. R/ggplot2保存图片中文字体至PDF——showtext包一文清除所有障碍
  16. mt6755完整原理图pdf mt6755lte-a智能手机应用程序处理器技术简介
  17. between ..... and 用法
  18. 小米10青春版刷鸿蒙,功能齐全也不行!小米10青春版现已跌至新低价,高刷已成趋势?...
  19. SQL语句group by 的求和sum
  20. 台式电脑网络连接配置异常_专为电竞和内容创作者而生!体验惠普 ENVY TE01台式机...

热门文章

  1. 七、《好先生》经典台词
  2. 真香!一款超级强大的SQL工具
  3. 商场三十六计——第24计 “假途伐虢”
  4. 带耳麦的耳机哪个牌子好?通话效果最好的耳机推荐
  5. 2.MySQL之DQL语言
  6. MySQL获取当前日期、时间、时间戳函数
  7. 页面置换算法(局部、全局)-局部性很关键
  8. 获取指定日期的第二天的凌晨时间 和获取指定时间+获取指定的天数的日期
  9. 搭配Online:再迎4000亿元活水,央行高频降准剑指“降成本”
  10. BZOJ 3118 Orz the MST 线性规划