如何将屏幕坐标转换为 z 变换元素上的坐标?
How to convert screen coordinates to coordinates on a z transformed element?
我有一个 z 变换元素,它有一个子标记,我需要将该标记放在鼠标单击位置。
我需要知道如何将屏幕坐标转换为 z 变换元素上的坐标。
这是我当前的代码:
function getPosition(screenCoords)
{
// This function should return x and y coordinates on z-transformed element and I have no idea how to achieve that.
return {x: 2500, y: 1500};
}
var $viewport = $(".viewport");
var $marker = $(".marker");
$viewport.on("click", function(e){
e.preventDefault();
var newMarkerPosition = getPosition({x: e.pageX, y: e.pageY});
$marker.css({
left: newMarkerPosition.x + "px",
top: newMarkerPosition.y + "px"
});
});
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
.viewport {
width: 100%;
height: 100%;
overflow: hidden;
perspective: 1000px;
perspective-origin: 50% 50%;
}
.z-transformed-element {
width: 5000px;
height: 3000px;
transform-origin: 2500px 1500px;
background-color: gray;
position: relative;
transform: translateX(-2500px) translateY(-1500px) translateZ(-10000px);
}
.marker {
left: 0;
top: 0;
width: 200px;
height: 200px;
margin-left: -100px;
margin-top: -100px;
background-color: red;
border-radius: 100px;
position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="viewport">
<div class="z-transformed-element">
<div class="marker"></div>
</div>
</div>
这里最困难的部分似乎是将点击的屏幕 space 坐标转换为转换后的坐标。执行此操作的一种方法是使用 getBoundingClientRect()
函数(在应用所有转换后 returns 对象的 dimensions/position),并使用其尺寸来计算显示之间的比率元素的尺寸及其 "actual" 尺寸。
获得此比率后,只需将其与点击坐标相乘(在将它们相对于元素显示的中心坐标进行偏移后)即可获得转换后的点击坐标。
我已经添加到您的代码中以展示如何使用这种方法将您的 CSS 转换元素移动到鼠标点击位置:
function getPosition(screenCoords)
{
var $transformedEl = $(".z-transformed-element");
// Calculating "actual" center of element
var elementCenter = {
x: $transformedEl.innerWidth() / 2,
y: $transformedEl.innerHeight() / 2
}
// Determining ratio of displayed dimensions to "actual" dimensions
var boundingRect = $transformedEl[0].getBoundingClientRect();
var dimRatio = $transformedEl.innerWidth() / boundingRect.width;
// Determining offset click coordinates (relative to displayed center of element)
var clickOffset = {
x: screenCoords.x - $transformedEl.offset().left - boundingRect.width / 2,
y: screenCoords.y - $transformedEl.offset().top - boundingRect.height / 2
}
// Calculating coordinates of click, relative to element's "actual" center and ratio of displayed to "actual" dimensions
var finalCoords = {
x: elementCenter.x + clickOffset.x * dimRatio,
y: elementCenter.y + clickOffset.y * dimRatio
}
return finalCoords;
}
var $viewport = $(".viewport");
var $marker = $(".marker");
$viewport.on("click", function(e){
e.preventDefault();
console.log(e.pageX, e.pageY);
var newMarkerPosition = getPosition({x: e.pageX, y: e.pageY});
$marker.css({
left: newMarkerPosition.x + "px",
top: newMarkerPosition.y + "px"
});
});
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
.viewport {
width: 100%;
height: 100%;
overflow: hidden;
perspective: 1000px;
perspective-origin: 50% 50%;
}
.z-transformed-element {
width: 5000px;
height: 3000px;
transform-origin: 2500px 1500px;
background-color: gray;
position: relative;
transform: translateX(-2500px) translateY(-1500px) translateZ(-10000px);
}
.marker {
left: 0;
top: 0;
width: 200px;
height: 200px;
margin-left: -100px;
margin-top: -100px;
background-color: red;
border-radius: 100px;
position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="viewport">
<div class="z-transformed-element">
<div class="marker"></div>
</div>
</div>
(我承认找到最简单的方法对我来说很难 - 我几乎走上了尝试用变换矩阵变换坐标的路线!哎呀。)
希望对您有所帮助!如果您有任何问题,请告诉我。
我有一个 z 变换元素,它有一个子标记,我需要将该标记放在鼠标单击位置。
我需要知道如何将屏幕坐标转换为 z 变换元素上的坐标。
这是我当前的代码:
function getPosition(screenCoords)
{
// This function should return x and y coordinates on z-transformed element and I have no idea how to achieve that.
return {x: 2500, y: 1500};
}
var $viewport = $(".viewport");
var $marker = $(".marker");
$viewport.on("click", function(e){
e.preventDefault();
var newMarkerPosition = getPosition({x: e.pageX, y: e.pageY});
$marker.css({
left: newMarkerPosition.x + "px",
top: newMarkerPosition.y + "px"
});
});
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
.viewport {
width: 100%;
height: 100%;
overflow: hidden;
perspective: 1000px;
perspective-origin: 50% 50%;
}
.z-transformed-element {
width: 5000px;
height: 3000px;
transform-origin: 2500px 1500px;
background-color: gray;
position: relative;
transform: translateX(-2500px) translateY(-1500px) translateZ(-10000px);
}
.marker {
left: 0;
top: 0;
width: 200px;
height: 200px;
margin-left: -100px;
margin-top: -100px;
background-color: red;
border-radius: 100px;
position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="viewport">
<div class="z-transformed-element">
<div class="marker"></div>
</div>
</div>
这里最困难的部分似乎是将点击的屏幕 space 坐标转换为转换后的坐标。执行此操作的一种方法是使用 getBoundingClientRect()
函数(在应用所有转换后 returns 对象的 dimensions/position),并使用其尺寸来计算显示之间的比率元素的尺寸及其 "actual" 尺寸。
获得此比率后,只需将其与点击坐标相乘(在将它们相对于元素显示的中心坐标进行偏移后)即可获得转换后的点击坐标。
我已经添加到您的代码中以展示如何使用这种方法将您的 CSS 转换元素移动到鼠标点击位置:
function getPosition(screenCoords)
{
var $transformedEl = $(".z-transformed-element");
// Calculating "actual" center of element
var elementCenter = {
x: $transformedEl.innerWidth() / 2,
y: $transformedEl.innerHeight() / 2
}
// Determining ratio of displayed dimensions to "actual" dimensions
var boundingRect = $transformedEl[0].getBoundingClientRect();
var dimRatio = $transformedEl.innerWidth() / boundingRect.width;
// Determining offset click coordinates (relative to displayed center of element)
var clickOffset = {
x: screenCoords.x - $transformedEl.offset().left - boundingRect.width / 2,
y: screenCoords.y - $transformedEl.offset().top - boundingRect.height / 2
}
// Calculating coordinates of click, relative to element's "actual" center and ratio of displayed to "actual" dimensions
var finalCoords = {
x: elementCenter.x + clickOffset.x * dimRatio,
y: elementCenter.y + clickOffset.y * dimRatio
}
return finalCoords;
}
var $viewport = $(".viewport");
var $marker = $(".marker");
$viewport.on("click", function(e){
e.preventDefault();
console.log(e.pageX, e.pageY);
var newMarkerPosition = getPosition({x: e.pageX, y: e.pageY});
$marker.css({
left: newMarkerPosition.x + "px",
top: newMarkerPosition.y + "px"
});
});
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
.viewport {
width: 100%;
height: 100%;
overflow: hidden;
perspective: 1000px;
perspective-origin: 50% 50%;
}
.z-transformed-element {
width: 5000px;
height: 3000px;
transform-origin: 2500px 1500px;
background-color: gray;
position: relative;
transform: translateX(-2500px) translateY(-1500px) translateZ(-10000px);
}
.marker {
left: 0;
top: 0;
width: 200px;
height: 200px;
margin-left: -100px;
margin-top: -100px;
background-color: red;
border-radius: 100px;
position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="viewport">
<div class="z-transformed-element">
<div class="marker"></div>
</div>
</div>
(我承认找到最简单的方法对我来说很难 - 我几乎走上了尝试用变换矩阵变换坐标的路线!哎呀。)
希望对您有所帮助!如果您有任何问题,请告诉我。