0

私はすでに px の親への子要素 ​​wrt の getBoundingClientRect() を使用して左と上の位置を計算し、あるコンポーネントから別のコンポーネントに渡し、期待される位置に子要素を配置することができますが、子要素を wrt に反応させたい親要素 、そのためには % で上と左の位置が必要です。コンソールから値と単位を 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 のみを行っていたため、値は pixel であったため、 viewRect.left で除算してから * 100 で割って % に変換しようとしましたが、パーセンテージ値は子を配置しません要素を正しく。

位置を計算するためのディレクティブによる更新

moving.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);
   }
   }
4

1 に答える 1