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

 /*
* 作者:http://cloudgamer.cnblogs.com/
*
* 改进与增强
* 作者:http://yoker.sc0826.com/
* 时间:2008年11月09日
* 功能:远程web图片在线裁剪,图片预加载比例缩放,裁剪参数个性设置,裁剪比例缩放等。
*/ /* -------------这里定义一些环境变量--------------- */ //获取dom对象的方法
var $ = function(id) {
return "string" == typeof id ? document.getElementById(id) : id;
};
//判断是否ie
var isIE = (document.all) ? true : false;
//添加事件
function addEventHandler(oTarget, sEventType, fnHandler) {
if (oTarget.addEventListener) {
oTarget.addEventListener(sEventType, fnHandler, false);
} else if (oTarget.attachEvent) {
oTarget.attachEvent("on" + sEventType, fnHandler);
} else {
oTarget["on" + sEventType] = fnHandler;
}
};
//移除事件
function removeEventHandler(oTarget, sEventType, fnHandler) {
if (oTarget.removeEventListener) {
oTarget.removeEventListener(sEventType, fnHandler, false);
} else if (oTarget.detachEvent) {
oTarget.detachEvent("on" + sEventType, fnHandler);
} else {
oTarget["on" + sEventType] = null;
}
};
//这相当于一个类工厂。
//js中函数即是类,new function()就是用该函数作为构造函数生成一个对象
//当然,默认的该对象需自定义一个initialize方法
var Class = {
create: function() {
return function() {
this.initialize.apply(this, arguments);
}
}
} //这是对象拷贝函数
Object.extend = function(destination, source) {
for (var property in source) {
destination[property] = source[property];
}
return destination;
}

环境变量

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

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

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

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

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

除此之外没什么好处。

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

 //拖放程序
var Drag = Class.create();
Drag.prototype = {
//拖放对象,触发对象
initialize: function(obj, drag, options) {
var oThis = this; this._obj = $(obj); //拖放对象
this.Drag = $(drag); //触发对象
this._x = this._y = 0; //记录鼠标相对拖放对象的位置
//事件对象(用于移除事件)
this._fM = function(e) { oThis.Move(window.event || e); }
this._fS = function() { oThis.Stop(); } this.SetOptions(options); this.Limit = !!this.options.Limit;
this.mxLeft = parseInt(this.options.mxLeft);
this.mxRight = parseInt(this.options.mxRight);
this.mxTop = parseInt(this.options.mxTop);
this.mxBottom = parseInt(this.options.mxBottom); this.onMove = this.options.onMove; this._obj.style.position = "absolute";
addEventHandler(this.Drag, "mousedown", function(e) { oThis.Start(window.event || e); });
},
//设置默认属性
SetOptions: function(options) {
this.options = {//默认值
Limit: false, //是否设置限制(为true时下面参数有用,可以是负数)
mxLeft: 0, //左边限制
mxRight: 0, //右边限制
mxTop: 0, //上边限制
mxBottom: 0, //下边限制
onMove: function() { } //移动时执行
};
Object.extend(this.options, options || {});
},
//准备拖动
Start: function(oEvent) {
//记录鼠标相对拖放对象的位置
this._x = oEvent.clientX - this._obj.offsetLeft;
this._y = oEvent.clientY - this._obj.offsetTop;
//mousemove时移动 mouseup时停止
addEventHandler(document, "mousemove", this._fM);
addEventHandler(document, "mouseup", this._fS);
//使鼠标移到窗口外也能释放
if (isIE) {
addEventHandler(this.Drag, "losecapture", this._fS);
this.Drag.setCapture();
} else {
addEventHandler(window, "blur", this._fS);
}
},
//拖动
Move: function(oEvent) {
//清除选择(ie设置捕获后默认带这个)
window.getSelection && window.getSelection().removeAllRanges();
//当前鼠标位置减去相对拖放对象的位置得到offset位置
var iLeft = oEvent.clientX - this._x, iTop = oEvent.clientY - this._y;
//设置范围限制
if (this.Limit) {
//获取超出长度
var iRight = iLeft + this._obj.offsetWidth - this.mxRight, iBottom = iTop + this._obj.offsetHeight - this.mxBottom;
//这里是先设置右边下边再设置左边上边,可能会不准确
if (iRight > 0) iLeft -= iRight;
if (iBottom > 0) iTop -= iBottom;
if (this.mxLeft > iLeft) iLeft = this.mxLeft;
if (this.mxTop > iTop) iTop = this.mxTop;
}
//设置位置
this._obj.style.left = iLeft + "px";
this._obj.style.top = iTop + "px";
//附加程序
this.onMove();
},
//停止拖动
Stop: function() {
//移除事件
removeEventHandler(document, "mousemove", this._fM);
removeEventHandler(document, "mouseup", this._fS);
if (isIE) {
removeEventHandler(this.Drag, "losecapture", this._fS);
this.Drag.releaseCapture();
} else {
removeEventHandler(window, "blur", this._fS);
}
}
};

