【踩坑】大屏展示方案使用了scale来实现,做拖拽效果时定位信息不准确

315 阅读1分钟

由于大屏方案选用设置scale来实现,正常来说是不影响position的定位效果的,做拖拽效果时踩了个小坑,引以为戒。~~~~
代码如下

import { useCallback, useEffect, useState } from "react";

const useWindowScale = (param: {
  designWidth?: number; // 设计稿尺寸
  designHeight?: number;
  width?: number;
  height?: number;
}) => {
  const { designWidth = 1920, designHeight = 1080, width, height } = param;
  const [scale, setScale] = useState(1);
  const handleResize = useCallback(() => {
    const wrapperWidth = width ?? window.innerWidth;
    const wrapperHeight = height ?? window.innerHeight;
    //根据屏幕的变化适配的比例
    const scale =
      wrapperWidth / wrapperHeight < designWidth / designHeight
        ? wrapperWidth / designWidth
        : wrapperHeight / designHeight;
    setScale(scale);
  }, [designHeight, designWidth, height, width]);
  useEffect(() => {
    window.addEventListener("resize", handleResize);
    handleResize();
  }, [handleResize, width]);
  useEffect((): (() => void) | void => {
    return () => {
      window.removeEventListener("resize", handleResize);
    };
  }, [handleResize]);
  return {
    scale,
  };
};

export default useWindowScale;


//使用
import React from "react";
import useWindowScale from "../hooks/useWindowScale";

export interface ScaleLayoutProps {
  className?: any;
  style?: React.CSSProperties;
  children?: React.ReactNode;
  width?: number;
  height?: number;
}

const ScaleLayout = (props: ScaleLayoutProps) => {
  const { children, style, width, height } = props;
  const { scale } = useWindowScale({ width, height });
  return (
    <div
      style={{
        width: width ? `${width}px` : "100vw",
        height: height ? `${height}px` : "100vh",
        overflow: "hidden",
        background: "rgba(5,22,4,1)",
        position: "relative",
        ...style,
      }}
    >
      <div
        style={{
          width: "1920px",
          height: "1080px",
          transformOrigin: "left top",
          transform: `scale(${scale}) translate(-50%, -50%)`,
          transition: "transform .3s ease-in-out",
          position: "absolute",
          top: "50%",
          left: "50%",
        }}
      >
        {children}
      </div>
    </div>
  );
};
export default ScaleLayout;
~~~~

如果缩放的容器内有元素写了拖拽事件,想通过

 onMouseDown={(e) => {
		console.log(e.pageX)	
		console.log(e.pageY)	
 }}

拿定位信息设置元素position,这样e里面拿到的是缩放之前的数值,导致算出来的定位不准确。

解决方案
把scale的数值传递下来参与计算就好了。

不仅仅是onMouseDown,还有onDragEnd、onDragStart回调里拿到的e.pageX都是未缩放的数值,