簡體   English   中英

使用 event.clientX 和 y 坐標刪除 Angular 中的 div 的最佳做法是什么?

[英]What is the best practice to delete a div in Angular with the event.clientX and y coordinates?

我為跳棋游戲動態創建了 64 個 div。 當我跳棋子時,我需要能夠刪除跳棋子。 我將如何跟蹤跳棋以刪除跳跳跳棋? 所有的 div 和圖像都有 id。 由於我使用的是 Angular cdkDragDrop,因此 event.target.id 和 event.target.value 不是一個選項。 我正在考慮將 event.clientX 和 event.clientY 值減去兩個方向的正方形高度並嘗試刪除 div。 我被困住了。 任何幫助,將不勝感激。

這是 HTML:

<div class="checkerboard-wrapper" cdkDropListGroup>
    <div #square *ngFor="let item of items;let i=index">
        <div id={{item.squareId}} class={{item.class}} cdkDropList [cdkDropListData]="item"
            (cdkDropListDropped)="drop($event)" (pointerdown)="getId($event, i)">
            <div *ngIf="newGame" class="images" (pointerdown)="grabChecker($event, i)"
                (pointerup)="placeChecker($event,id)" (cdkDragEnded)="onDragEnded($event)" cdkDrag>
                <div *cdkDragPlaceholder></div>
                <img appHide loading="lazy" *ngIf="item.img" id={{i}} class="checkerImg" src={{item.img}} />
            </div>
        </div>
    </div>
</div>

這是我的 ts 代碼:

