mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-06-10 14:13:01 +08:00
fix(stage): 只有当组件不在视窗内才自动滚动,新增scrollIntoView配置
This commit is contained in:
parent
e7b9123fd5
commit
dbcd4201ea
@ -14,6 +14,7 @@
|
||||
<slot name="workspace">
|
||||
<workspace
|
||||
:runtime-url="runtimeUrl"
|
||||
:auto-scroll-into-view="autoScrollIntoView"
|
||||
:render="render"
|
||||
:moveable-options="moveableOptions"
|
||||
:can-select="canSelect"
|
||||
@ -101,6 +102,9 @@ export default defineComponent({
|
||||
/** 中间工作区域中画布通过iframe渲染时的页面url */
|
||||
runtimeUrl: String,
|
||||
|
||||
/** 选中时是否自动滚动到可视区域 */
|
||||
autoScrollIntoView: Boolean,
|
||||
|
||||
/** 组件的属性配置表单的dsl */
|
||||
propsConfigs: {
|
||||
type: Object as PropType<Record<string, FormConfig>>,
|
||||
|
@ -59,6 +59,7 @@ export default defineComponent({
|
||||
},
|
||||
|
||||
runtimeUrl: String,
|
||||
autoScrollIntoView: Boolean,
|
||||
|
||||
canSelect: {
|
||||
type: Function as PropType<(el: HTMLElement) => boolean | Promise<boolean>>,
|
||||
@ -100,6 +101,7 @@ export default defineComponent({
|
||||
render: props.render,
|
||||
runtimeUrl: props.runtimeUrl,
|
||||
zoom: zoom.value,
|
||||
autoScrollIntoView: props.autoScrollIntoView,
|
||||
canSelect: (el, event, stop) => {
|
||||
const elCanSelect = props.canSelect(el);
|
||||
// 在组件联动过程中不能再往下选择,返回并触发 ui-select
|
||||
|
@ -3,6 +3,7 @@
|
||||
<magic-stage
|
||||
:key="page?.id"
|
||||
:runtime-url="runtimeUrl"
|
||||
:auto-scroll-into-view="autoScrollIntoView"
|
||||
:render="render"
|
||||
:moveable-options="moveableOptions"
|
||||
:can-select="canSelect"
|
||||
@ -41,6 +42,7 @@ export default defineComponent({
|
||||
|
||||
props: {
|
||||
runtimeUrl: String,
|
||||
autoScrollIntoView: Boolean,
|
||||
|
||||
render: {
|
||||
type: Function as PropType<() => HTMLDivElement>,
|
||||
|
@ -155,7 +155,10 @@ export default class StageCore extends EventEmitter {
|
||||
|
||||
this.mask.setLayout(el);
|
||||
this.dr.select(el, event);
|
||||
this.mask.scrollIntoView(el);
|
||||
|
||||
if (this.config.autoScrollIntoView || el.dataset.autoScrollIntoView) {
|
||||
this.mask.intersectionObserver?.observe(el);
|
||||
}
|
||||
|
||||
this.selectedDom = el;
|
||||
|
||||
|
@ -83,6 +83,7 @@ export default class StageMask extends Rule {
|
||||
public wrapperWidth = 0;
|
||||
public maxScrollTop = 0;
|
||||
public maxScrollLeft = 0;
|
||||
public intersectionObserver: IntersectionObserver | null = null;
|
||||
|
||||
private mode: Mode = Mode.ABSOLUTE;
|
||||
private pageResizeObserver: ResizeObserver | null = null;
|
||||
@ -132,6 +133,27 @@ export default class StageMask extends Rule {
|
||||
this.page = page;
|
||||
this.pageScrollParent = getScrollParent(page) || this.core.renderer.contentWindow?.document.documentElement || null;
|
||||
this.pageResizeObserver?.disconnect();
|
||||
this.wrapperResizeObserver?.disconnect();
|
||||
this.intersectionObserver?.disconnect();
|
||||
|
||||
if (typeof IntersectionObserver !== 'undefined') {
|
||||
this.intersectionObserver = new IntersectionObserver(
|
||||
(entries) => {
|
||||
entries.forEach((entry) => {
|
||||
const { target, intersectionRatio } = entry;
|
||||
if (intersectionRatio <= 0) {
|
||||
this.scrollIntoView(target);
|
||||
}
|
||||
this.intersectionObserver?.unobserve(target);
|
||||
});
|
||||
},
|
||||
{
|
||||
root: this.pageScrollParent,
|
||||
rootMargin: '0px',
|
||||
threshold: 1.0,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof ResizeObserver !== 'undefined') {
|
||||
this.pageResizeObserver = new ResizeObserver((entries) => {
|
||||
@ -173,9 +195,7 @@ export default class StageMask extends Rule {
|
||||
this.setMode(isFixedParent(el) ? Mode.FIXED : Mode.ABSOLUTE);
|
||||
}
|
||||
|
||||
public scrollIntoView(el: HTMLElement): void {
|
||||
if (this.mode === Mode.FIXED) return;
|
||||
|
||||
public scrollIntoView(el: Element): void {
|
||||
el.scrollIntoView();
|
||||
if (!this.pageScrollParent) return;
|
||||
this.scrollLeft = this.pageScrollParent.scrollLeft;
|
||||
|
@ -37,6 +37,7 @@ export type StageCoreConfig = {
|
||||
/** runtime 的HTML地址,可以是一个HTTP地址,如果和编辑器不同域,需要设置跨域,也可以是一个相对或绝对路径 */
|
||||
runtimeUrl?: string;
|
||||
render?: (renderer: StageCore) => Promise<HTMLElement> | HTMLElement;
|
||||
autoScrollIntoView?: boolean;
|
||||
};
|
||||
|
||||
export interface StageRenderConfig {
|
||||
|
Loading…
x
Reference in New Issue
Block a user