拖放类

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

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

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

缩放类

与拖放类思路基本相同。

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

 //图片切割
var ImgCropper = Class.create();
ImgCropper.prototype = {
//容器对象,拖放缩放对象,图片地址,宽度,高度
initialize: function(container, drag, url, width, height, options) {
var oThis = this; //容器对象
this.Container = $(container);
this.Container.style.position = "relative";
this.Container.style.overflow = "hidden"; //拖放对象
this.Drag = $(drag);
this.Drag.style.cursor = "move";
this.Drag.style.zIndex = 200;
if (isIE) {
//设置overflow解决ie6的渲染问题(缩放时填充对象高度的问题)
this.Drag.style.overflow = "hidden";
//ie下用一个透明的层填充拖放对象 不填充的话onmousedown会失效(未知原因)
(function(style) {
style.width = style.height = "100%";
style.backgroundColor = "#fff";
style.opacity = 0;
style.filter = 'alpha(opacity = 0)';
})(this.Drag.appendChild(document.createElement("div")).style)
} this._cropper = this.Container.appendChild(document.createElement("img")); //切割对象
this._pic = this.Container.appendChild(document.createElement("img")); //图片对象
this._pic.style.position = "absolute";
this._cropper.style.position = "absolute";
this._pic.style.top = this._pic.style.left = this._cropper.style.top = this._cropper.style.left = "0"; //对齐
this._pic.style.zIndex = 100;
this._cropper.style.zIndex = 150;
this._cropper.onload = function() { oThis.SetPos(); } this.Url = url; //图片地址
this.Width = parseInt(width); //宽度
this.Height = parseInt(height); //高度 this.SetOptions(options); this.Opacity = parseInt(this.options.Opacity);
this.dragTop = parseInt(this.options.dragTop);
this.dragLeft = parseInt(this.options.dragLeft);
this.dragWidth = parseInt(this.options.dragWidth);
this.dragHeight = parseInt(this.options.dragHeight); //设置预览对象
this.View = $(this.options.View) || null; //预览对象
this.viewWidth = parseInt(this.options.viewWidth);
this.viewHeight = parseInt(this.options.viewHeight);
this._view = null; //预览图片对象
if (this.View) {
this.View.style.position = "relative";
this.View.style.overflow = "hidden";
this._view = this.View.appendChild(document.createElement("img"));
this._view.style.position = "absolute";
} this.Scale = parseInt(this.options.Scale); //设置拖放
this._drag = new Drag(this.Drag, this.Drag, { Limit: true, onMove: function() { oThis.SetPos(); } });
//设置缩放
this._resize = this.GetResize();
this.Init();
},
//设置默认属性
SetOptions: function(options) {
this.options = {//默认值
Opacity: 50, //透明度(0到100)
//拖放位置和宽高
dragTop: 0,
dragLeft: 0,
dragWidth: 100,
dragHeight: 100,
//缩放触发对象
Right: "",
Left: "",
Up: "",
Down: "",
RightDown: "",
LeftDown: "",
RightUp: "",
LeftUp: "",
Scale: false, //是否按比例缩放
//预览对象设置
View: "", //预览对象
viewWidth: 100, //预览宽度
viewHeight: 100//预览高度
};
Object.extend(this.options, options || {});
},
//初始化对象
Init: function() {
var oThis = this; //设置拖放对象
this.Drag.style.top = this.dragTop + "px";
this.Drag.style.left = this.dragLeft + "px";
this.Drag.style.width = this.dragWidth + "px";
this.Drag.style.height = this.dragHeight + "px"; //Yoker.Wu前台缩放效果改善,图片加载完成后,得到缩放大小再初始化显示
var trueImg = new Image();
trueImg.src = this.Url;
//图片已经加载并缓存
if (trueImg.complete) {
if (trueImg.width > oThis.Width || trueImg.height > oThis.Height) {
if (this.Width / this.Height > trueImg.width / trueImg.height) {
this.Width = parseInt(trueImg.width * this.Height / trueImg.height);
} else {
this.Height = parseInt(trueImg.height * this.Width / trueImg.width);
}
} else {
this.Width = trueImg.width;
this.Height = trueImg.height;
} //设置容器
this.Container.style.width = this.Width + "px";
this.Container.style.height = this.Height + "px"; //设置切割对象
this._cropper.src = this.Url;
this._pic.src = this.Url;
this._pic.style.width = this._cropper.style.width = this.Width + "px";
this._pic.style.height = this._cropper.style.height = this.Height + "px";
if (isIE) {
if (navigator.appVersion.indexOf("MSIE 6.0") != -1
|| navigator.appVersion.indexOf("MSIE 7.0") != -1
|| navigator.appVersion.indexOf("MSIE 8.0") != -1) {
this._pic.style.filter = "alpha(opacity:" + this.Opacity + ")";
}
else if (navigator.appVersion.indexOf("MSIE 9.0") != -1) {
this._pic.style.filter = "alpha(opacity:" + this.Opacity + ")";
this._pic.style.opacity = this.Opacity / 100;
}
else {
this._pic.style.opacity = this.Opacity / 100;
}
} else {
this._pic.style.opacity = this.Opacity / 100;
}
this._cropper.style.filter = "alpha(opacity:100)";
this._cropper.style.opacity = 1;
//设置预览对象
if (this.View) { this._view.src = this.Url; } //设置拖放
this._drag.mxRight = this.Width; this._drag.mxBottom = this.Height;
//设置缩放
if (this._resize) { this._resize.mxRight = this.Width; this._resize.mxBottom = this.Height; this._resize.Scale = this.Scale; }
}
//新加载的情况
trueImg.onload = function() {
if (this.width > oThis.Width || this.height > oThis.Height) {
if (oThis.Width / oThis.Height > this.width / this.height) {
oThis.Width = parseInt(this.width * oThis.Height / this.height);
} else {
oThis.Height = parseInt(this.height * oThis.Width / this.width);
}
} else {
oThis.Width = this.width;
oThis.Height = this.height;
}
//设置容器
oThis.Container.style.width = oThis.Width + "px";
oThis.Container.style.height = oThis.Height + "px"; //设置切割对象
oThis._cropper.src = oThis.Url;
oThis._pic.src = oThis.Url;
oThis._pic.style.width = oThis._cropper.style.width = oThis.Width + "px";
oThis._pic.style.height = oThis._cropper.style.height = oThis.Height + "px";
if (isIE) {
if (navigator.appVersion.indexOf("MSIE 6.0") != -1
|| navigator.appVersion.indexOf("MSIE 7.0") != -1
|| navigator.appVersion.indexOf("MSIE 8.0") != -1) {
oThis._pic.style.filter = "alpha(opacity:" + oThis.Opacity + ")";
}
else if (navigator.appVersion.indexOf("MSIE 9.0") != -1) {
oThis._pic.style.filter = "alpha(opacity:" + oThis.Opacity + ")";
oThis._pic.style.opacity = oThis.Opacity / 100;
}
else {
oThis._pic.style.opacity = oThis.Opacity / 100;
}
} else {
oThis._pic.style.opacity = oThis.Opacity / 100;
}
oThis._cropper.style.filter = "alpha(opacity:100)";
oThis._cropper.style.opacity = 1; //设置预览对象
if (oThis.View) { oThis._view.src = oThis.Url; } //设置拖放
oThis._drag.mxRight = oThis.Width; oThis._drag.mxBottom = oThis.Height;
//设置缩放
if (oThis._resize) { oThis._resize.mxRight = oThis.Width; oThis._resize.mxBottom = oThis.Height; oThis._resize.Scale = oThis.Scale; }
}
},
//设置获取缩放对象
GetResize: function() {
var op = this.options;
//有触发对象时才设置
if (op.RightDown || op.LeftDown || op.RightUp || op.LeftUp || op.Right || op.Left || op.Up || op.Down) {
var oThis = this, _resize = new Resize(this.Drag, { Limit: true, onResize: function() { oThis.SetPos(); } }); //设置缩放触发对象
if (op.RightDown) { _resize.Set(op.RightDown, "right-down"); }
if (op.LeftDown) { _resize.Set(op.LeftDown, "left-down"); } if (op.RightUp) { _resize.Set(op.RightUp, "right-up"); }
if (op.LeftUp) { _resize.Set(op.LeftUp, "left-up"); } if (op.Right) { _resize.Set(op.Right, "right"); }
if (op.Left) { _resize.Set(op.Left, "left"); } if (op.Up) { _resize.Set(op.Up, "up"); }
if (op.Down) { _resize.Set(op.Down, "down"); } return _resize;
} else { return null; }
},
//设置切割
SetPos: function() {
var o = this.Drag;
//按拖放对象的参数进行切割
this._cropper.style.clip = "rect(" + o.offsetTop + "px " + (o.offsetLeft + o.offsetWidth) + "px " + (o.offsetTop + o.offsetHeight) + "px " + o.offsetLeft + "px)"; //切割预览
if (this.View) this.PreView();
},
//切割预览
PreView: function() {
//按比例设置宽度和高度
var o = this.Drag, h = this.viewWidth, w = h * o.offsetWidth / o.offsetHeight;
if (w > this.viewHeight) { w = this.viewHeight; h = w * o.offsetHeight / o.offsetWidth; }
//获取对应比例尺寸
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;
//设置样式
styleView.width = pw + "px"; styleView.height = ph + "px";
styleView.top = -pt + "px "; styleView.left = -pl + "px";
//切割预览图
styleView.clip = "rect(" + pt + "px " + (pl + w) + "px " + (pt + h) + "px " + pl + "px)";
}
}

切割类

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

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

最新文章

  1. IOS系列swift语言之课时三
  2. linux 定时执行scrapy命令
  3. php字符串比较函数
  4. Java 读Properties
  5. mac 下安装nginx
  6. Linux c字符串中不可打印字符转换成16进制
  7. C# - linq查询现有的DataTable
  8. 段落排版--缩进(text-indent)
  9. C#运行时鼠标移动控件 - 调用Windows API(ReleaseCapture)
  10. SpringCloud的服务注册中心(三) - 进一步了解 Eureka
  11. Hibernate原理及应用
  12. JS元素意外点击元素消失
  13. 如何绘制UML图?
  14. Ubuntu 离线安装Mysql
  15. THUWC2018酱油记
  16. 如何在Linux下写无线网卡的驱动【转】
  17. MYSQL时间类别总结: TIMESTAMP、DATETIME、DATE、TIME、YEAR
  18. Jboss EAP 6 EJB调用常见问题
  19. OpenACC 简单的原子操作
  20. 泛型深入--java泛型的继承和实现、泛型擦除

热门文章

  1. Bellman-Ford模板
  2. bzoj2662
  3. swig的语法和用法
  4. 开源项目ScriptGate,Delphi与JavaScript相互调用的神器
  5. vim/vi用法总结
  6. 1.1.3 A+B for Input-Output Practice (III)
  7. matplotlib 操作子图(subplot,axes)
  8. MQTT连接服务器返回2
  9. Java工具创建密钥库,用于Unity 3D打包、签名、发布
  10. 《DSP using MATLAB》Problem 4.13