Compare commits

...

5 commits

Author SHA1 Message Date
2f87621756 feat: Change clock layout
- Clock is now centered in window
- Clock is resized according to window
2026-02-26 19:30:30 +01:00
a924065931 feat: Add functions to clock
- Add toggle button for sections
- Add function to draw background
2026-02-26 00:40:54 +01:00
8fb6181154 feat: Add day of year to clock
- Add ring for day of year
- New sections
- Move button
- Center clock
2026-02-25 23:35:29 +01:00
6e75d9b290 feat: New content for clock
- Add background canvas
- Add marker
- Add sections
2026-02-25 21:13:53 +01:00
8af4dc92d9 docs: Update content of TODO
- Add demo tasks
- Remove clock task
2026-02-25 21:09:13 +01:00
4 changed files with 278 additions and 76 deletions

View file

@ -16,6 +16,10 @@
- Change io stuff
- Find name for styled interactive elements
- Find name for io module with nested class names
- Change demo module
- Keep placeholder and demo stuff
- Move other things
- Prevent styles to be global
# Content
@ -133,5 +137,3 @@
- [ ] template
- [ ] slot
- [ ] canvas
- *Clock*
- Add overlays to better distinguish day, week and year

View file

@ -7,81 +7,162 @@ tags:
{% layout 'hippie/simple.liquid' %}
{% block body %}
<header class="io pos_fix pin_top pin_right pin_left">
<button id="tglFormat" title="Toggle hour display">12-Stunden-Format</button>
<button id="tglSections" title="Toggle sections">Abschnitte</button>
</header>
<main>
<canvas id="rings" width="512" height="512"></canvas>
<p>
<button id="tglFormat">12-Stunden-Format</button>
</p>
<div class="wrap">
<canvas id="background" width="768" height="768"></canvas>
<canvas id="rings" width="768" height="768"></canvas>
</div>
</main>
{% endblock %}
{% block script %}
<script>
// Page script
const canvas = document.getElementById('rings');
const ctx = canvas.getContext('2d');
const canvasBkg = document.getElementById('background');
const ctxBkg = canvasBkg.getContext('2d');
const canvasRings = document.getElementById('rings');
const ctxRings = canvasRings.getContext('2d');
const wrap = document.querySelector('.wrap');
let is24HourFormat = true;
const colorDayOfWeek = getComputedStyle(document.documentElement).getPropertyValue('--clock-color-yellow').trim();
const colorDayOfMonth = getComputedStyle(document.documentElement).getPropertyValue('--clock-color-orange').trim();
const colorMonth = getComputedStyle(document.documentElement).getPropertyValue('--clock-color-pink').trim();
let drawSections = false;
let currentDate = new Date();
let currentMonth = currentDate.getMonth() + 1; // Get current month (0-11)
let daysInCurrentMonth = daysInMonth(currentMonth, currentDate.getFullYear());
const outerMargin = 8;
const ringWidth = 16;
const ringGap = 8;
let centerX = canvasRings.width / 2;
let centerY = canvasRings.height / 2;
let maxSize = (canvasRings.width / 2 - ringWidth / 2) - outerMargin;
resizeClock();
const rings = [
{
radius: maxSize,
color: 'black'
},
{
radius: maxSize - (ringWidth + ringGap),
color: 'lightgrey'
},
{
radius: maxSize - (ringWidth + ringGap) * 2,
color: 'white'
},
{
radius: maxSize - (ringWidth + ringGap) * 3 - ringGap,
color: getComputedStyle(document.documentElement).getPropertyValue('--clock-color-yellow').trim()
},
{
radius: maxSize - (ringWidth + ringGap) * 4 - ringGap * 2,
color: getComputedStyle(document.documentElement).getPropertyValue('--clock-color-orange').trim()
},
{
radius: maxSize - (ringWidth + ringGap) * 5 - ringGap * 3,
color: getComputedStyle(document.documentElement).getPropertyValue('--clock-color-pink').trim()
},
{
radius: maxSize - (ringWidth + ringGap) * 6 - ringGap * 3,
color: getComputedStyle(document.documentElement).getPropertyValue('--clock-color-purple').trim()
}
];
const groups = [
{
radius: rings[1].radius,
color: `rgba(0, 0, 0, .1)`,
width: 72
},
{
radius: rings[3].radius,
color: `rgba(0, 0, 0, .2)`,
width: ringWidth + ringGap
},
{
radius: rings[4].radius,
color: `rgba(0, 0, 0, .3)`,
width: ringWidth + ringGap
},
{
radius: maxSize - (ringWidth + ringGap) * 6 - ringGap - ringGap / 2,
color: `rgba(0, 0, 0, .4)`,
width: ringWidth * 2 + ringGap * 2
}
];
const sectionMarkerColor = `rgba(0, 0, 0, .2)`;
let sections = [
{
amount: 60,
radius: maxSize,
width: 1
},
{
amount: 60,
radius: rings[1].radius,
width: 1
},
{
amount: is24HourFormat ? 24 : 12,
radius: rings[2].radius,
width: 3
},
{
amount: 7,
radius: rings[3].radius,
width: 5
},
{
amount: daysInCurrentMonth,
radius: rings[4].radius,
width: 3
},
{
amount: 365,
radius: rings[5].radius,
width: 1
},
{
amount: 12,
radius: rings[6].radius,
width: 3
}
];
document.getElementById('tglFormat').addEventListener('click', () => {
is24HourFormat = !is24HourFormat;
document.getElementById('tglFormat').textContent = is24HourFormat ? '12-Stunden-Format' : '24-Stunden-Format';
sections[2].amount = is24HourFormat ? 24 : 12;
drawBackground();
});
function drawRings(seconds, minutes, hours, dayOfWeek, dayOfMonth, month, daysInCurrentMonth) {
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
const lineWidth = 16;
const lineGap = 8;
const maxSize = canvas.width / 2 - lineWidth;
document.getElementById('tglSections').addEventListener('click', () => {
drawSections = !drawSections;
drawBackground();
});
ctx.clearRect(0, 0, canvas.width, canvas.height);
// FIXME: Konstanten mit maxSize werden nicht verändert
window.addEventListener('resize', resizeClock);
function drawArc(value, maxValue, radius, strokeStyle) {
const startAngle = -0.5 * Math.PI; // Start at the top
const endAngle = startAngle + (2 * Math.PI * (value / maxValue));
ctx.beginPath();
ctx.arc(centerX, centerY, radius, startAngle, endAngle, false);
ctx.lineWidth = 16;
ctx.strokeStyle = strokeStyle;
ctx.stroke();
}
drawArc(
(seconds === 0) ? 60 : seconds,
60,
maxSize,
'black'
);
drawArc(
(minutes === 0) ? 60 : minutes,
60,
maxSize - lineWidth - lineGap,
'lightgrey'
);
drawArc(
is24HourFormat ? hours : hours % 12,
is24HourFormat ? 24 : 12,
maxSize - (lineWidth + lineGap) * 2,
'white'
);
drawArc(dayOfWeek, 7, maxSize - (lineWidth + lineGap) * 3, colorDayOfWeek);
drawArc(dayOfMonth, daysInCurrentMonth, maxSize - (lineWidth + lineGap) * 4, colorDayOfMonth);
drawArc(month, 12, maxSize - (lineWidth + lineGap) * 5, colorMonth);
}
drawBackground();
updateRings();
// TODO: TimeDisplay nutzen, ev. erweitern oder ähnliche Umsetzung anwenden
setInterval(updateRings, 1000);
function updateRings() {
const currentDate = new Date();
currentDate = new Date();
const currentSeconds = currentDate.getSeconds();
const currentMinutes = currentDate.getMinutes();
const currentHours = currentDate.getHours();
const currentDayOfWeek = getNumericWeekday(currentDate);
const currentDayOfMonth = currentDate.getDate();
const currentMonth = currentDate.getMonth() + 1; // Get current month (0-11)
const daysInCurrentMonth = daysInMonth(currentMonth, currentDate.getFullYear());
const currentDayOfYear = getNumericYearDay(currentDate);
currentMonth = currentDate.getMonth() + 1; // Get current month (0-11)
daysInCurrentMonth = daysInMonth(currentMonth, currentDate.getFullYear());
drawRings(
currentSeconds,
@ -90,6 +171,7 @@ tags:
currentDayOfWeek,
currentDayOfMonth,
currentMonth,
currentDayOfYear,
daysInCurrentMonth
);
}
@ -100,11 +182,116 @@ tags:
return (weekday === 0) ? 7 : weekday;
}
function getNumericYearDay(date) {
const start = new Date(date.getFullYear(), 0, 0);
return Math.floor((date - start) / 86400000);
}
function daysInMonth(month, year) {
return new Date(year, month, 0).getDate();
}
updateRings();
setInterval(updateRings, 1000);
function drawArc(value, maxValue, radius, strokeStyle) {
const startAngle = -0.5 * Math.PI; // Start at the top
const endAngle = startAngle + (2 * Math.PI * (value / maxValue));
ctxRings.lineWidth = 16;
ctxRings.strokeStyle = strokeStyle;
ctxRings.beginPath();
ctxRings.arc(centerX, centerY, radius, startAngle, endAngle, false);
ctxRings.stroke();
}
// TODO: Array rings nutzen
function drawRings(seconds, minutes, hours, dayOfWeek, dayOfMonth, month, dayOfYear, daysInCurrentMonth) {
ctxRings.clearRect(0, 0, canvasRings.width, canvasRings.height);
drawArc(
(seconds === 0) ? 60 : seconds,
60,
rings[0].radius,
rings[0].color
);
drawArc(
(minutes === 0) ? 60 : minutes,
60,
rings[1].radius,
rings[1].color
);
drawArc(
// is24HourFormat ? ((hours === 0) ? 24 : hours) : hours % 12,
is24HourFormat ? hours : hours % 12,
is24HourFormat ? 24 : 12,
rings[2].radius,
rings[2].color
);
drawArc(dayOfWeek, 7, rings[3].radius, rings[3].color);
drawArc(dayOfMonth, daysInCurrentMonth, rings[4].radius, rings[4].color);
drawArc(dayOfYear, 365, rings[5].radius, rings[5].color);
drawArc(month, 12, rings[6].radius, rings[6].color);
}
function drawBackground() {
ctxBkg.clearRect(0, 0, canvasBkg.width, canvasBkg.height);
groups.forEach((section) => {
ctxBkg.strokeStyle = section.color;
ctxBkg.lineWidth = section.width;
ctxBkg.beginPath();
ctxBkg.arc(centerX, centerY, section.radius, 0, 2 * Math.PI);
ctxBkg.stroke();
});
if (drawSections) {
sections.forEach((marker) => {
for (let i = 0; i < marker.amount; i++) {
const angle = (i * (360 / marker.amount) - 90) * (Math.PI / 180); // -90 to start at top
const outerRadius = marker.radius + ringWidth / 2;
const outerX = centerX + outerRadius * Math.cos(angle);
const outerY = centerY + outerRadius * Math.sin(angle);
const innerRadius = marker.radius - ringWidth / 2;
const innerX = centerX + innerRadius * Math.cos(angle);
const innerY = centerY + innerRadius * Math.sin(angle);
ctxBkg.strokeStyle = sectionMarkerColor;
ctxBkg.lineWidth = marker.width;
ctxBkg.beginPath();
ctxBkg.moveTo(outerX, outerY);
ctxBkg.lineTo(innerX, innerY);
ctxBkg.stroke();
}
});
}
}
function resizeClock() {
const height = window.innerHeight;
const width = window.innerWidth;
const windowDimension = {
value: Math.min(height, width),
smaller: height < width ? 'height' : 'width'
};
const clockSize = Math.floor(windowDimension.value * 0.9);
canvasBkg.style.width = clockSize + 'px';
canvasBkg.style.height = clockSize + 'px';
canvasRings.style.width = clockSize + 'px';
canvasRings.style.height = clockSize + 'px';
canvasBkg.width = clockSize;
canvasBkg.height = clockSize;
canvasRings.width = clockSize;
canvasRings.height = clockSize;
centerX = canvasRings.width / 2;
centerY = canvasRings.height / 2;
maxSize = (canvasRings.width / 2 - ringWidth / 2) - outerMargin;
wrap.style.width = clockSize + 'px';
wrap.style.height = clockSize + 'px';
console.debug(windowDimension);
console.debug('Clock size: ', clockSize);
console.debug('Radius: ', maxSize);
}
</script>
{% endblock %}

View file

@ -14,10 +14,23 @@
.body_clock {
main {
@extend .sec_main_center;
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: center;
height: 100vh;
width: 100%;
overflow: hidden;
}
.wrap {
position: relative;
}
canvas {
position: absolute;
top: 0;
left: 0;
}
p {

View file

@ -270,8 +270,7 @@
padding-left: hippie.$space_double;
}
// Index
// -----------------------------------------------------------------------------
#demo {
.wrap {
display: flex;
// height: 100%;
@ -288,3 +287,4 @@
background-color: hippie.$color_darker;
}
}
}