wip
This commit is contained in:
parent
e3aae009b4
commit
cd296d60d8
|
@ -5,10 +5,6 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
|
||||
<template>
|
||||
<div :class="$style.root" class="_gaps">
|
||||
<div>
|
||||
<MkButton inline rounded primary @click="chooseFile">{{ i18n.ts.selectFile }}</MkButton>
|
||||
</div>
|
||||
|
||||
<template v-if="layer.type === 'text'">
|
||||
<MkInput v-model="layer.text">
|
||||
<template #label>{{ i18n.ts._watermarkEditor.text }}</template>
|
||||
|
@ -42,6 +38,41 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<template #label>{{ i18n.ts._watermarkEditor.opacity }}</template>
|
||||
</MkRange>
|
||||
|
||||
<MkSwitch v-model="layer.repeat">
|
||||
<template #label>{{ i18n.ts._watermarkEditor.repeat }}</template>
|
||||
</MkSwitch>
|
||||
</template>
|
||||
<template v-else-if="layer.type === 'image'">
|
||||
<MkButton inline rounded primary @click="chooseFile">{{ i18n.ts.selectFile }}</MkButton>
|
||||
|
||||
<FormSlot>
|
||||
<template #label>{{ i18n.ts._watermarkEditor.position }}</template>
|
||||
<MkPositionSelector
|
||||
v-model:x="layer.alignX"
|
||||
v-model:y="layer.alignY"
|
||||
></MkPositionSelector>
|
||||
</FormSlot>
|
||||
|
||||
<MkRange
|
||||
v-model="layer.scale"
|
||||
:min="0"
|
||||
:max="1"
|
||||
:step="0.01"
|
||||
continuousUpdate
|
||||
>
|
||||
<template #label>{{ i18n.ts._watermarkEditor.scale }}</template>
|
||||
</MkRange>
|
||||
|
||||
<MkRange
|
||||
v-model="layer.opacity"
|
||||
:min="0"
|
||||
:max="1"
|
||||
:step="0.01"
|
||||
continuousUpdate
|
||||
>
|
||||
<template #label>{{ i18n.ts._watermarkEditor.opacity }}</template>
|
||||
</MkRange>
|
||||
|
||||
<MkSwitch v-model="layer.repeat">
|
||||
<template #label>{{ i18n.ts._watermarkEditor.repeat }}</template>
|
||||
</MkSwitch>
|
||||
|
@ -84,14 +115,7 @@ onMounted(async () => {
|
|||
});
|
||||
|
||||
function chooseFile(ev: MouseEvent) {
|
||||
selectFile({
|
||||
anchorElement: ev.currentTarget ?? ev.target,
|
||||
multiple: false,
|
||||
label: i18n.ts.selectFile,
|
||||
features: {
|
||||
watermark: false,
|
||||
},
|
||||
}).then((file) => {
|
||||
selectFile(ev.currentTarget ?? ev.target, i18n.ts.selectFile).then((file) => {
|
||||
if (!file.type.startsWith('image')) {
|
||||
os.alert({
|
||||
type: 'warning',
|
||||
|
@ -101,9 +125,8 @@ function chooseFile(ev: MouseEvent) {
|
|||
return;
|
||||
}
|
||||
|
||||
fileId.value = file.id;
|
||||
fileUrl.value = file.url;
|
||||
fileName.value = file.name;
|
||||
layer.value.imageId = file.id;
|
||||
layer.value.imageUrl = file.url;
|
||||
driveFileError.value = false;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -97,6 +97,32 @@ function cancel() {
|
|||
}
|
||||
|
||||
const type = ref(preset.layers[0].type);
|
||||
watch(type, () => {
|
||||
if (type.value === 'text') {
|
||||
preset.layers = [{
|
||||
id: uuid(),
|
||||
type: type.value,
|
||||
text: `(c) @${$i.username}`,
|
||||
alignX: 'right',
|
||||
alignY: 'bottom',
|
||||
scale: 0.3,
|
||||
opacity: 0.75,
|
||||
repeat: false,
|
||||
}];
|
||||
} else if (type.value === 'image') {
|
||||
preset.layers = [{
|
||||
id: uuid(),
|
||||
type: type.value,
|
||||
imageId: null,
|
||||
imageUrl: null,
|
||||
alignX: 'right',
|
||||
alignY: 'bottom',
|
||||
scale: 0.3,
|
||||
opacity: 0.75,
|
||||
repeat: false,
|
||||
}];
|
||||
}
|
||||
});
|
||||
|
||||
watch(preset, async (newValue, oldValue) => {
|
||||
if (renderer != null) {
|
||||
|
|
|
@ -68,11 +68,11 @@ type WatermarkerTextLayer = {
|
|||
opacity: number;
|
||||
};
|
||||
|
||||
export type WatermarkerImageLayer = {
|
||||
type WatermarkerImageLayer = {
|
||||
id: string;
|
||||
type: 'image';
|
||||
imageUrl: string;
|
||||
imageId: string;
|
||||
imageUrl: string | null;
|
||||
imageId: string | null;
|
||||
repeat: boolean;
|
||||
scale: number;
|
||||
alignX: 'left' | 'center' | 'right';
|
||||
|
@ -234,10 +234,17 @@ export class Watermarker {
|
|||
img.src = layer.imageUrl;
|
||||
});
|
||||
|
||||
const texture = this.createTexture();
|
||||
gl.activeTexture(gl.TEXTURE0);
|
||||
gl.bindTexture(gl.TEXTURE_2D, this.originalImageTexture);
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, image.width, image.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, image);
|
||||
gl.bindTexture(gl.TEXTURE_2D, null);
|
||||
|
||||
this.bakedTextures.set(layer.id, {
|
||||
texture: texture,
|
||||
width: image.width,
|
||||
height: image.height,
|
||||
});
|
||||
} else if (layer.type === 'text') {
|
||||
const measureCtx = window.document.createElement('canvas').getContext('2d')!;
|
||||
measureCtx.canvas.width = this.renderWidth;
|
||||
|
@ -323,7 +330,7 @@ export class Watermarker {
|
|||
return shaderProgram;
|
||||
}
|
||||
|
||||
private renderTextLayer(layer: WatermarkerTextLayer) {
|
||||
private renderTextOrImageLayer(layer: WatermarkerTextLayer | WatermarkerImageLayer) {
|
||||
const gl = this.gl;
|
||||
if (gl == null) {
|
||||
throw new Error('gl is not initialized');
|
||||
|
@ -385,9 +392,9 @@ export class Watermarker {
|
|||
|
||||
private renderLayer(layer: WatermarkerLayer) {
|
||||
if (layer.type === 'image') {
|
||||
this.renderImageLayer(layer);
|
||||
this.renderTextOrImageLayer(layer);
|
||||
} else if (layer.type === 'text') {
|
||||
this.renderTextLayer(layer);
|
||||
this.renderTextOrImageLayer(layer);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue