html+jquery实现简单图片裁剪
有了上一篇图片放大镜的铺垫,今天的这个例子是缩小镜,因为裁剪的原图往往很大,不能在工作区域看到全部图片,所以,要有缩小镜来显示,当前裁剪的区域是原图的个部分.按照惯例首先看下效果图:
功能一:载入默认图片
功能二:选择本地图片
功能三:拖拽(鼠标直接拖动工作区视窗)
功能四:放大,缩小(点击按钮放大/缩小0.5倍,鼠标滚轮图片缩放)
功能五:利用canvas绘图裁剪图片
以下是源码,分享下,防止忘记:
html:
- <script src="./javascript/jquery.min.js"></script>
- <div id="workplace">
- <div id="workplacewrap">
- <div id="operateplace">
- <div class="showinfo">
- <span class="mouseposition">
- 坐标(px):
- x:<span class="mouseposition-x">0</span>
- y:<span class="mouseposition-y">0</span>
- </span>
- </div>
- <div id="sourceImage">
- <img src="./images/show-window/1-1.jpg" alt="" draggable="false">
- </div>
- <div id="clipregion"></div>
- <div class="operation">
- <input id="fileselector" type="file" hidden style="">
- <label class="btn" for="fileselector">选择文件</label>
- <span id="btn-ResizeUp" class="btn">放大</span>
- <span id="btn-ResizeDown" class="btn">缩小</span>
- <span id="btn-Clip" class="btn">裁剪</span>
- </div>
- </div>
- <div id="showwindow">
- <div class="showinfo">
- <span class="mouseposition">
- 缩放比例:
- <span class="enlargeratio"></span>%
- </span>
- </div>
- <div style="position: absolute;">
- <div id="pologen"></div>
- </div>
- <div id="previewwindow">
- <img src="" alt="" draggable="false">
- </div>
- <div class="operation">
- <span class="btn">保存</span>
- </div>
- </div>
- </div>
css:
- * {
- font-size: 14px;
- letter-spacing: 1px;
- color: #000;
- -ms-text-justify: auto;
- text-justify: auto;
- font-size: 12px;
- }
- #workplace {
- width: 100%;
- height: auto;
- background: #f4f4f4;
- }
- #workplacewrap {
- margin: 0px auto;
- width: 1200px;
- display: flex;
- flex-direction: row;
- align-items: flex-start;
- justify-content: flex-start;
- border-right: 1px solid #f0f0f0;
- border-left: 1px solid #f0f0f0;
- background: #f4f4f4;
- font-family: "微软雅黑 Light";
- padding: 5px;
- }
- #operateplace {
- padding: 4px;
- border: 1px solid #bababa;
- }
- #sourceImage {
- width: 500px;
- height: 300px;
- border: 1px solid #bababa;
- background: none;
- margin-bottom: -1px;
- overflow: hidden;
- }
- #sourceImage img {
- position: relative;
- top:;
- left:;
- }
- .btn {
- background: #aa0000;
- border: #F8F8F8;
- color: white;
- padding: 5px;
- }
- .btn:hover {
- cursor: pointer;
- background: #cc1234;
- }
- .operation {
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: space-around;
- height: 50px;
- }
- .showinfo {
- margin-bottom: -1px;
- font-size: 12px;
- }
- #showwindow {
- justify-self: flex-end;
- align-items: flex-end;
- width: 500px;
- height: auto;
- border: #baabba 1px solid;
- margin-left: 5px;
- padding: 5px;
- overflow: hidden;
- position:relative;
- }
- #previewwindow {
- border: 1px solid #bababa;
- width: 500px;
- height: 300px;
- }
- #pologen
- {
- border:1px solid red;
- position:relative;
- display:none;
- }
javascript:
- //代码重新修订
- class ClipTools {
- constructor() {
- this.workview = $('#sourceImage');
- this.showview = $('#previewwindow');
- this.workviewimg=$('#sourceImage>img');
- this.showviewimg = $('#previewwindow>img');
- //工作区实际尺寸,由于图片有缩放,工作区尺寸实际是有workvimg尺寸决定的,而工作区视窗的是尺寸是固定的,本例中是500*300,这个尺寸默认就是最终截图的尺寸
- //后面扩展,可以对工作视图的尺寸进行调整,截出不同尺寸的图片
- this.workvwidth = 0;
- this.workvheight = 0;
- //同样展示框的尺寸,实际是右侧展示框图片缩放后的尺寸,本例中图片一定要全部放入展示视窗,所以,这个尺寸是小于等于展示视窗的尺寸的
- this.showvwidth = $('#sourceImage').width();
- this.showvheight = $('#sourceImage').height();
- //右侧显示区图片缩放后的高度
- this.showvimgheight=0;
- //右侧显示区图片缩放后的宽度
- this.showvimgwidth=0;
- this.resizeRate = 0.5;
- this.isScrollMouseResize = false;
- //后面扩展,比如绘制裁剪区域时用,本例中没有实际意义
- this.isClip=false;
- this.isMouseDown=false;
- //标识鼠标在工作区的坐标,offsetX 和offsetY(相对于视窗)
- this.workpos_x = 0;
- this.workpos_y = 0;
- //图片顶点位置
- this.sourceimg_l=0;
- this.sourceimg_t=0;
- //图片在计算拖动距离的时候,需要记录鼠标的起始位置,在鼠标的down->move中,起始位置以鼠标的down点为基准
- this.lastMouse_x=0;
- this.lastMouse_y=0;
- //记录图片的原始尺寸
- this.sourceimg_w = 0;
- this.sourceimg_h = 0;
- //记录图片缩放的比例
- this.enlargeratio = 1.0;
- //显示区图片和显示区域的比例
- this.showToSourceWidthRatio=0.1;
- this.showToSouceHeightRatio=0.1;
- this.Init = this.Init.bind(this);
- this.ImgInputFileChanged = this.ImgInputFileChanged.bind(this);
- this.ResizeUp = this.ResizeUp.bind(this);
- this.ResizeDown = this.ResizeDown.bind(this);
- this.ShowWorkPos = this.ShowWorkPos.bind(this);
- this.DrawClipRegionTosShow=this.DrawClipRegionTosShow.bind(this);
- }
- ShowWorkPos(x, y) {
- $('.mouseposition-x').text(this.workpos_x);
- $('.mouseposition-y').text(this.workpos_y);
- $(".enlargeratio").text(($("#pologen").height()/this.showvimgwidth)*100);
- this.DrawClipRegionTosShow();
- }
- Init() {
- //如果工作区域有默认图片
- this.sourceimg_h = this.workviewimg.height();
- this.sourceimg_w = this.workviewimg.width();
- this.workvwidth = this.sourceimg_w;
- this.workvheight = this.sourceimg_h;
- this.showToSouceHeightRatio=this.showvheight/this.sourceimg_h;
- this.showToSourceWidthRatio=this.showvwidth/this.sourceimg_w;
- //右侧展示区域,展示当前工作区处于图片的区域
- //按照最小比例对图片进行缩放
- if (this.showToSouceHeightRatio<this.showToSourceWidthRatio)
- {
- this.showvimgheight=this.showvheight;
- this.showvimgwidth=this.showToSouceHeightRatio*this.sourceimg_w;
- }
- else
- {
- this.showvimgheight=this.sourceimg_h*this.showToSourceWidthRatio;
- this.showvimgwidth=this.showvwidth;
- }
- this.showviewimg.attr('src',this.workviewimg.attr('src')).width(this.showvimgwidth).height(this.showvimgheight);
- $('#btn-Clip').click(()=>{
- let _cropCanvas = document.createElement('canvas');
- // 计算截取时从原图片的原始长度的坐标
- //图片有缩放等,所以要利用原始数据进行计算
- let _sy =-this.sourceimg_t/ (this.workvheight/this.sourceimg_h);
- let _sx=-this.sourceimg_l/(this.workvwidth/this.sourceimg_w);
- let _swidth=this.workview.width()/(this.workvwidth/this.sourceimg_w);
- let _sheight=this.workview.height()/(this.workvheight/this.sourceimg_h);
- let width=this.workview.width();
- let height=this.workview.height();
- //工作区域视窗就是图片的大小
- _cropCanvas.width = width;
- _cropCanvas.height = height;
- // 绘制图片
- _cropCanvas.getContext('2d').drawImage(this.workviewimg[0], _sx, _sy, _swidth, _sheight, 0, 0, width, height);
- // 保存图片信息
- let _lastImageData = _cropCanvas.toDataURL('image/png');
- // 将裁剪出来的信息展示
- this.showviewimg.attr({"src": _lastImageData}).css({"width":width+"px","height":height+"px"});
- $('#pologen').css('display',"none");
- alert("裁剪成功");
- });
- $('#fileselector').on("change", this.ImgInputFileChanged);
- $("#btn-ResizeUp").click(this.ResizeUp);
- $("#btn-ResizeDown").click(this.ResizeDown);
- //this.DrawClipRegionTosShow();
- this.workviewimg.mousemove((e) => {
- if(this.isMouseDown)
- {
- if (this.workviewimg)
- var left_s= e.offsetX- this.lastMouse_x;
- var top_s=e.offsetY-this.lastMouse_y;
- this.sourceimg_l+=left_s;
- this.sourceimg_t+=top_s;
- this.workviewimg.css({"left":this.sourceimg_l+"px","top":this.sourceimg_t+"px"});
- }
- this.workpos_x = e.offsetX+this.sourceimg_l;
- this.workpos_y = e.offsetY+this.sourceimg_t;
- this.ShowWorkPos(e.offsetX,e.offsetY);
- return false;
- });
- //工作区滚轮事件,调整图片缩放,相当于是微调
- this.workviewimg.on("mousewheel DOMMouseScroll",(e)=> {
- this.isScrollMouseResize=true;
- var delta = (e.originalEvent.wheelDelta && (e.originalEvent.wheelDelta > 0 ? 1 : -1)) || // chrome & ie
- (e.originalEvent.detail && (e.originalEvent.detail > 0 ? -1 : 1)); // firefox
- if(delta>0)//向上滚
- {
- if(this.enlargeratio>=1)
- {
- return;
- }
- this.workvwidth += 1;
- this.workvheight +=this.sourceimg_h/this.sourceimg_w;
- }
- else if(delta<0)
- {
- this.workvwidth -= 1;
- this.workvheight -=this.sourceimg_h/this.sourceimg_w;
- }
- this.workviewimg.css({"width":this.workvwidth+"px","height":this.workvheight+"px"});
- this.workviewimg.height(this.workvheight);
- //this.DrawClipRegionTosShow();
- });
- //工作区图片拖拽
- this.workviewimg.mousedown((e)=>{
- this.isMouseDown=true;
- if(!this.isClip)
- {
- this.workviewimg.css({"cursor":"move"});
- }
- this.lastMouse_x=e.offsetX;
- this.lastMouse_y=e.offsetY;
- });
- //鼠标未松开,移出工作区
- this.workviewimg.mouseleave((e)=>{
- this.isMouseDown=false;
- if(!this.isClip)
- {
- this.workviewimg.css({"cursor":"default"});
- }
- });
- //防止鼠标松开的事件,遗漏,所以拖拽的终事件,放在body中监听
- $('body').mouseup((e)=>{
- this.isMouseDown=false;
- if(!this.isClip)
- {
- this.workviewimg.css({"cursor":"default"});
- }
- });
- }
- //在展示区域,标识出被截图的范围
- DrawClipRegionTosShow()
- {
- //1.首先将工作区左上角的位置还原到原图的位置,因为有滚轮的放大和缩小,所以原本定义在放大或者缩小按钮上的缩放比例不能再使用,要重新计算
- //不管是放大缩小按钮,还是滚轮缩放的比例在工作区都是一样的
- //计算在右侧展示区,缩放后投影裁剪区域的位置
- this.showToSouceHeightRatio=this.showvheight/this.workvheight;
- this.showToSourceWidthRatio=this.showvwidth/this.workvwidth;
- let showLeft=0;
- let showTop=0;
- let showWidth=0;
- let showHeight=0;
- if (this.showToSouceHeightRatio<this.showToSourceWidthRatio)
- {
- showWidth=this.workview.width()*this.showToSouceHeightRatio;
- showHeight=this.workview.height()*this.showToSouceHeightRatio;
- showLeft=-this.sourceimg_l*this.showToSouceHeightRatio;
- showTop=-this.sourceimg_t*this.showToSouceHeightRatio;
- }
- else
- {
- showWidth=this.workview.width()*this.showToSourceWidthRatio;
- showHeight=this.workview.height()*this.showToSourceWidthRatio;
- showLeft=-this.sourceimg_l*this.showToSourceWidthRatio;
- showTop=-this.sourceimg_t*this.showToSourceWidthRatio;
- }
- $('#pologen').css({"display":"block","top":showTop+"px","left":showLeft+"px","width":showWidth+"px","height":showHeight+"px"});
- }
- ResizeDown(e) {
- this.sourceimg_t=0;
- this.sourceimg_l=0;
- this.workviewimg.css({"left":this.sourceimg_l+"px","top":this.sourceimg_t+"px"});
- //鼠标滑轮调整过尺寸,则将图复原
- if (this.isScrollMouseResize) {
- this.enlargeratio = 1.0;
- this.workvwidth=this.sourceimg_w;
- this.workvheight=this.sourceimg_h;
- this.workviewimg.css({"width":this.sourceimg_w+"px","height":this.sourceimg_h+"px"});
- }
- this.isScrollMouseResize = false;
- //不允许对完全在工作区展示的图片,再缩小
- if (this.workvheight < this.showvheight && this.workvwidth < this.showvwidth) {
- return;
- }
- else {
- this.enlargeratio *= this.resizeRate;
- this.workvwidth = this.sourceimg_w * this.enlargeratio;
- this.workvheight = this.sourceimg_h * this.enlargeratio;
- this.workviewimg.css({"width":this.workvwidth+"px","height":this.workvheight+"px"});
- this.DrawClipRegionTosShow();
- }
- }
- ResizeUp(e) {
- this.sourceimg_t=0;
- this.sourceimg_l=0;
- this.workviewimg.css({"left":this.sourceimg_l+"px","top":this.sourceimg_t+"px"});
- //鼠标滑轮调整过尺寸,则将图复原
- if (this.isScrollMouseResize) {
- this.enlargeratio = 1.0;
- this.workvwidth=this.sourceimg_w;
- this.workvheight=this.sourceimg_h;
- this.workviewimg.css({"width":this.sourceimg_w+"px","height":this.sourceimg_h+"px"});
- }
- this.isScrollMouseResize = false;
- //不允许,对原样展示的图片再进行放大
- if (this.enlargeratio >= 1) {
- return;
- }
- else {
- this.enlargeratio /= this.resizeRate;
- this.workvwidth = this.sourceimg_w * this.enlargeratio;
- this.workvheight = this.sourceimg_h * this.enlargeratio;
- this.workviewimg.css({"width":this.workvwidth+"px","height":this.workvheight+"px"});
- }
- this.DrawClipRegionTosShow();
- }
- ImgInputFileChanged(e) {
- let file = e.target.files[0];
- let reader = new FileReader();
- reader.readAsDataURL(file);
- //读取完成时
- reader.onloadend = (e) => {
- this.workviewimg.attr('src', e.target.result);
- this.sourceimg_h = this.workviewimg.height();
- this.sourceimg_w = this.workviewimg.width();
- this.showToSouceHeightRatio=this.showvheight/this.sourceimg_h;
- this.showToSourceWidthRatio=this.showvwidth/this.sourceimg_w;
- //右侧展示区域,展示当前工作区处于图片的区域
- //按照短边的比例对图片进行缩放
- if (this.showToSouceHeightRatio<this.showToSourceWidthRatio)
- {
- this.showvimgheight=this.showvheight;
- this.showvimgwidth=this.showToSouceHeightRatio*this.sourceimg_w;
- }
- else
- {
- this.showvimgheight=this.sourceimg_h*this.showToSourceWidthRatio;
- this.showvimgwidth=this.showvwidth;
- }
- this.showviewimg.attr('src',this.workviewimg.attr('src')).css({"width":this.showvimgwidth+"px","height":this.showvimgheight+"px"});
- this.DrawClipRegionTosShow();
- }
- }
- }
- $(function () {
- let clip = new ClipTools();
- clip.Init();
- })
还有个文件保存的功能,由于裁剪之后,展示区域的图片路径是base64,所以可以直接发送给服务器,或者用于本地图直接展示
有问题,希望指正,本人刚接触前端不久,谢谢!
html+jquery实现简单图片裁剪的更多相关文章
- struts2+jsp+jquery+Jcrop实现图片裁剪并上传
<1> 使用html标签上传需要裁剪的大图. <2> 在页面呈现大图,使用Jcrop(Jquery)对大图进行裁剪,并且可以进行预览. <3> 选择好截取部分之后发 ...
- Jquery实现简单图片轮播
html代码: <div class="show"> <div class="left"> <div class="sh ...
- Cropper – 简单的 jQuery 图片裁剪插件
Cropper 是一个简单的 jQuery 图像裁剪插件.它支持选项,方法,事件,触摸(移动),缩放,旋转.输出的裁剪数据基于原始图像大小,这样你就可以用它们来直接裁剪图像. 如果你尝试裁剪跨域图像, ...
- 【jQuery插件分享】Cropper——一个简单方便的图片裁剪插件
原文:https://segmentfault.com/a/1190000012344970 插件介绍 这是一个我在写以前的项目的途中发现的一个国人写的jQuery图像裁剪插件,当时想实现用户资料的头 ...
- Croppic – 免费开源的 jQuery 图片裁剪插件
Croppic 这款开源的 jQuery 图片裁剪插件能够满足网站开发人员各种不同的使用需要.只需要简单的上传图片,就可以实现你想要的图像缩放和裁剪功能.因为使用了 HTML5 FormData 对 ...
- jQuery 图片裁剪插件 Jcrop
Jcrop是一个jQuery图片裁剪插件,它能为你的WEB应用程序快速简单地提供图片裁剪的功能.特点如下: 对所有图片均unobtrusively(无侵入的,保持DOM简洁) 支持宽高比例锁定 支持 ...
- jquery实现简单瀑布流布局(续):图片懒加载
# jquery实现简单瀑布流布局(续):图片懒加载 这篇文章是jquery实现简单瀑布流布局思想的小小扩展.代码基于前作的代码继续完善. 图片懒加载就是符合某些条件时才触发图片的加载.最常见的具体表 ...
- Jquery插件-Html5图片上传并裁剪
/** * 图片裁剪 * @author yanglizhe * 2015/11/16 */ (function($){ /** * Drag */ var Drag={obj:null,init:f ...
- 移动端 H5图片裁剪插件,内置简单手势操作
前面曾经写过一篇<H5图片裁剪升级版>,但里面需要借助第三方手势库,这次就不需要使用手势库,全部封装在代码中. 下图是裁剪的展示,下面就做了拖放和裁剪,没有做缩放,在插件中需要用到大量的计 ...
随机推荐
- [leecode]---11.container with most water
description: Input: [1,8,6,2,5,4,8,3,7]Output: 49 思路1: 从(1,a1)开始向后算面积,需要两层n循环,时间复杂度n2 思路2: 找出数组中最大的数 ...
- angular2学习笔记3
一.项目搭建 二.生成首页的4个tab页面 三.运行部署及配置
- Redhat 6.3上安装OpenSSL
需求是:在Redhat 6.3上安装OpenSSL 1.1.0b. 一开始试图去搜索rpm,没有对应版本.https://pkgs.org/http://rpmfind.net/放弃! 只能通过编译源 ...
- Python3自定义日志类教程
一.说明 Python3的logging功能是比较丰富的支持不同层次的日志输出,但或是我们想在日志前输出时间.或是我们想要将日志输入到文件,我们还是想要自定义日志类. 之前自己也尝试写过但感觉文档太乱 ...
- SQL语句实现行转列
最近在维护一个项目,出现了一下bug需要进行调试,于是把正式库上面的代码搬到本地库上面,数据库是本地的,跑项目的时候调试发现代码里面带有wmsys.wm_concat函数的SQL语句出现错误,经排查发 ...
- javascript 中的number
大家都知道javascript中有五种简单数据类型,number,string,boolean,null,undefined,复杂数据类型是object.本文主要记录下number类型的一些可能不太常 ...
- 构建web应用之——SpringMVC实现CRUD
配置好SpringMVC最基本的配置后,开始实现处理数据的CRUD(CREATE, READ, UPDATE, DELETE) 为实现模块上的松耦合,我们将与数据库的交互任务交给DAO(Data Ac ...
- 免费代理ip爬虫分享
分享一个某代理网站的免费代理ip的爬虫,直接复制到pycharm运行就可以了. 注意:爬取的代理ip有点坑,因为是免费的所以过期时间很快,可能1分钟后就会失效.并且在scrapy使用这些代理ip还会给 ...
- 在Ubuntu14.04上配置jdk环境
服务器环境:Ubuntu14.04 server 1.进入oracle官网下载jdk1.7.0_71_x64.gz 重命名为jdk1.7 2.使用tar -xvf jdk1.7.0_71_x64. ...
- CSS3动画与JS动画的优缺点?
JS动画: 缺点:1.JS在浏览器的主线程中运行,而主线程还有其他的js脚本,样式布局,绘制任务等,对其干扰可能导致线程出现阻塞,从而造成丢帧的情况. 2.JS动画代码复杂度高于CSS3动画. 优点: ...