S
Everything turned out to be much easier than I thought. In my own writing, I went to the Material Library. https://material.angular.io/cdk/drag-drop/overview And I realized I could use it easily.
We're going to need a dropList, each element of which is allowed to move only on the axis x (cdkDragLockAxis="x) and a caste-pliseholder, where we're housed. It's the way I wanted it! It's not all the questions yet, but who's gonna need to be able to fix all the things. I hope that helps someone. All I have to do is hang out on swaips and clicks. How to identify the Material, not to describe it, but to show directly the implementation (please apologize for the name of the variables - they are tied to my context):HTML:<div cdkDropList class="tables-list" (cdkDropListDropped)="drop($event)"> <!-- метод cdkDropListDropped в моем случае не задействован, решил для вас оставить. -->
<div class="table-drag-box"
*ngFor="let table of myTables$ | async"
cdkDragLockAxis="x" cdkDrag
(cdkDragStarted)="swipeStarted($event)" (cdkDragMoved)="swipeMoved($event)" (cdkDragReleased)="swipeEnded($event)" (click)="showOrderDetails(table.id)">
<div class="custom-placeholder" *cdkDragPlaceholder>
<span class="left-icon" [ngStyle]="{'opacity': offsetDistance > 0 ? offsetPercent *4 : 0}"> <!--умножаем на 4, чтобы быстрее выводить иконку из прозрачности. -->
<mat-icon>credit_card</mat-icon> <!--Left swipe icon-->
<span>Send to payment</span>
</span>
<span class="fill-remaining-space"></span>
<span class="right-icon" [ngStyle]="{'opacity': offsetDistance < 0 ? offsetPercent *4 : 0}">
<mat-icon>close</mat-icon> <!--Right swipe icon-->
<span>Close all sessons</span>
</span>
</div>
<span> {{table.id}}</span>
</div>
</div>
CSS:.table-container, .table-drag-box {
height: 50px;
}
.table-drag-box{
width: 100vw;
background-color: white;
}
.left-icon, .right-icon{
position: absolute;
height: inherit;
display: flex;
align-items: center;
opacity: 0;
}
.right-icon{
right: 0;
}
.fill-remaining-space{
flex: 1 1 auto;
}
.cdk-drag-animating {
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}
.tables-list.cdk-drop-list-dragging .table-drag-box:not(.cdk-drag-placeholder) {
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}
.custom-placeholder {
background: #ccc;
min-height: 50px;
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}
TS:import { Component, OnInit, Input, ElementRef } from '@angular/core';
import { Observable } from 'rxjs';
import { CdkDragDrop } from '@angular/cdk/drag-drop';
import { FullscreenOverlayContainer } from '@angular/cdk/overlay';
@Component({
selector: 'tables',
templateUrl: './table.component.html',
styleUrls: ['./table.component.scss']
})
export class TableComponent implements OnInit {
@Input() tableId: string;
@Input() myTables$: Observable<object>;
offsetPercent: number = 0; //данное значение влияет на прозрачность иконок свайпа
offsetDistance: number = 0; //отрицательное значение отображает правую иконку, а положительное - левую.
constructor(private element:ElementRef) { }
ngOnInit() {
}
ngAfterViewInit() {
//this.elementWidth = this.elementView.nativeElement.offsetWidth;
}
swipeStarted($event){
//console.log("Started:" ,$event)
}
swipeMoved($event){
this.offsetDistance = $event.distance.x;
this.offsetPercent = Math.abs($event.distance.x / this.element.nativeElement.offsetWidth);
}
swipeEnded($event){
//зная % смещения можно выполнять различные действия. Вот, к примеру вот так:
if(this.offsetPercent > 0.25){
//таймер - это костыль так как нужно дождаться окончания анимации смещения элемента.
//Если вы знаете как подписаться на событие завершения анимации - ожидаю ваших комментариев. Заранее спасибо.
timer(250).subscribe(_ => {
switch (this.offsetDistance > 0) {
case true:
//TODO send to payment
this.showConfirmationDialog("Send orders on payment?")
.subscribe(result => {
console.log("TODO send to payment " + result)
return result;
})
break;
case false:
//TODO close sessions
this.showConfirmationDialog("Close all sessions on table " + tableOrders.table.location.deviceNameForLocation)
.subscribe(result => {
console.log("TODO close sessions: " + result)
return result;
})
break;
}
this.offsetDistance = 0;
this.offsetPercent = 0;
});
}
else{
this.offsetDistance = 0;
this.offsetPercent = 0;
}
}
drop(event: CdkDragDrop<string[]>) {
//console.log("drop: ",event)
//moveItemInArray(this.movies, event.previousIndex, event.currentIndex);
}
showOrderDetails(tableId){
//TODO open full-screen dialog
console.log(tableId);
}
}