src/app/shared/components/rotation-slider/rotation-slider.component.ts
Component that enables the setting of a Rotation object via either 3 draggable sliders or through an Input method.
changeDetection | ChangeDetectionStrategy.OnPush |
selector | ccf-rotation-slider |
styleUrls | ./rotation-slider.component.scss |
templateUrl | ./rotation-slider.component.html |
Properties |
|
Methods |
Inputs |
Outputs |
HostBindings |
constructor(ga: GoogleAnalyticsService)
|
||||||||
Creates an instance of rotation slider component.
Parameters :
|
rotation | |
Type : Rotation
|
|
Default value : DEFAULT_ROTATION
|
|
Input that allows the rotation to be changed from outside of the component |
rotationChange | |
Type : EventEmitter
|
|
Output that emits the new rotation whenever it is changed from within the component |
class |
Type : "ccf-rotation-slider"
|
Default value : 'ccf-rotation-slider'
|
HTML class name |
changeRotation | ||||||||||||
changeRotation(newRotation: number | string, axis: string)
|
||||||||||||
Function that handles updating the rotation and emitting the new value If rotation value is < -180 or > 180, set to -180 or 180
Parameters :
Returns :
void
|
resetRotation | ||||||
resetRotation(dimension: "x" | "y" | "z")
|
||||||
Function to easily reset the rotations to 0 and emit this change.
Parameters :
Returns :
void
|
Readonly clsName |
Type : string
|
Default value : 'ccf-rotation-slider'
|
Decorators :
@HostBinding('class')
|
HTML class name |
import { ChangeDetectionStrategy, Component, EventEmitter, HostBinding, Input, Output } from '@angular/core';
import { GoogleAnalyticsService } from 'ngx-google-analytics';
/** Type in which the values of the sliders are stored. */
export interface Rotation {
/** X slider value */
x: number;
/** Y slider value */
y: number;
/** Z slider value */
z: number;
}
/** Default values for rotation. */
const DEFAULT_ROTATION: Rotation = {
x: 0,
y: 0,
z: 0,
};
/**
* Component that enables the setting of a Rotation object via either 3 draggable sliders
* or through an Input method.
*/
@Component({
selector: 'ccf-rotation-slider',
templateUrl: './rotation-slider.component.html',
styleUrls: ['./rotation-slider.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class RotationSliderComponent {
/** HTML class name */
@HostBinding('class') readonly clsName = 'ccf-rotation-slider';
/** Input that allows the rotation to be changed from outside of the component */
@Input() rotation = DEFAULT_ROTATION;
/** Output that emits the new rotation whenever it is changed from within the component */
@Output() readonly rotationChange = new EventEmitter<Rotation>();
/**
* Creates an instance of rotation slider component.
*
* @param ga Analytics service
*/
constructor(private readonly ga: GoogleAnalyticsService) {}
/**
* Function that handles updating the rotation and emitting the new value
* If rotation value is < -180 or > 180, set to -180 or 180
* @param newRotation the new value for one of the axis to be set to
* @param axis which axis to update
*/
changeRotation(newRotation: number | string, axis: string): void {
const updatedNewRotation = +newRotation > 180 ? 180 : +newRotation < -180 ? -180 : +newRotation;
this.rotation = { ...this.rotation, [axis]: +updatedNewRotation };
this.ga.event('rotation_update', 'rotation_slider', axis, +updatedNewRotation);
this.rotationChange.emit(this.rotation);
}
/**
* Function to easily reset the rotations to 0 and emit this change.
*/
resetRotation(dimension: 'x' | 'y' | 'z'): void {
this.rotation = { ...this.rotation, [dimension]: 0 };
this.ga.event('rotation_reset', 'rotation_slider');
this.rotationChange.emit(this.rotation);
}
}
<div class="header">
<span class="text title" matTooltip="Use sliders below to rotate tissue block for registration"
>Tissue Block Rotation</span
>
<div class="filler"></div>
<div class="refresh-button-container">
<mat-icon
matRipple
[matRippleCentered]="true"
[matRippleUnbounded]="true"
class="icon reset"
(click)="resetRotation('x'); resetRotation('y'); resetRotation('z')"
>refresh</mat-icon
>
</div>
</div>
<div class="slider-box red">
<span class="text label">X</span>
<div class="slider-container">
<mat-slider class="slider" [max]="180" [min]="-180" disableRipple discrete>
<input
class="slider-x"
matSliderThumb
[value]="rotation.x"
(input)="changeRotation(sliderX.value, 'x')"
#sliderX
/>
</mat-slider>
</div>
<mat-form-field>
<input
matInput
class="input"
type="number"
[value]="rotation.x"
[min]="-180"
[max]="180"
(change)="changeRotation($any($event.target).value, 'x')"
/>
</mat-form-field>
</div>
<div class="slider-box green">
<span class="text label">Y</span>
<div class="slider-container">
<mat-slider class="slider" [max]="180" [min]="-180" disableRipple discrete>
<input
class="slider-y"
matSliderThumb
[value]="rotation.y"
(input)="changeRotation(sliderY.value, 'y')"
#sliderY
/>
</mat-slider>
</div>
<mat-form-field>
<input
matInput
class="input"
type="number"
[value]="rotation.y"
[min]="-180"
[max]="180"
(change)="changeRotation($any($event.target).value, 'y')"
/>
</mat-form-field>
</div>
<div class="slider-box blue">
<span class="text label">Z</span>
<div class="slider-container">
<mat-slider class="slider" [max]="180" [min]="-180" disableRipple discrete>
<input
class="slider-z"
matSliderThumb
[value]="rotation.z"
(input)="changeRotation(sliderZ.value, 'z')"
#sliderZ
/>
</mat-slider>
</div>
<mat-form-field>
<input
matInput
class="input"
type="number"
[value]="rotation.z"
[min]="-180"
[max]="180"
(change)="changeRotation($any($event.target).value, 'z')"
/>
</mat-form-field>
</div>
./rotation-slider.component.scss
:host {
.header {
display: flex;
align-items: center;
justify-content: space-between;
height: 1.5rem;
padding: 0.5rem 0;
.title {
font-weight: 400;
padding: 0.5rem 0;
}
}
.reset {
transform: scaleX(-1);
cursor: pointer;
transition: 0.6s;
&:hover {
border-radius: 2px;
}
}
.refresh-button-container {
display: flex;
height: 1rem;
justify-content: flex-end;
}
.slider-box {
display: flex;
justify-content: space-between;
align-items: center;
height: 4rem;
mat-form-field {
height: 100%;
width: 5rem;
::ng-deep .mdc-text-field {
padding: 0;
}
.input {
text-align: center;
}
}
.slider-container {
width: 100%;
padding-left: 0.5rem;
padding-right: 2rem;
.slider {
width: 100%;
}
::ng-deep mat-slider-visual-thumb {
transition: none;
}
}
.filler {
flex-grow: 1;
}
}
}