mirror of
https://github.com/directus/directus.git
synced 2026-04-25 03:00:53 -04:00
Support custom aspect ratios in image editor (#14786)
* Support custom aspect ratios in image editor * Add custom aspect ratios in file items as well * Revert file item custom-aspect-ratio changes * Use globally configured custom aspect ratios * Remove previos custom-aspect-ratio logic * code style tweak * use migration instead of seed * rename field to custom_aspect_ratios * keep defaults + change icon Co-authored-by: qborisb <boris@qdentity.nl> Co-authored-by: Rijk van Zanten <rijkvanzanten@me.com>
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
import { Knex } from 'knex';
|
||||
|
||||
export async function up(knex: Knex): Promise<void> {
|
||||
await knex.schema.alterTable('directus_settings', (table) => {
|
||||
table.json('custom_aspect_ratios');
|
||||
});
|
||||
}
|
||||
|
||||
export async function down(knex: Knex): Promise<void> {
|
||||
await knex.schema.alterTable('directus_settings', (table) => {
|
||||
table.dropColumn('custom_aspect_ratios');
|
||||
});
|
||||
}
|
||||
@@ -392,3 +392,36 @@ fields:
|
||||
- field: translation_strings
|
||||
special: cast-json
|
||||
hidden: true
|
||||
|
||||
- field: image_editor
|
||||
interface: presentation-divider
|
||||
options:
|
||||
icon: image
|
||||
title: $t:fields.directus_settings.image_editor
|
||||
special:
|
||||
- alias
|
||||
- no-data
|
||||
width: full
|
||||
|
||||
- field: custom_aspect_ratios
|
||||
interface: list
|
||||
special: cast-json
|
||||
options:
|
||||
template: '{{text}}'
|
||||
fields:
|
||||
- field: text
|
||||
name: $t:text
|
||||
type: string
|
||||
meta:
|
||||
interface: text-input
|
||||
width: half
|
||||
options:
|
||||
placeholder: $t:text
|
||||
- field: value
|
||||
name: $t:value
|
||||
type: float
|
||||
meta:
|
||||
interface: input
|
||||
width: half
|
||||
options:
|
||||
placeholder: $t:value
|
||||
|
||||
@@ -1048,6 +1048,8 @@ fields:
|
||||
transformations_all: Allow all transformations
|
||||
transformations_none: Disable transformations
|
||||
transformations_presets: Limit transformations to presets below
|
||||
image_editor: Image Editor
|
||||
custom_aspect_ratios: Custom Aspect Ratios
|
||||
directus_shares:
|
||||
name: Name
|
||||
role: Role
|
||||
|
||||
@@ -1154,6 +1154,8 @@ fields:
|
||||
transformations_all: Allow all transformations
|
||||
transformations_none: Disable transformations
|
||||
transformations_presets: Limit transformations to presets below
|
||||
image_editor: Image Editor
|
||||
custom_aspect_ratios: Custom Aspect Ratios
|
||||
directus_shares:
|
||||
name: Name
|
||||
role: Role
|
||||
|
||||
@@ -52,6 +52,19 @@
|
||||
</template>
|
||||
|
||||
<v-list>
|
||||
<template v-if="customAspectRatios">
|
||||
<v-list-item
|
||||
v-for="customAspectRatio in customAspectRatios"
|
||||
:key="customAspectRatio.text"
|
||||
clickable
|
||||
:active="aspectRatio === customAspectRatio.value"
|
||||
@click="aspectRatio = customAspectRatio.value"
|
||||
>
|
||||
<v-list-item-icon><v-icon name="aspect_ratio" /></v-list-item-icon>
|
||||
<v-list-item-content>{{ customAspectRatio.text }}</v-list-item-content>
|
||||
</v-list-item>
|
||||
<v-divider />
|
||||
</template>
|
||||
<v-list-item clickable :active="aspectRatio === 16 / 9" @click="aspectRatio = 16 / 9">
|
||||
<v-list-item-icon><v-icon name="crop_16_9" /></v-list-item-icon>
|
||||
<v-list-item-content>16:9</v-list-item-content>
|
||||
@@ -119,6 +132,7 @@ import api, { addTokenToURL } from '@/api';
|
||||
import { computed, defineComponent, nextTick, reactive, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
import { getRootPath } from '@/utils/get-root-path';
|
||||
import { unexpectedError } from '@/utils/unexpected-error';
|
||||
import Cropper from 'cropperjs';
|
||||
@@ -148,6 +162,8 @@ export default defineComponent({
|
||||
setup(props, { emit }) {
|
||||
const { t, n } = useI18n();
|
||||
|
||||
const settingsStore = useSettingsStore();
|
||||
|
||||
const localActive = ref(false);
|
||||
|
||||
const internalActive = computed({
|
||||
@@ -195,6 +211,8 @@ export default defineComponent({
|
||||
return addTokenToURL(`${getRootPath()}assets/${props.id}?${randomId.value}`);
|
||||
});
|
||||
|
||||
const customAspectRatios = settingsStore.settings?.custom_aspect_ratios ?? null;
|
||||
|
||||
return {
|
||||
t,
|
||||
n,
|
||||
@@ -216,6 +234,7 @@ export default defineComponent({
|
||||
dragMode,
|
||||
cropping,
|
||||
setAspectRatio,
|
||||
customAspectRatios,
|
||||
};
|
||||
|
||||
function useImage() {
|
||||
@@ -322,6 +341,11 @@ export default defineComponent({
|
||||
const aspectRatioIcon = computed(() => {
|
||||
if (!imageData.value) return 'crop_original';
|
||||
|
||||
if (customAspectRatios) {
|
||||
const customAspectRatio = customAspectRatios.find((customAR) => customAR.value == aspectRatio.value);
|
||||
if (customAspectRatio) return 'crop_square';
|
||||
}
|
||||
|
||||
switch (aspectRatio.value) {
|
||||
case 16 / 9:
|
||||
return 'crop_16_9';
|
||||
|
||||
@@ -26,6 +26,11 @@ export type SettingsStorageAssetPreset = {
|
||||
transforms: any[] | null;
|
||||
};
|
||||
|
||||
export type CustomAspectRatio = {
|
||||
text: string;
|
||||
value: number;
|
||||
};
|
||||
|
||||
export type Settings = {
|
||||
id: 1;
|
||||
project_name: string;
|
||||
@@ -39,6 +44,7 @@ export type Settings = {
|
||||
auth_password_policy: string | null;
|
||||
storage_asset_transform: string;
|
||||
storage_asset_presets: SettingsStorageAssetPreset[] | null;
|
||||
custom_aspect_ratios: CustomAspectRatio[] | null;
|
||||
custom_css: string | null;
|
||||
storage_default_folder: string | null;
|
||||
basemaps: any[] | null;
|
||||
|
||||
Reference in New Issue
Block a user