autoformat, fix lint errors

This commit is contained in:
Tomáš Mládek 2021-09-15 19:13:26 +02:00
parent 054f9a9218
commit 5734774366

View file

@ -1,100 +1,145 @@
<template> <template>
<div class="collage"> <div class="collage">
<div class="canvas"> <div class="canvas">
<canvas id="canvas" ref="canvas" :width="canvasSize.width" :height="canvasSize.height"></canvas> <canvas
id="canvas"
ref="canvas"
:width="canvasSize.width"
:height="canvasSize.height"
></canvas>
<div class="canvas-size"> <div class="canvas-size">
<label> <label>
Width: Width:
<input type="number" step="16" min="128" v-model="canvasSize.width"> <input type="number" step="16" min="128" v-model="canvasSize.width" />
</label> </label>
<label> <label>
Height: Height:
<input type="number" step="16" min="128" v-model="canvasSize.height"> <input
type="number"
step="16"
min="128"
v-model="canvasSize.height"
/>
</label> </label>
</div> </div>
</div> </div>
<div class="controls"> <div class="controls">
<div class="modes"> <div class="modes">
<ul class="modes-list"> <ul class="modes-list">
<li v-for="(mode, idx) in modes.modes" <li
:class="['mode', { v-for="(mode, idx) in modes.modes"
:class="[
'mode',
{
disabled: images.length < mode.minImages, disabled: images.length < mode.minImages,
excluded: excludedModes.includes(idx), excluded: excludedModes.includes(idx),
selected: idx === currentModeType, selected: idx === currentModeType,
lastActive: lastActiveModeTypes.includes(idx)}]"> lastActive: lastActiveModeTypes.includes(idx),
<label class="handle">{{mode.name}}<input type="radio" :value="idx" },
v-model="currentModeType"></label> ]"
<span class="mode-plus" :key="idx"
v-if="['recursive', 'shuffle'].includes(currentModeType) && images.length >= minImages"> >
<label class="handle"
>{{ mode.name
}}<input type="radio" :value="idx" v-model="currentModeType"
/></label>
<span
class="mode-plus"
v-if="
['recursive', 'shuffle'].includes(currentModeType) &&
images.length >= minImages
"
>
<span class="separator"></span> <span class="separator"></span>
<label>{{ excludedModes.includes(idx) ? 'o' : 'x'}}<input type="checkbox" :value="idx" <label
v-model="excludedModes"></label> >{{ excludedModes.includes(idx) ? "o" : "x"
}}<input type="checkbox" :value="idx" v-model="excludedModes"
/></label>
</span> </span>
</li> </li>
</ul> </ul>
<hr> <hr />
<label :class="{disabled: images.length < minImages, <label
selected: 'shuffle' === currentModeType}"> :class="{
disabled: images.length < minImages,
selected: 'shuffle' === currentModeType,
}"
>
!SHUFFLE ALL! !SHUFFLE ALL!
<input type="radio" value="shuffle" v-model="currentModeType"> <input type="radio" value="shuffle" v-model="currentModeType" />
</label> </label>
<label :class="{disabled: images.length < minImages, <label
selected: 'recursive' === currentModeType}"> :class="{
disabled: images.length < minImages,
selected: 'recursive' === currentModeType,
}"
>
#RECURSIVE# #RECURSIVE#
<input type="radio" value="recursive" v-model="currentModeType"> <input type="radio" value="recursive" v-model="currentModeType" />
</label> </label>
</div> </div>
<button :disabled="images.length < minImages" @click="renderCollage">REPAINT</button> <button :disabled="images.length < minImages" @click="renderCollage">
<hr> REPAINT
</button>
<hr />
<div class="config"> <div class="config">
<template v-if="currentModeType !== 'recursive'"> <template v-if="currentModeType !== 'recursive'">
<label class="config-numimages"> <label class="config-numimages">
#N of images: #N of images:
<input type="number" :min="minImages" :max="images.length" <input
type="number"
:min="minImages"
:max="images.length"
placeholder="RND" placeholder="RND"
:disabled="Object.keys(forceConfig).includes('numImages')" :disabled="Object.keys(forceConfig).includes('numImages')"
v-model="forceConfig.numImages || collageConfig.numImages"> :value="forceConfig.numImages || collageConfig.numImages"
@input="(n) => (collageConfig.numImages = n)"
/>
</label> </label>
</template> </template>
<template v-else> <template v-else>
<label> <label>
Recursion levels: Recursion levels:
<input type="number" :min="1" :max="10" v-model="recursiveConfig.level"> <input
type="number"
:min="1"
:max="10"
v-model="recursiveConfig.level"
/>
</label> </label>
<label> <label>
<input type="checkbox" v-model="recursiveConfig.repeat"> <input type="checkbox" v-model="recursiveConfig.repeat" />
Repeat images? Repeat images?
</label> </label>
</template> </template>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import {Component, Prop, Vue, Watch} from "vue-property-decorator"; import { Component, Prop, Vue, Watch } from "vue-property-decorator";
import {CollageModeType} from "../common/collages";
import {CollageConfig, CollageMode, Segment} from "../common/types";
import {choice, shuffle} from "../common/utils";
import BrowserCollageModes from "../collages"; import BrowserCollageModes from "../collages";
import { CollageModeType } from "../common/collages";
import { CollageConfig, CollageMode, Segment } from "../common/types";
import { choice, shuffle } from "../common/utils";
type DisplayCollageModeType = CollageModeType | & "shuffle" | & "recursive"; type DisplayCollageModeType = CollageModeType | "shuffle" | "recursive";
@Component @Component
export default class Collage extends Vue { export default class Collage extends Vue {
@Prop({required: true}) private images!: ImageBitmap[]; @Prop({ required: true }) private images!: ImageBitmap[];
private context!: CanvasRenderingContext2D; private context!: CanvasRenderingContext2D;
private canvasSize = { private canvasSize = {
width: 640, width: 640,
height: 640 height: 640,
}; };
private collageConfig: CollageConfig = { private collageConfig: CollageConfig = {
numImages: undefined numImages: undefined,
}; };
private recursiveConfig = { private recursiveConfig = {
level: 2, level: 2,
repeat: true repeat: true,
}; };
private currentModeType: DisplayCollageModeType = "shuffle"; private currentModeType: DisplayCollageModeType = "shuffle";
private lastActiveModeTypes: CollageModeType[] = []; private lastActiveModeTypes: CollageModeType[] = [];
@ -102,8 +147,13 @@ export default class Collage extends Vue {
private modes = new BrowserCollageModes(); private modes = new BrowserCollageModes();
private get minImages() { private get minImages() {
if (this.currentModeType === "shuffle" || this.currentModeType === "recursive") { if (
return Math.min(...Object.values(this.modes.modes).map((mode) => mode.minImages)); this.currentModeType === "shuffle" ||
this.currentModeType === "recursive"
) {
return Math.min(
...Object.values(this.modes.modes).map((mode) => mode.minImages)
);
} else { } else {
return this.modes.modes[this.currentModeType].minImages; return this.modes.modes[this.currentModeType].minImages;
} }
@ -120,20 +170,25 @@ export default class Collage extends Vue {
} }
private mounted() { private mounted() {
const canvas = (this.$refs.canvas as HTMLCanvasElement); const canvas = this.$refs.canvas as HTMLCanvasElement;
this.context = canvas.getContext("2d") as CanvasRenderingContext2D; this.context = canvas.getContext("2d") as CanvasRenderingContext2D;
} }
@Watch("images") @Watch("images")
@Watch("currentModeType") @Watch("currentModeType")
@Watch("collageConfig", {deep: true}) @Watch("collageConfig", { deep: true })
@Watch("recursiveConfig", {deep: true}) @Watch("recursiveConfig", { deep: true })
private renderCollage() { private renderCollage() {
if (this.images.length >= this.minImages) { if (this.images.length >= this.minImages) {
this.reset(); this.reset();
const permissibleModeKeys = (Object.keys(this.modes.modes) as CollageModeType[]) const permissibleModeKeys = (
.filter(k => !this.excludedModes.includes(k) && this.modes.modes[k].minImages <= this.images.length); Object.keys(this.modes.modes) as CollageModeType[]
).filter(
(k) =>
!this.excludedModes.includes(k) &&
this.modes.modes[k].minImages <= this.images.length
);
if (this.currentModeType !== "recursive") { if (this.currentModeType !== "recursive") {
let mode: CollageMode<any, any>; let mode: CollageMode<any, any>;
@ -146,15 +201,30 @@ export default class Collage extends Vue {
mode = this.modes.modes[this.currentModeType]; mode = this.modes.modes[this.currentModeType];
} }
const shuffledImages = shuffle(this.images); const shuffledImages = shuffle(this.images);
const segments = mode.getSegments(this.context, this.collageConfig, shuffledImages); const segments = mode.getSegments(
this.context,
this.collageConfig,
shuffledImages
);
mode.place(this.context, shuffledImages, segments); mode.place(this.context, shuffledImages, segments);
} else { } else {
this.lastActiveModeTypes = []; this.lastActiveModeTypes = [];
const shuffledImages = shuffle(this.images); const shuffledImages = shuffle(this.images);
const rootSegment: Segment = {x: 0, y: 0, w: this.context.canvas.width, h: this.context.canvas.height}; const rootSegment: Segment = {
const processSegment = async (segment: Segment, level: number): Promise<ImageBitmap> => { x: 0,
y: 0,
w: this.context.canvas.width,
h: this.context.canvas.height,
};
const processSegment = async (
segment: Segment,
level: number
): Promise<ImageBitmap> => {
console.debug(segment, level); console.debug(segment, level);
if (segment === rootSegment || level <= this.recursiveConfig.level - 1) { if (
segment === rootSegment ||
level <= this.recursiveConfig.level - 1
) {
let canvas = document.createElement("canvas"); let canvas = document.createElement("canvas");
canvas.width = segment.w; canvas.width = segment.w;
canvas.height = segment.h; canvas.height = segment.h;
@ -165,7 +235,9 @@ export default class Collage extends Vue {
let ctx = canvas.getContext("2d") as CanvasRenderingContext2D; let ctx = canvas.getContext("2d") as CanvasRenderingContext2D;
let segments = mode.getSegments(ctx); let segments = mode.getSegments(ctx);
console.debug(segments); console.debug(segments);
let bitmaps = await Promise.all(segments.map((segment) => processSegment(segment, level + 1))); let bitmaps = await Promise.all(
segments.map((segment) => processSegment(segment, level + 1))
);
mode.place(ctx, bitmaps, segments); mode.place(ctx, bitmaps, segments);
return await createImageBitmap(canvas); return await createImageBitmap(canvas);
} else { } else {
@ -180,17 +252,19 @@ export default class Collage extends Vue {
} }
} }
}; };
processSegment(rootSegment, 0).then((finalCollage) => { processSegment(rootSegment, 0)
.then((finalCollage) => {
console.debug(finalCollage); console.debug(finalCollage);
this.context.drawImage(finalCollage, 0, 0); this.context.drawImage(finalCollage, 0, 0);
}).catch((error) => { })
.catch((error) => {
alert(error); alert(error);
}); });
} }
} }
} }
@Watch("canvasSize", {deep: true}) @Watch("canvasSize", { deep: true })
private onCanvasSizeChange() { private onCanvasSizeChange() {
this.$nextTick(() => { this.$nextTick(() => {
this.renderCollage(); this.renderCollage();
@ -199,7 +273,7 @@ export default class Collage extends Vue {
private reset() { private reset() {
this.context.globalCompositeOperation = "source-over"; this.context.globalCompositeOperation = "source-over";
const canvas = (this.$refs.canvas as HTMLCanvasElement); const canvas = this.$refs.canvas as HTMLCanvasElement;
this.context.clearRect(0, 0, canvas.width, canvas.height); this.context.clearRect(0, 0, canvas.width, canvas.height);
} }
} }
@ -254,11 +328,12 @@ export default class Collage extends Vue {
.separator { .separator {
border: 1px solid gray; border: 1px solid gray;
width: 0; width: 0;
margin: 0 .5em; margin: 0 0.5em;
align-self: stretch; align-self: stretch;
} }
.mode .mode-plus, .mode .mode-plus label { .mode .mode-plus,
.mode .mode-plus label {
color: gray; color: gray;
font-size: 14px; font-size: 14px;
} }
@ -269,7 +344,7 @@ export default class Collage extends Vue {
} }
.controls .modes hr { .controls .modes hr {
margin-top: .5rem; margin-top: 0.5rem;
width: 100%; width: 100%;
color: lightgray; color: lightgray;
} }
@ -277,14 +352,16 @@ export default class Collage extends Vue {
.controls label { .controls label {
font-size: 14pt; font-size: 14pt;
cursor: pointer; cursor: pointer;
margin: .25rem; margin: 0.25rem;
} }
.modes input { .modes input {
display: none; display: none;
} }
.controls button, .controls hr, .controls .config { .controls button,
.controls hr,
.controls .config {
margin-top: 1rem; margin-top: 1rem;
} }