feat:add continuity page mode

pr675
黄云飞 4 years ago
parent 7c37e84497
commit 361e4394f7

@ -197,6 +197,15 @@
<div class="editor" editor-component="main"></div>
<div class="footer" editor-component="footer">
<div>
<div class="page-mode">
<i></i>
<div class="options">
<ul>
<li data-page-mode="paging" class="active">分页</li>
<li data-page-mode="continuity">连页</li>
</ul>
</div>
</div>
<span>可见页码:<span class="page-no-list">1</span></span>
<span>页面:<span class="page-no">1</span>/<span class="page-size">1</span></span>
</div>

@ -0,0 +1 @@
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><g transform="translate(2 1)"><rect stroke="#3D4757" x=".5" y=".5" width="11" height="8" rx="1"/><path fill="#3D4757" fill-rule="nonzero" d="M2 3h4v1H2zm0 2h8v1H2z"/></g><g fill="#3D4757" fill-rule="nonzero"><path d="M14 15h-1v-5H3v5H2V9h12v6z"/><path d="M4 12h4v1H4zm0 2h8v1H4z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 413 B

@ -1,5 +1,5 @@
import { IElement } from '../..'
import { EditorMode } from '../../dataset/enum/Editor'
import { EditorMode, PageMode } from '../../dataset/enum/Editor'
import { RowFlex } from '../../dataset/enum/Row'
import { IDrawImagePayload, IPainterOptions } from '../../interface/Draw'
import { IEditorResult } from '../../interface/Editor'
@ -57,6 +57,7 @@ export class Command {
private static print: Function
private static getImage: Function
private static getValue: Function
private static pageMode: Function
private static pageScaleRecovery: Function
private static pageScaleMinus: Function
private static pageScaleAdd: Function
@ -111,6 +112,7 @@ export class Command {
Command.print = adapt.print.bind(adapt)
Command.getImage = adapt.getImage.bind(adapt)
Command.getValue = adapt.getValue.bind(adapt)
Command.pageMode = adapt.pageMode.bind(adapt)
Command.pageScaleRecovery = adapt.pageScaleRecovery.bind(adapt)
Command.pageScaleMinus = adapt.pageScaleMinus.bind(adapt)
Command.pageScaleAdd = adapt.pageScaleAdd.bind(adapt)
@ -313,7 +315,11 @@ export class Command {
return Command.getValue()
}
// 页面缩放
// 页面模式、页面缩放
public executePageMode(payload: PageMode) {
return Command.pageMode(payload)
}
public executePageScaleRecovery() {
return Command.pageScaleRecovery()
}

@ -2,7 +2,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 { EditorContext, EditorMode } from '../../dataset/enum/Editor'
import { EditorContext, EditorMode, PageMode } from '../../dataset/enum/Editor'
import { ElementType } from '../../dataset/enum/Element'
import { ElementStyleKey } from '../../dataset/enum/ElementStyle'
import { RowFlex } from '../../dataset/enum/Row'
@ -1243,6 +1243,10 @@ export class CommandAdapt {
return this.draw.getValue()
}
public pageMode(payload: PageMode) {
this.draw.setPageMode(payload)
}
public pageScaleRecovery() {
const { scale } = this.options
if (scale !== 1) {

@ -34,7 +34,7 @@ import { SubscriptParticle } from './particle/Subscript'
import { SeparatorParticle } from './particle/Separator'
import { PageBreakParticle } from './particle/PageBreak'
import { Watermark } from './frame/Watermark'
import { EditorMode } from '../../dataset/enum/Editor'
import { EditorMode, PageMode } from '../../dataset/enum/Editor'
import { Control } from './control/Control'
import { zipElementList } from '../../utils/element'
import { CheckboxParticle } from './particle/CheckboxParticle'
@ -97,7 +97,7 @@ export class Draw {
this.pageList = []
this.ctxList = []
this.pageNo = 0
this.mode = options.defaultMode
this.mode = options.mode
this.options = options
this.elementList = elementList
this.listener = listener
@ -168,6 +168,16 @@ export class Draw {
return Math.floor(this.options.height * this.options.scale)
}
public getCanvasWidth(): number {
const page = this.getPage()
return page.width
}
public getCanvasHeight(): number {
const page = this.getPage()
return page.height
}
public getInnerWidth(): number {
const width = this.getWidth()
const margins = this.getMargins()
@ -394,6 +404,26 @@ export class Draw {
})
}
public setPageMode(payload: PageMode) {
if (!payload || this.options.pageMode === payload) return
this.options.pageMode = payload
// 纸张大小重置
if (payload === PageMode.PAGING) {
const { height } = this.options
const dpr = window.devicePixelRatio
const canvas = this.pageList[0]
canvas.style.height = `${height}px`
canvas.height = height * dpr
}
this.render({ isSubmitHistory: false, isSetCursor: false })
// 回调
setTimeout(() => {
if (this.listener.pageModeChange) {
this.listener.pageModeChange(payload)
}
})
}
public setPageScale(payload: number) {
this.options.scale = payload
const width = this.getWidth()
@ -855,12 +885,12 @@ export class Draw {
}
private _drawPage(positionList: IElementPosition[], rowList: IRow[], pageNo: number) {
const width = this.getWidth()
const height = this.getHeight()
const { pageMode } = this.options
const margins = this.getMargins()
const innerWidth = this.getInnerWidth()
const ctx = this.ctxList[pageNo]
ctx.clearRect(0, 0, width, height)
const pageDom = this.pageList[pageNo]
ctx.clearRect(0, 0, pageDom.width, pageDom.height)
// 绘制背景
this.background.render(ctx)
// 绘制页边距
@ -891,12 +921,13 @@ export class Draw {
this.search.render(ctx, pageNo)
}
// 绘制水印
if (this.options.watermark.data) {
if (pageMode !== PageMode.CONTINUITY && this.options.watermark.data) {
this.waterMark.render(ctx)
}
}
public render(payload?: IDrawOption) {
const { pageMode } = this.options
const {
isSubmitHistory = true,
isSetCursor = true,
@ -922,15 +953,32 @@ export class Draw {
let pageHeight = marginHeight
let pageNo = 0
const pageRowList: IRow[][] = [[]]
for (let i = 0; i < this.rowList.length; i++) {
const row = this.rowList[i]
if (row.height + pageHeight > height || this.rowList[i - 1]?.isPageBreak) {
pageHeight = marginHeight + row.height
pageRowList.push([row])
pageNo++
if (pageMode === PageMode.CONTINUITY) {
pageRowList[0] = this.rowList
// 重置高度
pageHeight += this.rowList.reduce((pre, cur) => pre + cur.height, 0)
const dpr = window.devicePixelRatio
const pageDom = this.pageList[0]
const pageDomHeight = Number(pageDom.style.height.replace('px', ''))
if (pageHeight > pageDomHeight) {
pageDom.style.height = `${pageHeight}px`
pageDom.height = pageHeight * dpr
} else {
pageHeight += row.height
pageRowList[pageNo].push(row)
const reduceHeight = pageHeight < height ? height : pageHeight
pageDom.style.height = `${reduceHeight}px`
pageDom.height = reduceHeight * dpr
}
} else {
for (let i = 0; i < this.rowList.length; i++) {
const row = this.rowList[i]
if (row.height + pageHeight > height || this.rowList[i - 1]?.isPageBreak) {
pageHeight = marginHeight + row.height
pageRowList.push([row])
pageNo++
} else {
pageHeight += row.height
pageRowList[pageNo].push(row)
}
}
}
// 绘制元素

@ -1,3 +1,4 @@
import { PageMode } from '../../../dataset/enum/Editor'
import { IEditorOption } from '../../../interface/Editor'
import { Draw } from '../Draw'
@ -12,9 +13,11 @@ export class Margin {
}
public render(ctx: CanvasRenderingContext2D) {
const { marginIndicatorColor } = this.options
const { marginIndicatorColor, pageMode } = this.options
const width = this.draw.getWidth()
const height = this.draw.getHeight()
const height = pageMode === PageMode.CONTINUITY
? this.draw.getCanvasHeight()
: this.draw.getHeight()
const margins = this.draw.getMargins()
const marginIndicatorSize = this.draw.getMarginIndicatorSize()
ctx.save()

@ -1,3 +1,4 @@
import { PageMode } from '../../../dataset/enum/Editor'
import { IEditorOption } from '../../../interface/Editor'
import { Draw } from '../Draw'
@ -12,9 +13,11 @@ export class PageNumber {
}
public render(ctx: CanvasRenderingContext2D, pageNo: number) {
const { pageNumberSize, pageNumberFont, scale } = this.options
const { pageNumberSize, pageNumberFont, scale, pageMode } = this.options
const width = this.draw.getWidth()
const height = this.draw.getHeight()
const height = pageMode === PageMode.CONTINUITY
? this.draw.getCanvasHeight()
: this.draw.getHeight()
const pageNumberBottom = this.draw.getPageNumberBottom()
ctx.save()
ctx.fillStyle = '#00000'

@ -2,6 +2,7 @@ import {
IContentChange,
IControlChange,
IIntersectionPageNoChange,
IPageModeChange,
IPageScaleChange,
IPageSizeChange,
IRangeStyleChange,
@ -19,6 +20,7 @@ export class Listener {
public saved: ISaved | null
public contentChange: IContentChange | null
public controlChange: IControlChange | null
public pageModeChange: IPageModeChange | null
constructor() {
this.rangeStyleChange = null
@ -29,6 +31,7 @@ export class Listener {
this.saved = null
this.contentChange = null
this.controlChange = null
this.pageModeChange = null
}
}

@ -16,4 +16,9 @@ export enum EditorMode {
EDIT = 'edit',
CLEAN = 'clean',
READONLY = 'readonly'
}
export enum PageMode {
PAGING = 'paging',
CONTINUITY = 'continuity'
}

@ -13,7 +13,7 @@ import { globalMenus } from './core/contextmenu/menus/globalMenus'
import { ContextMenu } from './core/contextmenu/ContextMenu'
import { tableMenus } from './core/contextmenu/menus/tableMenus'
import { IContextMenuContext, IRegisterContextMenu } from './interface/contextmenu/ContextMenu'
import { EditorComponent, EditorMode } from './dataset/enum/Editor'
import { EditorComponent, EditorMode, PageMode } from './dataset/enum/Editor'
import { EDITOR_COMPONENT } from './dataset/constant/Editor'
import { IHeader } from './interface/Header'
import { IWatermark } from './interface/Watermark'
@ -51,7 +51,7 @@ export default class Editor {
}
const editorOptions: DeepRequired<IEditorOption> = {
defaultMode: EditorMode.EDIT,
mode: EditorMode.EDIT,
defaultType: 'TEXT',
defaultFont: 'Yahei',
defaultSize: 16,
@ -77,6 +77,7 @@ export default class Editor {
marginIndicatorSize: 35,
marginIndicatorColor: '#BABABA',
margins: [100, 120, 100, 120],
pageMode: PageMode.PAGING,
tdPadding: 5,
defaultTdHeight: 40,
defaultHyperlinkColor: '#0000FF',
@ -116,7 +117,8 @@ export {
ElementType,
ControlType,
EditorComponent,
EDITOR_COMPONENT
EDITOR_COMPONENT,
PageMode
}
// 对外类型

@ -1,12 +1,12 @@
import { IElement } from '..'
import { EditorMode } from '../dataset/enum/Editor'
import { EditorMode, PageMode } from '../dataset/enum/Editor'
import { ICheckboxOption } from './Checkbox'
import { IControlOption } from './Control'
import { IHeader } from './Header'
import { IWatermark } from './Watermark'
export interface IEditorOption {
defaultMode?: EditorMode;
mode?: EditorMode;
defaultType?: string;
defaultFont?: string;
defaultSize?: number;
@ -32,6 +32,7 @@ export interface IEditorOption {
marginIndicatorSize?: number;
marginIndicatorColor?: string,
margins?: [top: number, right: number, bottom: number, left: number],
pageMode?: PageMode;
tdPadding?: number;
defaultTdHeight?: number;
defaultHyperlinkColor?: string;

@ -1,4 +1,4 @@
import { ElementType } from '..'
import { ElementType, PageMode } from '..'
import { RowFlex } from '../dataset/enum/Row'
import { IControl } from './Control'
import { IEditorResult } from './Editor'
@ -34,4 +34,6 @@ export type ISaved = (payload: IEditorResult) => void
export type IContentChange = () => void
export type IControlChange = (payload: IControl | null) => void
export type IControlChange = (payload: IControl | null) => void
export type IPageModeChange = (payload: PageMode) => void

@ -1,7 +1,7 @@
import { data, options } from './mock'
import './style.css'
import prism from 'prismjs'
import Editor, { ControlType, EditorMode, ElementType, IElement } from './editor'
import Editor, { ControlType, EditorMode, ElementType, IElement, PageMode } from './editor'
import { Dialog } from './components/dialog/Dialog'
import { formatPrismToken } from './utils/prism'
@ -586,7 +586,17 @@ window.onload = function () {
instance.command.executePrint()
}
// 6. 纸张缩放
// 6. 页面模式 | 纸张缩放
const pageModeDom = document.querySelector<HTMLDivElement>('.page-mode')!
const pageModeOptionsDom = pageModeDom.querySelector<HTMLDivElement>('.options')!
pageModeDom.onclick = function () {
pageModeOptionsDom.classList.toggle('visible')
}
pageModeOptionsDom.onclick = function (evt) {
const li = evt.target as HTMLLIElement
instance.command.executePageMode(<PageMode>li.dataset.pageMode!)
}
document.querySelector<HTMLDivElement>('.page-scale-percentage')!.onclick = function () {
console.log('page-scale-recovery')
instance.command.executePageScaleRecovery()
@ -738,6 +748,12 @@ window.onload = function () {
})
}
instance.listener.pageModeChange = function (payload) {
const activeMode = pageModeOptionsDom.querySelector<HTMLLIElement>(`[data-page-mode='${payload}']`)!
pageModeOptionsDom.querySelectorAll('li').forEach(li => li.classList.remove('active'))
activeMode.classList.add('active')
}
instance.listener.saved = function (payload) {
console.log('elementList: ', payload)
}

@ -551,7 +551,6 @@ ul {
justify-content: space-between;
background: #f2f4f7;
z-index: 9;
overflow: hidden;
position: fixed;
bottom: 0;
left: 0;
@ -560,6 +559,60 @@ ul {
box-sizing: border-box;
}
.footer>div:first-child {
display: flex;
align-items: center;
}
.footer .page-mode {
padding: 1px;
position: relative;
}
.footer .page-mode i {
width: 16px;
height: 16px;
margin-right: 5px;
cursor: pointer;
display: inline-block;
background-image: url('./assets/images/page-mode.svg');
}
.footer .page-mode .options {
width: 70px;
position: absolute;
left: 0;
bottom: 25px;
padding: 10px;
background: #fff;
font-size: 14px;
box-shadow: 0 2px 12px 0 rgb(56 56 56 / 20%);
border: 1px solid #e2e6ed;
border-radius: 2px;
display: none;
}
.footer .page-mode .options.visible {
display: block;
}
.footer .page-mode .options li {
padding: 5px;
margin: 5px 0;
user-select: none;
transition: all .3s;
text-align: center;
cursor: pointer;
}
.footer .page-mode .options li:hover {
background-color: #ebecef;
}
.footer .page-mode .options li.active {
background-color: #e2e6ed;
}
.footer>div:first-child>span {
display: inline-block;
margin-right: 5px;

Loading…
Cancel
Save