我们在网页上经常看到这种效果,就是鼠标从方块的四个不同方向移入方块时会展示不同的效果,实现这种效果首要的就是判断鼠标移入的方向,判断方向的方法有很多,今天我们就说其中的一种实现方法。
先看一个示意图
通过示意图我们很容易求出角α的弧度为:α = arctan(m/n),这里使用的是反三角函数中的反正切。同样的方法也可以得出β角的大小。 当β > α时,我们就可以确定a点在矩形的上方进入,反之就是在右方进入。四个方向都可以这样判断。由此,问题就简单了,我们需要求的就是这个角度,而求角度要知道的只是其对边和斜边,而根据点的位置,这两边非常容易得出。
判断方向的方法我封装成jquery插件。
// 传入参数必须是一个、四个或八个,传入的参数必须是回调函数,回调函数第一个参数代表当前对象
(function ($) {
$.fn.extend({
intoDir () {
var arg = arguments
return this.each(function (i, s) {
// 监听mouseover事件
$(s).mouseover(function (e) {
// 获取进入点在块中的位置
var x = e.offsetX, y = e.offsetY
var sw = $(this).outerWidth(), sh = $(this).outerHeight()
var dir = dirGet(x, y, sw, sh)
// 根据方向依次运行需采取的动作
var len = arg.length
if (len == 1) {
arg[0](this)
} else if (len == 4) {
if (dir == 'topleft' || dir == 'topright') {
arg[0](this)
}
if (dir == 'righttop' || dir == 'rightbottom') {
arg[1](this)
}
if (dir == 'bottomright' || dir == 'bottomleft') {
arg[2](this)
}
if (dir == 'leftbottom' || dir == 'lefttop') {
arg[3](this)
}
} else if (len == 8) {
switch (dir) {
case 'topleft':
arg[0](this)
break
case 'topright':
arg[1](this)
break
case 'righttop':
arg[2](this)
break
case 'rightbottom':
arg[3](this)
break
case 'bottomright':
arg[4](this)
break
case 'bottomleft':
arg[5](this)
break
case 'leftbottom':
arg[6](this)
break
case 'lefttop':
arg[7](this)
break
default:
throw new Error('错误的方向')
}
} else {
throw new Error('传入参数数量错误')
}
})
// 方向判断
// x 点的left, y点的top, W块的宽度,H块的高度
var dirGet = function (x, y, W, H) {
var halfW = W / 2, halfH = H / 2
var limit = Math.atan(halfH / halfW)
var dirX = '', dirY = ''
// 先判断点距离那条边较近,做一个粗略的位置判定
if (x < halfW) {
dirX = 'left'
} else {
dirX = 'right'
}
if (y < halfH) {
dirY = 'top'
} else {
dirY = 'bottom'
}
// 依次求反正切值,判断具体方向
switch (dirX + dirY) {
case 'lefttop':
if (Math.atan((halfH -y) / (halfW - x)) > limit) {
return 'topleft'
} else {
return 'lefttop'
}
case 'leftbottom':
if (Math.atan((y - halfH) / (halfW - x)) > limit) {
return 'bottomleft'
} else {
return 'leftbottom'
}
case 'righttop':
if (Math.atan((halfH - y) / (x - halfW)) > limit) {
return 'topright'
} else {
return 'righttop'
}
case 'rightbottom':
if (Math.atan((y - halfH) / (x - halfW)) > limit) {
return 'bottomright'
} else {
return 'rightbottom'
}
default:
throw new Error('未知的方向')
}
}
})
}
})
})(jQuery)
jquery插件可直接使用,只需选择一个块元素即可。