diff --git a/source/screens/demo/examples/clock.liquid b/source/screens/demo/examples/clock.liquid index 4bb0a32..ff28d37 100644 --- a/source/screens/demo/examples/clock.liquid +++ b/source/screens/demo/examples/clock.liquid @@ -290,14 +290,14 @@ tags: } class HippieClock { - constructor(element, options) { + constructor(element, date, options) { this.element = element; - this.shapes = []; - this.id = null; + this.date = this.getTime(date); this.options = options || { size: Math.floor(this.getSize().value * 0.9) }; this.parts = this.createContext(['bkg', 'hands']); + this.shapes = []; this.init(); } @@ -317,6 +317,7 @@ tags: } draw() { + // TODO: Nur geänderte Teile löschen this.parts.forEach(part => { part.context.clearRect(0, 0, part.element.width, part.element.height); }); @@ -337,6 +338,8 @@ tags: this.parts[0].context.fill(); } else if (shape.type === 'ring') { const radius = this.toPixelSize(shape.radius) / 2 - shape.stroke / 2; + const start = -0.5 * Math.PI; // Start at the top + const angle = start + (2 * Math.PI * (shape.angle / shape.max)); this.parts[1].context.strokeStyle = shape.color; this.parts[1].context.lineWidth = shape.stroke; @@ -345,14 +348,21 @@ tags: this.toPixelX(shape.center), this.toPixelY(shape.center), radius, - 0, - Math.PI * 2 + start, + angle ); this.parts[1].context.stroke(); } }); } + update() { + const second = this.getTime().second; + + this.updateShape('seconds', (second === 0) ? 60 : second); + this.draw(); + } + toPixelX(number) { return number * this.parts[0].element.width; } @@ -365,6 +375,23 @@ tags: return number * Math.min(this.parts[0].element.width, this.parts[0].element.height); } + // TODO: Parameter für Wochenstart ergänzen + getNumericWeekday(date) { + const weekday = date.getDay(); // 0 (Sunday) to 6 (Saturday) + + return (weekday === 0) ? 7 : weekday; + } + + getNumericYearDay(date) { + const start = new Date(date.getFullYear(), 0, 0); + + return Math.floor((date - start) / 86400000); + } + + daysInMonth(month, year) { + return new Date(year, month, 0).getDate(); + } + getSize() { const height = window.innerHeight; const width = window.innerWidth; @@ -375,9 +402,25 @@ tags: }; } + getTime(date) { + this.date = date || new Date(); + + return { + second: this.date.getSeconds(), + minute: this.date.getMinutes(), + hour: this.date.getHours(), + dayOfWeek: getNumericWeekday(this.date), + dayOfMonth: this.date.getDate(), + dayOfYear: getNumericYearDay(this.date), + month: this.date.getMonth() + 1, // Get current month (0-11) + daysInMonth: this.daysInMonth(this.date.getMonth() + 1, this.date.getFullYear()) + }; + } + 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'; @@ -403,19 +446,31 @@ tags: return parts; } + updateShape(id, value) { + const shape = this.shapes.find(s => s.id === id); + + if (shape) { + shape.angle = value; + } + } + 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}); + addRing(id, center, radius, angle, max, color = `rgb(250, 216, 3)`, stroke = 16) { + this.shapes.push({type: 'ring', id, center, radius, angle, max, color, stroke}); } } const container = document.querySelector('#clock main'); const clock = new HippieClock(container); clock.addCircle('base', .5, 1); - clock.addRing('seconds', .5, 1); + clock.addRing('seconds', .5, 1, 0, 60); clock.draw(); + + setInterval(() => { + clock.update(); + }, 1000); {% endblock %} \ No newline at end of file