Saya sudah menghitung posisi kiri dan atas menggunakan getBoundingClientRect() dari elemen anak wrt ke induk di px dan meneruskan dari satu komponen ke komponen lainnya, dan dapat menempatkan elemen anak pada posisi yang diharapkan, namun saya ingin membuat elemen anak responsif wrt ke elemen induk , untuk itu saya perlu posisi atas dan kiri di % Saya sudah mencoba mengubah nilai dan unit dari px ke % dari konsol dan bisa mendapatkan respons yang diinginkan, namun mencoba menghitung dalam persentase dalam kode tidak berfungsi seperti yang diharapkan, itu tidak menempatkan elemen anak pada posisi yang benar, meskipun responsivitas tercapai.

  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
  }

Pada kode sebelumnya saya hanya melakukan viewRect.left - movableClientRect.left , jadi nilainya dalam piksel, dan sekarang saya mencoba membagi dengan viewRect.left dan kemudian * 100 untuk mengubahnya menjadi % tetapi nilai persentase tidak menempatkan anak elemen dengan benar.

Memperbarui dengan arahan untuk menghitung posisi

Movable.directive Dalam hal ini saya menghitung pos x dan y dari elemen anak

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};
    }
   }
   }

Arahan di mana saya menghitung kiri dan atas elemen anak dan menugaskannya ke 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);
   }
   }
0
Enthu 14 Agustus 2019, 18:30

1 menjawab

Jawaban Terbaik

Jika Anda sudah memiliki posisi dalam piksel relatif terhadap elemen wadah, maka yang Anda butuhkan hanyalah membagi nilai ini dalam px dengan ukuran wadah dalam piksel dan mengalikannya dengan 100:

perc_x = px_x / px_width * 100;
perc_y = px_y / px_height * 100;
elem = document.querySelector('.content');
container = document.querySelector('.container');
const mouse = {
  x: null,
  y: null,
  down: false
};
let will_draw = false;

elem.onmousedown = e => {
  mouse.down = true;
};
onmouseup = e => {
  mouse.down = false;
};
document.onmousemove = e => {
  if(!mouse.down) { return; }

  const container_rect = container.getBoundingClientRect();
  // relative to container, in px
  mouse.x = e.clientX - container_rect.left;
  mouse.y = e.clientY - container_rect.top;
  if(!will_draw) {
    requestAnimationFrame(draw);
    will_draw = true;
  }
}

function draw() {
  will_draw = false;
  const { width, height} = container.getBoundingClientRect();
  const perc_x = mouse.x / width * 100;
  const perc_y = mouse.y / height * 100;
  // -5 to center (elem has its width set to 10%)
  elem.style.setProperty('left', (perc_x - 5) + '%');
  // -5 to center (elem has its height set to 10%)
  elem.style.setProperty('top', (perc_y - 5) + '%');
}
.container {
  width: 80vw;
  height: 80vh;
  border: 1px solid;
  position: relative;
}
.content {
  width: 10%;
  height: 10%;
  position: absolute;
  top: 45%;
  left: 45%;
  background: green;
}
<div class="container">
  <div class="content">
  </div>
</div>
2
Kaiido 15 Agustus 2019, 03:21