"calendar_aspect_ratio" into store

This commit is contained in:
Jörn-Michael Miehe 2023-11-05 22:36:58 +00:00
parent 9413b96c1a
commit e613ead635
3 changed files with 26 additions and 41 deletions

View file

@ -1,10 +1,10 @@
<template>
<foreignObject
:x="Math.round(parent_aspect_ratio * rectangle.left)"
:x="Math.round(store.calendar_aspect_ratio * rectangle.left)"
:y="rectangle.top"
:width="Math.round(parent_aspect_ratio * rectangle.width)"
:width="Math.round(store.calendar_aspect_ratio * rectangle.width)"
:height="rectangle.height"
:style="`transform: scaleX(${1 / parent_aspect_ratio})`"
:style="`transform: scaleX(${1 / store.calendar_aspect_ratio})`"
>
<div
v-if="variant !== undefined"
@ -16,7 +16,6 @@
</div>
</foreignObject>
<rect
ref="rect"
v-bind="$attrs"
:class="variant !== undefined ? variant : ''"
:x="rectangle.left"
@ -28,6 +27,7 @@
<script lang="ts">
import { Rectangle } from "@/lib/rectangle";
import { advent22Store } from "@/plugins/store";
import { Options, Vue } from "vue-class-component";
type BulmaVariant =
@ -51,43 +51,7 @@ export default class extends Vue {
public variant?: BulmaVariant;
public rectangle!: Rectangle;
private refreshKey = 0;
declare $refs: {
rect: unknown;
};
private refresh() {
window.setTimeout(() => {
// don't loop endlessly
if (this.refreshKey < 10000) {
this.refreshKey++;
}
}, 100);
}
public get parent_aspect_ratio(): number {
this.refreshKey; // read it just to force recompute on change
if (
!(this.$refs.rect instanceof SVGRectElement) ||
this.$refs.rect.parentElement === null
) {
this.refresh();
return 1;
}
const parent = this.$refs.rect.parentElement;
const result = parent.clientWidth / parent.clientHeight;
// force recompute for suspicious results
if (result === 0 || result === Infinity) {
this.refresh();
return 1;
}
return result;
}
public readonly store = advent22Store();
}
</script>

View file

@ -17,6 +17,7 @@
<script lang="ts">
import { Vector2D } from "@/lib/vector2d";
import { advent22Store } from "@/plugins/store";
import { Options, Vue } from "vue-class-component";
function get_event_thous(event: MouseEvent): Vector2D {
@ -56,6 +57,17 @@ function mouse_event_validator(event: object, point: object): boolean {
},
})
export default class extends Vue {
public readonly store = advent22Store();
public mounted(): void {
new ResizeObserver(([first, ...rest]) => {
if (rest.length > 0)
console.warn(`Unexpected ${rest.length} extra entries!`);
this.store.set_calendar_aspect_ratio(first.contentRect);
}).observe(this.$el);
}
public transform_mouse_event(event: MouseEvent) {
const point = get_event_thous(event);
this.$emit(event.type, event, point);

View file

@ -27,6 +27,7 @@ export const advent22Store = defineStore({
content: "",
footer: "",
} as SiteConfigModel,
calendar_aspect_ratio: 1,
user_doors: [] as DoorsSaved,
next_door_target: null as number | null,
}),
@ -98,6 +99,14 @@ export const advent22Store = defineStore({
toggle_touch_device(): void {
this.is_touch_device = !this.is_touch_device;
},
set_calendar_aspect_ratio(rect: DOMRectReadOnly): void {
const result = rect.width / rect.height;
// filter suspicious results
if (result !== 0 && isFinite(result) && !isNaN(result))
this.calendar_aspect_ratio = result;
},
},
});