Вы можете играть с молотком и использовать ударную нагрузку или использовать cdk DragDropModule.
У попытки есть что-то вроде
<div #picker class="gesture__zone">
<div #inner>
<div class="dragZone" cdkDrag cdkDragLockAxis="y" (cdkDragEnded)="onDrop($event)" >
</div>
<div #d class="item" [ngClass]="{'selected':i==value}"
*ngFor="let item of items;let i=index"
(click)="value=i;move(i)">
{{item}}</div>
</div>
</div>
Смотри, что мне нужен "picker", "inner" и «элемент» в качестве ссылочной переменной. Это позволяет нам получить их в ViewChild и иметь его меру
@ViewChild("d", { static: false, read: ElementRef }) item;
@ViewChild("picker", { static: false, read: ElementRef }) picker;
@ViewChild("inner", { static: false, read: ElementRef }) inner;
(я делаю так, что щелчок также меняет значение, потому что мне трудно сделать «перетаскивание»)
Если наш. css похоже на
.gesture__zone {
background-color: #efefef;
padding: 1.5rem;
margin: 10px;
border-radius: 3px;
height: 4rem;
width:3rem;
text-align: center;
overflow: hidden;
position:relative;
}
.item
{
padding:.5rem 0;
opacity:.3;
display:block;
margin:0 auto;
width:1rem;
background-color:white;
}
.item.selected
{
opacity:1;
}
.dragZone
{
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
background-color:transparent;
}
мы можем поиграть с событием onDrop - действительно, когда вы закончите перетаскивание -
onDrop(event)
{
const oldValue = this.value;
if (event.distance.y > 40 && this.value > 0)
{
if (event.distance.y>100 && this.value>2)
this.value-=2
else
this.value--;
}
if (event.distance.y < -40 && this.value < this.items.length - 1)
{
if (event.distance.y<-100 && this.value<this.items.length - 2)
this.value+=2
else
this.value++;
}
if (oldValue != this.value) {
this.move(this.value)
}
//this three lines of code make the "zone" return o the initial position
event.source.element.nativeElement.style.transform = 'none'
const source: any = event.source
source._passiveTransform = { x: 0, y: 0 }
}
"Перемещение" создает небольшую анимацию
move(value)
{
if (!this.picker || !this.item)
return;
const marginInit =
this.picker.nativeElement.clientHeight / 2 -
1 * this.item.nativeElement.clientHeight;
const offset =
marginInit - value * this.item.nativeElement.clientHeight;
const myAnimation = this.builder.build([
animate(this.timing, style({ marginTop: offset + "px" }))
]);
this.player = myAnimation.create(this.inner.nativeElement);
this.player.play();
this.onChange(this.items[value])
}
В stackblitz я делаю пользовательский элемент управления, реализующий ControlValueAccessor. Я надеюсь, что это даст вам представление о том, как сделать сборщик чисел