import { AfterViewInit, Component, OnInit, Input, ViewChildren, QueryList, Renderer2 } from '@angular/core';
import { CdkDragDrop, CdkDragEnd, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop';
import { BreakpointState } from '@angular/cdk/layout';
import { HideDirective } from '../../directives/hide.directive';

import { SharedService } from '../../services/shared.service';
import { ScreenService } from '../../services/screen.service';

@Component({
  selector: 'app-checkerboard',
  templateUrl: './checkerboard.component.html',
  styleUrls: ['./checkerboard.component.css'],

})
export class CheckerboardComponent implements OnInit, AfterViewInit {

  isBelowLg: boolean = false;
  disabled: boolean = false;
  newGame: boolean = false;
  currentIndex;
  previousIndex;
  imgId: string;
  @ViewChildren(HideDirective) hideDirectives!: QueryList<HideDirective>;
@ViewChildren('square') squares: QueryList<ElementRef>
  xPointerGrabPosition: number;
  yPointerGrabPosition: number;
  xPointerReleasePosition: number;
  yPointerReleasePosition: number;
  items: Array<any> = [
    { squareId: '1-1', id: '1', class: 'square checkerboard-square-red', img: '' },
    { squareId: '1-2', id: '2', class: 'square checkerboard-square-black', img: ' ../../assets/images/beige-checker-piece.svg' },
    { squareId: '1-3', id: '3', class: 'square checkerboard-square-red', img: '' },
    { squareId: '1-4', id: '4', class: 'square checkerboard-square-black', img: ' ../../assets/images/beige-checker-piece.svg' },
    { squareId: '1-5', id: '5', class: 'square checkerboard-square-red', img: '' },
    { squareId: '1-6', id: '6', class: 'square checkerboard-square-black', img: ' ../../assets/images/beige-checker-piece.svg' },
    { squareId: '1-7', id: '7', class: 'square checkerboard-square-red', img: '' },
    { squareId: '1-8', id: '8', class: 'square checkerboard-square-black', img: ' ../../assets/images/beige-checker-piece.svg' },

    { squareId: '2-1', id: '9', class: 'square checkerboard-square-black', img: ' ../../assets/images/beige-checker-piece.svg' },
    { squareId: '2-2', id: '10', class: 'square checkerboard-square-red', img: '' },
    { squareId: '2-3', id: '11', class: 'square checkerboard-square-black', img: ' ../../assets/images/beige-checker-piece.svg' },
    { squareId: '2-4', id: '12', class: 'square checkerboard-square-red', img: '' },
    { squareId: '2-5', id: '13', class: 'square checkerboard-square-black', img: ' ../../assets/images/beige-checker-piece.svg' },
    { squareId: '2-6', id: '14', class: 'square checkerboard-square-red', img: '' },
    { squareId: '2-7', id: '15', class: 'square checkerboard-square-black', img: '../../assets/images/beige-checker-piece.svg' },
    { squareId: '2-8', id: '16', class: 'square checkerboard-square-red', img: '' },

    { squareId: '3-1', id: '17', class: 'square checkerboard-square-red', img: '' },
    { squareId: '3-2', id: '18', class: 'square checkerboard-square-black', img: '../../assets/images/beige-checker-piece.svg' },
    { squareId: '3-3', id: '19', class: 'square checkerboard-square-red', img: '' },
    { squareId: '3-4', id: '20', class: 'square checkerboard-square-black', img: '../../assets/images/beige-checker-piece.svg' },
    { squareId: '3-5', id: '21', class: 'square checkerboard-square-red', img: '' },
    { squareId: '3-6', id: '22', class: 'square checkerboard-square-black', img: '../../assets/images/beige-checker-piece.svg' },
    { squareId: '3-7', id: '23', class: 'square checkerboard-square-red', img: '' },
    { squareId: '3-8', id: '24', class: 'square checkerboard-square-black', img: '../../assets/images/beige-checker-piece.svg' },

    { squareId: '4-1', id: '25', class: 'square checkerboard-square-black', img: '' },
    { squareId: '4-2', id: '26', class: 'square checkerboard-square-red', img: '' },
    { squareId: '4-3', id: '27', class: 'square checkerboard-square-black', img: '' },
    { squareId: '4-4', id: '28', class: 'square checkerboard-square-red', img: '' },
    { squareId: '4-5', id: '29', class: 'square checkerboard-square-black', img: '' },
    { squareId: '4-6', id: '30', class: 'square checkerboard-square-red', img: '' },
    { squareId: '4-7', id: '31', class: 'square checkerboard-square-black', img: '' },
    { squareId: '4-8', id: '32', class: 'square checkerboard-square-red', img: '' },

    { squareId: '5-1', id: '33', class: 'square checkerboard-square-red', img: '' },
    { squareId: '5-2', id: '34', class: 'square checkerboard-square-black', img: '' },
    { squareId: '5-3', id: '35', class: 'square checkerboard-square-red', img: '' },
    { squareId: '5-4', id: '36', class: 'square checkerboard-square-black', img: '' },
    { squareId: '5-5', id: '37', class: 'square checkerboard-square-red', img: '' },
    { squareId: '5-6', id: '38', class: 'square checkerboard-square-black', img: '' },
    { squareId: '5-7', id: '39', class: 'square checkerboard-square-red', img: '' },
    { squareId: '5-8', id: '40', class: 'square checkerboard-square-black', img: '' },

    { squareId: '6-1', id: '41', class: 'square checkerboard-square-black', img: '../../assets/images/gray-checker-piece.svg' },
    { squareId: '6-2', id: '42', class: 'square checkerboard-square-red', img: '' },
    { squareId: '6-3', id: '43', class: 'square checkerboard-square-black', img: '../../assets/images/gray-checker-piece.svg' },
    { squareId: '6-4', id: '44', class: 'square checkerboard-square-red', img: '' },
    { squareId: '6-5', id: '45', class: 'square checkerboard-square-black', img: '../../assets/images/gray-checker-piece.svg' },
    { squareId: '6-6', id: '46', class: 'square checkerboard-square-red', img: '' },
    { squareId: '6-7', id: '47', class: 'square checkerboard-square-black', img: '../../assets/images/gray-checker-piece.svg' },
    { squareId: '6-8', id: '48', class: 'square checkerboard-square-red', img: '' },

    { squareId: '7-1', id: '49', class: 'square checkerboard-square-red', img: '' },
    { squareId: '7-2', id: '50', class: 'square checkerboard-square-black', img: '../../assets/images/gray-checker-piece.svg' },
    { squareId: '7-3', id: '51', class: 'square checkerboard-square-red', img: '' },
    { squareId: '7-4', id: '52', class: 'square checkerboard-square-black', img: '../../assets/images/gray-checker-piece.svg' },
    { squareId: '7-5', id: '53', class: 'square checkerboard-square-red', img: '' },
    { squareId: '7-6', id: '54', class: 'square checkerboard-square-black', img: '../../assets/images/gray-checker-piece.svg' },
    { squareId: '7-7', id: '55', class: 'square checkerboard-square-red', img: '' },
    { squareId: '7-8', id: '56', class: 'square checkerboard-square-black', img: '../../assets/images/gray-checker-piece.svg' },

    { squareId: '8-1', id: '57', class: 'square checkerboard-square-black', img: '../../assets/images/gray-checker-piece.svg' },
    { squareId: '8-2', id: '58', class: 'square checkerboard-square-red', img: '' },
    { squareId: '8-3', id: '59', class: 'square checkerboard-square-black', img: '../../assets/images/gray-checker-piece.svg' },
    { squareId: '8-4', id: '60', class: 'square checkerboard-square-red', img: '' },
    { squareId: '8-5', id: '61', class: 'square checkerboard-square-black', img: '../../assets/images/gray-checker-piece.svg' },
    { squareId: '8-6', id: '62', class: 'square checkerboard-square-red', img: '' },
    { squareId: '8-7', id: '63', class: 'square checkerboard-square-black', img: '../../assets/images/gray-checker-piece.svg' },
    { squareId: '8-8', id: '64', class: 'square checkerboard-square-red', img: '' },
  ];

  constructor(private sharedService: SharedService, private screenService: ScreenService) { }

  ngOnInit(): void {
    this.sharedService.sendStartGame().subscribe(data => this.addPieces());
    this.sharedService.sendEndGame().subscribe(data => this.newGame = data);
  }

  ngAfterViewInit(): void {
    this.screenService.isBelowLg().subscribe((isBelowLg: BreakpointState) => {
      this.isBelowLg = isBelowLg.matches;
    });

  }

  drop(event: CdkDragDrop<string[]>) {
    console.log(event.container.data[event.currentIndex]['id']);
    if (event.previousContainer === event.container) {
      moveItemInArray(this.items, event.previousIndex, event.currentIndex);
      this.previousIndex = this.items[event.previousIndex];
      this.currentIndex = this.items[event.currentIndex];
      console.log(event.container.data[event.currentIndex]['id']);
      // console.log('this.currentIndex', event.currentIndex);
      // console.log('this.previousIndex', event.previousIndex);
    } else {
      transferArrayItem(event.previousContainer.data,
        event.container.data,
        event.previousIndex,
        event.currentIndex);
      console.log(event.container.data[event.currentIndex]['id']);
      // console.log('this.currentIndex', event.currentIndex);
      // console.log('this.previousIndex', event.previousIndex);
    }
  }

  getId(event, id) {
    // console.log('event.target.id', event.target.id);
    // console.log('id', id);
    // console.log('this.currentIndex', event.currentIndex);
  }


  addPieces() {
    this.newGame = true;
    this.disabled = true;
    this.sharedService.player1Active.next(true);
  }

  onActivePlayer(player) {
  }

  grabChecker(event, index) {
    this.xPointerGrabPosition = event.clientX;
    this.yPointerGrabPosition = event.clientY;
 
  }

  placeChecker(event) {
    this.xPointerReleasePosition = event.clientX;
    this.yPointerReleasePosition = event.clientY;
   console.log('Squares', this.squares);
  }

  moveCheckers3(event) {
    console.log('Event from the pointer capture', event);
  }

  onDragEnded(event: CdkDragEnd, id): void {
    console.log('This is the id of thee item being dragged', id);
    console.log(event.source.getFreeDragPosition());
    let xPointerReleaseMinusGrab = (this.xPointerReleasePosition - this.xPointerGrabPosition);
    let xPointerGrabMinusRelease = (this.xPointerGrabPosition - this.xPointerReleasePosition);
    let yPointerReleaseMinusGrab = (this.yPointerReleasePosition - this.yPointerGrabPosition);
    let yPointerGrabMinusRelease = (this.yPointerGrabPosition - this.yPointerReleasePosition);
    let x;
    let y;
    if (xPointerGrabMinusRelease > 0) {
      x = xPointerGrabMinusRelease;
    } else if (xPointerReleaseMinusGrab > 0) {
      x = xPointerReleaseMinusGrab;
    }

    if (yPointerGrabMinusRelease > 0) {
      y = yPointerGrabMinusRelease;
    } else if (yPointerReleaseMinusGrab > 0) {
      y = yPointerReleaseMinusGrab;
    }
    console.log('x', x);
    console.log('y', y);

    if (this.isBelowLg) {
      if (x === undefined || y === undefined || y > 70 && x > 70 || x < 10 && y < 212 || x < 212 && y < 10) {
        event.source._dragRef.reset();
      }
    } else {

      if (x === undefined || y === undefined || x < 6 || y < 6 || y < 40 && x < 600 || x < 40 && y < 600 || x > 201 && y > 201) {
        event.source._dragRef.reset();
      }

    }
  }

  hideChecker(id: number) {
    console.log('id', id);
    this.hideDirectives.find((p) => p.id === id.toString()).shouldShow = 'none';
  }



}   

我在大學里創造了一個國際象棋,我理解你。 您可以通過多種方式解決此問題:

  1. 在您的 items Array 中創建一個 state 屬性並控制其中的位置。 或者。
  2. 使用 Angular Input()Output()指令在多個組件之間共享數據。 為了做到這一點,正方形應該是一個組件,如下所示:

 <div *ngIf="let item of items; i = index"> <div id="item.id" class="red-square"> <my-cool-component id="1" [item]="item" src="../assests/red-checker.svg"> </my-cool-component> </div> </div>

並且帶有位置的表邏輯可以是父組件中的變量。 把它想象成一個 excel 網格,你可以在其中保存每個單元格的位置,以便知道上面有什么棋子。

我希望這可以幫助你!

我想發表一些我的評論。 想象一個二維數組“板”

但首先我定義一個枚舉來幫助我定義板上的部分

export enum TYPE{
  none,
  empty,
  whitePeon,
  whiteChecker,
  blackPeon,
  blackChecker
}

函數 initBoard 可以像

  initBoard()
  {
    [0,1,2,3,4,5,6,7].forEach(x=>{
      this.board[x]=[0,1,2,3,4,5,6,7].map(y=>({
        x:x,y:y,type:(x%2==0 && y%2==1) || (x%2==1 && y%2==0) ?
              x<3?TYPE.whitePeon:
              x>4?TYPE.blackPeon:
              TYPE.empty:
              TYPE.none
      }))
    })

  }

因此,例如 board[0][0].type=TYPE.None 和 board 0 .type=TYPE.whitePeon

如果我們在“白色”scaques 中使用 cdkDropList 制作一個板子

<div cdkDropListGroup>
  <div class="flex" *ngFor="let row of board; let rowOdd = odd">
    <ng-container *ngFor="let cell of row; let colOdd = odd">
      <div
        class="cell"
        [class.black]="(rowOdd && colOdd) || (!rowOdd && !colOdd)"
      >
        <div
          *ngIf="cell.type != TYPE.none"
          cdkDropList cdkDropListOrientation="horizontal"
          [cdkDropListData]="cell"
          (cdkDropListDropped)="drop($event)"
        >
          <div cdkDrag *ngIf="cell.type!=TYPE.empty">{{ cell.x }}{{ cell.y }}{{ cell.type }}
          <div *cdkDragPlaceholder class="none"></div>
          </div>
        </div>
      </div>
    </ng-container>
  </div>
</div>

我們只需要使用函數 drop

  drop(event: CdkDragDrop<any>){
    console.log(event.container.data,event.previousContainer.data)
  }

看到在 event.containerData 和 event.previousContainer.data 我們有一個 board 元素。 所以“只”我們需要檢查移動是否有效,我們可以將一塊放在另一個地方,......

例如這個

  drop(event: CdkDragDrop<any>){
    if (event.container.data.type==TYPE.empty)
    {
      event.container.data.type=event.previousContainer.data.type
      event.previousContainer.data.type=TYPE.empty
    }
  }

如果我們在棋盤中拖入一個空方塊,則移動一塊(我們還需要檢查移動是否有效,這只是如何使用事件數據更改“棋盤”數組的示例

“啟動堆棧閃電戰”

注意:我更喜歡使用枚舉並在 .html 中顯示一個或另一個圖像,但請記住變量是由我們選擇的,我們可以使用更舒適的

在重新思考如何進行跳棋后,我覺得“關鍵”是能夠掌握棋子的可能動作。

我想像一個二維陣列板在路上

board=[ 
  [ { "x": 0, "y": 0, "type": -1 }, 
    { "x": 1, "y": 0, "type": 1 }, 
    { "x": 2, "y": 0, "type": -1 }, 
    { "x": 3, "y": 0, "type": 1 }
    ....]
  [ { "x": 0, "y": 1, "type": 1 }, 
    { "x": 1, "y": 1, "type": -1 }, 
    { "x": 2, "y": 1, "type": 1 }, 
    { "x": 3, "y": 1, "type": -1 }
    ....]
 ] 

類型可以是 none,empty,black,white,blackKing 和 whiteKing

我們需要一個 function 需要 arguments: x, y 並鍵入並返回一個數組,其中包含可能的移動方式

  getMovements(x: number, y: number, type: number) {
    const mov:any=[]
    ....
    const elementOfBoard=this.board[index]
    const elementDelete=this.board[anotherIndex] || null
    ...
    mov.push(move:elementOfBoard,delete:elementDelete)
    ...
    return mov;
  }

所以可以返回,例如

[ 
  { "move": { "x": 5, "y": 2, "type": 0 }, 
    "delete": { "x": 4, "y": 3, "type": 1 } 
  }, 
  { "move": { "x": 2, "y": 3, "type": 0 }, 
    "delete": null } 
] 

真的不要返回一個新的 object,否則 this.board 的一個元素所以我們的 drop function 更簡單

  drop(event: CdkDragDrop<any>) {
    const fromData = event.previousContainer.data;
    const toData = event.container.data;

      const allowMovements = this.getMovements(
        fromData.x,
        fromData.y,
        fromData.type
      );
      const move = allowMovements.find((x) => x.move == toData);
      if (move) { //<--(move.move) is an element of board
         ....
         fromData.type=TYPE.empty;

         move.move.type=TYPE.pieceWeMove

         if (move.delete) { //<---is an element of board
           ...
           move.delete.type=TYPE.empty
         }
      }
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM