Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Leibinger015/7d011a688831f8d47a1fc3ea8d99af56 to your computer and use it in GitHub Desktop.
Save Leibinger015/7d011a688831f8d47a1fc3ea8d99af56 to your computer and use it in GitHub Desktop.
An HomeScreen widget for a Concentric circle calendar.
// This is a "Concentric circle calendar" widget script for the iPhone app "Scriptable".
// Script-Code: ©️anb030.de
// Script-Datum: 26.10.2024
// Script-Last-Edit: 01.11.2024
// Version: 1.5e: BugFixes: The script has been slightly revised. Integration for calc of leap years and years with 52 or 53 calendar weeks. Fine tuning of the circular ring values. Note: Switching between light or dark mode can take a few seconds in automatic mode because the value in the script is dynamic and iOS 18.x is currently causing problems. For reason: New with manual Light/Dark mode selection per Parameter Widget-Setup.
// Start-Script
// Parameter einlesen
let mode = args.widgetParameter;
// Farben für die Ringe
const yearCircleColor = new Color('#FF4040'); // Außenring (Korallrot für Kalenderwochen)
const monthCircleColor = new Color('#00b0ba'); // Mittelring (anb030 Blau für Monat)
const dayCircleColor = new Color('#a69a7d'); // Innenring (light Gold für Tag)
// Bestimme den Darstellungsmodus
let isDarkMode;
if (mode === "Dark") {
isDarkMode = true;
} else if (mode === "Light") {
isDarkMode = false;
} else {
isDarkMode = Device.isUsingDarkAppearance();
}
// Hintergrundfarbe und darauf basierende Textfarbe
const widgetBackgroundColor = isDarkMode ? new Color('#1c1c1e') : new Color('#ffffff');
const circleTextColor = isDarkMode ? new Color('#ffffff') : new Color('#000000');
const bgCircleColor = isDarkMode ? new Color('#424242') : new Color('#D8D8D8');
// Datumswerte
let today = new Date();
let dayNumber = Math.ceil((today - new Date(today.getFullYear(), 0, 1)) / 86400000);
let thisDayDate = today.getDate();
let thisMonth = today.getMonth();
let thisYear = today.getFullYear();
let daysYear = (leapYear(thisYear)) ? 366 : 365;
let daysThisMonth = daysInMonth(thisMonth + 1, thisYear);
let totalWeeks = getTotalWeeksInYear(thisYear);
let weekNumber = getWeekNumber(today);
// Canvas und Layout-Einstellungen
const canvSize = 282;
const canvTextSize = 22;
const canvRadius = 120; // Radius des Kreises
const canvWidth = 22; // Breite des Kreises
const canvas = new DrawContext();
canvas.opaque = false;
canvas.size = new Size(canvSize, canvSize);
canvas.respectScreenScale = true;
// Berechnung der Kreisdrehungen
let yearDegree = Math.floor((weekNumber / totalWeeks) * 100 * 3.6); // Für Kalenderwochen im Außenring
let monthDegree = Math.floor((thisMonth / 11) * 100 * 3.6); // Für den Monat im Mittelring
let dayDegree = Math.floor((thisDayDate / daysThisMonth) * 100 * 3.6);
/*
BEGIN Widget Layout
*/
let widget = new ListWidget();
widget.setPadding(0, 5, 1, 0);
// Kalenderwochen-Kreis (außen)
makeCircle(0, bgCircleColor, yearCircleColor, yearDegree);
drawMyText(thisYear.toString().slice(-2), circleTextColor, 258); // Text bleibt das aktuelle Jahr
// Monats-Kreis (Mitte)
let monthRadiusOffset = 27;
makeCircle(monthRadiusOffset, bgCircleColor, monthCircleColor, monthDegree);
drawMyText((thisMonth + 1).toString(), circleTextColor, 232); // Zeigt den aktuellen Monat (1-12)
// Tag-Kreis (innen)
let dayRadiusOffset = 54;
makeCircle(dayRadiusOffset, bgCircleColor, dayCircleColor, dayDegree);
drawMyText(thisDayDate.toString(), circleTextColor, 205);
// Kalenderwoche in der Mitte
drawMyText("KW", circleTextColor, 120, canvTextSize * 1.25);
drawMyText(weekNumber.toString(), circleTextColor, 155, canvTextSize * 2.25);
// Widget-Hintergrundfarbe und Aktualisierungsintervall
widget.backgroundColor = widgetBackgroundColor;
widget.refreshAfterDate = new Date(Date.now() + 5 * 60 * 1000);
widget.addImage(canvas.getImage());
Script.setWidget(widget);
widget.presentSmall();
Script.complete();
/*
END Widget Layout
*/
function makeCircle(radiusOffset, bgCircleColor, fgCircleColor, degree) {
let ctr = new Point(canvSize / 2, canvSize / 2);
// Hintergrundkreis
let bgx = ctr.x - (canvRadius - radiusOffset);
let bgy = ctr.y - (canvRadius - radiusOffset);
let bgd = 2 * (canvRadius - radiusOffset);
let bgr = new Rect(bgx, bgy, bgd, bgd);
canvas.setStrokeColor(bgCircleColor);
canvas.setLineWidth(canvWidth);
canvas.strokeEllipse(bgr);
// Vordergrundkreis
canvas.setFillColor(fgCircleColor);
for (let t = 0; t < degree; t++) {
let rect_x = ctr.x + (canvRadius - radiusOffset) * sinDeg(t) - canvWidth / 2;
let rect_y = ctr.y - (canvRadius - radiusOffset) * cosDeg(t) - canvWidth / 2;
let rect_r = new Rect(rect_x, rect_y, canvWidth, canvWidth);
canvas.fillEllipse(rect_r);
}
}
function drawMyText(txt, txtColor, txtOffset, fontSize = canvTextSize) {
const txtRect = new Rect(
canvTextSize / 2 - 10,
txtOffset - fontSize / 2,
canvSize,
fontSize
);
canvas.setTextColor(txtColor);
canvas.setFont(Font.boldSystemFont(fontSize));
canvas.setTextAlignedCenter();
canvas.drawTextInRect(txt, txtRect);
}
function sinDeg(deg) {
return Math.sin((deg * Math.PI) / 180);
}
function cosDeg(deg) {
return Math.cos((deg * Math.PI) / 180);
}
function leapYear(year) {
return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}
function daysInMonth(month, year) {
return new Date(year, month, 0).getDate();
}
// Funktion zur Ermittlung der Kalenderwoche
function getWeekNumber(d) {
d = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));
d.setUTCDate(d.getUTCDate() + 4 - (d.getUTCDay() || 7));
let yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
return Math.ceil(((d - yearStart) / 86400000 + 1) / 7);
}
// Funktion zur Bestimmung der Gesamtanzahl der Wochen im Jahr
function getTotalWeeksInYear(year) {
let lastDayOfYear = new Date(Date.UTC(year, 11, 31));
return getWeekNumber(lastDayOfYear) === 53 ? 53 : 52;
}
// Script-Ende
@Leibinger015
Copy link
Author

This is a "Concentric circle" script for the Scriptable iPhone app.

Which displays a customised widget for "year, month, day and centrically the calendar week txt" in an dynamic system colours light / dark.

IMG_8728

@Leibinger015
Copy link
Author

BugFixes: The script has been slightly revised. Integration for calc of leap years and years with 52 or 53 calendar weeks. Fine tuning of the circular ring values. Note: Switching between light or dark mode can take a few seconds in automatic mode because the value in the script is dynamic and iOS 18.x is currently causing problems. For reason: New with manual Light/Dark mode selection per Parameter Widget-Setup.

IMG_8803

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment