首页 > 代码库 > 切图js
切图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 //判断是否ie17 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 = http://www.mamicode.com/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 = http://www.mamicode.com/this.Url;131 this._pic.src = http://www.mamicode.com/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") != -1136 || navigator.appVersion.indexOf("MSIE 7.0") != -1137 || 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 = http://www.mamicode.com/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 =http://www.mamicode.com/ oThis.Url;178 oThis._pic.src =http://www.mamicode.com/ 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") != -1183 || navigator.appVersion.indexOf("MSIE 7.0") != -1184 || 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 =http://www.mamicode.com/ 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();用途不明,待查。
缩放中防止冒泡用户不明。
切图js