Я уже вычисляю левую и верхнюю позиции, используя getBoundingClientRect() дочернего элемента по отношению к родительскому в px и переходя от одного компонента к другому, и могу размещать дочерние элементы в ожидаемых позициях, однако я хочу, чтобы дочерние элементы реагировали на родительский элемент, для этого мне нужны верхняя и левая позиции в % Я уже пытался изменить значения и единицу измерения с px на % с консоли и смог получить желаемую отзывчивость, однако попытка вычислить в процентах в коде не работает должным образом, это не помещает дочерний элемент в правильное положение, хотя достигается отзывчивость.
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, чтобы преобразовать его в %, но процентное значение не помещает дочерний элемент элементы правильно.
Обновление с директивами для расчета позиции
movable.directive В этом я вычисляю позиции 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);
}
}