切图js
首先引用一段关于拖动,缩放,剪切的基础代码
/*
* 作者: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();用途不明,待查。
缩放中防止冒泡用户不明。
切图js的更多相关文章
- php网页切图/js切图
PhantomJS抓取网站页面信息以及网站截图 http://phantomjs.org/download.html PHP imagegrabscreen和imagegrabwindow(截取网站缩 ...
- vue基于video.js实现视频播放暂停---切图网
切图网是最早致力于PSD2HTML切图等web前端外包服务的,随着前端技术的更新迭代,现在也已经全面投入了vue的浪潮了,下面是vue中实现视频播放的方法. vue.js中引入video视频播放器 m ...
- 在vue中继续使用layer.js来做弹出层---切图网
layer.js是一个方便的弹出层插件,切图网专注于PSD2HTML等前端切图多年,后转向Vue开发.在vue开发过程中引入layer.js的时候遇到了麻烦.原因是layer.js不支持import导 ...
- [开发笔记]-页面切图、CSS前端设计、JS
这两天在学习页面的切图,样式设计,把学习过程中注意的地方记录下来. 一. input输入框点击时去掉外边框 一般在IE,firefox下,设置 border:0 none; 即可.但在chrome下, ...
- 前端开发工程师必备JS技能-切图
/******************************************** 学习时间:2015年12月21日 学习者:易天曦 学习目的:掌握切图技巧 学习目标:1.学会从网页设计师的P ...
- 移动端rem切图
1.为什么用rem 根据屏幕大小,自动调整大小 2.如何使用rem 分以下几步 a.用ps把设置稿弄成640px或者750px的(记得等比例缩放) b.调试时记得把浏览器默认最小字体设置为最小.手机端 ...
- ArcGIS Server 缓存服务切图范围
win10 + Server 10.4 + ArcMap 10.4 ArcGIS Server 缓存服务分为创建服务后手动建立缓存和创建服务时同时自动建立缓存两种. 10.2帮助文档:http:/ ...
- ArcGIS Server建立缓存(切图)原理解析[图解] (转载)
GoogleMap ,VirtualEarth ,YahooMap 等,目前所有的WebGIS都使用了缓存机制 以提高地图访问速度.原理都是将地图设定为多个比例尺,对于每个比例尺提前将地图分成若干小图 ...
- ArcGIS Server的切图原理深入(转载)
http://forum.osgearth.org/template/NamlServlet.jtp?macro=search_page&node=2174485&query=arcg ...
随机推荐
- BZOJ1342 [Baltic2007]Sound静音问题
越来越水了... 这道题是简单的单调队列,同时维护最大值和最小值即可. 另解:multiset大法求区间最大最小,但是复杂度会上升... /****************************** ...
- git HEAD游离状态问题解决
最近在迭代一个版本的时候,出现 HEAD detached at xxx 提示,应该是我切换分支的时候,哪里没弄对. 那么可以通过如下办法解决 git checkout 05 # 先checkou ...
- Python Django 前后端数据交互 之 前端向后端发送数据
Python Django 之 前端向后端发送数据
- vue 表格导出excel
首先要install两个依赖, 1 npm install -S file-saver xlsx 2 npm install -D script-loader 在项目src目录下新建一个文件夹ven ...
- Django(四)模板文件中的循环
编辑views.py from django.shortcuts import render from django.shortcuts import HttpResponse #此行增加 # Cre ...
- 《Python》 面向对象三大特性之继承
一.继承大纲: 继承和抽象(两个概念) 1.单继承: 语法: 父类.基类.超类 子类.派生类 继承与重用:子类可以使用父类中的名字(变量和方法) 继承与派生:子类在父类的基础上又新创建了自己需要的方法 ...
- Spring学习笔记之各个包的作用
(1) spring-core.jar 这个jar文件包含Spring框架基本的核心工具类,Spring其它组件要都要使用到这个包里的类,是其它组件的基本核心,当然你也可以在自己的应用系统中使用这些工 ...
- Linux:man命令显示颜色
man命令显示颜色 在.bashrc下添加 export LESS_TERMCAP_mb=$'\E[01;31m' export LESS_TERMCAP_md=$'\E[01;31m' export ...
- putc,fputc,和putchar
putc()功能和fputc()差不多,一个是宏,一个是函数 putc(int ch,FILE *fp),即将字符ch输出到fp所指的文件中:putchar(char ch),即将字符ch输出到标准输 ...
- 蓝桥杯 ALGO-1:区间k大数查询
算法训练 区间k大数查询 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个 ...