-
Notifications
You must be signed in to change notification settings - Fork 38
/
Copy pathcircular.js
96 lines (85 loc) · 2.47 KB
/
circular.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
class CircularSlider extends HTMLElement {
constructor() {
super();
this.__angle = 0;
this.addEventListener("mousedown", this.__handleMouseDown);
window.addEventListener("mouseup", event => this.__handleMouseUp(event));
window.addEventListener("mousemove", event => this.__handleMouseMove(event));
const dot = document.createElement("div");
dot.classList.add("dot");
setTimeout(() => {
this.appendChild(dot);
this.attributeChangedCallback("value", undefined, this.getAttribute("value"));
}, 0);
}
__handleMouseDown(event) {
this.__mousedown = true;
this.__handleMouseMove(event);
}
__handleMouseUp(event) {
if (this.__mousedown) {
this.dispatchEvent(new Event('change', {
bubbles: true,
cancelable: true
}));
}
this.__mousedown = false;
}
__handleMouseMove(event) {
if (this.__mousedown) {
this.__angle = this.__getAngle(event);
this.value = this.__angle;
this.dispatchEvent(new Event('input', {
bubbles: true,
cancelable: true
}));
}
}
connectedCallback() {
this.__initialized = true;
//this.attributeChangedCallback("value", undefined, this.getAttribute("value"));
}
attributeChangedCallback(attribute, oldValue, newValue) {
const attributeHandlers = {
value: value => this.__setAngle(value)
};
if (attribute in attributeHandlers && this.__initialized) {
attributeHandlers[attribute](newValue);
}
}
get dot() {
return this.getElementsByClassName("dot")[0];
}
__getAngle(event) {
const boundings = this.getBoundingClientRect();
const center = {
x: boundings.left + boundings.width / 2,
y: boundings.top + boundings.height / 2
};
const diff = {
x: event.pageX - center.x,
y: event.pageY - center.y
};
const tan = diff.x / diff.y;
const angle = (diff.y >= 0 ? 200 : (diff.x >= 0 ? 0 : 400)) - Math.atan(tan) * (200 / Math.PI);
return angle;
}
__render() {
const deg = 360 / 400 * this.__angle;
this.dot.style.transform = 'translate(0px, -140%) rotate(' + deg + 'deg)';
}
__setAngle(angle) {
this.__angle = parseFloat(angle);
this.__render();
}
set value(value) {
this.__setAngle(value);
this.setAttribute("value", value);
}
get value() {
return this.__angle;
}
}
CircularSlider.observedAttributes = ["value"];
customElements.define("circular-slider", CircularSlider);
module.exports = CircularSlider;