Commit d232d707 by Яков

update

parent 79263e8a
{
"name": "react-ag-qeditor",
"version": "1.0.96",
"version": "1.0.97",
"description": "WYSIWYG html editor",
"author": "atma",
"license": "MIT",
......
......@@ -11,6 +11,13 @@ const ResizableImageTemplate = ({ node, updateAttributes, editor, getPos, select
const wrapperRef = useRef(null);
const [showAlignMenu, setShowAlignMenu] = useState(false);
const isInitialized = useRef(false);
const [isResizing, setIsResizing] = useState(false);
// Получаем ширину редактора для масштабирования изображений
const getEditorWidth = () => {
const editorElement = editor?.options?.element?.closest('.atma-editor-content');
return editorElement ? editorElement.clientWidth : null;
};
// Генерация уникального ID при создании
useEffect(() => {
......@@ -36,8 +43,27 @@ const ResizableImageTemplate = ({ node, updateAttributes, editor, getPos, select
const initImageSize = () => {
try {
const width = node.attrs.width || imgRef.current.naturalWidth;
const height = node.attrs.height || imgRef.current.naturalHeight;
const editorWidth = getEditorWidth();
const naturalWidth = imgRef.current.naturalWidth;
const naturalHeight = imgRef.current.naturalHeight;
let width = node.attrs.width || naturalWidth;
let height = node.attrs.height || naturalHeight;
// Масштабируем изображение, если оно шире редактора
if (editorWidth && width > editorWidth) {
const ratio = editorWidth / width;
width = editorWidth;
height = Math.round(height * ratio);
}
// Проверяем минимальный размер
if (width < MIN_WIDTH) {
const ratio = MIN_WIDTH / width;
width = MIN_WIDTH;
height = Math.round(height * ratio);
}
if (width > 0 && height > 0) {
updateAttributes({
width: Math.round(width),
......@@ -66,7 +92,7 @@ const ResizableImageTemplate = ({ node, updateAttributes, editor, getPos, select
e.preventDefault();
e.stopPropagation();
// Явно устанавливаем выделение перед началом ресайза
setIsResizing(true);
editor.commands.setNodeSelection(getPos());
const startWidth = node.attrs.width || imgRef.current.naturalWidth;
......@@ -109,7 +135,7 @@ const ResizableImageTemplate = ({ node, updateAttributes, editor, getPos, select
const onMouseUp = () => {
window.removeEventListener('mousemove', onMouseMove);
window.removeEventListener('mouseup', onMouseUp);
// Явно восстанавливаем выделение после ресайза
setIsResizing(false);
editor.commands.setNodeSelection(getPos());
editor.commands.focus();
};
......@@ -124,38 +150,62 @@ const ResizableImageTemplate = ({ node, updateAttributes, editor, getPos, select
editor.commands.focus();
};
const getWrapperStyle = () => ({
const getWrapperStyle = () => {
const baseStyle = {
display: 'inline-block',
lineHeight: 0,
margin: '0.5rem 0',
position: 'relative',
outline: selected ? `1px dashed ${BORDER_COLOR}` : 'none',
outline: (selected || isResizing) ? `1px dashed ${BORDER_COLOR}` : 'none',
verticalAlign: 'top',
...(node.attrs.align === 'left' && { float: 'left', marginRight: '1rem' }),
...(node.attrs.align === 'right' && { float: 'right', marginLeft: '1rem' }),
...(node.attrs.align === 'center' && {
margin: '0.5rem 0',
};
// Для выравнивания по центру
if (node.attrs.align === 'center') {
return {
...baseStyle,
display: 'block',
marginLeft: 'auto',
marginRight: 'auto',
width: node.attrs.width ? `${node.attrs.width}px` : 'fit-content',
maxWidth: '100%',
textAlign: 'center'
};
}
// Для других вариантов выравнивания
return {
...baseStyle,
...(node.attrs.align === 'left' && {
float: 'left',
marginRight: '1rem',
width: node.attrs.width ? `${node.attrs.width}px` : 'auto',
}),
...(node.attrs.align === 'right' && {
float: 'right',
marginLeft: '1rem',
width: node.attrs.width ? `${node.attrs.width}px` : 'auto',
}),
...(node.attrs.align === 'text' && {
display: 'inline-block',
float: 'none',
margin: '0 0.2rem',
verticalAlign: 'middle'
})
});
verticalAlign: 'middle',
width: node.attrs.width ? `${node.attrs.width}px` : 'auto',
}),
};
};
const getImageStyle = () => ({
width: node.attrs.width ? `${node.attrs.width}px` : 'auto',
height: node.attrs.height ? `${node.attrs.height}px` : 'auto',
height: 'auto', // Автоматическая высота для сохранения пропорций
maxWidth: '100%',
display: 'block',
cursor: 'default',
userSelect: 'none',
margin: node.attrs.align === 'center' ? '0 auto' : '0',
verticalAlign: node.attrs.align === 'text' ? 'middle' : 'top'
verticalAlign: node.attrs.align === 'text' ? 'middle' : 'top',
objectFit: 'contain' // Сохраняем пропорции изображения
});
return (
......@@ -173,12 +223,31 @@ const ResizableImageTemplate = ({ node, updateAttributes, editor, getPos, select
<img
{...node.attrs}
ref={imgRef}
draggable={true} // обязательно true для работы dragstart
draggable={true}
style={getImageStyle()}
onLoad={() => {
if (imgRef.current && !isInitialized.current) {
const width = imgRef.current.naturalWidth;
const height = imgRef.current.naturalHeight;
const editorWidth = getEditorWidth();
const naturalWidth = imgRef.current.naturalWidth;
const naturalHeight = imgRef.current.naturalHeight;
let width = naturalWidth;
let height = naturalHeight;
// Масштабируем изображение, если оно шире редактора
if (editorWidth && width > editorWidth) {
const ratio = editorWidth / width;
width = editorWidth;
height = Math.round(height * ratio);
}
// Проверяем минимальный размер
if (width < MIN_WIDTH) {
const ratio = MIN_WIDTH / width;
width = MIN_WIDTH;
height = Math.round(height * ratio);
}
updateAttributes({
width: Math.round(width),
height: Math.round(height),
......@@ -189,7 +258,7 @@ const ResizableImageTemplate = ({ node, updateAttributes, editor, getPos, select
}}
/>
{selected && (
{(selected || isResizing) && (
<Fragment>
{['nw', 'ne', 'sw', 'se'].map(dir => (
<div
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment