在上一节中,我们在监听鼠标移动事件时,将其坐标范围处理为了[-1,1]的范围,使用如下代码
document.addEventListener('mousemove',function( event ) {
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1 //处理为 -1 ~ 1 的范围
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1 //处理为 -1 ~ 1 的范围
})
那么我们为什么要这么转换呢?
标准坐标系
我们之所以要进行上面的转换,这是因为在Three.js中Canvas画布具有一个标准设备坐标系,该坐标系的坐标原点在canvas画布的中间位置,x轴水平向右,y轴竖直向上。
标准设备坐标系的坐标值不是绝对值,是相对值,其范围是[-1,1]区间,也就是说canvas画布上任何一个位置的坐标,如果用标准设备坐标系来表示,那么坐标的值都是在-1到1之间的。
HTML中的坐标系
有前端基础的人都知道HTML中有四个坐标系,分别是screen,page,client和offset,他们用于描述DOM元素的Box尺寸和MouseEvent中的位置
1 screen坐标系
坐标原点:用户显示器屏幕左上角。
screenX:鼠标点击位置相对于电脑屏幕左上角的水平偏移量。
screenY:鼠标点击位置相对于电脑屏幕左上角的垂直偏移量。
screen坐标的最大范围是 (screen.width, screen.height),最大值不会超过屏幕分辨率。
2 page坐标系
坐标原点:整个页面的左上角(整个页面的意思就是你整个网页的全部,按照整个html文档的长度和宽度来计算)。
pageX:鼠标点击位置相对于网页左上角的水平偏移量,也就是 clientX + 水平滚动条滚动的距离。
pageY:鼠标点击位置相对于网页左上角的垂直平偏移量,也就是 clientY + 垂直滚动条滚动的距离。
坐标系上某一个元素的pageX/pageY 不会 随着滚动条滚动而改变。
page坐标的最大范围是 (document.body.clientWidth + 垂直滚动条宽度, document.body.clientHeight + 水平滚动条高度)。
3 client
坐标原点:浏览器内容区域左上角(即浏览器中用户所看到区域的左上角,内容区域不包括工具栏和滚动条)。
clientX:鼠标点击位置相对于浏览器可视区域的水平偏移量(不会计算水平滚动的距离)。
clientY:鼠标点击位置相对于浏览器可视区域的垂直偏移量(不会计算垂直滚动的距离)。
坐标系上某一个元素的clientX/clientY 会 随着滚动条滚动而改变。
client坐标的最大范围是 (window.innerWidth - 垂直滚动条宽度, window.innerHeight - 水平滚动条高度)。
*计算这个坐标时,由于是基于浏览器窗口中用来显示网页的可视区域,那么也就是说需要拖动滚动条才能看到的区域不算;当你将浏览器窗口缩小时,clientX/clientY 的最大值也会缩小,但始终,它们的最大值不会超过你浏览器可视区域。
4 offset
坐标原点:父级中最近的一个带有CSS定位(position为absolute/relative)的父元素,如果当前元素的父级元素中没有进行CSS定位,那么就是body。
offsetX:鼠标点击位置相对于触发事件对象的水平距离。
offsetY:鼠标点击位置相对于触发事件对象的垂直距离。
offset坐标的最大范围是 (document.body.offsetWidth, document.body.offsetHeight)。
获取鼠标坐标事件
我们可以通过点击事件回调函数中的event来获取鼠标相关的位置信息
addEventListener('click',function(event){
// event对象有很多鼠标事件相关信息
console.log('event',event)
const ox = event.offsetX
const oy = event.offsetY
const cx = event.clientX
const cy = event.clientY
})
屏幕坐标转换标准设备坐标
在项目开发中,我们可以用.clientX、.clientY计算标准设备坐标,也可以用.offsetX、.offsetY计算标准设备坐标。
.offsetX和.offsetY坐标转化为标准设备坐标坐标
// 坐标转化公式
addEventListener('click',function(event){
const px = event.offsetX;
const py = event.offsetY;
//屏幕坐标px、py转标准设备坐标x、y
//width、height表示canvas画布宽高度
const x = (px / width) * 2 - 1;
const y = -(py / height) * 2 + 1;
})
画布的宽度是width,.offsetX的范围是0-width,.offsetX除以canvas画布宽度width,就可以从绝对值变成相对值,范围是0-1,相对值乘以2,范围0-2,再减去1,范围是-1-1,刚好和canvas画布标准设备坐标的范围-1~1能够对应起来。
用.clientX、.clientY计算canvas画布屏幕坐标
用.offsetX、.offsetY可以直接表示canvas画布屏幕坐标,但是如果用.clientX、.clientY表示,这时候要注意,把.clientX、.clientY转化为以canvas画布左上角为原点的坐标。
// 屏幕坐标转标准设备坐标
addEventListener('click',function(event){
// left、top表示canvas画布布局,距离顶部和左侧的距离(px)
const px = event.clientX-left;
const py = event.clientY-top;
//屏幕坐标px、py转标准设备坐标x、y
//width、height表示canvas画布宽高度
const x = (px / width) * 2 - 1
const y = -(py / height) * 2 + 1
})
ok,关于屏幕坐标转标准设备坐标就聊到这里。