|
|
请马上登录,朋友们都在花潮里等着你哦:)
您需要 登录 才可以下载或查看,没有账号?立即注册
x
在svg中检测鼠标指针经过圆 | 马黑黑
svg绘制圆,使用 fill 方法画出的是实心圆,使用 stroke 方法画出的是圆环。本帖只讨论鼠标指针经过实心圆的检测方法。我们先用 fill 方法绘制一个圆:
<svg id="sc" width="200" height="200" style="background: gray">
<circle cx="100" cy="100" r="50" fill="lightblue" />
</svg>
这是在 200*200 的灰色底 svg 画布上以(100,100)为圆心,绘制一个半径为 50 的浅蓝色实心圆。现在,我们就来检测鼠标是否经过浅蓝色圆的区域,如果经过,鼠标指针变为手型,否则是默认形状。
具体思路是,鼠标点击的点 p(x,y)与圆心 o 连成线段 op,o→p 方向的直线 op 或 op 的延长线必然与圆周线相交于某一点 k,ok 等于圆的半径 r,我们可以将 op 的长度与圆的半径 r 进行比较,从而判断点 p 是否在圆内。这时,我们可以考虑用勾股定理来完成这个判断,方法是:经过 p 点往X轴方向画一根与Y轴平行的辅助线,与X轴相交于 d 点,我们就得到一个直角三角形 △opd,其中,op 为斜线,od 和 dp 为两条直角线,这两根直角线的长度分别对应于点 p 坐标的 x 和 y 值,我们通过鼠标相关事件可以获得这个xy坐标值。那么,如果两个直角边的长度的平方和小于等于圆半径的平方,说明点 p 在圆内,反之在圆外。这是中小学数学知识的应用,按理应该不难理解,除非大家把中小学数学知识还给了美术老师了。
JS有一个内置数学(Math)函数 pow,用于计算 x 的 y 次幂:
Math.pow(x,y);
设直角线分别为 a、b,斜线为 c ,则 JS 中各条线的平方运算公式分别为:
Math.pow(a,2);
Math.pow(b,2);
Math.pow(c,2);
当然也可以用最原始的运算式子:a*a,b*b,c*c。
知识铺垫到位,现在可以用 JS 编写一个检测函数了:
function isCircle(cx, cy, r, ex, ey) {
return Math.pow(ex - cx, 2) + Math.pow(ey - cy, 2) <= Math.pow(r, 2);
}
函数需要 5 个参数:cx,圆心x坐标,cy,圆心y坐标,r是圆的半径,ex 和 ey 分别是鼠标经过或点击时的x、y坐标。
计算式子中,Math.pow(ex - cx, 2) 里,ex - cx 得出鼠标点击的坐标点的x位置离圆心的距离,其中,ex 我们会通过 offsetX 获取,它的实际数值是从事件源对象(元素)的左边到点击点的水平距离,它减去圆心x坐标值就是三角形直角边水平线段的长度;Math.pow(ey - cy, 2) 同理,ey - cy 得到的是垂直于X轴的直角边的长度;Math.pow(r, 2) 计算半径的平方值,无须解释吧。
上述函数被调用时会返回上述式子的计算结果,如果式子成立,返回真(true),否则返回假(false),这是布尔值,非真即假、非假即真,不存在第三方的值。下面是函数调用实例,检测鼠标经过画布与否并作出相应响应,画布的 id 为 sc:
sc.onmousemove = (e) => {
if(isCircle(100, 100, 50, e.offsetX, e.offsetY)) {
sc.style.cursor = 'pointer';
} else {
sc.style.cursor = 'default';
}
}
鼠标移动代码中,带入的参数里,100 和 100 是圆心xy坐标,50 是圆的半径,后两个值就是鼠标经过或点击时的xy坐标值。如此,鼠标在svg画布上移动时,浅蓝色圆的区域鼠标指针为手型,圆外区域鼠标指针为默认形状。
最后附上完整代码:
- <svg id="sc" width="200" height="200" style="background: gray">
- <circle cx="100" cy="100" r="50" fill="lightblue" />
- </svg>
- <script>
- sc.onmousemove = (e) => {
- if(isCircle(100, 100, 50, e.offsetX, e.offsetY)) {
- sc.style.cursor = 'pointer';
- } else {
- sc.style.cursor = 'default';
- }
- }
- function isCircle(cx, cy, r, ex, ey) {
- return Math.pow(ex - cx, 2) + Math.pow(ey - cy, 2) <= Math.pow(r, 2);
- }
- </script>
复制代码
|
评分
-
| 参与人数 1 | 威望 +50 |
金钱 +100 |
经验 +50 |
收起
理由
|
红影
| + 50 |
+ 100 |
+ 50 |
赞一个! |
查看全部评分
|