feat: New class HippieClock

Adapt everything to a class based prototype.

- Functionality of clock still missing
- Original version is hidden
- Size now is dynamic
- Parts can be added
This commit is contained in:
sthag 2026-02-28 11:31:57 +01:00
parent 743d9fba9e
commit 62b21b5e68
2 changed files with 135 additions and 9 deletions

View file

@ -285,12 +285,137 @@ tags:
wrap.style.width = clockSize + 'px';
wrap.style.height = clockSize + 'px';
console.debug(windowDimension);
console.debug('Clock size: ', clockSize);
console.debug('Radius: ', maxSize);
}
drawBackground();
updateRings();
}
class HippieClock {
constructor(element, options) {
this.element = element;
this.shapes = [];
this.id = null;
this.options = options || {
size: Math.floor(this.getSize().value * 0.9)
};
this.parts = this.createContext(['bkg', 'hands']);
this.init();
}
init() {
// TODO: shapes[] ist zu diesem Zeitpunkt noch leer
this.resize();
window.addEventListener('resize', () => this.resize());
}
resize() {
this.parts.forEach(part => {
part.element.width = part.element.offsetWidth;
part.element.height = part.element.offsetHeight;
this.draw();
});
}
draw() {
this.parts.forEach(part => {
part.context.clearRect(0, 0, part.element.width, part.element.height);
});
this.shapes.forEach(shape => {
if (shape.type === 'circle') {
const radius = this.toPixelSize(shape.radius) / 2;
this.parts[0].context.fillStyle = shape.color;
this.parts[0].context.beginPath();
this.parts[0].context.arc(
this.toPixelX(shape.center),
this.toPixelY(shape.center),
radius,
0,
Math.PI * 2
);
this.parts[0].context.fill();
} else if (shape.type === 'ring') {
const radius = this.toPixelSize(shape.radius) / 2 - shape.stroke / 2;
this.parts[1].context.strokeStyle = shape.color;
this.parts[1].context.lineWidth = shape.stroke;
this.parts[1].context.beginPath();
this.parts[1].context.arc(
this.toPixelX(shape.center),
this.toPixelY(shape.center),
radius,
0,
Math.PI * 2
);
this.parts[1].context.stroke();
}
});
}
toPixelX(number) {
return number * this.parts[0].element.width;
}
toPixelY(number) {
return number * this.parts[0].element.height;
}
toPixelSize(number) {
return number * Math.min(this.parts[0].element.width, this.parts[0].element.height);
}
getSize() {
const height = window.innerHeight;
const width = window.innerWidth;
return {
value: Math.min(height, width),
smaller: height < width ? 'height' : 'width'
};
}
createContext(names) {
let parts = [];
const wrap = document.createElement('div');
wrap.style.position = 'relative';
wrap.style.height = this.options.size + 'px';
wrap.style.width = this.options.size + 'px';
names.forEach(name => {
const canvas = document.createElement('canvas');
canvas.style.position = 'absolute';
canvas.style.top = '0px';
canvas.style.left = '0px';
canvas.style.height = '100%';
canvas.style.width = '100%';
canvas.height = canvas.offsetHeight;
canvas.width = canvas.offsetWidth;
wrap.appendChild(canvas);
parts.push({name: name, element: canvas, context: canvas.getContext('2d')});
});
this.element.appendChild(wrap);
return parts;
}
addCircle(id, center, radius, color = `rgba(0, 0, 0, .1)`) {
this.shapes.push({type: 'circle', id, center, radius, color});
}
addRing(id, center, radius, color = `rgb(250, 216, 3)`, stroke = 16) {
this.shapes.push({type: 'ring', id, center, radius, color, stroke});
}
}
const container = document.querySelector('#clock main');
const clock = new HippieClock(container);
clock.addCircle('base', .5, 1);
clock.addRing('seconds', .5, 1);
clock.draw();
</script>
{% endblock %}

View file

@ -24,13 +24,14 @@
}
.wrap {
display: none;
position: relative;
}
canvas {
position: absolute;
top: 0;
left: 0;
canvas {
position: absolute;
top: 0;
left: 0;
}
}
p {