Canvas实例教程:图像移动、大小调整和裁剪
本文介绍如何使用JavaScript和HTML5 Canvas元素来移动、调整大小和裁剪图像,这些技术适用于图片编辑器、照片分享等应用场景。
一般而言图像的剪裁会放在服务端进行,但是图片传送会消耗较多的流量。借助HTML5 Canvas绘图功能,可以在浏览器端以比较简单的方式来实现。
代码和在线演示地址:http://wow.techbrood.com/fiddle/2580,可以先操作下,有个整体印象,界面截图如下:
构建界面布局和元素
HTML页面由源图片、Crop操作按钮、裁剪矩形框以及图片容器(含4个角的调整小方块)组成,主体代码如下:
<div class="component"> <div class="overlay"> <div class="overlay-inner"> </div> </div> <img class="resize-image" src="/assets/beauty.jpg" alt="image for resizing"> <button class="btn-crop js-crop">Crop<img class="icon-crop" src="/assets/crop.svg"> </button> </div>
img[class=resize-image] 元素为本服务器图片资源,是要进行调整和裁剪的图片。注意出于安全策略,不能在浏览器中跨域操作图片,否则会出现类似下面的报错信息:
Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
button[class=btn-crop] 是SVG矢量图标按钮。
div[class=overlay] 元素是裁剪矩形框。
此外图片容器使用JavaScript动态包装在 img[class=resize-image] 元素外部:
// Wrap the image with the container and add resize handles $('.resize-image').wrap('<div class="resize-container"></div>') .before('<span class="resize-handle resize-handle-nw"></span>') .before('<span class="resize-handle resize-handle-ne"></span>') .after('<span class="resize-handle resize-handle-se"></span>') .after('<span class="resize-handle resize-handle-sw"></span>');
实现大小调整的功能
大小调整通过先在Canvas上绘制一个对应大小的图像,接着通过Canvas的toDataURL方法转化为base64编码的字符串形式的图片数据。
最后把该data:URL通过设置为img的src属性,附着到目标图像元素上。
resizeImage = function(width, height){ resize_canvas.width = width; resize_canvas.height = height; resize_canvas.getContext('2d').drawImage(orig_src, 0, 0, width, height); $('.resize-image').attr('src', resize_canvas.toDataURL("image/png")); };
实现移动功能
通过mouseup事件获取新的位置,然后通过jQuery的offset方法来完成元素偏移。
moving = function(e){ var mouse={}; e.preventDefault(); e.stopPropagation(); mouse.x = (e.clientX || e.pageX) + $(window).scrollLeft(); mouse.y = (e.clientY || e.pageY) + $(window).scrollTop(); $container.offset({ 'left': mouse.x - ( event_state.mouse_x - event_state.container_left ), 'top': mouse.y - ( event_state.mouse_y - event_state.container_top ) }); };
实现裁剪功能
这个主要是实现一个居中的覆盖矩形(overlay),接着通过计算背景图片和该覆盖矩形的偏移来获取图片裁剪区域的坐标,
然后再通过Canvas的drawImage和toDataURL完成裁剪图的绘制。
crop = function(){ var crop_canvas, left = $('.overlay').offset().left - $container.offset().left, top = $('.overlay').offset().top - $container.offset().top, width = $('.overlay').width(), height = $('.overlay').height(); crop_canvas = document.createElement('canvas'); crop_canvas.width = width; crop_canvas.height = height; crop_canvas.getContext('2d').drawImage(image_target, left, top, width, height, 0, 0, width, height); window.open(crop_canvas.toDataURL("image/png")); }
最后再加上一些移动功能,如触摸事件(Touch)和手势(Gesture)检测的支持。
参考链接
1. http://madebymike.com.au/
2. http://stackoverflow.com/questions/18922880/html5-canvas-resize-downscale-image-high-quality
3. http://www.techbrood.com/ideas?q=Makethumbnails
- 相关文章
微信公众号在线生成二维码带参数怎么搞?
带参数二维码是微信公众号渠道二维码的一种实现
微信的带参数二维码有两种,一种是临时二维码,一种是永久二维码,但是永久二维码的生成是有个数限制的,微...CentOS6 Apache2.2多站点HTTPS配置
可以使用letsencrypt(certbot)免费证书服务。支持多系统、多站点和多目录,支持wildcard(通配符域名),90天生效,可用定时任务自动更新。需要注意一点的是apache2.4以下版本需要在默认的ssl配置中添加如下的指令:NameVirtualHost
CentOS6 Apache2.2用域名配置多虚拟机
在CentOS下使用域名配置多虚拟机的步骤如下:
1. 使用Blender2.7给平面模型添加纹理贴图
在blender中给模型添加纹理,需要有2个步骤:首先在对象属性栏中给该对象添加材料和纹理建立纹理映射添加材料和纹理这是常见操作,略过步骤。但是仅仅这样操作,...
JavaScript语言多编程范式简介
和C++等语言类似,JS支持多范式(paradigms)编程。我们常常混合这些范式来完成一些大型Web项目。JS支持3种编程范式:命令式、面向对象和函数式。命令式(Imperative JavaScript)命令式就是简单的从上而下完成任务,流水账过程式编码风格:function
JavaScript事件模型图解
在JavaScript中用户交互的核心部分就是事件处理。本文为对事件模型和处理机制的总体性描述。Event是什么?
event是用户操作网页时发生的交互动作,比如clic...前端开发框架技术选型:Angular2 VS React VS jQuery
Angular和React是主流的2个前端开发框架,但是严格来说两者并非对等的概念。Angular是一个基于MVC(或者MVVM)的框架,包含model(模型)/view(视图)/controll...
使用HTML5 FileReader和Canvas压缩用户上传的图片
手机用户拍的照片通常会有2M以上,这对服务器带宽产生较大压力。因此在某些应用下(对图片要求不那么高)我们可以在客户端来压缩图片,然后再提交给服务器。总体...
HTTP1.1协议现状、问题和解决方案
HTTP的现状最早的HTTP协议非常简单,只能用来传送文本,方法也只有GET,后来逐步发展到1.1,能够支持多种MIME格式数据(如文本、文件),支持GET,POST,HEAD,OPTI...
Three.js入门教程2 - 着色器(下)
这是WebGL着色器教程的后半部分,如果你没看过前一篇,阅读这一篇教程可能会使你感到困惑,建议你翻阅前面的教程。
浏览器控制台报JS脚本执行错误:Module is not defined
现在JS分成了两个分支,一部分在服务器端发展如NodeJS,一部分是传统的浏览器运行环境。
有些插件在编写JS代码时,是针对Node编写的,所以直接在浏览器中使...Three.js 开发基础知识 - 绘制3D对象
Three.js是一个用来简化WebGL开发的JavaScript库,比如绘制一个三维立方体,使用WebGL需要100多行,那Three.js只要10几行就能够完成。本文通过创建一个立方体来...
如何使用CSS3实现一个平滑的3D文本标题
要实现3D文本,基本上有3种方法:1. 使用CSS3的投影滤镜(filter: drop-shadow)2. 使用3d建模和CSS3 3d变换来实现(最真实)3. 使用CSS3 text-shadow属性来实现...
更多...