Skip to content

Instantly share code, notes, and snippets.

@all12jus
Created August 13, 2021 01:23
Show Gist options
  • Save all12jus/a09f1933efd43a32406bd266aff6ff97 to your computer and use it in GitHub Desktop.
Save all12jus/a09f1933efd43a32406bd266aff6ff97 to your computer and use it in GitHub Desktop.
ToggleSwitch V2
class ToggleSwitch extends HTMLElement {
currentR = 0;
currentG = 0;
currentB = 0;
lerp (start, end, amt){
return (1-amt)*start+amt*end;
}
createCapsule(ctx, point1, point2, radius){
ctx.beginPath()
ctx.arc(point1.x,point1.y, radius, Math.PI/2, -Math.PI/2);
ctx.lineTo(point2.x - radius, point2.y - radius);
ctx.arc(point2.x,point2.y, radius, -Math.PI/2, Math.PI/2);
ctx.closePath()
// ctx.stroke()
}
currentX = 0;
// TODO: allow a disabled state
// TODO: allow users to select initial state
// TODO: allow users to design some parts of it
// TODO: make the ellipse a capsule instead.
lastState = false;
value = true;
listeners = {};
addListener(key, listener){
this.listeners[key] = listener;
}
removeListener(key) {
delete this.listeners[key];
}
constructor() {
super();
this.attachShadow({mode: 'open'});
const wrapper = document.createElement('div');
wrapper.setAttribute('class','wrapper');
const canvas = document.createElement("canvas");
canvas.width = 100;
canvas.height = 50;
wrapper.appendChild(canvas);
const ctx = canvas.getContext('2d');
const draw = () => {
ctx.clearRect(0,0, canvas.width, canvas.height);
if (this.lastState != this.value){
for (const listenersKey in this.listeners) {
this.listeners[listenersKey](this.value);
}
this.lastState = this.value;
}
const capsulePoint1 = {x: (canvas.height / 2) + 2, y : canvas.height / 2};
const capsulePoint2 = {x: canvas.width - ((canvas.height / 2) + 2), y : canvas.height / 2};
this.createCapsule(ctx, capsulePoint1, capsulePoint2, (canvas.height - 1) / 2);
ctx.strokeStyle = "3px black"
ctx.stroke();
// lerp the fill style
this.currentR = this.lerp(this.currentR, ((this.value) ? 0 : 255),0.2);
this.currentG = this.lerp(this.currentG, ((this.value) ? 200 : 255), 0.2);
this.currentB = this.lerp(this.currentB, ((this.value) ? 0 : 255), 0.2);
// TODO: add alpha?
this.createCapsule(ctx, capsulePoint1, capsulePoint2, (canvas.height-3)/ 2);
// ctx.fillStyle = "blue"
ctx.fillStyle = `rgb(${this.currentR}, ${this.currentG}, ${this.currentB})`;
ctx.fill();
// TODO: add alpha?
// TODO: draw circle
ctx.beginPath();
const onPos = (canvas.width / 3) * 2;
const offPost = canvas.width / 3;
this.currentX = this.lerp(this.currentX, ((this.value) ? onPos : offPost), 0.2);
ctx.arc(this.currentX, canvas.height / 2, (canvas.height - 15)/2, 0, 2 * Math.PI, false);
ctx.stroke();
ctx.fillStyle = "rgb(255, 255, 255)"
ctx.fill();
requestAnimationFrame(draw);
}
// TODO: could also impliment the dragging when in the canvas to move the handle.
const info = wrapper.appendChild(document.createElement('span'));
info.setAttribute('class','info');
info.textContent = this.getAttribute('data-text');
const style = document.createElement('style');
style.textContent = '.wrapper { cursor: pointer; ' +
'-webkit-touch-callout: none; /* iOS Safari */\n' +
' -webkit-user-select: none; /* Safari */\n' +
' -khtml-user-select: none; /* Konqueror HTML */\n' +
' -moz-user-select: none; /* Old versions of Firefox */\n' +
' -ms-user-select: none; /* Internet Explorer/Edge */\n' +
' user-select: none; /* Non-prefixed version, currently\n' +
' supported by Chrome, Edge, Opera and Firefox */' +
'}' +
'canvas { height: 1em; vertical-align: middle; padding-right: 0.25em; }' +
'span {vertical-align: baseline;}' +
'' +
'' +
'';
// attach the created elements to the shadow DOM
this.shadowRoot.append(style,wrapper);
this.addEventListener('click', () => {
this.value = !this.value;
});
draw();
}
}
customElements.define('toggle-switch', ToggleSwitch);
const element = document.getElementById("TestingElement");
element.addListener("main", (val) => {
console.log("New Value: " + val);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment