有了上一篇图片放大镜的铺垫,今天的这个例子是缩小镜,因为裁剪的原图往往很大,不能在工作区域看到全部图片,所以,要有缩小镜来显示,当前裁剪的区域是原图的个部分.按照惯例首先看下效果图:

功能一:载入默认图片

功能二:选择本地图片

功能三:拖拽(鼠标直接拖动工作区视窗)

功能四:放大,缩小(点击按钮放大/缩小0.5倍,鼠标滚轮图片缩放)

功能五:利用canvas绘图裁剪图片

以下是源码,分享下,防止忘记:

html:

  1. <script src="./javascript/jquery.min.js"></script>
  2. <div id="workplace">
  3. <div id="workplacewrap">
  4. <div id="operateplace">
  5. <div class="showinfo">
  6. <span class="mouseposition">
  7. 坐标(px):
  8. x:<span class="mouseposition-x">0</span>
  9. y:<span class="mouseposition-y">0</span>
  10. </span>
  11. </div>
  12. <div id="sourceImage">
  13. <img src="./images/show-window/1-1.jpg" alt="" draggable="false">
  14. </div>
  15. <div id="clipregion"></div>
  16. <div class="operation">
  17. <input id="fileselector" type="file" hidden style="">
  18. <label class="btn" for="fileselector">选择文件</label>
  19. <span id="btn-ResizeUp" class="btn">放大</span>
  20. <span id="btn-ResizeDown" class="btn">缩小</span>
  21. <span id="btn-Clip" class="btn">裁剪</span>
  22. </div>
  23. </div>
  24. <div id="showwindow">
  25. <div class="showinfo">
  26. <span class="mouseposition">
  27. 缩放比例:
  28. <span class="enlargeratio"></span>%
  29. </span>
  30. </div>
  31. <div style="position: absolute;">
  32. <div id="pologen"></div>
  33. </div>
  34. <div id="previewwindow">
  35. <img src="" alt="" draggable="false">
  36. </div>
  37. <div class="operation">
  38. <span class="btn">保存</span>
  39. </div>
  40.  
  41. </div>
  42. </div>

css:

  1. * {
  2. font-size: 14px;
  3. letter-spacing: 1px;
  4. color: #000;
  5. -ms-text-justify: auto;
  6. text-justify: auto;
  7. font-size: 12px;
  8. }
  9.  
  10. #workplace {
  11. width: 100%;
  12. height: auto;
  13. background: #f4f4f4;
  14.  
  15. }
  16.  
  17. #workplacewrap {
  18. margin: 0px auto;
  19. width: 1200px;
  20. display: flex;
  21. flex-direction: row;
  22. align-items: flex-start;
  23. justify-content: flex-start;
  24. border-right: 1px solid #f0f0f0;
  25. border-left: 1px solid #f0f0f0;
  26. background: #f4f4f4;
  27. font-family: "微软雅黑 Light";
  28. padding: 5px;
  29. }
  30.  
  31. #operateplace {
  32. padding: 4px;
  33. border: 1px solid #bababa;
  34.  
  35. }
  36.  
  37. #sourceImage {
  38. width: 500px;
  39. height: 300px;
  40. border: 1px solid #bababa;
  41. background: none;
  42. margin-bottom: -1px;
  43. overflow: hidden;
  44. }
  45.  
  46. #sourceImage img {
  47. position: relative;
  48. top:;
  49. left:;
  50. }
  51.  
  52. .btn {
  53. background: #aa0000;
  54. border: #F8F8F8;
  55. color: white;
  56. padding: 5px;
  57. }
  58.  
  59. .btn:hover {
  60. cursor: pointer;
  61. background: #cc1234;
  62. }
  63.  
  64. .operation {
  65. display: flex;
  66. flex-direction: row;
  67. align-items: center;
  68. justify-content: space-around;
  69. height: 50px;
  70. }
  71.  
  72. .showinfo {
  73.  
  74. margin-bottom: -1px;
  75. font-size: 12px;
  76. }
  77.  
  78. #showwindow {
  79. justify-self: flex-end;
  80. align-items: flex-end;
  81. width: 500px;
  82. height: auto;
  83. border: #baabba 1px solid;
  84. margin-left: 5px;
  85. padding: 5px;
  86. overflow: hidden;
  87. position:relative;
  88. }
  89.  
  90. #previewwindow {
  91. border: 1px solid #bababa;
  92. width: 500px;
  93. height: 300px;
  94. }
  95. #pologen
  96. {
  97. border:1px solid red;
  98. position:relative;
  99. display:none;
  100. }

