与使用 getBoundingClientRect 之前放置的位置相比,元素的位置不会保持不变
The position of the elements do not remain the same compared to their previous placed position using getBoundingClientRect
我将一些元素拖放到 div(包含背景图片)上并上传内容。在上传之前,我计算了丢弃的元素顶部、左侧位置 wrt 到父 div,这样当它们与正在传递的背景图像(png 或 jpeg)。但问题是元素放置的位置与其初始放置位置相比略有不同。
HTML
上传前
<div id="toget"
class="dropzone"
[ngStyle]="{'width':'100%',
'background-image': 'url('+urlFloorZoneIn+')',
'background-repeat': 'no-repeat',
'background-position': 'center',
'background-size': '100% 100%',
'border':'1px solid black',
'height':'340px',
'position': 'relative'}">
<div class="box"
*ngFor="let existingZone of existingDroppedItemZoneIn"
[ngStyle] = "{'position': 'absolute' ,
'top.%':existingZone.spans[1],
'left.%':existingZone.spans[0]}"
(dragEnd)="onDragEnd($event,existingZone)">
{{ existingZone.main }}
<span>{{existingZone.spans[0]}}</span>
<span>{{existingZone.spans[1]}}</span>
</div>
</div>
计算左上角位置的TS代码
onDragEnd(event,b){
const existingMovingBlockIndex = (this.existingDroppedItemZoneIn.indexOf(this.currentBox));
if(existingMovingBlockIndex>-1){
console.log(b)
console.log(`got drag end x and y ${event.clientX} ${event.clientY}`)
console.log(this.dr.onDragMove);
const container_rect = this.parentparent.nativeElement.getBoundingClientRect();
this.mouse.x = event.clientX - container_rect.left;
this.mouse.y = event.clientY - container_rect.top;
const{width,height} = this.parentparent.nativeElement.getBoundingClientRect();
const perc_x = this.mouse.x / width * 100;
const perc_y = this.mouse.y / height * 100;
this.left = perc_x-5;
this.topLeft = []
this.topLeft.push(this.left);
this.top = perc_y-5;
this.topLeft.push(this.top);
this.existingDroppedItemZoneIn[existingMovingBlockIndex].spans[0] = (perc_x);
this.existingDroppedItemZoneIn[existingMovingBlockIndex].spans[1] = (perc_y);
}
}
CSS
.box {
width: 10%;
height: 10%;
background: rgba(254, 249, 247, 1);
border: 1.5px solid #e24301;
margin: 5px;
line-height: 100px;
text-align: center;
font-size: 0.8rem;
}
.dropzone {
padding: 20px;
margin: 20px 0;
background: lightgray;
min-height: 200px;
border: 1px solid black;
}
在渲染之前,我获取了上面上传的 HTML 内容的顶部、左侧、背景图像值,并应用了 background-image、 top, left 值渲染下面的内容
不同屏幕渲染后
[![在此处输入图片描述][2]][2]
<ul>
<li #allFloors
*ngFor="let floor of buildings.floors"
[ngStyle]="{'width': singleFloorFlagStyle ?'40%':'100%',
'background-image': 'url('+floor.urlFloorZoneIn+')',
'background-repeat': 'no-repeat',
'background-position': 'center',
'background-size': '100% 100%',
'border':'1px solid black',
'height': singleFloorFlagStyle ? '340px' : '700px',
'position': 'relative', 'max-width': '80%'}"
[ngClass]="{'width':'80% !important'}">
<span (click)="loadFloorInfo(floor._id)">{{ floor.name }}</span>
<div class="fs-heatmap-wrapper__content__box"
*ngFor="let existingZone of floor.droppeditem"
[ngStyle]="{'position':'absolute',
'top.%': existingZone.spans[1],
'left.%': existingZone.spans[0]}">
{{ existingZone.main }}
</div>
</li>
</ul>
CSS
.fs-heatmap-wrapper {
display: grid;
*min-height: 800px;
&__content {
padding: 70px 40px 0;
min-height: 300px;
ul {
margin: 0;
padding: 0;
display: flex;
flex-wrap: wrap;
justify-content: center;
li {
list-style: none;
min-width: 48%;
margin: 12px;
margin-bottom: 2.5%;
span {
cursor: pointer;
background: #fff;
text-align: left;
font-weight: 800;
font-size: 0.9rem;
letter-spacing: 0.05rem;
position: relative;
top: -30px;
}
}
}
&__box{
width: 100px;
height: 100px;
background: rgba(254, 249, 247, 1);
border: 1.5px solid #e24301;
margin: 5px;
line-height: 100px;
text-align: center;
font-size: 0.8rem;
}
}
}
这个问题的主要原因是您在 % 中提供的顶部和左侧 属性。不要将值转换为 %,而是尝试直接以像素为单位使用它们。
C - 可拖动元素,P - 放置区父元素
问题是您使用鼠标的指针位置来计算 C 相对于 P 的新位置,而 C 位置的实际来源是:
C.getBoundingClientRect().left - P.parent.getBoundingClientRect().left
鼠标指针可以放在 C 上的任何位置。假设我通过将鼠标指向 C 的中心来开始拖动 C,所以您得到的 event.clientX 不是从 C 开始的更新位置相对于客户端呈现,但它是:
(clientPosition of C + (clientPosition of Mouse Pointer - clientPosition of C))
肯定不是C的ClientPosition
所以只要使用第一个公式就可以纠正你的立场。您可以为可拖动元素分配 id,然后访问它们。
此外,在您的 Stackblitz 示例中,您在拖动结束后对拖动的元素同时使用变换和位置,这也会增加不正确的位置。使用其中之一。
我将一些元素拖放到 div(包含背景图片)上并上传内容。在上传之前,我计算了丢弃的元素顶部、左侧位置 wrt 到父 div,这样当它们与正在传递的背景图像(png 或 jpeg)。但问题是元素放置的位置与其初始放置位置相比略有不同。
HTML 上传前
<div id="toget"
class="dropzone"
[ngStyle]="{'width':'100%',
'background-image': 'url('+urlFloorZoneIn+')',
'background-repeat': 'no-repeat',
'background-position': 'center',
'background-size': '100% 100%',
'border':'1px solid black',
'height':'340px',
'position': 'relative'}">
<div class="box"
*ngFor="let existingZone of existingDroppedItemZoneIn"
[ngStyle] = "{'position': 'absolute' ,
'top.%':existingZone.spans[1],
'left.%':existingZone.spans[0]}"
(dragEnd)="onDragEnd($event,existingZone)">
{{ existingZone.main }}
<span>{{existingZone.spans[0]}}</span>
<span>{{existingZone.spans[1]}}</span>
</div>
</div>
计算左上角位置的TS代码
onDragEnd(event,b){
const existingMovingBlockIndex = (this.existingDroppedItemZoneIn.indexOf(this.currentBox));
if(existingMovingBlockIndex>-1){
console.log(b)
console.log(`got drag end x and y ${event.clientX} ${event.clientY}`)
console.log(this.dr.onDragMove);
const container_rect = this.parentparent.nativeElement.getBoundingClientRect();
this.mouse.x = event.clientX - container_rect.left;
this.mouse.y = event.clientY - container_rect.top;
const{width,height} = this.parentparent.nativeElement.getBoundingClientRect();
const perc_x = this.mouse.x / width * 100;
const perc_y = this.mouse.y / height * 100;
this.left = perc_x-5;
this.topLeft = []
this.topLeft.push(this.left);
this.top = perc_y-5;
this.topLeft.push(this.top);
this.existingDroppedItemZoneIn[existingMovingBlockIndex].spans[0] = (perc_x);
this.existingDroppedItemZoneIn[existingMovingBlockIndex].spans[1] = (perc_y);
}
}
CSS
.box {
width: 10%;
height: 10%;
background: rgba(254, 249, 247, 1);
border: 1.5px solid #e24301;
margin: 5px;
line-height: 100px;
text-align: center;
font-size: 0.8rem;
}
.dropzone {
padding: 20px;
margin: 20px 0;
background: lightgray;
min-height: 200px;
border: 1px solid black;
}
在渲染之前,我获取了上面上传的 HTML 内容的顶部、左侧、背景图像值,并应用了 background-image、 top, left 值渲染下面的内容
不同屏幕渲染后
[![在此处输入图片描述][2]][2]
<ul>
<li #allFloors
*ngFor="let floor of buildings.floors"
[ngStyle]="{'width': singleFloorFlagStyle ?'40%':'100%',
'background-image': 'url('+floor.urlFloorZoneIn+')',
'background-repeat': 'no-repeat',
'background-position': 'center',
'background-size': '100% 100%',
'border':'1px solid black',
'height': singleFloorFlagStyle ? '340px' : '700px',
'position': 'relative', 'max-width': '80%'}"
[ngClass]="{'width':'80% !important'}">
<span (click)="loadFloorInfo(floor._id)">{{ floor.name }}</span>
<div class="fs-heatmap-wrapper__content__box"
*ngFor="let existingZone of floor.droppeditem"
[ngStyle]="{'position':'absolute',
'top.%': existingZone.spans[1],
'left.%': existingZone.spans[0]}">
{{ existingZone.main }}
</div>
</li>
</ul>
CSS
.fs-heatmap-wrapper {
display: grid;
*min-height: 800px;
&__content {
padding: 70px 40px 0;
min-height: 300px;
ul {
margin: 0;
padding: 0;
display: flex;
flex-wrap: wrap;
justify-content: center;
li {
list-style: none;
min-width: 48%;
margin: 12px;
margin-bottom: 2.5%;
span {
cursor: pointer;
background: #fff;
text-align: left;
font-weight: 800;
font-size: 0.9rem;
letter-spacing: 0.05rem;
position: relative;
top: -30px;
}
}
}
&__box{
width: 100px;
height: 100px;
background: rgba(254, 249, 247, 1);
border: 1.5px solid #e24301;
margin: 5px;
line-height: 100px;
text-align: center;
font-size: 0.8rem;
}
}
}
这个问题的主要原因是您在 % 中提供的顶部和左侧 属性。不要将值转换为 %,而是尝试直接以像素为单位使用它们。
C - 可拖动元素,P - 放置区父元素
问题是您使用鼠标的指针位置来计算 C 相对于 P 的新位置,而 C 位置的实际来源是:
C.getBoundingClientRect().left - P.parent.getBoundingClientRect().left
鼠标指针可以放在 C 上的任何位置。假设我通过将鼠标指向 C 的中心来开始拖动 C,所以您得到的 event.clientX 不是从 C 开始的更新位置相对于客户端呈现,但它是:
(clientPosition of C + (clientPosition of Mouse Pointer - clientPosition of C))
肯定不是C的ClientPosition
所以只要使用第一个公式就可以纠正你的立场。您可以为可拖动元素分配 id,然后访问它们。
此外,在您的 Stackblitz 示例中,您在拖动结束后对拖动的元素同时使用变换和位置,这也会增加不正确的位置。使用其中之一。