Html 以百分比计算getBoundingClientRect
我已经在使用px中的子元素wrt到父元素的getBoundingClientRect()以及从一个组件到另一个组件的传递来计算左位置和顶部位置,并且能够将子元素放置在预期的位置上,但是我希望使子元素响应于父元素的wrt,因此我需要%中的左位置和顶部位置 我已经尝试过从控制台将px中的值和单位更改为%,并且能够获得所需的响应,但是尝试在代码中计算百分比并没有像预期的那样起作用,它没有将子元素放置在正确的位置,尽管实现了响应Html 以百分比计算getBoundingClientRect,html,css,angular,getboundingclientrect,Html,Css,Angular,Getboundingclientrect,我已经在使用px中的子元素wrt到父元素的getBoundingClientRect()以及从一个组件到另一个组件的传递来计算左位置和顶部位置,并且能够将子元素放置在预期的位置上,但是我希望使子元素响应于父元素的wrt,因此我需要%中的左位置和顶部位置 我已经尝试过从控制台将px中的值和单位更改为%,并且能够获得所需的响应,但是尝试在代码中计算百分比并没有像预期的那样起作用,它没有将子元素放置在正确的位置,尽管实现了响应 minX: viewRect.left - movableClient
minX: viewRect.left - movableClientRect.left + movable.position.x,
maxX: viewRect.right - movableClientRect.right + movable.position.x,
minY: viewRect.top - movableClientRect.top + movable.position.y,
maxY: viewRect.bottom - movableClientRect.bottom + movable.position.y
this.dataService.setData(this.zonePosition =
{
x : (viewRect.left - movableClientRect.left)/viewRect.left ,
y: (viewRect.top - movableClientRect.top)/viewRect.top
}
在前面的代码中,我只执行viewRect.left-movableClientRect.left,所以值是以像素为单位的,现在我尝试除以viewRect.left,然后再除以*100将其转换为%,但百分比值不能正确放置子元素
使用用于计算位置的指令进行更新
可移动指令
在这里,我计算子元素的x和y位置
interface Position {
x: number;
y: number;
}
@Directive({
selector: '[appMovable]'
})
export class MovableDirective extends DraggableDirective {
@HostBinding('style.transform') get transform(): SafeStyle {
return this.sanitizer.bypassSecurityTrustStyle(
`translateX(${this.position.x}%) translateY(${this.position.y}%)`
);
}
@HostBinding('class.movable') movable = true;
position: Position = {x: 0, y: 0};
zonePosition = {x:0, y:0, id:""}
private startPosition: Position;
@Input('appMovableReset') reset = false;
constructor(private sanitizer: DomSanitizer, public element: ElementRef,
private dataService: DataService) {
super(element);
}
@HostListener('dragStart', ['$event'])
onDragStart(event: PointerEvent) {
this.startPosition = {
x: event.clientX - this.position.x,
y: event.clientY - this.position.y
}
}
@HostListener('dragMove', ['$event'])
onDragMove(event: PointerEvent) {
this.position.x = event.clientX - this.startPosition.x;
this.position.y = event.clientY - this.startPosition.y;
}
@HostListener('dragEnd', ['$event'])
onDragEnd(event: PointerEvent) {
if (this.reset) {
this.position = {x: 0, y: 0};
}
}
}
我在其中计算子元素的左侧和顶部并将其分配给dataService的指令
Directive({
selector: '[appMovableArea]'
})
export class MovableAreaDirective implements AfterContentInit {
@ContentChildren(MovableDirective) movables: QueryList<MovableDirective>;
private boundaries: Boundaries;
private subscriptions: Subscription[] = [];
zonePosition = {x:0, y:0, id:""}
constructor(private element: ElementRef, private dataService: DataService)
{}
ngAfterContentInit(): void {
this.movables.changes.subscribe(() => {
this.subscriptions.forEach(s => s.unsubscribe());
this.movables.forEach(movable => {
this.subscriptions.push(movable.dragStart.subscribe(() =>
this.measureBoundaries(movable)));
this.subscriptions.push(movable.dragMove.subscribe(() =>
this.maintainBoundaries(movable)));
});
});
this.movables.notifyOnChanges();
}
private measureBoundaries(movable: MovableDirective) {
const viewRect: ClientRect =
this.element.nativeElement.getBoundingClientRect();
const movableClientRect: ClientRect =
movable.element.nativeElement.getBoundingClientRect();
this.dataService.setData(this.zonePosition= {x : (viewRect.left -
movableClientRect.left)/viewRect.left , y: (viewRect.top -
movableClientRect.top)/viewRect.top, id: "" })
this.boundaries = {
minX: viewRect.left - movableClientRect.left + movable.position.x,
maxX: viewRect.right - movableClientRect.right + movable.position.x,
minY: viewRect.top - movableClientRect.top + movable.position.y,
maxY: viewRect.bottom - movableClientRect.bottom + movable.position.y
};
}
private maintainBoundaries(movable: MovableDirective) {
movable.position.x = Math.max(this.boundaries.minX,
movable.position.x);
movable.position.x = Math.min(this.boundaries.maxX, movable.position.x);
movable.position.y = Math.max(this.boundaries.minY, movable.position.y);
movable.position.y = Math.min(this.boundaries.maxY, movable.position.y);
}
}
指令({
选择器:“[appMovableArea]”
})
export类MovableArea指令在ContentInit之后实现{
@ContentChildren(MovableDirective)动产:QueryList;
私人边界:边界;
私人订阅:订阅[]=[];
zonePosition={x:0,y:0,id:“”
构造函数(私有元素:ElementRef,私有数据服务:数据服务)
{}
ngAfterContentInit():void{
此.movables.changes.subscribe(()=>{
this.subscriptions.forEach(s=>s.unsubscribe());
this.movables.forEach(movable=>{
this.subscriptions.push(movable.dragStart.subscripte(()=>
这是测量基础(可移动);
this.subscriptions.push(movable.dragMove.subscripte(()=>
这是(可移动的);
});
});
this.movables.notifyOnChanges();
}
专用计量基础(可移动:可移动指令){
const viewRect:ClientRect=
this.element.nativeElement.getBoundingClientRect();
常量movableClient:ClientRect=
movable.element.nativeElement.getBoundingClientRect();
this.dataService.setData(this.zonePosition={x:(viewRect.left-
movableCliert.left)/viewRect.left,y:(viewRect.top-
movableClientRect.top)/viewRect.top,id:“}”)
此值为0.1,边界={
minX:viewRect.left-movableClientRect.left+movable.position.x,
maxX:viewRect.right-movableClientRect.right+movable.position.x,
minY:viewRect.top-movableClientRect.top+movable.position.y,
maxY:viewRect.bottom-movableClientRect.bottom+movable.position.y
};
}
私有边界(可移动:可移动指令){
movable.position.x=Math.max(this.bounders.minX,
可移动(位置x);
movable.position.x=Math.min(this.bounders.maxX,movable.position.x);
movable.position.y=Math.max(this.bounders.minY,movable.position.y);
movable.position.y=Math.min(this.bounders.maxY,movable.position.y);
}
}
如果您已经拥有相对于容器元素的像素位置,则只需将px中的该值除以像素中容器的大小,然后将其乘以100:
perc_x = px_x / px_width * 100;
perc_y = px_y / px_height * 100;
elem=document.querySelector('.content');
container=document.querySelector('.container');
常数鼠标={
x:null,
y:空,
唐:错
};
让will_draw=false;
elem.onmousedown=e=>{
mouse.down=true;
};
onmouseup=e=>{
mouse.down=false;
};
document.onmousemove=e=>{
如果(!mouse.down){return;}
const container_rect=container.getBoundingClientRect();
//相对于容器,以px为单位
mouse.x=e.clientX-container_rect.left;
mouse.y=e.clientY-container_rect.top;
如果(!will_draw){
请求动画帧(绘制);
will_draw=true;
}
}
函数绘图(){
will_draw=false;
const{width,height}=container.getBoundingClientRect();
const perc_x=鼠标.x/宽度*100;
const perc_y=鼠标.y/高度*100;
//-5到中心(elem的宽度设置为10%)
elem.style.setProperty('left',(perc_x-5)+'%');
//-5到中心(elem的高度设置为10%)
elem.style.setProperty('top',(perc_y-5)+'%');
}
.container{
宽度:80vw;
高度:80vh;
边框:1px实心;
位置:相对位置;
}
.内容{
宽度:10%;
身高:10%;
位置:绝对位置;
最高:45%;
左:45%;
背景:绿色;
}
如果您已经拥有相对于容器元素的像素位置,则只需将px中的该值除以像素中容器的大小,然后将其乘以100:
perc_x = px_x / px_width * 100;
perc_y = px_y / px_height * 100;
elem=document.querySelector('.content');
container=document.querySelector('.container');
常数鼠标={
x:null,
y:空,
唐:错
};
让will_draw=false;
elem.onmousedown=e=>{
mouse.down=true;
};
onmouseup=e=>{
mouse.down=false;
};
document.onmousemove=e=>{
如果(!mouse.down){return;}
const container_rect=container.getBoundingClientRect();
//相对于容器,以px为单位
mouse.x=e.clientX-container_rect.left;
mouse.y=e.clientY-container_rect.top;
如果(!will_draw){
请求动画帧(绘制);
will_draw=true;
}
}
函数绘图(){
will_draw=false;
const{width,height}=container.getBoundingClientRect();
const perc_x=鼠标.x/宽度*100;
const perc_y=鼠标.y/高度*100;
//-5到中心(elem的宽度设置为10%)
elem.style.setProperty('left',(perc_x-5)+'%');
//-5到中心(elem的高度设置为10%)
elem.style.setProperty('top',(perc_y-5)+'%');
}
.container{
宽度:80vw;
高度:80vh;
边框:1px实心;
位置:相对位置;
}
.内容{
宽度:10%;
身高:10%;
位置:绝对位置;
最高:45%;
左:45%;
背景:绿色;