mirror of
https://code.lenaisten.de/Lenaisten/advent22.git
synced 2024-11-22 15:53:01 +00:00
Rework SVGRect and Doors
This commit is contained in:
parent
de5fff311c
commit
cfea9b051f
3 changed files with 89 additions and 76 deletions
|
@ -1,5 +1,10 @@
|
|||
<template>
|
||||
<SVGRect :rectangle="door.position" @click.left="on_click" />
|
||||
<SVGRect
|
||||
style="cursor: pointer"
|
||||
:rectangle="door.position"
|
||||
@click.left="on_click"
|
||||
>
|
||||
</SVGRect>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
|
@ -32,9 +37,3 @@ export default class extends Vue {
|
|||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
rect {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,5 +1,22 @@
|
|||
<template>
|
||||
<foreignObject
|
||||
:x="Math.round(parent_aspect_ratio * rectangle.left)"
|
||||
:y="rectangle.top"
|
||||
:width="Math.round(parent_aspect_ratio * rectangle.width)"
|
||||
:height="rectangle.height"
|
||||
:style="`transform: scaleX(${1 / parent_aspect_ratio})`"
|
||||
>
|
||||
<div
|
||||
v-if="variant !== undefined"
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
class="px-4 is-flex is-align-items-center is-justify-content-center is-size-1 has-text-weight-bold"
|
||||
>
|
||||
<slot name="default" />
|
||||
</div>
|
||||
</foreignObject>
|
||||
<rect
|
||||
ref="rect"
|
||||
v-bind="$attrs"
|
||||
:class="variant !== undefined ? variant : ''"
|
||||
:x="rectangle.left"
|
||||
:y="rectangle.top"
|
||||
|
@ -12,7 +29,13 @@
|
|||
import { Rectangle } from "@/lib/rectangle";
|
||||
import { Options, Vue } from "vue-class-component";
|
||||
|
||||
type RectColor = "primary" | "link" | "info" | "success" | "warning" | "danger";
|
||||
type BulmaVariant =
|
||||
| "primary"
|
||||
| "link"
|
||||
| "info"
|
||||
| "success"
|
||||
| "warning"
|
||||
| "danger";
|
||||
|
||||
@Options({
|
||||
props: {
|
||||
|
@ -24,14 +47,56 @@ type RectColor = "primary" | "link" | "info" | "success" | "warning" | "danger";
|
|||
},
|
||||
})
|
||||
export default class extends Vue {
|
||||
public variant?: RectColor;
|
||||
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;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "@/bulma-vars";
|
||||
|
||||
foreignObject > div {
|
||||
height: inherit;
|
||||
}
|
||||
|
||||
rect {
|
||||
fill: transparent;
|
||||
fill-opacity: 0.3;
|
||||
|
|
|
@ -1,35 +1,24 @@
|
|||
<template>
|
||||
<SVGRect
|
||||
style="cursor: text"
|
||||
:rectangle="door.position"
|
||||
:variant="editing ? 'success' : 'primary'"
|
||||
/>
|
||||
<foreignObject
|
||||
:x="Math.round(parent_aspect_ratio * door.position.left)"
|
||||
:y="door.position.top"
|
||||
:width="Math.round(parent_aspect_ratio * door.position.width)"
|
||||
:height="door.position.height"
|
||||
:style="`transform: scaleX(${1 / parent_aspect_ratio})`"
|
||||
@click.left="on_click"
|
||||
>
|
||||
<div
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
class="px-4 is-flex is-align-items-center is-justify-content-center"
|
||||
@click.left="on_click"
|
||||
>
|
||||
<input
|
||||
v-if="editing"
|
||||
v-model="day_str"
|
||||
ref="day_input"
|
||||
class="input is-large"
|
||||
type="number"
|
||||
:min="MIN_DAY"
|
||||
placeholder="Tag"
|
||||
@keydown="on_keydown"
|
||||
/>
|
||||
<div v-else class="is-size-1 has-text-weight-bold has-text-danger">
|
||||
{{ door.day > 0 ? door.day : "*" }}
|
||||
</div>
|
||||
<input
|
||||
v-if="editing"
|
||||
v-model="day_str"
|
||||
ref="day_input"
|
||||
class="input is-large"
|
||||
type="number"
|
||||
:min="MIN_DAY"
|
||||
placeholder="Tag"
|
||||
@keydown="on_keydown"
|
||||
/>
|
||||
<div v-else class="has-text-danger">
|
||||
{{ door.day > 0 ? door.day : "*" }}
|
||||
</div>
|
||||
</foreignObject>
|
||||
</SVGRect>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
|
@ -52,48 +41,18 @@ export default class extends Vue {
|
|||
|
||||
public day_str = "";
|
||||
public editing = false;
|
||||
private refreshKey = 0;
|
||||
|
||||
declare $refs: {
|
||||
day_input: HTMLInputElement | 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.$el instanceof Text) || this.$el.parentElement === null) {
|
||||
this.refresh();
|
||||
return 1;
|
||||
}
|
||||
|
||||
const parent = this.$el.parentElement;
|
||||
const result = parent.clientWidth / parent.clientHeight;
|
||||
|
||||
// force recompute for suspicious results
|
||||
if (result === 0 || result === Infinity) {
|
||||
this.refresh();
|
||||
return 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private toggle_editing() {
|
||||
this.day_str = String(this.door.day);
|
||||
this.editing = !this.editing;
|
||||
}
|
||||
|
||||
public on_click(event: MouseEvent) {
|
||||
if (event.target === null || !(event.target instanceof HTMLDivElement)) {
|
||||
if (event.target === null || !(event.target instanceof SVGRectElement)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -131,13 +90,3 @@ export default class extends Vue {
|
|||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
foreignObject {
|
||||
cursor: text;
|
||||
|
||||
> div {
|
||||
height: inherit;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
Loading…
Reference in a new issue