Loading .gitignore +2 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ logs *.log npm-debug.log* .yarn yarn-debug.log* yarn-error.log* pnpm-debug.log* Loading Loading @@ -29,3 +30,4 @@ coverage *.sw? *.tsbuildinfo /.yarnrc.yml package.json +5 −1 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ "private": true, "type": "module", "scripts": { "dev": "vite", "dev": "vite && npx tailwindcss -i ./src/input.css -o ./src/output.css --watch", "build": "run-p type-check \"build-only {@}\" --", "preview": "vite preview", "build-only": "vite build", Loading Loading @@ -62,5 +62,9 @@ "ecmaVersion": 2020 }, "rules": {} }, "volta": { "node": "20.17.0", "yarn": "4.5.0" } } src/app/assets/main.css +31 −3 Original line number Diff line number Diff line Loading @@ -35,6 +35,15 @@ --orange-700: #c2410c; --orange-800: #9a3412; --orange-900: #7c2d12; --amber-100: #fef3c7; --amber-200: #fde68a; --amber-300: #fcd34d; --amber-400: #fbbf24; --amber-500: #f59e0b; --amber-600: #d97706; --amber-700: #b45309; --amber-800: #92400e; --amber-900: #78350f; --yellow-100: #fef9c3; --yellow-200: #fef08a; --yellow-300: #fde047; Loading Loading @@ -276,10 +285,29 @@ input[type=file]::-webkit-file-upload-button { 0% { transform: scale(0); } 50% { transform: scale(1.25); } 100% { transform: scale(1); } } .v-enter-active, .v-leave-active { transition: all 0.5s ease; } .fading-enter-active, .fading-leave-active { transition: opacity 0.3s ease-in-out; } .fading-enter-active { animation: fading-in 0.5s; } .fading-leave-active { animation: fading-in 0.5s reverse; } @keyframes fading-in { 0% { opacity: 0; } 100% { opacity: 1; } } src/app/components.d.ts +13 −10 Original line number Diff line number Diff line Loading @@ -7,19 +7,23 @@ export {} /* prettier-ignore */ declare module 'vue' { export interface GlobalComponents { AlignCenterIcon: typeof import('./../shared/icons/AlignCenterIcon.vue')['default'] AlignLeftIcon: typeof import('./../shared/icons/AlignLeftIcon.vue')['default'] AlignRightIcon: typeof import('./../shared/icons/AlignRightIcon.vue')['default'] App: typeof import('./App.vue')['default'] AuthorizationForm: typeof import('./../modules/authorization/AuthorizationForm.vue')['default'] BaseLoader: typeof import('./../shared/BaseLoader.vue')['default'] BaseSidebarMenu: typeof import('./../modules/BaseSidebarMenu.vue')['default'] Button: typeof import('./../shared/ui/Button.vue')['default'] CloseCircle: typeof import('./../shared/icons/CloseCircle.vue')['default'] ConfirmDeleteEntityModal: typeof import('./../modules/ConfirmDeleteEntityModal.vue')['default'] CreateEntityMenu: typeof import('./../components/CreateEntityMenu.vue')['default'] CropIcon: typeof import('./../shared/icons/CropIcon.vue')['default'] CropImageModal: typeof import('./../modules/CropImageModal.vue')['default'] DashedIcon: typeof import('./../shared/icons/DashedIcon.vue')['default'] Divider: typeof import('./../shared/ui/Divider.vue')['default'] DividerItem: typeof import('./../modules/entities/DividerItem.vue')['default'] DividerMenu: typeof import('./../modules/entities/settings/DividerMenu.vue')['default'] DividerSettings: typeof import('./../components/entities/settings/DividerSettings.vue')['default'] DividerSettingsList: typeof import('./../components/entities/settings/lists/DividerSettingsList.vue')['default'] DottedIcon: typeof import('./../shared/icons/DottedIcon.vue')['default'] Drawer: typeof import('./../shared/ui/Drawer.vue')['default'] EntitiesList: typeof import('./../modules/entities/EntitiesList.vue')['default'] Loading @@ -32,37 +36,36 @@ declare module 'vue' { HorizontalLineIcon: typeof import('./../shared/icons/HorizontalLineIcon.vue')['default'] ImageIcon: typeof import('./../shared/icons/ImageIcon.vue')['default'] ImageItem: typeof import('./../modules/entities/ImageItem.vue')['default'] ImageMenu: typeof import('./../components/entities/settings/ImageMenu.vue')['default'] ImagePositionMenu: typeof import('./../components/entities/image/ImagePositionMenu.vue')['default'] ImageSettings: typeof import('./../components/entities/settings/ImageSettings.vue')['default'] ImageSizeMenu: typeof import('./../components/entities/image/ImageSizeMenu.vue')['default'] ImageStateMenu: typeof import('./../components/entities/image/ImageStateMenu.vue')['default'] ImageSettingsList: typeof import('./../components/entities/settings/lists/ImageSettingsList.vue')['default'] LogoAndLabel: typeof import('./../components/LogoAndLabel.vue')['default'] MenuDial: typeof import('./../shared/ui/MenuDial.vue')['default'] MenuHeader: typeof import('./../components/MenuHeader.vue')['default'] Modal: typeof import('./../shared/ui/Modal.vue')['default'] NavigationIcon: typeof import('./../shared/icons/NavigationIcon.vue')['default'] PageBackgroundMenu: typeof import('./../modules/PageBackgroundMenu.vue')['default'] PageHeader: typeof import('./../modules/PageHeader.vue')['default'] PageMenuButton: typeof import('./../components/PageMenuButton.vue')['default'] ParagraphIcon: typeof import('./../shared/icons/ParagraphIcon.vue')['default'] ParagraphItem: typeof import('./../modules/entities/ParagraphItem.vue')['default'] ParagraphSettings: typeof import('./../components/entities/settings/ParagraphSettings.vue')['default'] ParagraphSettingsList: typeof import('./../components/entities/settings/lists/ParagraphSettingsList.vue')['default'] PlusIcon: typeof import('./../shared/icons/PlusIcon.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] SaveIcon: typeof import('./../shared/icons/SaveIcon.vue')['default'] SettingsIcon: typeof import('./../shared/icons/SettingsIcon.vue')['default'] SheetPage: typeof import('./../pages/[uuid]/SheetPage.vue')['default'] SidebarMenuContent: typeof import('./../modules/SidebarMenuContent.vue')['default'] SidebarMenuHeader: typeof import('./../modules/SidebarMenuHeader.vue')['default'] SignIn: typeof import('./../pages/authorization/signIn.vue')['default'] SignUp: typeof import('./../pages/authorization/signUp.vue')['default'] Slider: typeof import('./../shared/ui/Slider.vue')['default'] SolidIcon: typeof import('./../shared/icons/SolidIcon.vue')['default'] TableIcon: typeof import('./../shared/icons/TableIcon.vue')['default'] TelegramSection: typeof import('./../modules/TelegramSection.vue')['default'] TextFontMenu: typeof import('./../components/entities/share/TextFontMenu.vue')['default'] TextItem: typeof import('./../modules/entities/TextItem.vue')['default'] TextPositionMenu: typeof import('./../components/entities/text/TextPositionMenu.vue')['default'] TextSettings: typeof import('./../components/entities/settings/TextSettings.vue')['default'] TextStateMenu: typeof import('./../components/entities/text/TextStateMenu.vue')['default'] ToggleButton: typeof import('./../shared/ui/ToggleButton.vue')['default'] ToggleSwitch: typeof import('./../shared/ui/ToggleSwitch.vue')['default'] TrashIcon: typeof import('./../shared/icons/TrashIcon.vue')['default'] Tree: typeof import('./../shared/ui/Tree.vue')['default'] Loading src/app/helpers/images.ts +106 −65 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ import { useFilesWebsocketStore } from '@/app/stores/filesWebsocket'; import type { IImage } from '@/app/interfaces/entities'; import { useWebsocketStore } from '@/app/stores/websocket'; import { useInterfaceStore } from '@/app/stores/interface'; import { imageScaleOptions } from '@/components/entities/settings/lists/constants/options'; export const setDefaultPageBackground = () => { const interfaceStore = useInterfaceStore(); Loading @@ -15,14 +16,17 @@ export const addUrlsToImageEntities = (entities: IEntity[]) => { let index = 0; const entitiesToReturn = entities.map((entity: IEntity) => { if (!entity?.image_width) return entity; if (entity.imageUrl) return entity; if (filesWebsocketStore.imageUrl) { if (entity.image_url) return entity; if (filesWebsocketStore.image_url) { // редактирование сущности изображения entity.imageUrl = filesWebsocketStore.imageUrl; entity.image_url = filesWebsocketStore.image_url; filesWebsocketStore.cleanImageUrl(); } else { filesBuffer[index] = new Blob([filesBuffer[index].data], { type: 'image/jpeg' }); entity.imageUrl = URL.createObjectURL(filesBuffer[index]); entity.image_url = URL.createObjectURL(filesBuffer[index]); index += 1; filesBuffer[index] = new Blob([filesBuffer[index].data], { type: 'image/jpeg' }); entity.image_url_initial = URL.createObjectURL(filesBuffer[index]); index += 1; } return entity; Loading @@ -37,18 +41,33 @@ export const checkIsImage = (entity: IEntity) => { } const entityToReturn = { ...entity }; const filesWebsocketStore = useFilesWebsocketStore(); filesWebsocketStore.saveImageUrl(entityToReturn.imageUrl!); delete entityToReturn.imageUrl; filesWebsocketStore.saveImageUrl(entityToReturn.image_url!); delete entityToReturn.image_url; return entityToReturn; }; export const cropImage = async (newUrl: string, entity: IImage) => { export const calcImageWidth = (fileWidth: number, windowWidth: number) => { let imageWidth = Math.ceil((fileWidth / (windowWidth - 128)) * 100); if (imageWidth > 100) { imageWidth = 100; } if (imageWidth < 5) { imageWidth = 5; } return imageWidth; }; export const sendCropImage = async (newUrl: string, entity: IImage) => { const filesWebsocketStore = useFilesWebsocketStore(); filesWebsocketStore.saveImageUrl(newUrl); const websocketStore = useWebsocketStore(); const response = await fetch(newUrl); const blob = await response.blob(); const buffer = await blob.arrayBuffer(); const dataSetCropNow = { event: 'setCropNow' }; websocketStore.sendData(dataSetCropNow); filesWebsocketStore.sendData(buffer); const data = { event: 'cropImage', Loading @@ -57,73 +76,95 @@ export const cropImage = async (newUrl: string, entity: IImage) => { websocketStore.sendData(data); }; export const getImageSpeedDialSizeSmallerLabelsToRemove = (entity: IImage) => { const elementsLabelsToRemove = []; const initialImageWidth = Math.ceil(entity.image_width / +entity.image_scale); const initialImageHeight = Math.ceil(entity.image_height / +entity.image_scale); if (initialImageWidth <= 400 || initialImageHeight <= 400) { elementsLabelsToRemove.push('x0.25'); if ( initialImageWidth <= 200 || initialImageHeight <= 200 || (initialImageWidth >= 1600 && entity.text_position) ) { elementsLabelsToRemove.push('x0.5'); if ( initialImageWidth <= 95 || initialImageHeight <= 95 || (initialImageWidth >= 1066 && entity.text_position) ) { elementsLabelsToRemove.push('x0.75'); export const getImageScalesToRemove = ( entity: IImage, isText?: boolean, isEntityWidthFull: boolean ) => { const valuesToRemove = []; let scale = entity.image_scale; if (scale[0] === 'x') scale = scale.slice(1); const initialImageWidth = Math.ceil(+entity.image_width / +scale); const initialImageHeight = +entity.file_height_initial; if (initialImageWidth <= 20) { valuesToRemove.push('x0.25'); if (initialImageWidth <= 10) { valuesToRemove.push('x0.5'); } } if (initialImageWidth <= 7 || (!isEntityWidthFull && isText && initialImageWidth > 66)) { valuesToRemove.push('x0.75'); } if ( (initialImageWidth >= 800 && entity.text_position) || entity.image_width < initialImageWidth ) { elementsLabelsToRemove.push('x1'); if (initialImageWidth > 75 && isText) { valuesToRemove.push('x1'); } return elementsLabelsToRemove; }; export const getImageSpeedDialSizeBiggerLabelsToRemove = (entity: IImage) => { const elementsLabelsToRemove = []; const initialImageWidth = Math.ceil(entity.image_width / +entity.image_scale); const initialImageHeight = Math.ceil(entity.image_height / +entity.image_scale); if ( (initialImageWidth >= 800 && entity.text_position) || entity.image_width > initialImageWidth initialImageWidth > 80 || (initialImageWidth > 60 && isText) || (!isEntityWidthFull && isText && initialImageWidth > 40) || initialImageHeight * 1.25 > 1000 ) { elementsLabelsToRemove.push('x1'); valuesToRemove.push('x1.25'); } if ( initialImageWidth >= 960 || initialImageHeight >= 560 || (initialImageWidth >= 640 && entity.text_position) initialImageWidth > 66 || (initialImageWidth > 50 && isText) || (!isEntityWidthFull && isText && initialImageWidth > 33) || initialImageHeight * 1.5 > 1000 ) { elementsLabelsToRemove.push('x1.25'); valuesToRemove.push('x1.5'); } if ( initialImageWidth >= 800 || initialImageHeight >= 467 || (initialImageWidth >= 533 && entity.text_position) initialImageWidth > 57 || (initialImageWidth > 42 && isText) || (!isEntityWidthFull && isText && initialImageWidth > 28) || initialImageHeight * 1.75 > 1000 ) { elementsLabelsToRemove.push('x1.5'); valuesToRemove.push('x1.75'); } if ( initialImageWidth >= 685 || initialImageHeight >= 400 || (initialImageWidth >= 457 && entity.text_position) initialImageWidth > 57 || (initialImageWidth > 42 && isText) || (!isEntityWidthFull && isText && initialImageWidth > 28) || initialImageHeight * 1.75 > 1000 ) { elementsLabelsToRemove.push('x1.75'); valuesToRemove.push('x1.75'); } if ( initialImageWidth >= 600 || initialImageHeight >= 350 || (initialImageWidth >= 400 && entity.text_position) initialImageWidth > 50 || (initialImageWidth > 37 && isText) || (!isEntityWidthFull && isText && initialImageWidth > 25) || initialImageHeight * 2 > 1000 ) { elementsLabelsToRemove.push('x2'); } } valuesToRemove.push('x2'); } return valuesToRemove; }; export const filterImageScaleOptions = ( entityData: IImage, isText: boolean, isEntityWidthFull: boolean ) => { const scalesToRemove = getImageScalesToRemove(entityData, isText, isEntityWidthFull); let initialScales = imageScaleOptions; if (!scalesToRemove.length) return imageScaleOptions; initialScales = initialScales.filter((item) => !~scalesToRemove.indexOf(item.label)); for (let i = 0; i < initialScales.length; i++) { initialScales[i].value = i; } return elementsLabelsToRemove; return initialScales; }; export const scaleImage = (entityData: IImage, prevScale: string) => { let scale = entityData.image_scale; if (scale[0] === 'x') scale = scale.slice(1); if (prevScale[0] === 'x') prevScale = prevScale.slice(1); const initialWidth = Math.ceil(+entityData.image_width / +prevScale); entityData.image_width = Math.ceil(initialWidth * +scale); return entityData; }; Loading
.gitignore +2 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ logs *.log npm-debug.log* .yarn yarn-debug.log* yarn-error.log* pnpm-debug.log* Loading Loading @@ -29,3 +30,4 @@ coverage *.sw? *.tsbuildinfo /.yarnrc.yml
package.json +5 −1 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ "private": true, "type": "module", "scripts": { "dev": "vite", "dev": "vite && npx tailwindcss -i ./src/input.css -o ./src/output.css --watch", "build": "run-p type-check \"build-only {@}\" --", "preview": "vite preview", "build-only": "vite build", Loading Loading @@ -62,5 +62,9 @@ "ecmaVersion": 2020 }, "rules": {} }, "volta": { "node": "20.17.0", "yarn": "4.5.0" } }
src/app/assets/main.css +31 −3 Original line number Diff line number Diff line Loading @@ -35,6 +35,15 @@ --orange-700: #c2410c; --orange-800: #9a3412; --orange-900: #7c2d12; --amber-100: #fef3c7; --amber-200: #fde68a; --amber-300: #fcd34d; --amber-400: #fbbf24; --amber-500: #f59e0b; --amber-600: #d97706; --amber-700: #b45309; --amber-800: #92400e; --amber-900: #78350f; --yellow-100: #fef9c3; --yellow-200: #fef08a; --yellow-300: #fde047; Loading Loading @@ -276,10 +285,29 @@ input[type=file]::-webkit-file-upload-button { 0% { transform: scale(0); } 50% { transform: scale(1.25); } 100% { transform: scale(1); } } .v-enter-active, .v-leave-active { transition: all 0.5s ease; } .fading-enter-active, .fading-leave-active { transition: opacity 0.3s ease-in-out; } .fading-enter-active { animation: fading-in 0.5s; } .fading-leave-active { animation: fading-in 0.5s reverse; } @keyframes fading-in { 0% { opacity: 0; } 100% { opacity: 1; } }
src/app/components.d.ts +13 −10 Original line number Diff line number Diff line Loading @@ -7,19 +7,23 @@ export {} /* prettier-ignore */ declare module 'vue' { export interface GlobalComponents { AlignCenterIcon: typeof import('./../shared/icons/AlignCenterIcon.vue')['default'] AlignLeftIcon: typeof import('./../shared/icons/AlignLeftIcon.vue')['default'] AlignRightIcon: typeof import('./../shared/icons/AlignRightIcon.vue')['default'] App: typeof import('./App.vue')['default'] AuthorizationForm: typeof import('./../modules/authorization/AuthorizationForm.vue')['default'] BaseLoader: typeof import('./../shared/BaseLoader.vue')['default'] BaseSidebarMenu: typeof import('./../modules/BaseSidebarMenu.vue')['default'] Button: typeof import('./../shared/ui/Button.vue')['default'] CloseCircle: typeof import('./../shared/icons/CloseCircle.vue')['default'] ConfirmDeleteEntityModal: typeof import('./../modules/ConfirmDeleteEntityModal.vue')['default'] CreateEntityMenu: typeof import('./../components/CreateEntityMenu.vue')['default'] CropIcon: typeof import('./../shared/icons/CropIcon.vue')['default'] CropImageModal: typeof import('./../modules/CropImageModal.vue')['default'] DashedIcon: typeof import('./../shared/icons/DashedIcon.vue')['default'] Divider: typeof import('./../shared/ui/Divider.vue')['default'] DividerItem: typeof import('./../modules/entities/DividerItem.vue')['default'] DividerMenu: typeof import('./../modules/entities/settings/DividerMenu.vue')['default'] DividerSettings: typeof import('./../components/entities/settings/DividerSettings.vue')['default'] DividerSettingsList: typeof import('./../components/entities/settings/lists/DividerSettingsList.vue')['default'] DottedIcon: typeof import('./../shared/icons/DottedIcon.vue')['default'] Drawer: typeof import('./../shared/ui/Drawer.vue')['default'] EntitiesList: typeof import('./../modules/entities/EntitiesList.vue')['default'] Loading @@ -32,37 +36,36 @@ declare module 'vue' { HorizontalLineIcon: typeof import('./../shared/icons/HorizontalLineIcon.vue')['default'] ImageIcon: typeof import('./../shared/icons/ImageIcon.vue')['default'] ImageItem: typeof import('./../modules/entities/ImageItem.vue')['default'] ImageMenu: typeof import('./../components/entities/settings/ImageMenu.vue')['default'] ImagePositionMenu: typeof import('./../components/entities/image/ImagePositionMenu.vue')['default'] ImageSettings: typeof import('./../components/entities/settings/ImageSettings.vue')['default'] ImageSizeMenu: typeof import('./../components/entities/image/ImageSizeMenu.vue')['default'] ImageStateMenu: typeof import('./../components/entities/image/ImageStateMenu.vue')['default'] ImageSettingsList: typeof import('./../components/entities/settings/lists/ImageSettingsList.vue')['default'] LogoAndLabel: typeof import('./../components/LogoAndLabel.vue')['default'] MenuDial: typeof import('./../shared/ui/MenuDial.vue')['default'] MenuHeader: typeof import('./../components/MenuHeader.vue')['default'] Modal: typeof import('./../shared/ui/Modal.vue')['default'] NavigationIcon: typeof import('./../shared/icons/NavigationIcon.vue')['default'] PageBackgroundMenu: typeof import('./../modules/PageBackgroundMenu.vue')['default'] PageHeader: typeof import('./../modules/PageHeader.vue')['default'] PageMenuButton: typeof import('./../components/PageMenuButton.vue')['default'] ParagraphIcon: typeof import('./../shared/icons/ParagraphIcon.vue')['default'] ParagraphItem: typeof import('./../modules/entities/ParagraphItem.vue')['default'] ParagraphSettings: typeof import('./../components/entities/settings/ParagraphSettings.vue')['default'] ParagraphSettingsList: typeof import('./../components/entities/settings/lists/ParagraphSettingsList.vue')['default'] PlusIcon: typeof import('./../shared/icons/PlusIcon.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] SaveIcon: typeof import('./../shared/icons/SaveIcon.vue')['default'] SettingsIcon: typeof import('./../shared/icons/SettingsIcon.vue')['default'] SheetPage: typeof import('./../pages/[uuid]/SheetPage.vue')['default'] SidebarMenuContent: typeof import('./../modules/SidebarMenuContent.vue')['default'] SidebarMenuHeader: typeof import('./../modules/SidebarMenuHeader.vue')['default'] SignIn: typeof import('./../pages/authorization/signIn.vue')['default'] SignUp: typeof import('./../pages/authorization/signUp.vue')['default'] Slider: typeof import('./../shared/ui/Slider.vue')['default'] SolidIcon: typeof import('./../shared/icons/SolidIcon.vue')['default'] TableIcon: typeof import('./../shared/icons/TableIcon.vue')['default'] TelegramSection: typeof import('./../modules/TelegramSection.vue')['default'] TextFontMenu: typeof import('./../components/entities/share/TextFontMenu.vue')['default'] TextItem: typeof import('./../modules/entities/TextItem.vue')['default'] TextPositionMenu: typeof import('./../components/entities/text/TextPositionMenu.vue')['default'] TextSettings: typeof import('./../components/entities/settings/TextSettings.vue')['default'] TextStateMenu: typeof import('./../components/entities/text/TextStateMenu.vue')['default'] ToggleButton: typeof import('./../shared/ui/ToggleButton.vue')['default'] ToggleSwitch: typeof import('./../shared/ui/ToggleSwitch.vue')['default'] TrashIcon: typeof import('./../shared/icons/TrashIcon.vue')['default'] Tree: typeof import('./../shared/ui/Tree.vue')['default'] Loading
src/app/helpers/images.ts +106 −65 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ import { useFilesWebsocketStore } from '@/app/stores/filesWebsocket'; import type { IImage } from '@/app/interfaces/entities'; import { useWebsocketStore } from '@/app/stores/websocket'; import { useInterfaceStore } from '@/app/stores/interface'; import { imageScaleOptions } from '@/components/entities/settings/lists/constants/options'; export const setDefaultPageBackground = () => { const interfaceStore = useInterfaceStore(); Loading @@ -15,14 +16,17 @@ export const addUrlsToImageEntities = (entities: IEntity[]) => { let index = 0; const entitiesToReturn = entities.map((entity: IEntity) => { if (!entity?.image_width) return entity; if (entity.imageUrl) return entity; if (filesWebsocketStore.imageUrl) { if (entity.image_url) return entity; if (filesWebsocketStore.image_url) { // редактирование сущности изображения entity.imageUrl = filesWebsocketStore.imageUrl; entity.image_url = filesWebsocketStore.image_url; filesWebsocketStore.cleanImageUrl(); } else { filesBuffer[index] = new Blob([filesBuffer[index].data], { type: 'image/jpeg' }); entity.imageUrl = URL.createObjectURL(filesBuffer[index]); entity.image_url = URL.createObjectURL(filesBuffer[index]); index += 1; filesBuffer[index] = new Blob([filesBuffer[index].data], { type: 'image/jpeg' }); entity.image_url_initial = URL.createObjectURL(filesBuffer[index]); index += 1; } return entity; Loading @@ -37,18 +41,33 @@ export const checkIsImage = (entity: IEntity) => { } const entityToReturn = { ...entity }; const filesWebsocketStore = useFilesWebsocketStore(); filesWebsocketStore.saveImageUrl(entityToReturn.imageUrl!); delete entityToReturn.imageUrl; filesWebsocketStore.saveImageUrl(entityToReturn.image_url!); delete entityToReturn.image_url; return entityToReturn; }; export const cropImage = async (newUrl: string, entity: IImage) => { export const calcImageWidth = (fileWidth: number, windowWidth: number) => { let imageWidth = Math.ceil((fileWidth / (windowWidth - 128)) * 100); if (imageWidth > 100) { imageWidth = 100; } if (imageWidth < 5) { imageWidth = 5; } return imageWidth; }; export const sendCropImage = async (newUrl: string, entity: IImage) => { const filesWebsocketStore = useFilesWebsocketStore(); filesWebsocketStore.saveImageUrl(newUrl); const websocketStore = useWebsocketStore(); const response = await fetch(newUrl); const blob = await response.blob(); const buffer = await blob.arrayBuffer(); const dataSetCropNow = { event: 'setCropNow' }; websocketStore.sendData(dataSetCropNow); filesWebsocketStore.sendData(buffer); const data = { event: 'cropImage', Loading @@ -57,73 +76,95 @@ export const cropImage = async (newUrl: string, entity: IImage) => { websocketStore.sendData(data); }; export const getImageSpeedDialSizeSmallerLabelsToRemove = (entity: IImage) => { const elementsLabelsToRemove = []; const initialImageWidth = Math.ceil(entity.image_width / +entity.image_scale); const initialImageHeight = Math.ceil(entity.image_height / +entity.image_scale); if (initialImageWidth <= 400 || initialImageHeight <= 400) { elementsLabelsToRemove.push('x0.25'); if ( initialImageWidth <= 200 || initialImageHeight <= 200 || (initialImageWidth >= 1600 && entity.text_position) ) { elementsLabelsToRemove.push('x0.5'); if ( initialImageWidth <= 95 || initialImageHeight <= 95 || (initialImageWidth >= 1066 && entity.text_position) ) { elementsLabelsToRemove.push('x0.75'); export const getImageScalesToRemove = ( entity: IImage, isText?: boolean, isEntityWidthFull: boolean ) => { const valuesToRemove = []; let scale = entity.image_scale; if (scale[0] === 'x') scale = scale.slice(1); const initialImageWidth = Math.ceil(+entity.image_width / +scale); const initialImageHeight = +entity.file_height_initial; if (initialImageWidth <= 20) { valuesToRemove.push('x0.25'); if (initialImageWidth <= 10) { valuesToRemove.push('x0.5'); } } if (initialImageWidth <= 7 || (!isEntityWidthFull && isText && initialImageWidth > 66)) { valuesToRemove.push('x0.75'); } if ( (initialImageWidth >= 800 && entity.text_position) || entity.image_width < initialImageWidth ) { elementsLabelsToRemove.push('x1'); if (initialImageWidth > 75 && isText) { valuesToRemove.push('x1'); } return elementsLabelsToRemove; }; export const getImageSpeedDialSizeBiggerLabelsToRemove = (entity: IImage) => { const elementsLabelsToRemove = []; const initialImageWidth = Math.ceil(entity.image_width / +entity.image_scale); const initialImageHeight = Math.ceil(entity.image_height / +entity.image_scale); if ( (initialImageWidth >= 800 && entity.text_position) || entity.image_width > initialImageWidth initialImageWidth > 80 || (initialImageWidth > 60 && isText) || (!isEntityWidthFull && isText && initialImageWidth > 40) || initialImageHeight * 1.25 > 1000 ) { elementsLabelsToRemove.push('x1'); valuesToRemove.push('x1.25'); } if ( initialImageWidth >= 960 || initialImageHeight >= 560 || (initialImageWidth >= 640 && entity.text_position) initialImageWidth > 66 || (initialImageWidth > 50 && isText) || (!isEntityWidthFull && isText && initialImageWidth > 33) || initialImageHeight * 1.5 > 1000 ) { elementsLabelsToRemove.push('x1.25'); valuesToRemove.push('x1.5'); } if ( initialImageWidth >= 800 || initialImageHeight >= 467 || (initialImageWidth >= 533 && entity.text_position) initialImageWidth > 57 || (initialImageWidth > 42 && isText) || (!isEntityWidthFull && isText && initialImageWidth > 28) || initialImageHeight * 1.75 > 1000 ) { elementsLabelsToRemove.push('x1.5'); valuesToRemove.push('x1.75'); } if ( initialImageWidth >= 685 || initialImageHeight >= 400 || (initialImageWidth >= 457 && entity.text_position) initialImageWidth > 57 || (initialImageWidth > 42 && isText) || (!isEntityWidthFull && isText && initialImageWidth > 28) || initialImageHeight * 1.75 > 1000 ) { elementsLabelsToRemove.push('x1.75'); valuesToRemove.push('x1.75'); } if ( initialImageWidth >= 600 || initialImageHeight >= 350 || (initialImageWidth >= 400 && entity.text_position) initialImageWidth > 50 || (initialImageWidth > 37 && isText) || (!isEntityWidthFull && isText && initialImageWidth > 25) || initialImageHeight * 2 > 1000 ) { elementsLabelsToRemove.push('x2'); } } valuesToRemove.push('x2'); } return valuesToRemove; }; export const filterImageScaleOptions = ( entityData: IImage, isText: boolean, isEntityWidthFull: boolean ) => { const scalesToRemove = getImageScalesToRemove(entityData, isText, isEntityWidthFull); let initialScales = imageScaleOptions; if (!scalesToRemove.length) return imageScaleOptions; initialScales = initialScales.filter((item) => !~scalesToRemove.indexOf(item.label)); for (let i = 0; i < initialScales.length; i++) { initialScales[i].value = i; } return elementsLabelsToRemove; return initialScales; }; export const scaleImage = (entityData: IImage, prevScale: string) => { let scale = entityData.image_scale; if (scale[0] === 'x') scale = scale.slice(1); if (prevScale[0] === 'x') prevScale = prevScale.slice(1); const initialWidth = Math.ceil(+entityData.image_width / +prevScale); entityData.image_width = Math.ceil(initialWidth * +scale); return entityData; };