Pridan fotoeditor

This commit is contained in:
Michal Kváček
2023-10-27 22:30:47 +02:00
parent 4c8952117b
commit 100e1fa33b
18 changed files with 502 additions and 23 deletions
+52
View File
@@ -0,0 +1,52 @@
import {computed, ref, watch} from "vue";
import {cropper} from "vue-picture-cropper";
import {roundWithPrecision} from "src/composables/utils";
import {photoAspectRatio} from "src/composables/photos/editor/photo";
export const cropperImgSizes = computed(() => [cropper.getImageData().width, cropper.getImageData().height]);
export const croppedArea = ref(null);
export const selectedAspectRatio = ref(null);
watch(() => selectedAspectRatio.value, (newVal) => {
cropper.setAspectRatio(newVal);
})
export const setCropData = () => {
const [w, h] = cropperImgSizes.value;
const cropData = cropper.getCropBoxData();
croppedArea.value = {
left: roundWithPrecision(cropData.left / w, 5),
top: roundWithPrecision(cropData.top / h, 5),
width: roundWithPrecision(cropData.width / w, 5),
height: roundWithPrecision(cropData.height / h, 5)
};
}
export const aspectRatioOptions = computed(() =>
[
{label: '16:9', value: roundWithPrecision(16 / 9, 5)},
{label: '4:3', value: roundWithPrecision(4 / 3, 5)},
{label: '9:16', value: roundWithPrecision(9 / 16, 5)},
{label: '3:4', value: roundWithPrecision(3 / 4, 5)},
{label: '1:1', value: 1},
{label: 'Volný', value: null},
{label: 'Původní', value: roundWithPrecision(photoAspectRatio.value, 5)},
]
);
export const cropperReady = (e) => {
if (croppedArea.value) {
const [w, h] = cropperImgSizes.value;
selectedAspectRatio.value = roundWithPrecision((croppedArea.value.width * w) / (croppedArea.value.height * h), 5);
cropper.setCropBoxData({
left: croppedArea.value.left * w,
top: croppedArea.value.top * h,
width: croppedArea.value.width * w,
height: croppedArea.value.height * h
});
} else {
selectedAspectRatio.value = roundWithPrecision(photoAspectRatio.value, 5);
}
}
+16
View File
@@ -0,0 +1,16 @@
import {computed, ref} from "vue";
import {usePhotosStore} from "stores/Photo";
export const loading = ref(true);
export const photo = ref(null);
export const fetchPhoto = (id) => {
loading.value = true;
return usePhotosStore().fetchDetail(id)
.then(resp => {
photo.value = resp;
return resp;
})
.finally(() => loading.value = false);
};
export const photoAspectRatio = computed(() => photo.value.width / photo.value.height);
+18
View File
@@ -0,0 +1,18 @@
import {computed} from "vue";
import {croppedArea} from "src/composables/photos/editor/crop";
export const getPreviewUrl = (photoId, adjustments) => {
const url = new URL(`${process.env.API_URL}/photo/editor-preview/${photoId}`);
url.search = new URLSearchParams(adjustments).toString();
return url.toString();
};
export const croppedAreaForPreview = computed(() => {
if (!croppedArea.value) return {};
return {
crop_left: croppedArea.value.left || 0,
crop_top: croppedArea.value.top || 0,
crop_width: croppedArea.value.width || 1,
crop_height: croppedArea.value.height || 1
}
});
+10
View File
@@ -0,0 +1,10 @@
import {computed, ref} from "vue";
import {photoAspectRatio} from "src/composables/photos/editor/photo";
export const compare = ref(false);
export const splitterWidth = ref(750); // TODO: doresit onresize a zmenu velikosti
export const splitter = ref(50);
export const onResize = (info) => {
splitterWidth.value = info.width < 750 ? info.width : 750;
}