一、前言:

上一篇随笔中已经把拖动程序完成了,这篇主要把缩放程序完成,后面合并后可以做成一个图片裁剪的功能

简易缩放程序DEMO:http://jsfiddle.net/UN99R/
限制缩放程序DEMO:http://jsfiddle.net/kHWQZ/

二、设计思路:

1、在一个可以缩放元素中,共有8个触发点(上、下、左、右、左上、右上、左下、右下),首先分别设置好它们的CSS属性cursor值。

2、同拖放程序一样,在触发点上绑定鼠标按下事件,在文档(document)上绑定鼠标移动、弹起事件处理程序,在移动事件中,完成拖放元素css的操作,
在鼠标弹起事件中,解绑移动事件处理程序。

主要难点:在于如何处理拖放元素的CSS属性

三、源码实现细节:

在8个触发点的事件处理程序中,diffX, diffY 分别获取的是鼠标在移动与按下过程时指针的差值

var diffX = e.clientX - clientX, // 负数代表向左移动,反之向右
diffY = e.clientY - clientY; // 负数代表想上移动,反之向下

在鼠标按下事件处理中,w, h, l, t 分别记录的是拖放元素的width, height, left, top 属性值,下面讲一下鼠标移动处理程序
举一个示例:

up事件程序代码:

up = function(e){
var diffY = e.clientY - clientY;
$target.css({
height: h - diffY + 'px',
top: t + Math.min(diffY, h) + 'px'
});
e.preventDefault();
};

1、在up事件程序中,拖放元素变动的是height, top属性;

2、如果鼠标向上移动,diffY为负数,而height应增,因此 height = h - diffY, top则相反,top = t + diffY;

3、反之,diffY为正数,而height应减,因此 height = h - diffY, top = t + diffY;

4、为了让top值不为负数,top = t + Math.min(diffY, h);

最后阻止默认浏览器事件,避免鼠标拖动过程中出现禁止icon

处理完up事件后,其他down, left, right事件处理同理,而后 upLeft, upRight, downLeft, downRight 这些事件处理都是在叠加前四个事件处理就行了

主程序代码:

jQuery.fn.extend({
/**
* Autor: 博客园华子yjh 2014/02/26
*/
resize: function(options) {
var controlSelector = '.cursor-north, .cursor-south, .cursor-west, .cursor-east,' +
'.cursor-north-west, .cursor-north-east, .cursor-south-west, .cursor-south-east';
$(this).each(function(){
var
// 上、下、左、右、左上、右上、左下、右下 八个点的鼠标拖动时的事件处理程序
up, down, left, right, upLeft, upRight, downLeft, downRight, // 鼠标拖动时的事件处理程序
handleEvent, // 记录鼠标按下时鼠标的位置
clientX, clientY, // 记录鼠标按下时元素的大小及位置
w, h, l, t, // 目标元素
$target = $(this), self = this; up = function(e){
var diffY = e.clientY - clientY;
$target.css({
height: h - diffY + 'px',
top: t + Math.min(diffY, h) + 'px'
});
e.preventDefault();
};
down = function(e){
var diffY = e.clientY - clientY;
$target.css({
height: h + diffY + 'px'
});
e.preventDefault();
};
left = function(e){
var diffX = e.clientX - clientX;
$target.css({
width: w - diffX + 'px',
left: l + Math.min(diffX, w) + 'px'
});
e.preventDefault();
};
right = function(e){
var diffX = e.clientX - clientX;
$target.css({
width: w + diffX + 'px'
});
e.preventDefault();
};
upLeft = function(e){
var diffX = e.clientX - clientX,
diffY = e.clientY - clientY;
$target.css({
height: h - diffY + 'px',
top: t + Math.min(diffY, h) + 'px',
width: w - diffX + 'px',
left: l + Math.min(diffX, w) + 'px'
});
e.preventDefault();
};
upRight = function(e){
var diffX = e.clientX - clientX,
diffY = e.clientY - clientY;
$target.css({
height: h - diffY + 'px',
top: t + Math.min(diffY, h) + 'px',
width: w + diffX + 'px'
});
e.preventDefault();
};
downLeft = function(e){
var diffX = e.clientX - clientX,
diffY = e.clientY - clientY;
$target.css({
width: w - diffX + 'px',
left: l + Math.min(diffX, w) + 'px',
height: h + diffY + 'px'
});
e.preventDefault();
};
downRight = function(e){
var diffX = e.clientX - clientX,
diffY = e.clientY - clientY;
$target.css({
width: w + diffX + 'px',
height: h + diffY + 'px'
});
e.preventDefault();
}; $target.delegate(controlSelector, 'mousedown', function(e){
var className = $(this).attr('class');
clientX = e.clientX;
clientY = e.clientY; w = $target.width(),
h = $target.height(),
l = $target.get(0).offsetLeft,
t = $target.get(0).offsetTop; // 根据触发元素的className选择要触发的事件处理程序
switch (className) {
case 'cursor-north':
handleEvent = up;
break; case 'cursor-south':
handleEvent = down;
break; case 'cursor-west':
handleEvent = left;
break; case 'cursor-east':
handleEvent = right;
break; case 'cursor-north-west':
handleEvent = upLeft;
break; case 'cursor-north-east':
handleEvent = upRight;
break; case 'cursor-south-west':
handleEvent = downLeft;
break; case 'cursor-south-east':
handleEvent = downRight;
break; default:
break;
} $(document)
.bind('mousemove', handleEvent)
.bind('mouseup', function(){
$(document).unbind('mousemove', handleEvent);
$target.removeData('data-resize'); // 移除标志
});
$target.data('data-resize', true); // 缓存标志
});
});
return this;
}
});

带限制范围缩放代码:

jQuery.fn.extend({
/**
* Autor: 博客园华子yjh 2014/02/26
*/
resize: function(options) {
var defaultOptions, boundaryElem, limitObj, controlSelector;
controlSelector = '.cursor-north, .cursor-south, .cursor-west, .cursor-east, .cursor-north-west, .cursor-north-east, .cursor-south-west, .cursor-south-east';
defaultOptions = { // 默认配置项
boundaryElem: 'body' // 边界容器
};
options = jQuery.extend( defaultOptions, options || {} );
boundaryElem = $(options.boundaryElem).get(0);
limitObj = {
_left: boundaryElem.offsetLeft,
_top: boundaryElem.offsetTop,
_right: boundaryElem.offsetLeft + boundaryElem.clientWidth,
_bottom: boundaryElem.offsetTop + boundaryElem.clientHeight
}; $(this).each(function(){
var up, down, left, right, upLeft, upRight, downLeft, downRight,
clientX, clientY, w, h, l, t,
$target = $(this), self = this,
handleEvent = function(){}; up = function(e){
var diffY = e.clientY - clientY;
$target.css({
height: h + Math.min(0 - diffY, t) + 'px',
top: Math.max(t + Math.min(diffY, h), 0) + 'px'
});
e.preventDefault();
};
down = function(e){
var diffY = e.clientY - clientY;
$target.css({
height: h + Math.min(diffY, limitObj._bottom - limitObj._top - t - h) + 'px'
});
e.preventDefault();
};
left = function(e){
var diffX = e.clientX - clientX;
$target.css({
width: w + Math.min(0- diffX, l) + 'px',
left: Math.max(l + Math.min(diffX, w), 0) + 'px'
});
e.preventDefault();
};
right = function(e){
var diffX = e.clientX - clientX;
$target.css({
width: w + Math.min(diffX, limitObj._right - limitObj._left - l - w) + 'px'
});
e.preventDefault();
};
upLeft = function(e){
var diffX = e.clientX - clientX,
diffY = e.clientY - clientY;
$target.css({
height: h + Math.min(0 - diffY, t) + 'px',
top: Math.max(t + Math.min(diffY, h), 0) + 'px',
width: w + Math.min(0- diffX, l) + 'px',
left: Math.max(l + Math.min(diffX, w), 0) + 'px'
});
e.preventDefault();
};
upRight = function(e){
var diffX = e.clientX - clientX,
diffY = e.clientY - clientY;
$target.css({
height: h + Math.min(0 - diffY, t) + 'px',
top: Math.max(t + Math.min(diffY, h), 0) + 'px',
width: w + Math.min(diffX, limitObj._right - limitObj._left - l - w) + 'px'
});
e.preventDefault();
};
downLeft = function(e){
var diffX = e.clientX - clientX,
diffY = e.clientY - clientY;
$target.css({
width: w + Math.min(0- diffX, l) + 'px',
left: Math.max(l + Math.min(diffX, w), 0) + 'px',
height: h + Math.min(diffY, limitObj._bottom - limitObj._top - t - h) + 'px'
});
e.preventDefault();
};
downRight = function(e){
var diffX = e.clientX - clientX,
diffY = e.clientY - clientY;
$target.css({
width: w + Math.min(diffX, limitObj._right - limitObj._left - l - w) + 'px',
height: h + Math.min(diffY, limitObj._bottom - limitObj._top - t - h) + 'px'
});
e.preventDefault();
}; $target.delegate(controlSelector, 'mousedown', function(e){
var className = $(this).attr('class');
clientX = e.clientX;
clientY = e.clientY; w = $target.width(),
h = $target.height(),
l = $target.get(0).offsetLeft,
t = $target.get(0).offsetTop; switch (className) {
case 'cursor-north':
handleEvent = up;
break; case 'cursor-south':
handleEvent = down;
break; case 'cursor-west':
handleEvent = left;
break; case 'cursor-east':
handleEvent = right;
break; case 'cursor-north-west':
handleEvent = upLeft;
break; case 'cursor-north-east':
handleEvent = upRight;
break; case 'cursor-south-west':
handleEvent = downLeft;
break; case 'cursor-south-east':
handleEvent = downRight;
break; default:
break;
}
$(document)
.bind('mousemove', handleEvent)
.bind('mouseup', function(){
$(document).unbind('mousemove', handleEvent);
$target.removeData('data-resize'); // 移除标志
});
$target.data('data-resize', true); // 缓存标志
})
});
return this;
}
});

PS: 如有描述错误,请帮忙指正,如果你们有不明白的地方也可以发邮件给我,

  如需转载,请附上本文地址及出处:博客园华子yjh,谢谢!

JavaScript简易缩放程序的更多相关文章

  1. JavaScript简易教程(转)

    原文:http://www.cnblogs.com/yanhaijing/p/3685304.html 这是我所知道的最完整最简洁的JavaScript基础教程. 这篇文章带你尽快走进JavaScri ...

  2. JavaScript简易教程

    这是我所知道的最完整最简洁的JavaScript基础教程. 这篇文章带你尽快走进JavaScript的世界——前提是你有一些编程经验的话.本文试图描述这门语言的最小子集.我给这个子集起名叫做“Java ...

  3. J2msi 自己制作的把exe打成安装包简易GUI程序(第二版 带DLL注册)

    J2msi 自己制作的把exe打成安装包简易GUI程序(第二版 带DLL注册) 之前那一版本(http://www.cnblogs.com/rojas/p/4794684.html)没考虑 DLL 注 ...

  4. JavaScript中国象棋程序(0) - 前言

    “JavaScript中国象棋程序” 这一系列教程将带你从头使用JavaScript编写一个中国象棋程序.希望通过这个系列,我们对博弈程序的算法有一定的了解.同时,我们也将构建出一个不错的中国象棋程序 ...

  5. JavaScript中国象棋程序(1) - 界面设计

    "JavaScript中国象棋程序" 这一系列教程将带你从头使用JavaScript编写一个中国象棋程序.这是教程的第1节. 这一系列共有9个部分: 0.JavaScript中国象 ...

  6. JavaScript中国象棋程序(2) - 校验棋子走法

    "JavaScript中国象棋程序" 这一系列教程将带你从头使用JavaScript编写一个中国象棋程序.这是教程的第2节. 这一系列共有9个部分: 0.JavaScript中国象 ...

  7. JavaScript中国象棋程序(3) - 电脑自动走棋

    "JavaScript中国象棋程序" 这一系列教程将带你从头使用JavaScript编写一个中国象棋程序.这是教程的第3节. 这一系列共有9个部分: 0.JavaScript中国象 ...

  8. JavaScript中国象棋程序(4) - 极大极小搜索算法

    "JavaScript中国象棋程序" 这一系列教程将带你从头使用JavaScript编写一个中国象棋程序.这是教程的第4节. 这一系列共有9个部分: 0.JavaScript中国象 ...

  9. JavaScript中国象棋程序(5) - Alpha-Beta搜索

    "JavaScript中国象棋程序" 这一系列教程将带你从头使用JavaScript编写一个中国象棋程序.这是教程的第5节. 这一系列共有9个部分: 0.JavaScript中国象 ...

随机推荐

  1. 编写高质量iOS代码与OS X代码的effective 方法小结

    一.熟悉OC: 了解OC的起源: OC和C++,Java等面向对象语言类似,不过有很方面差别.因为该语言使用  消息结构而非函数调用. 消息结构和函数调用的区别:前者是在其运行时所应执行的代码由运行环 ...

  2. 我是怎么开发一个小型java在线学习网站的

    2016/1/27 11:55:14 我是怎么开发一个小型java在线学习网站的 一直想做一个自己的网站(非博客),但是又不知道做什么内容的好,又一次看到了w3schools,就萌发了开发一个在线ja ...

  3. 【WEB API项目实战干货系列】- API登录与身份验证(三)

    上一篇: [WEB API项目实战干货系列]- 接口文档与在线测试(二) 这篇我们主要来介绍我们如何在API项目中完成API的登录及身份认证. 所以这篇会分为两部分, 登录API, API身份验证. ...

  4. Gitlab的develop角色的人没有权限无法提交的问题解决方案

    问题 事情是这样的,最近跟几位同事搞一些东西,打算在Gitlab上建一个仓库,然后协同开发. 我建好仓库,将其他几位同事添加进来,角色分配为Develop. 之后提交初始代码到master分支后,他们 ...

  5. IoC框架(转载)

      1 IoC理论的背景    我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑.  图1:软件系统中耦合的对象 如果 ...

  6. node的实践(项目三)

    渲染前台的方式. <!DOCTYPE html> <html> <head> <meta http-equiv="content-type" ...

  7. java网络编程基础

    前言 通过网络进行数据传输时,一般使用TCP/UDP进行数据传输.但是两个的区别就是TCP可靠,UDP不可靠.两个的共同之处就是都需要建立socket套接字,将IP地址和端口port进行绑定.但是服务 ...

  8. MVC——应用Ajax获取不到数据问题解答

    当我们使用控制器利用Ajax获取表单数据时,调试为null,这时看看你接受表单时定义的参数名字是否为action 其实不能起这个名字的,这个名字和控制器关键字冲突了 随便换个其它名字就好了,比如我起个 ...

  9. Sublime Text 3 破解版 + 注册机 + 汉化包 + 教程

    SublimeText 是一个代码编辑器,也是HTML和散文先进的文本编辑器. SublimeText 是由程序员 Jon Skinner 于2008年1月份所开发出来,它最初被设计为一个具有丰富扩展 ...

  10. 每天一个linux命令(8):cat 命令

    cat命令的用途是连接文件或标准输入并打印.这个命令常用来显示文件内容,或者将几个文件连接起来显示,或者从标准输入读取内容并显示,它常与重定向符号配合使用. 1.命令格式: cat [选项] [文件] ...