summaryrefslogtreecommitdiff
path: root/packages/frontend/src/components/MkImageEffectorFxForm.vue
blob: 6bbec6c868bbe2260336eb08a3aa1d53c5011040 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
<!--
SPDX-FileCopyrightText: syuilo and misskey-project
SPDX-License-Identifier: AGPL-3.0-only
-->

<template>
<div class="_gaps">
	<div v-for="v, k in paramDefs" :key="k">
		<MkSwitch
			v-if="v.type === 'boolean'"
			v-model="params[k]"
		>
			<template #label>{{ v.label ?? k }}</template>
			<template v-if="v.caption != null" #caption>{{ v.caption }}</template>
		</MkSwitch>
		<MkRange
			v-else-if="v.type === 'number'"
			v-model="params[k]"
			continuousUpdate
			:min="v.min"
			:max="v.max"
			:step="v.step"
			:textConverter="v.toViewValue"
			@thumbDoubleClicked="() => {
				params[k] = v.default;
			}"
		>
			<template #label>{{ v.label ?? k }}</template>
			<template v-if="v.caption != null" #caption>{{ v.caption }}</template>
		</MkRange>
		<MkRadios v-else-if="v.type === 'number:enum'" v-model="params[k]" :options="v.enum">
			<template #label>{{ v.label ?? k }}</template>
			<template v-if="v.caption != null" #caption>{{ v.caption }}</template>
		</MkRadios>
		<div v-else-if="v.type === 'seed'">
			<MkRange v-model="params[k]" continuousUpdate type="number" :min="0" :max="10000" :step="1">
				<template #label>{{ v.label ?? k }}</template>
				<template v-if="v.caption != null" #caption>{{ v.caption }}</template>
			</MkRange>
		</div>
		<MkInput v-else-if="v.type === 'color'" :modelValue="getHex(params[k])" type="color" @update:modelValue="v => { const c = getRgb(v); if (c != null) params[k] = c; }">
			<template #label>{{ v.label ?? k }}</template>
			<template v-if="v.caption != null" #caption>{{ v.caption }}</template>
		</MkInput>
	</div>
	<div v-if="Object.keys(paramDefs).length === 0" :class="$style.nothingToConfigure">
		{{ i18n.ts.nothingToConfigure }}
	</div>
</div>
</template>

<script setup lang="ts">
import type { ImageEffectorRGB, ImageEffectorFxParamDefs } from '@/utility/image-effector/ImageEffector.js';
import MkInput from '@/components/MkInput.vue';
import MkRadios from '@/components/MkRadios.vue';
import MkSwitch from '@/components/MkSwitch.vue';
import MkRange from '@/components/MkRange.vue';
import { i18n } from '@/i18n.js';

defineProps<{
	paramDefs: ImageEffectorFxParamDefs;
}>();

const params = defineModel<Record<string, any>>({ required: true });

function getHex(c: ImageEffectorRGB) {
	return `#${c.map(x => Math.round(x * 255).toString(16).padStart(2, '0')).join('')}`;
}

function getRgb(hex: string | number): ImageEffectorRGB | null {
	if (
		typeof hex === 'number' ||
		typeof hex !== 'string' ||
		!/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(hex)
	) {
		return null;
	}

	const m = hex.slice(1).match(/[0-9a-fA-F]{2}/g);
	if (m == null) return [0, 0, 0];
	return m.map(x => parseInt(x, 16) / 255) as ImageEffectorRGB;
}
</script>

<style module>
.nothingToConfigure {
	opacity: 0.7;
	text-align: center;
	font-size: 14px;
	padding: 0 10px;
}
</style>