Created
August 13, 2021 01:23
-
-
Save all12jus/a09f1933efd43a32406bd266aff6ff97 to your computer and use it in GitHub Desktop.
ToggleSwitch V2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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