-
-
Notifications
You must be signed in to change notification settings - Fork 23
/
knob.js
112 lines (102 loc) · 2.93 KB
/
knob.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import Input from "@pencil.js/input";
import Component from "@pencil.js/component";
import Circle from "@pencil.js/circle";
import Line from "@pencil.js/line";
import MouseEvent from "@pencil.js/mouse-event";
import BaseEvent from "@pencil.js/base-event";
import { map, modulo } from "@pencil.js/math";
import "@pencil.js/rotatable";
/**
* @module Knob
*/
/**
* Knob class
* <br><img src="./media/examples/knob.png" alt="knob demo"/>
* @class
* @extends {module:Input}
*/
export default class Knob extends Input {
/**
* knob constructor
* @param {PositionDefinition} positionDefinition - Position of the center
* @param {KnobOptions} [options] - Specific options
*/
constructor (positionDefinition, options) {
super(positionDefinition, Circle, options);
const origin = this.getOrigin();
this.options.rotationCenter = origin;
const strokeWidth = this.options.radius * Knob.NOTCH_SIZE;
const margin = this.options.radius / 3;
const notch = new Line([0, -margin], [[0, -this.options.radius + margin + strokeWidth]], {
stroke: this.options.foreground,
strokeWidth,
cursor: Component.cursors.grab,
origin,
});
this
.add(notch)
.on(MouseEvent.events.rotate, () => this.fire(new BaseEvent(Knob.events.change, this)), true)
.rotatable();
}
/**
* Get this knob's radius
* @return {Number}
*/
get radius () {
return this.options.radius;
}
/**
* Set this knob's radius
* @param {Number} value - Radius of the knob
*/
set radius (value) {
this.options.radius = value;
}
/**
* @inheritDoc
*/
click () { // eslint-disable-line class-methods-use-this
// Do nothing
}
/**
* Returns this current value
* @return {Number}
*/
get value () {
return map(modulo(this.options.rotation, 1), 0, 1, this.options.min, this.options.max);
}
/**
* Change this current value
* @param {Number} newValue - A new value to set
*/
set value (newValue) {
this.options.rotation = modulo(map(newValue, this.options.min, this.options.max, 0, 1), 1);
}
/**
* @typedef {Object} KnobOptions
* @prop {Number} [min=0] - Minimum value when the knob is at lowest
* @prop {Number} [max=10] - Maximum value when the knob is at highest
* @prop {Number} [value=0] - Initial value
* @prop {Number} [radius=100] - Radius of the knob
*/
/**
* @type {KnobOptions}
*/
static get defaultOptions () {
return {
...super.defaultOptions,
cursor: Component.cursors.default,
min: 0,
max: 1,
value: 0,
radius: 100,
};
}
/**
* Width of the rotation marker
* @type {Number}
*/
static get NOTCH_SIZE () {
return 0.09;
}
}