切图js

首先引用一段关于拖动,缩放,剪切的基础代码

 1 /*
 2 *    作者:http://cloudgamer.cnblogs.com/
 3 *
 4 *    改进与增强
 5 *    作者:http://yoker.sc0826.com/
 6 *    时间:2008年11月09日
 7 *    功能:远程web图片在线裁剪,图片预加载比例缩放,裁剪参数个性设置,裁剪比例缩放等。
 8 */
 9 
10 /* -------------这里定义一些环境变量--------------- */
11 
12 //获取dom对象的方法
13 var $ = function(id) {
14     return "string" == typeof id ? document.getElementById(id) : id;
15 };
16 //判断是否ie
17 var isIE = (document.all) ? true : false;
18 //添加事件
19 function addEventHandler(oTarget, sEventType, fnHandler) {
20     if (oTarget.addEventListener) {
21         oTarget.addEventListener(sEventType, fnHandler, false);
22     } else if (oTarget.attachEvent) {
23         oTarget.attachEvent("on" + sEventType, fnHandler);
24     } else {
25         oTarget["on" + sEventType] = fnHandler;
26     }
27 };
28 //移除事件
29 function removeEventHandler(oTarget, sEventType, fnHandler) {
30     if (oTarget.removeEventListener) {
31         oTarget.removeEventListener(sEventType, fnHandler, false);
32     } else if (oTarget.detachEvent) {
33         oTarget.detachEvent("on" + sEventType, fnHandler);
34     } else {
35         oTarget["on" + sEventType] = null;
36     }
37 };
38 //这相当于一个类工厂。
39 //js中函数即是类,new function()就是用该函数作为构造函数生成一个对象
40 //当然,默认的该对象需自定义一个initialize方法
41 var Class = {
42     create: function() {
43         return function() {
44             this.initialize.apply(this, arguments);
45         }
46     }
47 }
48 
49 //这是对象拷贝函数
50 Object.extend = function(destination, source) {
51     for (var property in source) {
52         destination[property] = source[property];
53     }
54     return destination;
55 }
环境变量

这里定义了几个环境变量,包括挂载/卸载事件方法,根据id获取dom对象方法。比较有意思的是

var Class = {
create: function() {
return function() {
this.initialize.apply(this, arguments);
}
}
}

的写法。网上说prototype.js是这么写的。

看起来这样写实现了某种标准化,比如能产生一批受约束的类,这些类看起来是从某个抽象类中继承而来,然后更方便的用propertype定义方法。

整个编程看起来更加面向对象而不是面向函数。

除此之外没什么好处。

js的prototype相当于c#的直接初始化字段,function相当于在构造函数中初始化字段,无形中都生成对象。js中的this应是某个对象,

 1 //拖放程序
 2 var Drag = Class.create();
 3 Drag.prototype = {
 4     //拖放对象,触发对象
 5     initialize: function(obj, drag, options) {
 6         var oThis = this;
 7 
 8         this._obj = $(obj); //拖放对象
 9         this.Drag = $(drag); //触发对象
10         this._x = this._y = 0; //记录鼠标相对拖放对象的位置
11         //事件对象(用于移除事件)
12         this._fM = function(e) { oThis.Move(window.event || e); }
13         this._fS = function() { oThis.Stop(); }
14 
15         this.SetOptions(options);
16 
17         this.Limit = !!this.options.Limit;
18         this.mxLeft = parseInt(this.options.mxLeft);
19         this.mxRight = parseInt(this.options.mxRight);
20         this.mxTop = parseInt(this.options.mxTop);
21         this.mxBottom = parseInt(this.options.mxBottom);
22 
23         this.onMove = this.options.onMove;
24 
25         this._obj.style.position = "absolute";
26         addEventHandler(this.Drag, "mousedown", function(e) { oThis.Start(window.event || e); });
27     },
28     //设置默认属性
29     SetOptions: function(options) {
30         this.options = {//默认值
31             Limit: false, //是否设置限制(为true时下面参数有用,可以是负数)
32             mxLeft: 0, //左边限制
33             mxRight: 0, //右边限制
34             mxTop: 0, //上边限制
35             mxBottom: 0, //下边限制
36             onMove: function() { } //移动时执行
37         };
38         Object.extend(this.options, options || {});
39     },
40     //准备拖动
41     Start: function(oEvent) {
42         //记录鼠标相对拖放对象的位置
43         this._x = oEvent.clientX - this._obj.offsetLeft;
44         this._y = oEvent.clientY - this._obj.offsetTop;
45         //mousemove时移动 mouseup时停止
46         addEventHandler(document, "mousemove", this._fM);
47         addEventHandler(document, "mouseup", this._fS);
48         //使鼠标移到窗口外也能释放
49         if (isIE) {
50             addEventHandler(this.Drag, "losecapture", this._fS);
51             this.Drag.setCapture();
52         } else {
53             addEventHandler(window, "blur", this._fS);
54         }
55     },
56     //拖动
57     Move: function(oEvent) {
58         //清除选择(ie设置捕获后默认带这个)
59         window.getSelection && window.getSelection().removeAllRanges();
60         //当前鼠标位置减去相对拖放对象的位置得到offset位置
61         var iLeft = oEvent.clientX - this._x, iTop = oEvent.clientY - this._y;
62         //设置范围限制
63         if (this.Limit) {
64             //获取超出长度
65             var iRight = iLeft + this._obj.offsetWidth - this.mxRight, iBottom = iTop + this._obj.offsetHeight - this.mxBottom;
66             //这里是先设置右边下边再设置左边上边,可能会不准确
67             if (iRight > 0) iLeft -= iRight;
68             if (iBottom > 0) iTop -= iBottom;
69             if (this.mxLeft > iLeft) iLeft = this.mxLeft;
70             if (this.mxTop > iTop) iTop = this.mxTop;
71         }
72         //设置位置
73         this._obj.style.left = iLeft + "px";
74         this._obj.style.top = iTop + "px";
75         //附加程序
76         this.onMove();
77     },
78     //停止拖动
79     Stop: function() {
80         //移除事件
81         removeEventHandler(document, "mousemove", this._fM);
82         removeEventHandler(document, "mouseup", this._fS);
83         if (isIE) {
84             removeEventHandler(this.Drag, "losecapture", this._fS);
85             this.Drag.releaseCapture();
86         } else {
87             removeEventHandler(window, "blur", this._fS);
88         }
89     }
90 };
拖放类

拖放类的基本思路是给一个参照的dom对象,一个移动的dom对象,捕捉鼠标相对参照对象的变化,赋值给移动对象。

另外两个功能,其一允许用户自定义onmove,把移动中x,y值传出去,其二给移动对象定义mouseclik确保鼠标按下时记录相关参数,做好拖放准备。

总之是拖放功能的总管秘书。

缩放类

 与拖放类思路基本相同。

document.defaultView.getComputedStyle用于获取所有dom元素的style对象。

  1 //图片切割
  2 var ImgCropper = Class.create();
  3 ImgCropper.prototype = {
  4     //容器对象,拖放缩放对象,图片地址,宽度,高度
  5     initialize: function(container, drag, url, width, height, options) {
  6         var oThis = this;
  7 
  8         //容器对象
  9         this.Container = $(container);
 10         this.Container.style.position = "relative";
 11         this.Container.style.overflow = "hidden";
 12 
 13 
 14         //拖放对象
 15         this.Drag = $(drag);
 16         this.Drag.style.cursor = "move";
 17         this.Drag.style.zIndex = 200;
 18         if (isIE) {
 19             //设置overflow解决ie6的渲染问题(缩放时填充对象高度的问题)
 20             this.Drag.style.overflow = "hidden";
 21             //ie下用一个透明的层填充拖放对象 不填充的话onmousedown会失效(未知原因)
 22             (function(style) {
 23                 style.width = style.height = "100%";
 24                 style.backgroundColor = "#fff";
 25                 style.opacity = 0;
 26                 style.filter = 'alpha(opacity = 0)';
 27             })(this.Drag.appendChild(document.createElement("div")).style)
 28         }
 29 
 30         this._cropper = this.Container.appendChild(document.createElement("img")); //切割对象
 31         this._pic = this.Container.appendChild(document.createElement("img")); //图片对象
 32         this._pic.style.position = "absolute";
 33         this._cropper.style.position = "absolute";
 34         this._pic.style.top = this._pic.style.left = this._cropper.style.top = this._cropper.style.left = "0"; //对齐
 35         this._pic.style.zIndex = 100;
 36         this._cropper.style.zIndex = 150;
 37         this._cropper.onload = function() { oThis.SetPos(); }
 38 
 39 
 40 
 41         this.Url = url; //图片地址
 42         this.Width = parseInt(width); //宽度
 43         this.Height = parseInt(height); //高度
 44 
 45         this.SetOptions(options);
 46 
 47         this.Opacity = parseInt(this.options.Opacity);
 48         this.dragTop = parseInt(this.options.dragTop);
 49         this.dragLeft = parseInt(this.options.dragLeft);
 50         this.dragWidth = parseInt(this.options.dragWidth);
 51         this.dragHeight = parseInt(this.options.dragHeight);
 52 
 53         //设置预览对象
 54         this.View = $(this.options.View) || null; //预览对象
 55         this.viewWidth = parseInt(this.options.viewWidth);
 56         this.viewHeight = parseInt(this.options.viewHeight);
 57         this._view = null; //预览图片对象
 58         if (this.View) {
 59             this.View.style.position = "relative";
 60             this.View.style.overflow = "hidden";
 61             this._view = this.View.appendChild(document.createElement("img"));
 62             this._view.style.position = "absolute";
 63         }
 64 
 65         this.Scale = parseInt(this.options.Scale);
 66 
 67         //设置拖放
 68         this._drag = new Drag(this.Drag, this.Drag, { Limit: true, onMove: function() { oThis.SetPos(); } });
 69         //设置缩放
 70         this._resize = this.GetResize();
 71         this.Init();
 72     },
 73     //设置默认属性
 74     SetOptions: function(options) {
 75         this.options = {//默认值
 76             Opacity: 50, //透明度(0到100)    
 77             //拖放位置和宽高
 78             dragTop: 0,
 79             dragLeft: 0,
 80             dragWidth: 100,
 81             dragHeight: 100,
 82             //缩放触发对象
 83             Right: "",
 84             Left: "",
 85             Up: "",
 86             Down: "",
 87             RightDown: "",
 88             LeftDown: "",
 89             RightUp: "",
 90             LeftUp: "",
 91             Scale: false, //是否按比例缩放
 92             //预览对象设置
 93             View: "", //预览对象
 94             viewWidth: 100, //预览宽度
 95             viewHeight: 100//预览高度
 96         };
 97         Object.extend(this.options, options || {});
 98     },
 99     //初始化对象
100     Init: function() {
101         var oThis = this;
102 
103         //设置拖放对象
104         this.Drag.style.top = this.dragTop + "px";
105         this.Drag.style.left = this.dragLeft + "px";
106         this.Drag.style.width = this.dragWidth + "px";
107         this.Drag.style.height = this.dragHeight + "px";
108 
109         //Yoker.Wu前台缩放效果改善,图片加载完成后,得到缩放大小再初始化显示
110         var trueImg = new Image();
111         trueImg.src = this.Url;
112         //图片已经加载并缓存
113         if (trueImg.complete) {
114             if (trueImg.width > oThis.Width || trueImg.height > oThis.Height) {
115                 if (this.Width / this.Height > trueImg.width / trueImg.height) {
116                     this.Width = parseInt(trueImg.width * this.Height / trueImg.height);
117                 } else {
118                     this.Height = parseInt(trueImg.height * this.Width / trueImg.width);
119                 }
120             } else {
121                 this.Width = trueImg.width;
122                 this.Height = trueImg.height;
123             }
124 
125             //设置容器
126             this.Container.style.width = this.Width + "px";
127             this.Container.style.height = this.Height + "px";
128 
129             //设置切割对象
130             this._cropper.src = this.Url;
131             this._pic.src = this.Url;
132             this._pic.style.width = this._cropper.style.width = this.Width + "px";
133             this._pic.style.height = this._cropper.style.height = this.Height + "px";
134             if (isIE) {
135                 if (navigator.appVersion.indexOf("MSIE 6.0") != -1
136                 || navigator.appVersion.indexOf("MSIE 7.0") != -1
137                 || navigator.appVersion.indexOf("MSIE 8.0") != -1) {
138                     this._pic.style.filter = "alpha(opacity:" + this.Opacity + ")";
139                 }
140                 else if (navigator.appVersion.indexOf("MSIE 9.0") != -1) {
141                     this._pic.style.filter = "alpha(opacity:" + this.Opacity + ")";
142                     this._pic.style.opacity = this.Opacity / 100;
143                 }
144                 else {
145                     this._pic.style.opacity = this.Opacity / 100;
146                 }
147             } else {
148                 this._pic.style.opacity = this.Opacity / 100;
149             }
150             this._cropper.style.filter = "alpha(opacity:100)";
151             this._cropper.style.opacity = 1;
152             //设置预览对象
153             if (this.View) { this._view.src = this.Url; }
154 
155             //设置拖放
156             this._drag.mxRight = this.Width; this._drag.mxBottom = this.Height;
157             //设置缩放
158             if (this._resize) { this._resize.mxRight = this.Width; this._resize.mxBottom = this.Height; this._resize.Scale = this.Scale; }
159         }
160         //新加载的情况
161         trueImg.onload = function() {
162             if (this.width > oThis.Width || this.height > oThis.Height) {
163                 if (oThis.Width / oThis.Height > this.width / this.height) {
164                     oThis.Width = parseInt(this.width * oThis.Height / this.height);
165                 } else {
166                     oThis.Height = parseInt(this.height * oThis.Width / this.width);
167                 }
168             } else {
169                 oThis.Width = this.width;
170                 oThis.Height = this.height;
171             }
172             //设置容器
173             oThis.Container.style.width = oThis.Width + "px";
174             oThis.Container.style.height = oThis.Height + "px";
175 
176             //设置切割对象
177             oThis._cropper.src = oThis.Url;
178             oThis._pic.src = oThis.Url;
179             oThis._pic.style.width = oThis._cropper.style.width = oThis.Width + "px";
180             oThis._pic.style.height = oThis._cropper.style.height = oThis.Height + "px";
181             if (isIE) {
182                 if (navigator.appVersion.indexOf("MSIE 6.0") != -1
183                 || navigator.appVersion.indexOf("MSIE 7.0") != -1
184                 || navigator.appVersion.indexOf("MSIE 8.0") != -1) {
185                     oThis._pic.style.filter = "alpha(opacity:" + oThis.Opacity + ")";
186                 }
187                 else if (navigator.appVersion.indexOf("MSIE 9.0") != -1) {
188                     oThis._pic.style.filter = "alpha(opacity:" + oThis.Opacity + ")";
189                     oThis._pic.style.opacity = oThis.Opacity / 100;
190                 }
191                 else {
192                     oThis._pic.style.opacity = oThis.Opacity / 100;
193                 }
194             } else {
195                 oThis._pic.style.opacity = oThis.Opacity / 100;
196             }
197             oThis._cropper.style.filter = "alpha(opacity:100)";
198             oThis._cropper.style.opacity = 1;
199 
200             //设置预览对象
201             if (oThis.View) { oThis._view.src = oThis.Url; }
202 
203             //设置拖放
204             oThis._drag.mxRight = oThis.Width; oThis._drag.mxBottom = oThis.Height;
205             //设置缩放
206             if (oThis._resize) { oThis._resize.mxRight = oThis.Width; oThis._resize.mxBottom = oThis.Height; oThis._resize.Scale = oThis.Scale; }
207         }
208     },
209     //设置获取缩放对象
210     GetResize: function() {
211         var op = this.options;
212         //有触发对象时才设置
213         if (op.RightDown || op.LeftDown || op.RightUp || op.LeftUp || op.Right || op.Left || op.Up || op.Down) {
214             var oThis = this, _resize = new Resize(this.Drag, { Limit: true, onResize: function() { oThis.SetPos(); } });
215 
216             //设置缩放触发对象
217             if (op.RightDown) { _resize.Set(op.RightDown, "right-down"); }
218             if (op.LeftDown) { _resize.Set(op.LeftDown, "left-down"); }
219 
220             if (op.RightUp) { _resize.Set(op.RightUp, "right-up"); }
221             if (op.LeftUp) { _resize.Set(op.LeftUp, "left-up"); }
222 
223             if (op.Right) { _resize.Set(op.Right, "right"); }
224             if (op.Left) { _resize.Set(op.Left, "left"); }
225 
226             if (op.Up) { _resize.Set(op.Up, "up"); }
227             if (op.Down) { _resize.Set(op.Down, "down"); }
228 
229             return _resize;
230         } else { return null; }
231     },
232     //设置切割
233     SetPos: function() {
234         var o = this.Drag;
235         //按拖放对象的参数进行切割
236         this._cropper.style.clip = "rect(" + o.offsetTop + "px " + (o.offsetLeft + o.offsetWidth) + "px " + (o.offsetTop + o.offsetHeight) + "px " + o.offsetLeft + "px)";
237         
238         //切割预览
239         if (this.View) this.PreView();
240     },
241     //切割预览
242     PreView: function() {
243         //按比例设置宽度和高度
244         var o = this.Drag, h = this.viewWidth, w = h * o.offsetWidth / o.offsetHeight;
245         if (w > this.viewHeight) { w = this.viewHeight; h = w * o.offsetHeight / o.offsetWidth; }
246         //获取对应比例尺寸
247         var scale = h / o.offsetHeight, ph = this.Height * scale, pw = this.Width * scale, pt = o.offsetTop * scale, pl = o.offsetLeft * scale, styleView = this._view.style;
248         //设置样式
249         styleView.width = pw + "px"; styleView.height = ph + "px";
250         styleView.top = -pt + "px "; styleView.left = -pl + "px";
251         //切割预览图
252         styleView.clip = "rect(" + pt + "px " + (pl + w) + "px " + (pt + h) + "px " + pl + "px)";
253     }
254 }
切割类

拖放中 window.getSelection && window.getSelection().removeAllRanges();用途不明,待查。

缩放中防止冒泡用户不明。

原文地址:https://www.cnblogs.com/baozhu/p/3870468.html