由于之前公司项目的原因,我被要求完成一个头像上传功能,其中包括要实现上传图片的旋转,缩放和拖拽,更关键的是要用JS实现...

作为一个不大喜欢用JS的人来说这是一个很严峻的挑战,不过随着项目的进行我的这个功能模块也算是完成(人都是被逼出来的)最终的版本能够支持IE,谷歌,火狐浏览器(兼容多浏览器不容易啊)

下面仅提供核心思想和部分代码:

 拖拽:是使用网上现成的JS代码,在此基础上进行适当的修改即可满足自己的需求,最主要的就是判定拖拽的范围,上传的图片不能给拖没了,所以加上个范围限定,判断超出了这个范围便拖拽无效果。

旋转与缩放要区分浏览器..

旋转:IE浏览器下想要实现图片的旋转很简单只要调用IE提供的滤镜filter参数为一个旋转矩阵即可.谷歌和火狐浏览器图片显示用的是canvas标签而不是img标签所以图片的旋转需要用canvas标签相关的一些方法来实现(跟html5类似或者说就是html5,本人才疏学浅理解不透),并且旋转相关的数据需要自己进行数学计算。

缩放: IE下要实现图片的缩放很简单只要把img标签对应的width与length值增大或者缩小就可以,但是火狐和谷歌下的canvas标签是一个完全不同的处理方式。这是比较纠结的...详细可以看看代码.

效果图如下:

本身这个功能是在一个大项目中由于机密不能在大项目中展示运行,我后来自己简单的建了一个小项目单独的运行这个功能。

部分代码如下:

/*** 图片旋转方法* @param id 被旋转的图片* @param angle 旋转的角度* @param whence (此参数不传的话 旋转的角度会默认累加)*/
function rotate(id,angle,whence) {  var p = document.getElementById(id);  // we store the angle inside the image tag for persistence  if (!whence) {  p.angle = ((p.angle==undefined?0:p.angle) + angle) % 360;  //whence (此参数不传的话 旋转的角度会默认累加)} else {  p.angle = angle;  }  if (p.angle >= 0) {  var rotation = Math.PI * p.angle / 180;  } else {  var rotation = Math.PI * (360+p.angle) / 180;  }  var costheta = Math.cos(rotation);  var sintheta = Math.sin(rotation);  //数学知识....if (document.all && !window.opera) {//IE下 用img标签  var canvas = document.createElement('img');   canvas.src = p.src;  //将之前图片的src,height,width值赋予canvascanvas.height = p.height;  canvas.width = p.width; //用IE的滤镜(用了矩阵知识)实现图片的旋转展示canvas.style.filter = "progid:DXImageTransform.Microsoft.Matrix(M11="+costheta+",M12="+(-sintheta)+",M21="+sintheta+",M22="+costheta+",SizingMethod='auto expand')";                 } else {  //火狐谷歌浏览器下用canvas标签var canvas = document.createElement('canvas');  if (!p.oImage) {  //新建canvas标签的oImage对象 用来存储图片信息canvas.oImage = new Image();  canvas.oImage.src = p.src; canvas.oImage.height = p.height;  canvas.oImage.width = p.width;} else {  canvas.oImage = p.oImage;  }  //计算旋转之后的canvas标签的长和宽(不是图片的长和宽) 旋转之后oImage的height与width值不变canvas.style.width = canvas.width = Math.abs(costheta*canvas.oImage.width) + Math.abs(sintheta*canvas.oImage.height);  //数学知识...canvas.style.height = canvas.height = Math.abs(costheta*canvas.oImage.height) + Math.abs(sintheta*canvas.oImage.width);  //调用一些底层方法进行旋转并展示旋转之后的图片var context = canvas.getContext('2d');  context.save();  if (rotation <= Math.PI/2) {  context.translate(sintheta*canvas.oImage.height,0);  } else if (rotation <= Math.PI) {  context.translate(canvas.width,-costheta*canvas.oImage.height);  } else if (rotation <= 1.5*Math.PI) {  context.translate(-costheta*canvas.oImage.width,canvas.height);  } else {  context.translate(0,-sintheta*canvas.oImage.width);  }  context.rotate(rotation);  context.drawImage(canvas.oImage, 0, 0, canvas.oImage.width, canvas.oImage.height);  //将旋转之后的oImage对象绘制出来context.restore(); }  canvas.id = p.id;  canvas.angle = p.angle;  p.parentNode.replaceChild(canvas, p);  //将新的canvas 标签 替换之前的标签 从而可以展示旋转之后的图片//设置canvas元素的top值与left值     (图片旋转之后top值与left值都发生了变化 现在是要满足图片绕自己的中心的进行旋转,所以旋转之后要进行top与left值的设定)canvas.style.top =(y_center-(canvas.offsetHeight)/2)+"px";//注意加上"px"canvas.style.left = x_center-canvas.offsetWidth/2+"px";var imgpos = getStylepos(canvas);//与ImageCopper.js的里面的checkcutpos一样的效果max_x = Math.max(offsetx, offsetx + cutx - canvas.offsetWidth);min_x = Math.min(offsetx + cutx - canvas.offsetWidth, offsetx);if (imgpos.x > max_x)canvas.style.left = max_x + 'px';else if (imgpos.x < min_x)canvas.style.left = min_x + 'px';max_y = Math.max(offsety, offsety + cuty - canvas.offsetHeight);min_y = Math.min(offsety + cuty - canvas.offsetHeight, offsety);if (imgpos.y > max_y)canvas.style.top = max_y + 'px';else if (imgpos.y < min_y)canvas.style.top = min_y + 'px';x_center = Math.round(canvas.offsetWidth/2)+imgpos.x;//top值与left值变化后需要重新计算图片的中心点if(x_center -142<=1 &&x_center -142>=-1){//防止图片在预览区中心点旋转之后 导致中心点发生微小的偏离x_center=142;}     y_center = Math.round(canvas.offsetHeight/2)+imgpos.y;if(y_center +133<=1 && y_center +133>=-1){y_center=-133;}
} 
//图片逐步缩放function imageresize(flag) {//增加浏览器类型判断var userAgent = navigator.userAgent.toLowerCase();  jQuery.browser = {  version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],  safari: /safari/.test( userAgent ),  opera: /opera/.test( userAgent ),  msie: /msie/.test( userAgent ),  firefox: /firefox/.test( userAgent ),chrome: /chrome/.test( userAgent ) }; var rate = 1.08;//此值的设定是为了满足正好放大10次缩小10次这种需求的(需求要求只能放大一倍缩小一倍,为了点击10次正好放大一倍rate就设为了此值)if($.browser.firefox || $.browser.chrome){rate = 1.07;}cut_div = document.getElementById('cut_div');if (flag) {//放大if (zoom > 2*standardzoom) //超过标准比例的2倍的话就不能进行缩放return;zoom = zoom * rate;           } else {//缩小if (zoom < standardzoom/2)return;zoom = zoom / rate;            }if (document.all && !window.opera) {//IE浏览器下cut_img.width = Math.round(imgdefw * zoom); //只需要改变img标签的width和height 就可以实现缩放了cut_img.height = Math.round(imgdefh * zoom);cut_img.style.top =(y_center-(cut_img.offsetHeight)/2)+"px"; //缩放之后 图片的中心不发生变化 top与left值发生相应的变化cut_img.style.left = x_center-cut_img.offsetWidth/2+"px";}else{//火狐谷歌等浏览器
//首先改变canvas.oImage的width与height属性的值if(flag){var image_y=cut_img.oImage.height*rate;var image_x=cut_img.oImage.width*rate;}else{var image_y=cut_img.oImage.height/rate;var image_x=cut_img.oImage.width/rate;}cut_img.oImage.height=image_y;cut_img.oImage.width=image_x;         roTateRight('cut_img',0);//旋转0度以调整canvas的width与height值和left与top的值}checkcutpos();}

一个本来可以用flex实现的功能我用JS实现了......也算是个小成就,大家若想交流的话可以留言我一定奉陪。(其实QQ空间的头像上传功能做得挺好的,效果不错)

这个文章很早就想写了,现在终于把他憋出来也算心里的一块石头放下了吧...

图片的旋转,缩放和拖拽相关推荐

  1. html5 canvas图片缩放,拖拽

    想用html5 canvas来实现地图功能 主要是想把地图功能集合在系统中,而不是使用类似geoserver等发布,相当于两套系统了.地图是室内地图,所以高德百度什么的没用.我的理想情况是丢一副矢量图 ...

  2. flutter实现可缩放可拖拽双击放大的图片功能

    ### flutter_drag_scale ``` 可缩放可拖拽的功能,可实现图片或者其他widget的缩放已经拖拽 并支持双击放大的功能 ``` 我们知道官方提供了双击缩放,但是不支持拖拽的功能, ...

  3. C# Winform 相册功能,图片缩放,拖拽,预览图分页

    效果 1.图片放大,缩小,拖拽功能 2.添加图片,分页功能 一.前言 在一些项目中也会用到预览图片的功能,至于为什么有一个添加图片的按钮,是因为有些项目,比如视觉相关的项目,摄像头拍摄图片,然后显示在 ...

  4. C#实现GDI+基本图的缩放、拖拽、移动

    C#实现GDI+基本图的缩放.拖拽.移动示例代码如下: using System;using System.Collections.Generic;using System.ComponentMode ...

  5. UE4 二维地图的缩放与拖拽操作

    这里写自定义目录标题 UE4 二维地图的缩放与拖拽操作 拖拽和缩放 基础搭建 添加小图标 地图缩放 地图拖拽 实现部分 效果展示 小图标的重合显示 效果展示 UE4 二维地图的缩放与拖拽操作 纯蓝图实 ...

  6. PPT中要实现图片或图形的任意拖拽

    PPT中要实现图片或图形的任意拖拽需要通过VBA编程.现介绍利用图像控件实现图片任意拖拽的方法: 1.在演示文稿插入图像控件,打开属性窗口,将picture设成你想拖动的图片,遗憾的是Image控件不 ...

  7. vue-quill-editor图片大小的编辑,拖拽,上传视频

    vue-quill-editor图片大小的编辑,拖拽,上传视频 在vue组件中注册和使用 <quill-editor v-model="formInline.viewConfig&qu ...

  8. 图片的缩放和拖拽功能

    缩放:监听滚轮的滚动滑动事件,然后改变图片的zomm属性 拖拽 : 获取鼠标单击后,X.Y挪动的像素,  图片使用定位,更改left和top的值 <template><div sty ...

  9. canvas+vue实现图片的缩放、拖拽

    最近做项目遇到一个需求,对图片进行拖动+缩放,本来这个功能直接采用viewerjs这个插件就可以实现的. 但是我们还有其他需求啊,在底层图片上添加一些图片或者文字注释,并且随着底层图片的拖动和缩放后, ...

最新文章

  1. 未能加载文件或程序集“Report.Basic”或它的某一个依赖项。试图加载格式不正确的程序...
  2. [召集] .NET Framework基本类库中的设计模式
  3. 如何理解遗传算法中的编码与解码?以二进制编码为例
  4. gunicorn 几种 worker class 性能测试比较
  5. 信息学奥赛一本通(1217:棋盘问题)
  6. 网页看视频计算机休眠,晚上挂着下电影怎么让电脑不休眠 Win7关闭休眠图文教程...
  7. 在GNS3中如何让NETFLOW能够捕获到流量
  8. android content provider线程安全,Android ContentProvider的线程安全(二)
  9. 华胜天成助力中国银联实现移动互联时代的多渠道扩张
  10. Linux vi 替换字符串
  11. C语言 输出正三角形图形
  12. java项目ppt介绍_Java课设项目介绍及分析.ppt
  13. matlab imfilter与fft,imfilter与fspecial
  14. 怎么改变图片的尺寸?教你在线修改图片尺寸大小
  15. 算法(一)时间复杂度
  16. mq选型:rocketMq和kafka对比
  17. Bandwagon的配置记录(二) —— ftp文件传输
  18. DDos攻击解析(附现状和案例)
  19. 毕设教程:基于嵌入式Linux和Qt实现的视频监控系统(Arm/树莓派/jetson)
  20. break在c语言中的应用,c语言中break的用法

热门文章

  1. Excel技巧—开始菜单之剪切的高级用法
  2. MySQL-V5.7 压缩包版安装教程
  3. 使用word进行图片的有序命名
  4. 组织架构图,比较实用,收走
  5. 你可能不知道的canvas烟花秀
  6. 重启防火墙(iptables)命令#service iptable restart失效
  7. 使用ajax实现页面分页
  8. ipad html阅读器,iPad 超强文档阅读应用(GoodReader)
  9. ESP8266制作物联网万能遥控器
  10. springboot实现支付宝扫码支付