デコレーション拡張 resolve #57

This commit is contained in:
Fairy-Phy 2023-11-26 17:31:17 +09:00 committed by NoriDev
parent 886878b836
commit d5061ae0fc
7 changed files with 66 additions and 2 deletions

View file

@ -2,6 +2,10 @@
_lang_: "English"
maxinumLayerError: "You cannot stack more than 6 layers. Please delete other layers."
layer: "Layer"
Xcoordinate: "X-Coordinate"
Ycoordinate: "Y-Coordinate"
scale: "Scale"
opacity: "Opacity"
noteUpdatedAt: "Edited: {date} {time}"
editReaction: "Edit reactions"
removeReaction: "Remove reactions"

View file

@ -2,6 +2,10 @@ _lang_: "日本語"
maxinumLayerError: "6枚以上重ねることはできません。他のレイヤーを削除してください。"
layer: "レイヤー"
Xcoordinate: "X座標"
Ycoordinate: "Y座標"
scale: "大きさ"
opacity: "不透明度"
noteUpdatedAt: "編集済み: {date} {time}"
editReaction: "リアクションを編集"
removeReaction: "リアクションを削除"

View file

@ -398,6 +398,10 @@ export class UserEntityService implements OnModuleInit {
id: ud.id,
angle: ud.angle || undefined,
flipH: ud.flipH || undefined,
scale: ud.scale || undefined,
moveX: ud.moveX || undefined,
moveY: ud.moveY || undefined,
opacity: ud.opacity || undefined,
url: decorations.find(d => d.id === ud.id)!.url,
}))) : [],
isBot: user.isBot,

View file

@ -145,6 +145,10 @@ export class MiUser {
id: string;
angle: number;
flipH: boolean;
scale: number;
moveX: number;
moveY: number;
opacity: number;
}[];
@Index()

View file

@ -143,6 +143,10 @@ export const paramDef = {
id: { type: 'string', format: 'misskey:id' },
angle: { type: 'number', nullable: true, maximum: 0.5, minimum: -0.5 },
flipH: { type: 'boolean', nullable: true },
scale: { type: 'number', nullable: true, maximum: 1.5, minimum: 0.5 },
moveX: { type: 'number', nullable: true, maximum: 25, minimum: -25 },
moveY: { type: 'number', nullable: true, maximum: 25, minimum: -25 },
opacity: { type: 'number', nullable: true, maximum: 1, minimum: 0.1 },
},
required: ['id'],
} },
@ -339,6 +343,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
id: d.id,
angle: d.angle ?? 0,
flipH: d.flipH ?? false,
scale: d.scale ?? 1,
moveX: d.moveX ?? 0,
moveY: d.moveY ?? 0,
opacity: d.opacity ?? 1,
}));
}

View file

@ -42,6 +42,8 @@ SPDX-License-Identifier: AGPL-3.0-only
:style="{
rotate: getDecorationAngle(avatarDecoration),
scale: getDecorationScale(avatarDecoration),
transform: getDecorationTransform(avatarDecoration),
opacity: getDecorationOpacity(avatarDecoration),
}"
alt=""
>
@ -53,6 +55,8 @@ SPDX-License-Identifier: AGPL-3.0-only
:style="{
rotate: getDecorationAngle(decoration),
scale: getDecorationScale(decoration),
transform: getDecorationTransform(decoration),
opacity: getDecorationOpacity(decoration),
}"
alt=""
>
@ -85,6 +89,10 @@ const props = withDefaults(defineProps<{
angle?: number;
flipH?: boolean;
flipV?: boolean;
scale?: number;
moveX?: number;
moveY?: number;
opacity?: number;
};
forceShowDecoration?: boolean;
}>(), {
@ -128,6 +136,18 @@ function getDecorationScale(avatarDecoration) {
return scaleX === 1 ? undefined : `${scaleX} 1`;
}
function getDecorationTransform(avatarDecoration) {
let scale = avatarDecoration.scale ?? 1;
let moveX = avatarDecoration.moveX ?? 0;
let moveY = avatarDecoration.moveY ?? 0;
return `${scale === 1 ? '' : `scale(${scale})`} ${moveX === 0 && moveY === 0 ? '' : `translate(${moveX}%, ${moveY}%)`}`;
}
function getDecorationOpacity(avatarDecoration) {
let opacity = avatarDecoration.opacity ?? 1;
return opacity === 1 ? undefined : opacity;
}
function resetTimer() {
playAnimation = true;
clearTimeout(playAnimationTimer);

View file

@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkModalWindow
ref="dialog"
:width="400"
:height="450"
:height="600"
@close="cancel"
@closed="emit('closed')"
>
@ -17,7 +17,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkSpacer :marginMin="20" :marginMax="28">
<div style="text-align: center;">
<div :class="$style.name">{{ decoration.name }}</div>
<MkAvatar style="width: 64px; height: 64px; margin-bottom: 20px;" :user="$i" :decoration="{ url: decoration.url, angle, flipH }" forceShowDecoration/>
<MkAvatar style="width: 64px; height: 64px; margin-bottom: 20px;" :user="$i" :decoration="{ url: decoration.url, angle, flipH, scale, moveX, moveY, opacity }" forceShowDecoration/>
</div>
<div class="_gaps_s">
<MkRadios v-model="insertLayer">
@ -34,6 +34,18 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkSwitch v-model="flipH">
<template #label>{{ i18n.ts.flip }}</template>
</MkSwitch>
<MkRange v-model="scale" continuousUpdate :min="0.5" :max="1.5" :step="0.05" :textConverter="(v) => `${v.toFixed(2)}x`">
<template #label>{{ i18n.ts.scale }}</template>
</MkRange>
<MkRange v-model="moveX" continuousUpdate :min="-25" :max="25" :step="1">
<template #label>{{ i18n.ts.Xcoordinate }}</template>
</MkRange>
<MkRange v-model="moveY" continuousUpdate :min="-25" :max="25" :step="1">
<template #label>{{ i18n.ts.Ycoordinate }}</template>
</MkRange>
<MkRange v-model="opacity" continuousUpdate :min="0.1" :max="1" :step="0.05" :textConverter="(v) => `${(v * 100).toFixed(2)}%`">
<template #label>{{ i18n.ts.opacity }}</template>
</MkRange>
</div>
</MkSpacer>
@ -86,6 +98,10 @@ const layerNum = (() => {
const insertLayer = ref(layerNum === -1 ? String($i.avatarDecorations.length) : String(layerNum));
const angle = ref(using.value ? $i.avatarDecorations.find(x => x.id === props.decoration.id).angle ?? 0 : 0);
const flipH = ref(using.value ? $i.avatarDecorations.find(x => x.id === props.decoration.id).flipH ?? false : false);
const scale = ref(using.value ? $i.avatarDecorations.find(x => x.id === props.decoration.id).scale ?? 1 : 1);
const moveX = ref(using.value ? $i.avatarDecorations.find(x => x.id === props.decoration.id).moveX ?? 0 : 0);
const moveY = ref(using.value ? $i.avatarDecorations.find(x => x.id === props.decoration.id).moveY ?? 0 : 0);
const opacity = ref(using.value ? $i.avatarDecorations.find(x => x.id === props.decoration.id).opacity ?? 1 : 1);
function cancel() {
dialog.value.close();
@ -96,6 +112,10 @@ async function attach() {
id: props.decoration.id,
angle: angle.value,
flipH: flipH.value,
scale: scale.value,
moveX: moveX.value,
moveY: moveY.value,
opacity: opacity.value
};
const updatedDecorations = $i.avatarDecorations.toSpliced(layerNum, layerNum === -1 ? 0 : 1).toSpliced(Number(insertLayer.value), 0, decoration);
await os.apiWithDialog('i/update', {