diff --git a/src/editor/core/command/Command.ts b/src/editor/core/command/Command.ts index c73577e..62c18cc 100644 --- a/src/editor/core/command/Command.ts +++ b/src/editor/core/command/Command.ts @@ -1,4 +1,4 @@ -import { IElement } from '../..' +import { IElement, ImageDisplay } from '../..' import { EditorMode, PageMode } from '../../dataset/enum/Editor' import { RowFlex } from '../../dataset/enum/Row' import { IDrawImagePayload, IPainterOptions } from '../../interface/Draw' @@ -59,6 +59,7 @@ export class Command { private static print: CommandAdapt['print'] private static replaceImageElement: CommandAdapt['replaceImageElement'] private static saveAsImageElement: CommandAdapt['saveAsImageElement'] + private static changeImageDisplay: CommandAdapt['changeImageDisplay'] private static getImage: CommandAdapt['getImage'] private static getValue: CommandAdapt['getValue'] private static getWordCount: CommandAdapt['getWordCount'] @@ -122,6 +123,7 @@ export class Command { Command.print = adapt.print.bind(adapt) Command.replaceImageElement = adapt.replaceImageElement.bind(adapt) Command.saveAsImageElement = adapt.saveAsImageElement.bind(adapt) + Command.changeImageDisplay = adapt.changeImageDisplay.bind(adapt) Command.getImage = adapt.getImage.bind(adapt) Command.getValue = adapt.getValue.bind(adapt) Command.getWordCount = adapt.getWordCount.bind(adapt) @@ -342,6 +344,10 @@ export class Command { return Command.saveAsImageElement() } + public executeChangeImageDisplay(element: IElement, display: ImageDisplay) { + return Command.changeImageDisplay(element, display) + } + public getImage(): string[] { return Command.getImage() } diff --git a/src/editor/core/command/CommandAdapt.ts b/src/editor/core/command/CommandAdapt.ts index 28b963f..49c0de5 100644 --- a/src/editor/core/command/CommandAdapt.ts +++ b/src/editor/core/command/CommandAdapt.ts @@ -1,7 +1,7 @@ import { WRAP, ZERO } from '../../dataset/constant/Common' import { EDITOR_ELEMENT_STYLE_ATTR } from '../../dataset/constant/Element' import { defaultWatermarkOption } from '../../dataset/constant/Watermark' -import { ControlComponent } from '../../dataset/enum/Control' +import { ControlComponent, ImageDisplay } from '../../dataset/enum/Control' import { EditorContext, EditorMode, PageMode } from '../../dataset/enum/Editor' import { ElementType } from '../../dataset/enum/Element' import { ElementStyleKey } from '../../dataset/enum/ElementStyle' @@ -1355,6 +1355,15 @@ export class CommandAdapt { downloadFile(element.value, `${element.id!}.png`) } + public changeImageDisplay(element: IElement, display: ImageDisplay) { + if (element.imgDisplay === display) return + element.imgDisplay = display + this.draw.getPreviewer().clearResizer() + this.draw.render({ + isSetCursor: false + }) + } + public getImage(): string[] { return this.draw.getDataURL() } diff --git a/src/editor/core/contextmenu/menus/imageMenus.ts b/src/editor/core/contextmenu/menus/imageMenus.ts index adbc0f1..8daf0c8 100644 --- a/src/editor/core/contextmenu/menus/imageMenus.ts +++ b/src/editor/core/contextmenu/menus/imageMenus.ts @@ -1,5 +1,6 @@ +import { ImageDisplay } from '../../../dataset/enum/Control' import { ElementType } from '../../../dataset/enum/Element' -import { IRegisterContextMenu } from '../../../interface/contextmenu/ContextMenu' +import { IContextMenuContext, IRegisterContextMenu } from '../../../interface/contextmenu/ContextMenu' import { Command } from '../../command/Command' export const imageMenus: IRegisterContextMenu[] = [ @@ -36,5 +37,28 @@ export const imageMenus: IRegisterContextMenu[] = [ callback: (command: Command) => { command.executeSaveAsImageElement() } + }, + { + name: '文字环绕', + when: (payload) => { + return !payload.editorHasSelection && payload.startElement?.type === ElementType.IMAGE + }, + childMenus: [ + { + name: '嵌入型', + when: () => true, + callback: (command: Command, context: IContextMenuContext) => { + command.executeChangeImageDisplay(context.startElement!, ImageDisplay.BLOCK) + } + }, + { + name: '上下型环绕', + when: () => true, + callback: (command: Command, context: IContextMenuContext) => { + command.executeChangeImageDisplay(context.startElement!, ImageDisplay.INLINE) + + } + } + ] } ] \ No newline at end of file diff --git a/src/editor/core/draw/Draw.ts b/src/editor/core/draw/Draw.ts index b93a62c..de26977 100644 --- a/src/editor/core/draw/Draw.ts +++ b/src/editor/core/draw/Draw.ts @@ -40,7 +40,7 @@ import { Control } from './control/Control' import { zipElementList } from '../../utils/element' import { CheckboxParticle } from './particle/CheckboxParticle' import { DeepRequired } from '../../interface/Common' -import { ControlComponent } from '../../dataset/enum/Control' +import { ControlComponent, ImageDisplay } from '../../dataset/enum/Control' import { formatElementList } from '../../utils/element' import { WorkerManager } from '../worker/WorkerManager' import { Previewer } from './particle/previewer/Previewer' @@ -571,9 +571,10 @@ export class Draw { const elementWidth = element.width! * scale const elementHeight = element.height! * scale // 图片超出尺寸后自适应 - if (curRow.width + elementWidth > innerWidth) { + const curRowWidth = element.imgDisplay === ImageDisplay.INLINE ? 0 : curRow.width + if (curRowWidth + elementWidth > innerWidth) { // 计算剩余大小 - const surplusWidth = innerWidth - curRow.width + const surplusWidth = innerWidth - curRowWidth element.width = surplusWidth element.height = elementHeight * surplusWidth / elementWidth metrics.width = element.width @@ -733,7 +734,9 @@ export class Draw { // 超过限定宽度 const preElement = elementList[i - 1] if ( - (preElement && preElement.type === ElementType.TABLE) + preElement?.type === ElementType.TABLE + || preElement?.imgDisplay === ImageDisplay.INLINE + || element.imgDisplay === ImageDisplay.INLINE || curRow.width + metrics.width > innerWidth || (i !== 0 && element.value === ZERO) ) { @@ -793,9 +796,11 @@ export class Draw { for (let j = 0; j < curRow.elementList.length; j++) { const element = curRow.elementList[j] const metrics = element.metrics - const offsetY = element.type === ElementType.IMAGE || element.type === ElementType.LATEX - ? curRow.ascent - metrics.height - : curRow.ascent + const offsetY = + (element.imgDisplay !== ImageDisplay.INLINE && element.type === ElementType.IMAGE) + || element.type === ElementType.LATEX + ? curRow.ascent - metrics.height + : curRow.ascent const positionItem: IElementPosition = { pageNo, index, diff --git a/src/editor/core/draw/particle/previewer/Previewer.ts b/src/editor/core/draw/particle/previewer/Previewer.ts index ed45db1..6af0cd8 100644 --- a/src/editor/core/draw/particle/previewer/Previewer.ts +++ b/src/editor/core/draw/particle/previewer/Previewer.ts @@ -293,7 +293,7 @@ export class Previewer { public drawResizer(element: IElement, position: IElementPosition, options: IPreviewerDrawOption = {}) { this.previewerDrawOption = options const { scale } = this.options - const { coordinate: { leftTop: [left, top] } } = position + const { coordinate: { leftTop: [left, top] }, ascent } = position const elementWidth = element.width! * scale const elementHeight = element.height! * scale const height = this.draw.getHeight() @@ -302,7 +302,7 @@ export class Previewer { const preY = this.draw.getPageNo() * (height + pageGap) // 边框 this.resizerSelection.style.left = `${left}px` - this.resizerSelection.style.top = `${top + preY}px` + this.resizerSelection.style.top = `${top + preY + ascent}px` this.resizerSelection.style.width = `${elementWidth}px` this.resizerSelection.style.height = `${elementHeight}px` // handle diff --git a/src/editor/dataset/enum/Control.ts b/src/editor/dataset/enum/Control.ts index c40a8d4..fcbbbce 100644 --- a/src/editor/dataset/enum/Control.ts +++ b/src/editor/dataset/enum/Control.ts @@ -10,4 +10,9 @@ export enum ControlComponent { PLACEHOLDER = 'placeholder', VALUE = 'value', CHECKBOX = 'checkbox' +} + +export enum ImageDisplay { + INLINE = 'inline', + BLOCK = 'block' } \ No newline at end of file diff --git a/src/editor/index.ts b/src/editor/index.ts index 31a569e..9d22e92 100644 --- a/src/editor/index.ts +++ b/src/editor/index.ts @@ -17,7 +17,7 @@ import { IHeader } from './interface/Header' import { IWatermark } from './interface/Watermark' import { defaultHeaderOption } from './dataset/constant/Header' import { defaultWatermarkOption } from './dataset/constant/Watermark' -import { ControlType } from './dataset/enum/Control' +import { ControlType, ImageDisplay } from './dataset/enum/Control' import { defaultControlOption } from './dataset/constant/Control' import { IControlOption } from './interface/Control' import { ICheckboxOption } from './interface/Checkbox' @@ -115,7 +115,8 @@ export { ControlType, EditorComponent, EDITOR_COMPONENT, - PageMode + PageMode, + ImageDisplay } // 对外类型 diff --git a/src/editor/interface/Element.ts b/src/editor/interface/Element.ts index 8279961..66c34ff 100644 --- a/src/editor/interface/Element.ts +++ b/src/editor/interface/Element.ts @@ -1,4 +1,4 @@ -import { ControlComponent } from '../dataset/enum/Control' +import { ControlComponent, ImageDisplay } from '../dataset/enum/Control' import { ElementType } from '../dataset/enum/Element' import { RowFlex } from '../dataset/enum/Row' import { ICheckbox } from './Checkbox' @@ -74,6 +74,10 @@ export interface IDateElement { dateId?: string; } +export interface IImageElement { + imgDisplay?: ImageDisplay +} + export type IElement = IElementBasic & IElementStyle & ITable @@ -84,6 +88,7 @@ export type IElement = IElementBasic & ICheckboxElement & ILaTexElement & IDateElement + & IImageElement export interface IElementMetrics { width: number;