From 9799b2e80ebe969411eebb332f9cd899c73a4ee9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E6=94=BF=E6=9D=83?= <1978141412@qq.com> Date: Wed, 23 Oct 2024 14:03:40 +0800 Subject: [PATCH 1/4] =?UTF-8?q?add:=20=E6=96=B0=E5=A2=9E=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E9=A2=84=E8=A7=88=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/index.ts | 2 + src/common/preview-image/preview-image.scss | 5 + src/common/preview-image/preview-image.tsx | 132 ++++++++++++++++++ .../quill-editor-preview.scss | 1 + .../quill-editor-preview.tsx | 2 +- 5 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 src/common/preview-image/preview-image.scss create mode 100644 src/common/preview-image/preview-image.tsx diff --git a/src/common/index.ts b/src/common/index.ts index 85551332f..ec289dc3e 100644 --- a/src/common/index.ts +++ b/src/common/index.ts @@ -21,6 +21,7 @@ import { IBizFullscreenHeader } from './fullscreen-header/fullscreen-header'; import { IBizButtonList } from './button-list/button-list'; import { IBizEmojiSelect } from './emoji-select/emoji-select'; import { IBizMdCtrlSetting } from './md-ctrl-setting/md-ctrl-setting'; +import { IBizPreviewImage } from './preview-image/preview-image'; export * from './col/col'; export * from './row/row'; @@ -48,6 +49,7 @@ export const IBizCommonComponents = { v.component(IBizEmojiSelect.name, IBizEmojiSelect); v.component(IBizBadge.name, IBizBadge); v.component(IBizMdCtrlSetting.name, IBizMdCtrlSetting); + v.component(IBizPreviewImage.name, IBizPreviewImage); }, }; diff --git a/src/common/preview-image/preview-image.scss b/src/common/preview-image/preview-image.scss new file mode 100644 index 000000000..835149271 --- /dev/null +++ b/src/common/preview-image/preview-image.scss @@ -0,0 +1,5 @@ +@include b(preview-image) { + .van-image__img { + max-width: 100%; + } +} \ No newline at end of file diff --git a/src/common/preview-image/preview-image.tsx b/src/common/preview-image/preview-image.tsx new file mode 100644 index 000000000..1500fd643 --- /dev/null +++ b/src/common/preview-image/preview-image.tsx @@ -0,0 +1,132 @@ +import { useNamespace } from '@ibiz-template/vue3-util'; +import { defineComponent, ref, onMounted, onUnmounted, Ref } from 'vue'; +import './preview-image.scss'; +import { listenJSEvent, NOOP } from '@ibiz-template/core'; + +export const IBizPreviewImage = defineComponent({ + name: 'IBizPreviewImage', + props: { + url: { + type: String, + required: true, + }, + }, + setup() { + const ns = useNamespace('preview-image'); + const show: Ref = ref(true); + const imageRef = ref(); + + let startCleanup = NOOP; + let moveCleanup = NOOP; + let endCleanup = NOOP; + + // 拖动相关 + let startPoint = { x: 0, y: 0 }; // 记录初始触摸点位 + let isTouching = false; // 标记是否正在移动 + let offset = { left: 0, top: 0 }; + // 缩放相关 + let lastDistance = 0; + let lastScale = 1; // 记录下最后的缩放值 + let scale = 1; + let origin = 'center'; + let scaleOrigin = { x: 0, y: 0 }; + + // 获取两点之间距离 + const getDistance = (start: IData, end: IData) => { + return Math.hypot(end.pageX - start.pageX, end.pageY - start.pageY); + }; + + // 获取缩放中心点 + const getOffsetCorrection = (start: IData, end: IData) => { + const x = (start.pageX + end.pageX) / 2; + const y = (start.pageY + end.pageY) / 2; + origin = `${x}px ${y}px`; + const offsetLeft = (scale - 1) * (x - scaleOrigin.x) + offset.left; + const offsetTop = (scale - 1) * (y - scaleOrigin.y) + offset.top; + scaleOrigin = { x, y }; + return { left: offsetLeft, top: offsetTop }; + }; + + const changeStyle = (el: HTMLElement, arr: string[]) => { + const original = el.style.cssText.split(';'); + original.pop(); + el.style.cssText = `${original.concat(arr).join(';')};`; + }; + + onMounted(() => { + if (imageRef.value) { + const el = imageRef.value.$el; + startCleanup = listenJSEvent(el, 'touchstart', event => { + event.preventDefault(); + isTouching = true; + const touches = event.touches; + if (touches.length === 2) { + // 双指缩放 + lastDistance = getDistance(touches[0], touches[1]); + lastScale = scale; + } else if (touches.length === 1) { + // 单指拖动 + startPoint = { x: touches[0].clientX, y: touches[0].clientY }; + } + }); + moveCleanup = listenJSEvent(el, 'touchmove', event => { + if (!isTouching) { + return; + } + const touches = event.touches; + if (touches.length === 2) { + const ratio = getDistance(touches[0], touches[1]) / lastDistance; + scale = ratio * lastScale; + offset = getOffsetCorrection(touches[0], touches[1]); + changeStyle(el, [ + 'transition: all 0s', + `transform: translate(${`${offset.left}px`}, ${`${offset.top}px`}) scale(${scale})`, + `transform-origin: ${origin}`, + ]); + } else if (touches.length === 1) { + // 单指拖动 + offset = { + left: offset.left + (touches[0].clientX - startPoint.x), + top: offset.top + (touches[0].clientY - startPoint.y), + }; + changeStyle(el, [ + 'transition: all 0s', + `transform: translate(${`${offset.left}px`}, ${`${offset.top}px`}) scale(${scale})`, + `transform-origin: ${origin}`, + ]); + // 注意移动完也要更新初始点位,否则图片会加速逃逸可视区域 + startPoint = { x: touches[0].clientX, y: touches[0].clientY }; + } + }); + endCleanup = listenJSEvent(el, 'touchend', () => { + isTouching = false; + }); + } + }); + + onUnmounted(() => { + if (startCleanup !== NOOP) { + startCleanup(); + } + if (moveCleanup !== NOOP) { + moveCleanup(); + } + if (endCleanup !== NOOP) { + endCleanup(); + } + }); + + return { + ns, + show, + imageRef, + }; + }, + render() { + return ( +
+ +
+ ); + }, +}); diff --git a/src/editor/html/quill-editor-preview/quill-editor-preview.scss b/src/editor/html/quill-editor-preview/quill-editor-preview.scss index 0d093e5c2..874fed9bc 100644 --- a/src/editor/html/quill-editor-preview/quill-editor-preview.scss +++ b/src/editor/html/quill-editor-preview/quill-editor-preview.scss @@ -22,5 +22,6 @@ } @include e(image-popup) { background-color: transparent; + overflow: visible; } } \ No newline at end of file diff --git a/src/editor/html/quill-editor-preview/quill-editor-preview.tsx b/src/editor/html/quill-editor-preview/quill-editor-preview.tsx index 529942a6d..176063418 100644 --- a/src/editor/html/quill-editor-preview/quill-editor-preview.tsx +++ b/src/editor/html/quill-editor-preview/quill-editor-preview.tsx @@ -91,7 +91,7 @@ const IBizQuillPreview: any = defineComponent({ show={!!this.previewImage} onClose={this.handlePreviewClose} > - + ); -- Gitee From 50de566ef8f974e3f587adb0007ce8a519d4c766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E6=94=BF=E6=9D=83?= <1978141412@qq.com> Date: Wed, 23 Oct 2024 20:05:54 +0800 Subject: [PATCH 2/4] =?UTF-8?q?style:=20=E6=B7=BB=E5=8A=A0=E9=83=A8?= =?UTF-8?q?=E4=BB=B6=E6=BB=9A=E5=8A=A8=E9=BB=98=E8=AE=A4=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../view-content-panel-container.scss | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/panel-component/view-content-panel-container/view-content-panel-container.scss b/src/panel-component/view-content-panel-container/view-content-panel-container.scss index 47707b1a0..190837426 100644 --- a/src/panel-component/view-content-panel-container/view-content-panel-container.scss +++ b/src/panel-component/view-content-panel-container/view-content-panel-container.scss @@ -5,6 +5,10 @@ $control: ( 'overflow': hidden auto, ); +@include b(view) { + #{getCssVarName(control, overflow)}: hidden auto; +} + @include b(view-content) { #{--van-back-top-size}: rem(44px); @include set-component-css-var('panel-component-view-content', $panel-component-view-content); @@ -16,7 +20,7 @@ $control: ( @include when(scroll) { overflow-y: auto; - #{bem(control, overflow)}: unset; + #{getCssVarName(control, overflow)}: unset unset; } @include when(embed) { #{getCssVarName(control, overflow)}: hidden auto; -- Gitee From f5cde14b5018f3fa6642e564546554ee38db2c3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E6=94=BF=E6=9D=83?= <1978141412@qq.com> Date: Wed, 23 Oct 2024 20:06:28 +0800 Subject: [PATCH 3/4] =?UTF-8?q?feat:=20=E8=A1=A8=E5=8D=95=E9=A1=B9?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=98=BE=E7=A4=BA=E8=BE=B9=E6=A1=86=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../form-item-container.scss | 28 +++++++++++++++++-- .../form-item-container.tsx | 21 ++++++++++++-- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/control/form/form-detail/form-item/form-item-container/form-item-container.scss b/src/control/form/form-detail/form-item/form-item-container/form-item-container.scss index 99b85b7fd..bf9cba793 100644 --- a/src/control/form/form-detail/form-item/form-item-container/form-item-container.scss +++ b/src/control/form/form-detail/form-item/form-item-container/form-item-container.scss @@ -8,8 +8,9 @@ $form-item-container: (label-width: rem(130px), label-font-size: getCssVar(font-size, header-6), label-text-color: getCssVar(color, text, 0), container-error-padding:0 getCssVar(spacing, base), - border:rem(1px) getCssVar(color, border) solid, editor-padding: getCssVar(spacing, tight) getCssVar(spacing, none) getCssVar(spacing, tight) getCssVar(spacing, none), + border: rem(1px) getCssVar(color, border) solid, + border-radius: rem(4px), ); @@ -48,6 +49,22 @@ $form-item-label: (line-height: 1, } } + @include when(show-border) { + .#{bem(form-item-container, editor)} { + margin-top: rem(4px); + min-height: calc(getCssVar(form-item, line-height) + 2 * getCssVar(spacing, tight)); + outline: getCssVar(form-item-container, border); + border-radius: getCssVar(form-item-container, border-radius); + padding: getCssVar(spacing, tight); + } + &.#{bem(form-item-container, '', bottom)} { + .#{bem(form-item-container, editor)} { + margin-top: 0; + margin-bottom: rem(4px); + } + } + } + @include e(label) { position: relative; flex-shrink: 0; @@ -69,6 +86,7 @@ $form-item-label: (line-height: 1, @include e(editor) { width: 100%; text-align: getCssVar(form-item-container, editor-align); + min-height: calc(getCssVar(form-item, line-height) + 2 * getCssVar(spacing, tight)); .van-cell { padding-bottom: 0; @@ -110,12 +128,18 @@ $form-item-label: (line-height: 1, @include b(form-item-container) { @include m(left) { + .#{bem(form-item-container, editor)} { + min-height: getCssVar(form-item, line-height); + } &::after { bottom: 0; } } @include m(right) { + .#{bem(form-item-container, editor)} { + min-height: getCssVar(form-item, line-height); + } &::after { bottom: 0; } @@ -165,8 +189,6 @@ $form-item-label: (line-height: 1, // border @include b(form-item-container-content) { position: relative; - - // border-bottom: getCssVar('form-item-container', 'border') } // 控制布局方向 diff --git a/src/control/form/form-detail/form-item/form-item-container/form-item-container.tsx b/src/control/form/form-detail/form-item/form-item-container/form-item-container.tsx index de90f47bd..8c9d97d5e 100644 --- a/src/control/form/form-detail/form-item/form-item-container/form-item-container.tsx +++ b/src/control/form/form-detail/form-item/form-item-container/form-item-container.tsx @@ -33,14 +33,28 @@ export const IBizFormItemContainer = defineComponent({ const ns = useNamespace('form-item-container'); let labelAlign: 'right' | 'left' = 'left'; let editorAlign: 'right' | 'left' = 'right'; - const { mobformitemalignmode } = props.controller.form.controlParams; + const { mobformitemalignmode, mobshowunderline, mobshoweditorborder } = + props.controller.form.controlParams; const editorContentAlign = mobformitemalignmode || ibiz.config.form.mobFormItemAlignMode; let showUnderLine = ibiz.config.form.mobShowUnderLine; - const { mobshowunderline } = props.controller.form.controlParams; + let showEditorBorder = ibiz.config.form.mobShowEditorBorder; + // 部件参数优先级高于全局参数 if (mobshowunderline) { showUnderLine = Object.is(mobshowunderline, 'true'); } + if (mobshoweditorborder) { + showEditorBorder = Object.is(mobshoweditorborder, 'true'); + } + // 编辑器参数优先级最高 + const editorParams = props.controller.editor?.model?.editorParams || {}; + const { MOBSHOWEDITORBORDER, MOBSHOWUNDERLINE } = editorParams; + if (MOBSHOWUNDERLINE) { + showUnderLine = Object.is(MOBSHOWUNDERLINE, 'true'); + } + if (MOBSHOWEDITORBORDER) { + showEditorBorder = Object.is(MOBSHOWEDITORBORDER, 'true'); + } const cssVars = computed(() => { switch (props.labelPos) { case 'LEFT': @@ -74,7 +88,7 @@ export const IBizFormItemContainer = defineComponent({ } return ns.cssVarBlock(result); }); - return { ns, cssVars, showUnderLine }; + return { ns, cssVars, showUnderLine, showEditorBorder }; }, render() { return ( @@ -86,6 +100,7 @@ export const IBizFormItemContainer = defineComponent({ this.ns.is('error', !!this.error), this.ns.is('show-label', this.labelPos === 'NONE'), this.ns.is('show-underLine', this.showUnderLine), + this.ns.is('show-border', this.showEditorBorder), ]} style={this.cssVars} > -- Gitee From 0d4715a0b6265b749c1d7d84b238dacecdf8ad3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E6=94=BF=E6=9D=83?= <1978141412@qq.com> Date: Wed, 23 Oct 2024 20:08:08 +0800 Subject: [PATCH 4/4] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0=E6=97=A5?= =?UTF-8?q?=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98e798310..568ac9806 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,15 @@ ## [Unreleased] +### Fixed + +- 添加部件滚动默认变量 + +### Added + +- 表单项支持显示边框配置 +- 新增图片预览组件 + ## [0.0.29] - 2024-10-22 ### Added -- Gitee