@@ -134,6 +134,7 @@ import UserForm from '@/components/ai-chat/component/user-form/index.vue'
134134import Control from ' @/components/ai-chat/component/control/index.vue'
135135import { t } from ' @/locales'
136136import bus from ' @/bus'
137+ import { throttle } from ' lodash-es'
137138provide (' upload' , (file : any , loading ? : Ref <boolean >) => {
138139 return props .type === ' debug-ai-chat'
139140 ? applicationApi .postUploadFile (file , ' TEMPORARY_120_MINUTE' , ' TEMPORARY_120_MINUTE' , loading )
@@ -658,6 +659,29 @@ onBeforeMount(() => {
658659 return Promise .resolve (null )
659660 }
660661})
662+
663+ function parseTransform(transformStr : string ) {
664+ const result = { scale: 1 , translateX: 0 , translateY: 0 , translateZ: 0 }
665+
666+ if (! transformStr || transformStr === ' none' ) return result
667+
668+ // 使用正则表达式匹配 scale 和 translate3d 的值
669+ const scaleMatch = transformStr .match (/ scale\( ([^ )] + )\) / )
670+ const translateMatch = transformStr .match (/ translate3d\( ([^ )] + )\) / )
671+
672+ if (scaleMatch ) {
673+ // scale可能是一个值,也可能是两个值(scaleX, scaleY)
674+ const scaleValues = scaleMatch [1 ].split (' ,' ).map ((v ) => parseFloat (v .trim ()))
675+ result .scale = scaleValues [0 ]
676+ }
677+
678+ if (translateMatch ) {
679+ const translateValues = translateMatch [1 ].split (' ,' ).map ((v ) => parseFloat (v .trim ()))
680+ ;[result .translateX , result .translateY , result .translateZ ] = translateValues
681+ }
682+
683+ return result
684+ }
661685onMounted (() => {
662686 if (isUserInput .value && localStorage .getItem (` ${accessToken }userForm ` )) {
663687 const userFormData = JSON .parse (localStorage .getItem (` ${accessToken }userForm ` ) || ' {}' )
@@ -667,6 +691,47 @@ onMounted(() => {
667691 window .speechSynthesis .cancel ()
668692 }
669693
694+ const handleZoom = throttle ((event : WheelEvent , target : HTMLElement ) => {
695+ // 2. 解析当前变换状态
696+ const currentTransform = target .style .transform
697+ const transformValues = parseTransform (currentTransform )
698+ let { scale, translateX, translateY } = transformValues
699+ // 确保scale是数值类型
700+ const currentScale = Array .isArray (scale ) ? scale [0 ] : scale
701+
702+ // 3. 计算缩放方向和新的缩放比例
703+ const zoomIntensity = 0.05 // 每次滚轮的缩放步长
704+ const zoomFactor = event .deltaY < 0 ? 1 + zoomIntensity : 1 - zoomIntensity
705+ const newScale = Math .max (0.1 , currentScale * zoomFactor ) // 设置最小缩放限制
706+ // 4. 计算新的平移值
707+ const newTranslateX = (translateX * currentScale ) / newScale
708+ const newTranslateY = (translateY * currentScale ) / newScale
709+ // 5. 应用新的变换
710+ target .style .transform = ` scale(${newScale }) translate3d(${newTranslateX }px, ${newTranslateY }px, 0px) `
711+ }, 50 ) // 50ms 内只执行一次
712+
713+ document .body .addEventListener (
714+ ' wheel' ,
715+ (event ) => {
716+ // 1. 定位目标元素
717+ if (event .target ) {
718+ const target = event .target as HTMLElement
719+ // 假设打开状态的图片具有特定类名
720+ if (target .className && target .className .includes (' medium-zoom-overlay' )) {
721+ event .preventDefault ()
722+ event .stopPropagation ()
723+ }
724+ if (target .className && target .className .includes (' medium-zoom-image--opened' )) {
725+ event .preventDefault ()
726+ event .stopPropagation ()
727+
728+ handleZoom (event , target )
729+ }
730+ }
731+ },
732+ { passive: false },
733+ )
734+
670735 window .sendMessage = sendMessage
671736 bus .on (' on:transcribing' , (status : boolean ) => {
672737 transcribing .value = status
0 commit comments