1 | import * as i0 from '@angular/core';
|
---|
2 | import { forwardRef, EventEmitter, Component, ChangeDetectionStrategy, ViewEncapsulation, Input, Output, NgModule } from '@angular/core';
|
---|
3 | import * as i1 from '@angular/common';
|
---|
4 | import { CommonModule } from '@angular/common';
|
---|
5 | import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
---|
6 |
|
---|
7 | const KNOB_VALUE_ACCESSOR = {
|
---|
8 | provide: NG_VALUE_ACCESSOR,
|
---|
9 | useExisting: forwardRef(() => Knob),
|
---|
10 | multi: true
|
---|
11 | };
|
---|
12 | class Knob {
|
---|
13 | constructor(cd, el) {
|
---|
14 | this.cd = cd;
|
---|
15 | this.el = el;
|
---|
16 | this.valueColor = "var(--primary-color, Black)";
|
---|
17 | this.rangeColor = "var(--surface-d, LightGray)";
|
---|
18 | this.textColor = "var(--text-color-secondary, Black)";
|
---|
19 | this.valueTemplate = "{value}";
|
---|
20 | this.size = 100;
|
---|
21 | this.step = 1;
|
---|
22 | this.min = 0;
|
---|
23 | this.max = 100;
|
---|
24 | this.strokeWidth = 14;
|
---|
25 | this.showValue = true;
|
---|
26 | this.readonly = false;
|
---|
27 | this.onChange = new EventEmitter();
|
---|
28 | this.radius = 40;
|
---|
29 | this.midX = 50;
|
---|
30 | this.midY = 50;
|
---|
31 | this.minRadians = 4 * Math.PI / 3;
|
---|
32 | this.maxRadians = -Math.PI / 3;
|
---|
33 | this.value = null;
|
---|
34 | this.onModelChange = () => { };
|
---|
35 | this.onModelTouched = () => { };
|
---|
36 | }
|
---|
37 | mapRange(x, inMin, inMax, outMin, outMax) {
|
---|
38 | return (x - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;
|
---|
39 | }
|
---|
40 | onClick(event) {
|
---|
41 | if (!this.disabled && !this.readonly) {
|
---|
42 | this.updateValue(event.offsetX, event.offsetY);
|
---|
43 | }
|
---|
44 | }
|
---|
45 | updateValue(offsetX, offsetY) {
|
---|
46 | let dx = offsetX - this.size / 2;
|
---|
47 | let dy = this.size / 2 - offsetY;
|
---|
48 | let angle = Math.atan2(dy, dx);
|
---|
49 | let start = -Math.PI / 2 - Math.PI / 6;
|
---|
50 | this.updateModel(angle, start);
|
---|
51 | }
|
---|
52 | updateModel(angle, start) {
|
---|
53 | let mappedValue;
|
---|
54 | if (angle > this.maxRadians)
|
---|
55 | mappedValue = this.mapRange(angle, this.minRadians, this.maxRadians, this.min, this.max);
|
---|
56 | else if (angle < start)
|
---|
57 | mappedValue = this.mapRange(angle + 2 * Math.PI, this.minRadians, this.maxRadians, this.min, this.max);
|
---|
58 | else
|
---|
59 | return;
|
---|
60 | let newValue = Math.round((mappedValue - this.min) / this.step) * this.step + this.min;
|
---|
61 | this.value = newValue;
|
---|
62 | this.onModelChange(this.value);
|
---|
63 | this.onChange.emit(this.value);
|
---|
64 | }
|
---|
65 | onMouseDown(event) {
|
---|
66 | if (!this.disabled && !this.readonly) {
|
---|
67 | this.windowMouseMoveListener = this.onMouseMove.bind(this);
|
---|
68 | this.windowMouseUpListener = this.onMouseUp.bind(this);
|
---|
69 | window.addEventListener('mousemove', this.windowMouseMoveListener);
|
---|
70 | window.addEventListener('mouseup', this.windowMouseUpListener);
|
---|
71 | event.preventDefault();
|
---|
72 | }
|
---|
73 | }
|
---|
74 | onMouseUp(event) {
|
---|
75 | if (!this.disabled && !this.readonly) {
|
---|
76 | window.removeEventListener('mousemove', this.windowMouseMoveListener);
|
---|
77 | window.removeEventListener('mouseup', this.windowMouseUpListener);
|
---|
78 | this.windowMouseUpListener = null;
|
---|
79 | this.windowMouseMoveListener = null;
|
---|
80 | event.preventDefault();
|
---|
81 | }
|
---|
82 | }
|
---|
83 | onTouchStart(event) {
|
---|
84 | if (!this.disabled && !this.readonly) {
|
---|
85 | this.windowTouchMoveListener = this.onTouchMove.bind(this);
|
---|
86 | this.windowTouchEndListener = this.onTouchEnd.bind(this);
|
---|
87 | window.addEventListener('touchmove', this.windowTouchMoveListener);
|
---|
88 | window.addEventListener('touchend', this.windowTouchEndListener);
|
---|
89 | event.preventDefault();
|
---|
90 | }
|
---|
91 | }
|
---|
92 | onTouchEnd(event) {
|
---|
93 | if (!this.disabled && !this.readonly) {
|
---|
94 | window.removeEventListener('touchmove', this.windowTouchMoveListener);
|
---|
95 | window.removeEventListener('touchend', this.windowTouchEndListener);
|
---|
96 | this.windowTouchMoveListener = null;
|
---|
97 | this.windowTouchEndListener = null;
|
---|
98 | event.preventDefault();
|
---|
99 | }
|
---|
100 | }
|
---|
101 | onMouseMove(event) {
|
---|
102 | if (!this.disabled && !this.readonly) {
|
---|
103 | this.updateValue(event.offsetX, event.offsetY);
|
---|
104 | event.preventDefault();
|
---|
105 | }
|
---|
106 | }
|
---|
107 | onTouchMove(event) {
|
---|
108 | if (!this.disabled && !this.readonly && event.touches.length == 1) {
|
---|
109 | const rect = this.el.nativeElement.children[0].getBoundingClientRect();
|
---|
110 | const touch = event.targetTouches.item(0);
|
---|
111 | const offsetX = touch.clientX - rect.left;
|
---|
112 | const offsetY = touch.clientY - rect.top;
|
---|
113 | this.updateValue(offsetX, offsetY);
|
---|
114 | }
|
---|
115 | }
|
---|
116 | writeValue(value) {
|
---|
117 | this.value = value;
|
---|
118 | this.cd.markForCheck();
|
---|
119 | }
|
---|
120 | registerOnChange(fn) {
|
---|
121 | this.onModelChange = fn;
|
---|
122 | }
|
---|
123 | registerOnTouched(fn) {
|
---|
124 | this.onModelTouched = fn;
|
---|
125 | }
|
---|
126 | setDisabledState(val) {
|
---|
127 | this.disabled = val;
|
---|
128 | this.cd.markForCheck();
|
---|
129 | }
|
---|
130 | containerClass() {
|
---|
131 | return {
|
---|
132 | 'p-knob p-component': true,
|
---|
133 | 'p-disabled': this.disabled
|
---|
134 | };
|
---|
135 | }
|
---|
136 | rangePath() {
|
---|
137 | return `M ${this.minX()} ${this.minY()} A ${this.radius} ${this.radius} 0 1 1 ${this.maxX()} ${this.maxY()}`;
|
---|
138 | }
|
---|
139 | valuePath() {
|
---|
140 | return `M ${this.zeroX()} ${this.zeroY()} A ${this.radius} ${this.radius} 0 ${this.largeArc()} ${this.sweep()} ${this.valueX()} ${this.valueY()}`;
|
---|
141 | }
|
---|
142 | zeroRadians() {
|
---|
143 | if (this.min > 0 && this.max > 0)
|
---|
144 | return this.mapRange(this.min, this.min, this.max, this.minRadians, this.maxRadians);
|
---|
145 | else
|
---|
146 | return this.mapRange(0, this.min, this.max, this.minRadians, this.maxRadians);
|
---|
147 | }
|
---|
148 | valueRadians() {
|
---|
149 | return this.mapRange(this._value, this.min, this.max, this.minRadians, this.maxRadians);
|
---|
150 | }
|
---|
151 | minX() {
|
---|
152 | return this.midX + Math.cos(this.minRadians) * this.radius;
|
---|
153 | }
|
---|
154 | minY() {
|
---|
155 | return this.midY - Math.sin(this.minRadians) * this.radius;
|
---|
156 | }
|
---|
157 | maxX() {
|
---|
158 | return this.midX + Math.cos(this.maxRadians) * this.radius;
|
---|
159 | }
|
---|
160 | maxY() {
|
---|
161 | return this.midY - Math.sin(this.maxRadians) * this.radius;
|
---|
162 | }
|
---|
163 | zeroX() {
|
---|
164 | return this.midX + Math.cos(this.zeroRadians()) * this.radius;
|
---|
165 | }
|
---|
166 | zeroY() {
|
---|
167 | return this.midY - Math.sin(this.zeroRadians()) * this.radius;
|
---|
168 | }
|
---|
169 | valueX() {
|
---|
170 | return this.midX + Math.cos(this.valueRadians()) * this.radius;
|
---|
171 | }
|
---|
172 | valueY() {
|
---|
173 | return this.midY - Math.sin(this.valueRadians()) * this.radius;
|
---|
174 | }
|
---|
175 | largeArc() {
|
---|
176 | return Math.abs(this.zeroRadians() - this.valueRadians()) < Math.PI ? 0 : 1;
|
---|
177 | }
|
---|
178 | sweep() {
|
---|
179 | return this.valueRadians() > this.zeroRadians() ? 0 : 1;
|
---|
180 | }
|
---|
181 | valueToDisplay() {
|
---|
182 | return this.valueTemplate.replace("{value}", this._value.toString());
|
---|
183 | }
|
---|
184 | get _value() {
|
---|
185 | return this.value != null ? this.value : this.min;
|
---|
186 | }
|
---|
187 | }
|
---|
188 | Knob.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: Knob, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
---|
189 | Knob.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.0", type: Knob, selector: "p-knob", inputs: { styleClass: "styleClass", style: "style", severity: "severity", valueColor: "valueColor", rangeColor: "rangeColor", textColor: "textColor", valueTemplate: "valueTemplate", name: "name", size: "size", step: "step", min: "min", max: "max", strokeWidth: "strokeWidth", disabled: "disabled", showValue: "showValue", readonly: "readonly" }, outputs: { onChange: "onChange" }, host: { classAttribute: "p-element" }, providers: [KNOB_VALUE_ACCESSOR], ngImport: i0, template: `
|
---|
190 | <div [ngClass]="containerClass()" [class]="styleClass" [ngStyle]="style">
|
---|
191 | <svg viewBox="0 0 100 100" [style.width]="size + 'px'" [style.height]="size + 'px'" (click)="onClick($event)" (mousedown)="onMouseDown($event)" (mouseup)="onMouseUp($event)"
|
---|
192 | (touchstart)="onTouchStart($event)" (touchend)="onTouchEnd($event)">
|
---|
193 | <path [attr.d]="rangePath()" [attr.stroke-width]="strokeWidth" [attr.stroke]="rangeColor" class="p-knob-range"></path>
|
---|
194 | <path [attr.d]="valuePath()" [attr.stroke-width]="strokeWidth" [attr.stroke]="valueColor" class="p-knob-value"></path>
|
---|
195 | <text *ngIf="showValue" [attr.x]="50" [attr.y]="57" text-anchor="middle" [attr.fill]="textColor" class="p-knob-text" [attr.name]="name">{{valueToDisplay()}}</text>
|
---|
196 | </svg>
|
---|
197 | </div>
|
---|
198 | `, isInline: true, styles: ["@keyframes dash-frame{to{stroke-dashoffset:0}}.p-knob-range{fill:none;transition:stroke .1s ease-in}.p-knob-value{animation-name:dash-frame;animation-fill-mode:forwards;fill:none}.p-knob-text{font-size:1.3rem;text-align:center}\n"], directives: [{ type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
---|
199 | i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: Knob, decorators: [{
|
---|
200 | type: Component,
|
---|
201 | args: [{ selector: 'p-knob', template: `
|
---|
202 | <div [ngClass]="containerClass()" [class]="styleClass" [ngStyle]="style">
|
---|
203 | <svg viewBox="0 0 100 100" [style.width]="size + 'px'" [style.height]="size + 'px'" (click)="onClick($event)" (mousedown)="onMouseDown($event)" (mouseup)="onMouseUp($event)"
|
---|
204 | (touchstart)="onTouchStart($event)" (touchend)="onTouchEnd($event)">
|
---|
205 | <path [attr.d]="rangePath()" [attr.stroke-width]="strokeWidth" [attr.stroke]="rangeColor" class="p-knob-range"></path>
|
---|
206 | <path [attr.d]="valuePath()" [attr.stroke-width]="strokeWidth" [attr.stroke]="valueColor" class="p-knob-value"></path>
|
---|
207 | <text *ngIf="showValue" [attr.x]="50" [attr.y]="57" text-anchor="middle" [attr.fill]="textColor" class="p-knob-text" [attr.name]="name">{{valueToDisplay()}}</text>
|
---|
208 | </svg>
|
---|
209 | </div>
|
---|
210 | `, providers: [KNOB_VALUE_ACCESSOR], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
|
---|
211 | 'class': 'p-element'
|
---|
212 | }, styles: ["@keyframes dash-frame{to{stroke-dashoffset:0}}.p-knob-range{fill:none;transition:stroke .1s ease-in}.p-knob-value{animation-name:dash-frame;animation-fill-mode:forwards;fill:none}.p-knob-text{font-size:1.3rem;text-align:center}\n"] }]
|
---|
213 | }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }]; }, propDecorators: { styleClass: [{
|
---|
214 | type: Input
|
---|
215 | }], style: [{
|
---|
216 | type: Input
|
---|
217 | }], severity: [{
|
---|
218 | type: Input
|
---|
219 | }], valueColor: [{
|
---|
220 | type: Input
|
---|
221 | }], rangeColor: [{
|
---|
222 | type: Input
|
---|
223 | }], textColor: [{
|
---|
224 | type: Input
|
---|
225 | }], valueTemplate: [{
|
---|
226 | type: Input
|
---|
227 | }], name: [{
|
---|
228 | type: Input
|
---|
229 | }], size: [{
|
---|
230 | type: Input
|
---|
231 | }], step: [{
|
---|
232 | type: Input
|
---|
233 | }], min: [{
|
---|
234 | type: Input
|
---|
235 | }], max: [{
|
---|
236 | type: Input
|
---|
237 | }], strokeWidth: [{
|
---|
238 | type: Input
|
---|
239 | }], disabled: [{
|
---|
240 | type: Input
|
---|
241 | }], showValue: [{
|
---|
242 | type: Input
|
---|
243 | }], readonly: [{
|
---|
244 | type: Input
|
---|
245 | }], onChange: [{
|
---|
246 | type: Output
|
---|
247 | }] } });
|
---|
248 | class KnobModule {
|
---|
249 | }
|
---|
250 | KnobModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: KnobModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
---|
251 | KnobModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: KnobModule, declarations: [Knob], imports: [CommonModule], exports: [Knob] });
|
---|
252 | KnobModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: KnobModule, imports: [[CommonModule]] });
|
---|
253 | i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: KnobModule, decorators: [{
|
---|
254 | type: NgModule,
|
---|
255 | args: [{
|
---|
256 | imports: [CommonModule],
|
---|
257 | exports: [Knob],
|
---|
258 | declarations: [Knob]
|
---|
259 | }]
|
---|
260 | }] });
|
---|
261 |
|
---|
262 | /**
|
---|
263 | * Generated bundle index. Do not edit.
|
---|
264 | */
|
---|
265 |
|
---|
266 | export { KNOB_VALUE_ACCESSOR, Knob, KnobModule };
|
---|