javascript:

  1. //代码重新修订
  2. class ClipTools {
  3. constructor() {
  4. this.workview = $('#sourceImage');
  5. this.showview = $('#previewwindow');
  6.  
  7. this.workviewimg=$('#sourceImage>img');
  8. this.showviewimg = $('#previewwindow>img');
  9. //工作区实际尺寸,由于图片有缩放,工作区尺寸实际是有workvimg尺寸决定的,而工作区视窗的是尺寸是固定的,本例中是500*300,这个尺寸默认就是最终截图的尺寸
  10. //后面扩展,可以对工作视图的尺寸进行调整,截出不同尺寸的图片
  11. this.workvwidth = 0;
  12. this.workvheight = 0;
  13. //同样展示框的尺寸,实际是右侧展示框图片缩放后的尺寸,本例中图片一定要全部放入展示视窗,所以,这个尺寸是小于等于展示视窗的尺寸的
  14. this.showvwidth = $('#sourceImage').width();
  15. this.showvheight = $('#sourceImage').height();
  16.  
  17. //右侧显示区图片缩放后的高度
  18. this.showvimgheight=0;
  19. //右侧显示区图片缩放后的宽度
  20. this.showvimgwidth=0;
  21. this.resizeRate = 0.5;
  22. this.isScrollMouseResize = false;
  23. //后面扩展,比如绘制裁剪区域时用,本例中没有实际意义
  24. this.isClip=false;
  25.  
  26. this.isMouseDown=false;
  27. //标识鼠标在工作区的坐标,offsetX 和offsetY(相对于视窗)
  28. this.workpos_x = 0;
  29. this.workpos_y = 0;
  30.  
  31. //图片顶点位置
  32. this.sourceimg_l=0;
  33. this.sourceimg_t=0;
  34. //图片在计算拖动距离的时候,需要记录鼠标的起始位置,在鼠标的down->move中,起始位置以鼠标的down点为基准
  35. this.lastMouse_x=0;
  36. this.lastMouse_y=0;
  37. //记录图片的原始尺寸
  38. this.sourceimg_w = 0;
  39. this.sourceimg_h = 0;
  40. //记录图片缩放的比例
  41. this.enlargeratio = 1.0;
  42.  
  43. //显示区图片和显示区域的比例
  44. this.showToSourceWidthRatio=0.1;
  45. this.showToSouceHeightRatio=0.1;
  46.  
  47. this.Init = this.Init.bind(this);
  48. this.ImgInputFileChanged = this.ImgInputFileChanged.bind(this);
  49. this.ResizeUp = this.ResizeUp.bind(this);
  50. this.ResizeDown = this.ResizeDown.bind(this);
  51. this.ShowWorkPos = this.ShowWorkPos.bind(this);
  52. this.DrawClipRegionTosShow=this.DrawClipRegionTosShow.bind(this);
  53. }
  54. ShowWorkPos(x, y) {
  55. $('.mouseposition-x').text(this.workpos_x);
  56. $('.mouseposition-y').text(this.workpos_y);
  57. $(".enlargeratio").text(($("#pologen").height()/this.showvimgwidth)*100);
  58.  
  59. this.DrawClipRegionTosShow();
  60. }
  61.  
  62. Init() {
  63. //如果工作区域有默认图片
  64. this.sourceimg_h = this.workviewimg.height();
  65. this.sourceimg_w = this.workviewimg.width();
  66.  
  67. this.workvwidth = this.sourceimg_w;
  68. this.workvheight = this.sourceimg_h;
  69.  
  70. this.showToSouceHeightRatio=this.showvheight/this.sourceimg_h;
  71. this.showToSourceWidthRatio=this.showvwidth/this.sourceimg_w;
  72.  
  73. //右侧展示区域,展示当前工作区处于图片的区域
  74. //按照最小比例对图片进行缩放
  75.  
  76. if (this.showToSouceHeightRatio<this.showToSourceWidthRatio)
  77. {
  78. this.showvimgheight=this.showvheight;
  79. this.showvimgwidth=this.showToSouceHeightRatio*this.sourceimg_w;
  80. }
  81. else
  82. {
  83. this.showvimgheight=this.sourceimg_h*this.showToSourceWidthRatio;
  84. this.showvimgwidth=this.showvwidth;
  85. }
  86. this.showviewimg.attr('src',this.workviewimg.attr('src')).width(this.showvimgwidth).height(this.showvimgheight);
  87.  
  88. $('#btn-Clip').click(()=>{
  89. let _cropCanvas = document.createElement('canvas');
  90. // 计算截取时从原图片的原始长度的坐标
  91. //图片有缩放等,所以要利用原始数据进行计算
  92. let _sy =-this.sourceimg_t/ (this.workvheight/this.sourceimg_h);
  93. let _sx=-this.sourceimg_l/(this.workvwidth/this.sourceimg_w);
  94. let _swidth=this.workview.width()/(this.workvwidth/this.sourceimg_w);
  95. let _sheight=this.workview.height()/(this.workvheight/this.sourceimg_h);
  96. let width=this.workview.width();
  97. let height=this.workview.height();
  98. //工作区域视窗就是图片的大小
  99. _cropCanvas.width = width;
  100. _cropCanvas.height = height;
  101. // 绘制图片
  102. _cropCanvas.getContext('2d').drawImage(this.workviewimg[0], _sx, _sy, _swidth, _sheight, 0, 0, width, height);
  103. // 保存图片信息
  104. let _lastImageData = _cropCanvas.toDataURL('image/png');
  105. // 将裁剪出来的信息展示
  106. this.showviewimg.attr({"src": _lastImageData}).css({"width":width+"px","height":height+"px"});
  107. $('#pologen').css('display',"none");
  108. alert("裁剪成功");
  109. });
  110. $('#fileselector').on("change", this.ImgInputFileChanged);
  111. $("#btn-ResizeUp").click(this.ResizeUp);
  112. $("#btn-ResizeDown").click(this.ResizeDown);
  113. //this.DrawClipRegionTosShow();
  114. this.workviewimg.mousemove((e) => {
  115.  
  116. if(this.isMouseDown)
  117. {
  118. if (this.workviewimg)
  119. var left_s= e.offsetX- this.lastMouse_x;
  120. var top_s=e.offsetY-this.lastMouse_y;
  121.  
  122. this.sourceimg_l+=left_s;
  123. this.sourceimg_t+=top_s;
  124. this.workviewimg.css({"left":this.sourceimg_l+"px","top":this.sourceimg_t+"px"});
  125. }
  126. this.workpos_x = e.offsetX+this.sourceimg_l;
  127. this.workpos_y = e.offsetY+this.sourceimg_t;
  128. this.ShowWorkPos(e.offsetX,e.offsetY);
  129. return false;
  130. });
  131. //工作区滚轮事件,调整图片缩放,相当于是微调
  132. this.workviewimg.on("mousewheel DOMMouseScroll",(e)=> {
  133. this.isScrollMouseResize=true;
  134. var delta = (e.originalEvent.wheelDelta && (e.originalEvent.wheelDelta > 0 ? 1 : -1)) || // chrome & ie
  135. (e.originalEvent.detail && (e.originalEvent.detail > 0 ? -1 : 1)); // firefox
  136.  
  137. if(delta>0)//向上滚
  138. {
  139. if(this.enlargeratio>=1)
  140. {
  141. return;
  142. }
  143. this.workvwidth += 1;
  144. this.workvheight +=this.sourceimg_h/this.sourceimg_w;
  145. }
  146. else if(delta<0)
  147. {
  148. this.workvwidth -= 1;
  149. this.workvheight -=this.sourceimg_h/this.sourceimg_w;
  150. }
  151. this.workviewimg.css({"width":this.workvwidth+"px","height":this.workvheight+"px"});
  152. this.workviewimg.height(this.workvheight);
  153. //this.DrawClipRegionTosShow();
  154. });
  155.  
  156. //工作区图片拖拽
  157. this.workviewimg.mousedown((e)=>{
  158. this.isMouseDown=true;
  159. if(!this.isClip)
  160. {
  161. this.workviewimg.css({"cursor":"move"});
  162. }
  163. this.lastMouse_x=e.offsetX;
  164. this.lastMouse_y=e.offsetY;
  165. });
  166. //鼠标未松开,移出工作区
  167. this.workviewimg.mouseleave((e)=>{
  168. this.isMouseDown=false;
  169. if(!this.isClip)
  170. {
  171. this.workviewimg.css({"cursor":"default"});
  172. }
  173. });
  174. //防止鼠标松开的事件,遗漏,所以拖拽的终事件,放在body中监听
  175. $('body').mouseup((e)=>{
  176. this.isMouseDown=false;
  177. if(!this.isClip)
  178. {
  179. this.workviewimg.css({"cursor":"default"});
  180. }
  181. });
  182. }
  183. //在展示区域,标识出被截图的范围
  184. DrawClipRegionTosShow()
  185. {
  186. //1.首先将工作区左上角的位置还原到原图的位置,因为有滚轮的放大和缩小,所以原本定义在放大或者缩小按钮上的缩放比例不能再使用,要重新计算
  187. //不管是放大缩小按钮,还是滚轮缩放的比例在工作区都是一样的
  188. //计算在右侧展示区,缩放后投影裁剪区域的位置
  189. this.showToSouceHeightRatio=this.showvheight/this.workvheight;
  190. this.showToSourceWidthRatio=this.showvwidth/this.workvwidth;
  191. let showLeft=0;
  192. let showTop=0;
  193. let showWidth=0;
  194. let showHeight=0;
  195. if (this.showToSouceHeightRatio<this.showToSourceWidthRatio)
  196. {
  197. showWidth=this.workview.width()*this.showToSouceHeightRatio;
  198. showHeight=this.workview.height()*this.showToSouceHeightRatio;
  199. showLeft=-this.sourceimg_l*this.showToSouceHeightRatio;
  200. showTop=-this.sourceimg_t*this.showToSouceHeightRatio;
  201. }
  202. else
  203. {
  204. showWidth=this.workview.width()*this.showToSourceWidthRatio;
  205. showHeight=this.workview.height()*this.showToSourceWidthRatio;
  206. showLeft=-this.sourceimg_l*this.showToSourceWidthRatio;
  207. showTop=-this.sourceimg_t*this.showToSourceWidthRatio;
  208. }
  209. $('#pologen').css({"display":"block","top":showTop+"px","left":showLeft+"px","width":showWidth+"px","height":showHeight+"px"});
  210.  
  211. }
  212. ResizeDown(e) {
  213. this.sourceimg_t=0;
  214. this.sourceimg_l=0;
  215. this.workviewimg.css({"left":this.sourceimg_l+"px","top":this.sourceimg_t+"px"});
  216. //鼠标滑轮调整过尺寸,则将图复原
  217. if (this.isScrollMouseResize) {
  218. this.enlargeratio = 1.0;
  219. this.workvwidth=this.sourceimg_w;
  220. this.workvheight=this.sourceimg_h;
  221. this.workviewimg.css({"width":this.sourceimg_w+"px","height":this.sourceimg_h+"px"});
  222. }
  223. this.isScrollMouseResize = false;
  224. //不允许对完全在工作区展示的图片,再缩小
  225. if (this.workvheight < this.showvheight && this.workvwidth < this.showvwidth) {
  226. return;
  227. }
  228. else {
  229. this.enlargeratio *= this.resizeRate;
  230. this.workvwidth = this.sourceimg_w * this.enlargeratio;
  231. this.workvheight = this.sourceimg_h * this.enlargeratio;
  232. this.workviewimg.css({"width":this.workvwidth+"px","height":this.workvheight+"px"});
  233. this.DrawClipRegionTosShow();
  234. }
  235. }
  236.  
  237. ResizeUp(e) {
  238. this.sourceimg_t=0;
  239. this.sourceimg_l=0;
  240. this.workviewimg.css({"left":this.sourceimg_l+"px","top":this.sourceimg_t+"px"});
  241. //鼠标滑轮调整过尺寸,则将图复原
  242. if (this.isScrollMouseResize) {
  243. this.enlargeratio = 1.0;
  244. this.workvwidth=this.sourceimg_w;
  245. this.workvheight=this.sourceimg_h;
  246. this.workviewimg.css({"width":this.sourceimg_w+"px","height":this.sourceimg_h+"px"});
  247.  
  248. }
  249. this.isScrollMouseResize = false;
  250. //不允许,对原样展示的图片再进行放大
  251. if (this.enlargeratio >= 1) {
  252. return;
  253. }
  254. else {
  255. this.enlargeratio /= this.resizeRate;
  256. this.workvwidth = this.sourceimg_w * this.enlargeratio;
  257. this.workvheight = this.sourceimg_h * this.enlargeratio;
  258. this.workviewimg.css({"width":this.workvwidth+"px","height":this.workvheight+"px"});
  259. }
  260. this.DrawClipRegionTosShow();
  261. }
  262. ImgInputFileChanged(e) {
  263. let file = e.target.files[0];
  264. let reader = new FileReader();
  265. reader.readAsDataURL(file);
  266. //读取完成时
  267. reader.onloadend = (e) => {
  268. this.workviewimg.attr('src', e.target.result);
  269.  
  270. this.sourceimg_h = this.workviewimg.height();
  271. this.sourceimg_w = this.workviewimg.width();
  272.  
  273. this.showToSouceHeightRatio=this.showvheight/this.sourceimg_h;
  274. this.showToSourceWidthRatio=this.showvwidth/this.sourceimg_w;
  275.  
  276. //右侧展示区域,展示当前工作区处于图片的区域
  277. //按照短边的比例对图片进行缩放
  278. if (this.showToSouceHeightRatio<this.showToSourceWidthRatio)
  279. {
  280. this.showvimgheight=this.showvheight;
  281. this.showvimgwidth=this.showToSouceHeightRatio*this.sourceimg_w;
  282. }
  283. else
  284. {
  285. this.showvimgheight=this.sourceimg_h*this.showToSourceWidthRatio;
  286. this.showvimgwidth=this.showvwidth;
  287. }
  288. this.showviewimg.attr('src',this.workviewimg.attr('src')).css({"width":this.showvimgwidth+"px","height":this.showvimgheight+"px"});
  289.  
  290. this.DrawClipRegionTosShow();
  291. }
  292.  
  293. }
  294. }
  295.  
  296. $(function () {
  297. let clip = new ClipTools();
  298. clip.Init();
  299. })

还有个文件保存的功能,由于裁剪之后,展示区域的图片路径是base64,所以可以直接发送给服务器,或者用于本地图直接展示

有问题,希望指正,本人刚接触前端不久,谢谢!

html+jquery实现简单图片裁剪的更多相关文章

  1. struts2+jsp+jquery+Jcrop实现图片裁剪并上传

    <1> 使用html标签上传需要裁剪的大图. <2> 在页面呈现大图,使用Jcrop(Jquery)对大图进行裁剪,并且可以进行预览. <3> 选择好截取部分之后发 ...

  2. Jquery实现简单图片轮播

    html代码: <div class="show"> <div class="left"> <div class="sh ...

  3. Cropper – 简单的 jQuery 图片裁剪插件

    Cropper 是一个简单的 jQuery 图像裁剪插件.它支持选项,方法,事件,触摸(移动),缩放,旋转.输出的裁剪数据基于原始图像大小,这样你就可以用它们来直接裁剪图像. 如果你尝试裁剪跨域图像, ...

  4. 【jQuery插件分享】Cropper——一个简单方便的图片裁剪插件

    原文:https://segmentfault.com/a/1190000012344970 插件介绍 这是一个我在写以前的项目的途中发现的一个国人写的jQuery图像裁剪插件,当时想实现用户资料的头 ...

  5. Croppic – 免费开源的 jQuery 图片裁剪插件

    Croppic 这款开源的 jQuery 图片裁剪插件能够满足网站开发人员各种不同的使用需要.只需要简单的上传图片,就可以实现你想要的图像缩放和裁剪功能.因为使用了 HTML5 FormData  对 ...

  6. jQuery 图片裁剪插件 Jcrop

    Jcrop是一个jQuery图片裁剪插件,它能为你的WEB应用程序快速简单地提供图片裁剪的功能.特点如下: 对所有图片均unobtrusively(无侵入的,保持DOM简洁) 支持宽高比例锁定 支持 ...

  7. jquery实现简单瀑布流布局(续):图片懒加载

    # jquery实现简单瀑布流布局(续):图片懒加载 这篇文章是jquery实现简单瀑布流布局思想的小小扩展.代码基于前作的代码继续完善. 图片懒加载就是符合某些条件时才触发图片的加载.最常见的具体表 ...

  8. Jquery插件-Html5图片上传并裁剪

    /** * 图片裁剪 * @author yanglizhe * 2015/11/16 */ (function($){ /** * Drag */ var Drag={obj:null,init:f ...

  9. 移动端 H5图片裁剪插件,内置简单手势操作

    前面曾经写过一篇<H5图片裁剪升级版>,但里面需要借助第三方手势库,这次就不需要使用手势库,全部封装在代码中. 下图是裁剪的展示,下面就做了拖放和裁剪,没有做缩放,在插件中需要用到大量的计 ...

随机推荐

  1. [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: 找出数组中最大的数 ...

  2. angular2学习笔记3

    一.项目搭建 二.生成首页的4个tab页面 三.运行部署及配置

  3. Redhat 6.3上安装OpenSSL

    需求是:在Redhat 6.3上安装OpenSSL 1.1.0b. 一开始试图去搜索rpm,没有对应版本.https://pkgs.org/http://rpmfind.net/放弃! 只能通过编译源 ...

  4. Python3自定义日志类教程

    一.说明 Python3的logging功能是比较丰富的支持不同层次的日志输出,但或是我们想在日志前输出时间.或是我们想要将日志输入到文件,我们还是想要自定义日志类. 之前自己也尝试写过但感觉文档太乱 ...

  5. SQL语句实现行转列

    最近在维护一个项目,出现了一下bug需要进行调试,于是把正式库上面的代码搬到本地库上面,数据库是本地的,跑项目的时候调试发现代码里面带有wmsys.wm_concat函数的SQL语句出现错误,经排查发 ...

  6. javascript 中的number

    大家都知道javascript中有五种简单数据类型,number,string,boolean,null,undefined,复杂数据类型是object.本文主要记录下number类型的一些可能不太常 ...

  7. 构建web应用之——SpringMVC实现CRUD

    配置好SpringMVC最基本的配置后,开始实现处理数据的CRUD(CREATE, READ, UPDATE, DELETE) 为实现模块上的松耦合,我们将与数据库的交互任务交给DAO(Data Ac ...

  8. 免费代理ip爬虫分享

    分享一个某代理网站的免费代理ip的爬虫,直接复制到pycharm运行就可以了. 注意:爬取的代理ip有点坑,因为是免费的所以过期时间很快,可能1分钟后就会失效.并且在scrapy使用这些代理ip还会给 ...

  9. 在Ubuntu14.04上配置jdk环境

    服务器环境:Ubuntu14.04 server 1.进入oracle官网下载jdk1.7.0_71_x64.gz  重命名为jdk1.7 2.使用tar -xvf  jdk1.7.0_71_x64. ...

  10. CSS3动画与JS动画的优缺点?

    JS动画: 缺点:1.JS在浏览器的主线程中运行,而主线程还有其他的js脚本,样式布局,绘制任务等,对其干扰可能导致线程出现阻塞,从而造成丢帧的情况. 2.JS动画代码复杂度高于CSS3动画. 优点: ...