91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

react如何實現縮放

發布時間:2022-12-28 10:44:30 來源:億速云 閱讀:528 作者:iii 欄目:web開發

這篇文章主要講解了“react如何實現縮放”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“react如何實現縮放”吧!

react實現縮放的方法:1、監聽onWheel事件;2、設置事件對象event的屬性deltaY,當向上滾動時“deltaY<0”,向下滾動時“deltay>0”;3、修改每次滾動時縮放的比例,同時更改transform樣式按比例進行縮放即可。

react圖片縮放、平移(position、transform實現)

很多網頁都會給文案附上一些圖片補充描述,例如在說到地址時,會在旁邊附上一張地圖,并且在地圖上標注該地址。如果附上的圖片很小,很難看清楚地址的具體信息,有些產品經理會給圖片設計一個可以平移、放大縮小的功能。本文將一一實現上述功能。

廢話不多說,先給上效果圖:

react如何實現縮放

主要三個功能點:

  • 圖片平移

  • 圖片縮放

  • 車站標注

圖片平移

圖片平移可以監聽這三個事件實現:onMouseDown、onMouseMove、onMouseUp
onMouseDown事件記錄每次鼠標按下的坐標位置;
onMouseMove事件計算出每次平移的距離,該距離加上拖動前圖片距離父元素的距離就等于拖動后圖片相對于父元素的距離;
onMouseUp事件觸發時,注銷或者不讓執行onMouseDown、onMouseMove事件,防止只要鼠標移入圖片就會平移。

這三個事件需要阻止瀏覽器的默認行為,不然在移動時會自動打開圖片。
react如何實現縮放

const WIDTH = 1200;const HEIGHT = 900;const DynamicStyle= () => {    
  const imgRef = React.createRef<HTMLImageElement>();  
  /** 圖片樣式 */  const [imgStyle, setImgStyle] = useState<React.CSSProperties>({});  /** 記錄鼠標是否按下 */  const [mouseDowmFlag, setMouseDowmFlag] = useState(false);  /** 記錄鼠標按下的坐標 */  const [mouseDowmPos, setMouseDowmPos] = useState<{x: number, y: number}>({x: 0, y: 0})  /** 鼠標可視區域時,重置鼠標按下的布爾值為false */  useEffect(() => {    document.onmouseover = () => {      if (mouseDowmFlag) {        setMouseDowmFlag(false);
      }
    };    return () => {      document.onmouseover = null;
    };
  }, [mouseDowmFlag])  /** 平移 */  const handleMouseDown = (event: React.MouseEvent<HTMLImageElement>) => {    const { clientX, clientY } = event;
    event.stopPropagation();
    event.preventDefault(); // 阻止瀏覽器默認行為,拖動會打開圖片    setMouseDowmFlag(true); // 控制只有在鼠標按下后才會執行mousemove    setMouseDowmPos({      x: clientX,      y: clientY,
    });
  };  const handleMouseMove = (event: React.MouseEvent<HTMLImageElement>) => {
    event.stopPropagation();
    event.preventDefault();    const { clientX, clientY } = event;    const diffX = clientX - mouseDowmPos.x;    const diffY = clientY - mouseDowmPos.y;    if (!mouseDowmFlag || (diffX === 0 && diffY === 0)) return;    const { offsetLeft, offsetTop } = imgRef.current as HTMLImageElement;    const offsetX = parseInt(`${diffX + offsetLeft}`, 10);    const offsetY = parseInt(`${diffY + offsetTop}`, 10);    setMouseDowmPos({      x: clientX,      y: clientY,
    });    setImgStyle({
      ...imgStyle,      left: offsetX,      top: offsetY,
    });
  };  const handleMouseUp = (event: React.MouseEvent<HTMLImageElement>) => {
    event.stopPropagation();
    event.preventDefault();    setMouseDowmFlag(false);
  };  return (    <div className={styles.imgArea}>      <img 
        src={mapImg} 
        alt='part'        ref={imgRef}        height={HEIGHT} 
        style={imgStyle}        onMouseDown={handleMouseDown}        onMouseMove={handleMouseMove}        onMouseUp={handleMouseUp}
      >      </img>    </div>
  )
}

圖片縮放

圖片縮放可以監聽onWheel事件,事件對象event有一個記錄滾輪滾動的屬性deltaY,當向上滾動時deltaY<0,向下滾動時deltaY>0。每次滾動修改其縮放的比例,同時更改transform樣式按比例進行縮放。

react如何實現縮放

const WIDTH = 1200;const HEIGHT = 900;const SCALE = 0.2;const DynamicStyle= () => {  const imgRef = React.createRef<HTMLImageElement>();  /** 初始化縮放比例,默認為1 */  const [rate, setRate] = useState(1);  /** 圖片樣式 */  const [imgStyle, setImgStyle] = useState<React.CSSProperties>({});  /** 記錄鼠標是否按下 */  const [mouseDowmFlag, setMouseDowmFlag] = useState(false);  /** 記錄鼠標按下的坐標 */  const [mouseDowmPos, setMouseDowmPos] = useState<{x: number, y: number}>({x: 0, y: 0})  /** 圖片現在大小 */  const [initial, setInitial] = useState<{width: number, height: number}>({width: WIDTH, height: HEIGHT});  useEffect(() => {    const { naturalWidth, naturalHeight, width, height } = imgRef.current as HTMLImageElement;    setInitial({ width, height });    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])  // console.log(natural, initial)  useEffect(() => {    document.onmouseover = () => {      if (mouseDowmFlag) {        setMouseDowmFlag(false);
      }
    };    return () => {      document.onmouseover = null;
    };
  }, [mouseDowmFlag])  /** 縮放 */  const handleWheelImage = (event: React.WheelEvent<HTMLImageElement>) => {    // 向上為負,向下為正    const bigger = event.deltaY > 0 ? -1 : 1;    // transform偏移量    const transformX = -initial.width / 2;    const transformY = -initial.height / 2;    if (bigger > 0 && rate < 2) {      const enlargeRate = rate + SCALE;      setImgStyle({
        ...imgStyle,        transform: `matrix(${enlargeRate}, 0, 0, ${enlargeRate}, ${transformX}, ${transformY})`, // 默認以圖片中心為原點進行縮放
      });      setRate(enlargeRate);
    } else if (bigger < 0 && rate > 1) {      const shrinkRate = rate - SCALE;      setImgStyle({
        ...imgStyle,        transform: `matrix(${shrinkRate}, 0, 0, ${shrinkRate}, ${transformX}, ${transformY})`,
      });      setRate(shrinkRate);
    }
  }  /** 平移 */  const handleMouseDown = (event: React.MouseEvent<HTMLImageElement>) => {    const { clientX, clientY } = event;
    event.stopPropagation();
    event.preventDefault(); // 阻止瀏覽器默認行為,拖動會打開圖片    setMouseDowmFlag(true); // 控制只有在鼠標按下后才會執行mousemove    setMouseDowmPos({      x: clientX,      y: clientY,
    });
  };  const handleMouseMove = (event: React.MouseEvent<HTMLImageElement>) => {
    event.stopPropagation();
    event.preventDefault();    const { clientX, clientY } = event;    const diffX = clientX - mouseDowmPos.x;    const diffY = clientY - mouseDowmPos.y;    if (!mouseDowmFlag || (diffX === 0 && diffY === 0)) return;    const { offsetLeft, offsetTop } = imgRef.current as HTMLImageElement;    const offsetX = parseInt(`${diffX + offsetLeft}`, 10);    const offsetY = parseInt(`${diffY + offsetTop}`, 10);    setMouseDowmPos({      x: clientX,      y: clientY,
    });    setImgStyle({
      ...imgStyle,      left: offsetX,      top: offsetY,
    });
  };  const handleMouseUp = (event: React.MouseEvent<HTMLImageElement>) => {
    event.stopPropagation();
    event.preventDefault();    setMouseDowmFlag(false);
  };  return (    <div className={styles.imgArea}>      <img 
        src={mapImg} 
        alt='part' 
        height={HEIGHT} 
        style={imgStyle}        ref={imgRef}        onWheel={handleWheelImage}        onMouseDown={handleMouseDown}        onMouseMove={handleMouseMove}        onMouseUp={handleMouseUp}
      >      </img>    </div>
  )
}
.imgArea {  position: relative;  width: 1200px;  height: 900px;  margin: auto;  border: 1px solid #da2727;  overflow: hidden;
  & > img {    position: absolute;    left: 50%;    top: 50%;    transform: translate(-50%, -50%);    cursor: move;
  }
}

如果沒有設置transformOrigin,默認是相對于圖片中心進行縮放,但是在初始為了讓圖片在可視區域內水平垂直居中,使用了transform: translate(-50%, -50%);,因此為了縮放時相對于圖片中心點,需要設置matrix的第5、6個參數矯正transformOrigintransform: matrix(${shrinkRate}, 0, 0, ${shrinkRate}, ${transformX}, ${transformY})

車站標注

首先,定義一個常量表示圖標的坐標,這個坐標是相對于原始圖片左上角的定位。

const imgInfo = {  lableLeft: "1900",  lableTop: "2000",}

這里,解釋一下原始圖的概念:
react如何實現縮放

隨便在網上查看一個圖片元素,比如上面。1200 x 900是頁面定的圖片大小,但圖片還有一個真實大小4535 x 3402。

要計算圖標在沒有平移縮放時的初始坐標之前,需要算出圖片的縮放比例(不是上面的rate):

/** 圖片原始大小,默認設置為1是防止計算圖片原始大小與初始大小比例出現無窮大 */const [natural, setNatural] = useState<{width: number, height: number}>({width: 1, height: 1});/** 圖片現在大小 */const [initial, setInitial] = useState<{width: number, height: number}>({width: WIDTH, height: HEIGHT});useEffect(() => {    const { naturalWidth, naturalHeight, width, height } = imgRef.current as HTMLImageElement;    setNatural({ width: naturalWidth, height: naturalHeight });    setInitial({ width, height });    // eslint-disable-next-line react-hooks/exhaustive-deps}, [])  
// 初始圖片縮放比例(圖片有原始的圖片大小)const imgScaleRateX = initial.width / natural.width;const imgScaleRateY = initial.height / natural.height;

圖標初始的坐標就可以計算出:

const labelLeft = parseInt(`${imgInfo.lableLeft}`, 10) * imgScaleRateX;const labelTop = parseInt(`${imgInfo.lableTop}`, 10) * imgScaleRateY;

當圖片平移時,圖標也需要跟著平移,這是的坐標計算:

// 圖標相對父元素坐標 = 圖標位置坐標 + 圖片坐標const labelLeft = parseInt(`${imgInfo.lableLeft}`, 10) * imgScaleRateX + Number(imgStyle.left || WIDTH / 2);
const labelTop = parseInt(`${imgInfo.lableTop}`, 10) * imgScaleRateY + Number(imgStyle.top || HEIGHT / 2);

react如何實現縮放

當圖片縮放時,圖標需要隨著圖片一起縮放。如果沒有對圖標設置transformOrigin,默認時相對圖標的中心縮放的。為了保證圖標隨著圖片一起縮放,那就必須使得圖片和圖標的縮放參照原點相同,圖標的transformOrigin應該設置為相對于圖片原點的距離。

const labelTransformOrigin = () => {    return `${initial.width / 2 - Number(imgInfo.lableLeft) * imgScaleRateX}px ${
        initial.height / 2 - Number(imgInfo.lableTop) * imgScaleRateY
    }px`;
}

react如何實現縮放

整體代碼示例:

const imgInfo = {
  lableLeft: "1900",
  lableTop: "2000",
}

const WIDTH = 1200;
const HEIGHT = 900;
const SCALE = 0.2;

const DynamicStyle= () => {

  const imgRef = React.createRef<HTMLImageElement>();
  /** 初始化縮放比例,默認為1 */
  const [rate, setRate] = useState(1);
  /** 圖片樣式 */
  const [imgStyle, setImgStyle] = useState<React.CSSProperties>({});
  /** 記錄鼠標是否按下 */
  const [mouseDowmFlag, setMouseDowmFlag] = useState(false);
  /** 記錄鼠標按下的坐標 */
  const [mouseDowmPos, setMouseDowmPos] = useState<{x: number, y: number}>({x: 0, y: 0})
  /** 圖片原始大小,默認設置為1是防止計算圖片原始大小與初始大小比例出現無窮大 */
  const [natural, setNatural] = useState<{width: number, height: number}>({width: 1, height: 1});
  /** 圖片現在大小 */
  const [initial, setInitial] = useState<{width: number, height: number}>({width: WIDTH, height: HEIGHT});

  useEffect(() => {
    const { naturalWidth, naturalHeight, width, height } = imgRef.current as HTMLImageElement;
    setNatural({ width: naturalWidth, height: naturalHeight });
    setInitial({ width, height });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])

  useEffect(() => {
    document.onmouseover = () => {
      if (mouseDowmFlag) {
        setMouseDowmFlag(false);
      }
    };
    return () => {
      document.onmouseover = null;
    };
  }, [mouseDowmFlag])

  /** 縮放 */
  const handleWheelImage = (event: React.WheelEvent<HTMLImageElement>) => {
    // 向上為負,向下為正
    const bigger = event.deltaY > 0 ? -1 : 1;
    // transform偏移量
    const transformX = -initial.width / 2;
    const transformY = -initial.height / 2;
    if (bigger > 0 && rate < 2) {
      const enlargeRate = rate + SCALE;
      setImgStyle({
        ...imgStyle,
        transform: `matrix(${enlargeRate}, 0, 0, ${enlargeRate}, ${transformX}, ${transformY})`, // 默認以圖片中心為原點進行縮放
      });
      setRate(enlargeRate);
    } else if (bigger < 0 && rate > 1) {
      const shrinkRate = rate - SCALE;
      setImgStyle({
        ...imgStyle,
        transform: `matrix(${shrinkRate}, 0, 0, ${shrinkRate}, ${transformX}, ${transformY})`,
      });
      setRate(shrinkRate);
    }
  }

  /** 平移 */
  const handleMouseDown = (event: React.MouseEvent<HTMLImageElement>) => {
    const { clientX, clientY } = event;
    event.stopPropagation();
    event.preventDefault(); // 阻止瀏覽器默認行為,拖動會打開圖片
    setMouseDowmFlag(true); // 控制只有在鼠標按下后才會執行mousemove
    setMouseDowmPos({
      x: clientX,
      y: clientY,
    });
  };

  const handleMouseMove = (event: React.MouseEvent<HTMLImageElement>) => {
    event.stopPropagation();
    event.preventDefault();
    const { clientX, clientY } = event;
    const diffX = clientX - mouseDowmPos.x;
    const diffY = clientY - mouseDowmPos.y;
    if (!mouseDowmFlag || (diffX === 0 && diffY === 0)) return;
    const { offsetLeft, offsetTop } = imgRef.current as HTMLImageElement;
    const offsetX = parseInt(`${diffX + offsetLeft}`, 10);
    const offsetY = parseInt(`${diffY + offsetTop}`, 10);

    setMouseDowmPos({
      x: clientX,
      y: clientY,
    });
    setImgStyle({
      ...imgStyle,
      left: offsetX,
      top: offsetY,
    });
  };

  const handleMouseUp = (event: React.MouseEvent<HTMLImageElement>) => {
    event.stopPropagation();
    event.preventDefault();
    setMouseDowmFlag(false);
  };

  // 初始圖片縮放比例(圖片有原始的圖片大小)
  const imgScaleRateX = initial.width / natural.width;
  const imgScaleRateY = initial.height / natural.height;

  const labelTransformOrigin = () => {
    return `${initial.width / 2 - Number(imgInfo.lableLeft) * imgScaleRateX}px ${
      initial.height / 2 - Number(imgInfo.lableTop) * imgScaleRateY
    }px`;
  }

  /** 圖標位置計算 */
  const labelStyle = (): React.CSSProperties => {
    const transformX = -initial.width / 2;
    const transformY = -initial.height / 2;
    // 圖標相對父元素坐標 = 圖標初始位置坐標 + 平移量
    const labelLeft = parseInt(`${imgInfo.lableLeft}`, 10) * imgScaleRateX + Number(imgStyle.left || WIDTH / 2);
    const labelTop = parseInt(`${imgInfo.lableTop}`, 10) * imgScaleRateY + Number(imgStyle.top || HEIGHT / 2);
    return {
      left: labelLeft,
      top: labelTop,
      transformOrigin: labelTransformOrigin(),
      transform: `matrix(${rate}, 0, 0, ${rate}, ${transformX}, ${transformY})`,
    }
  }


  return (
    <div className={styles.imgArea}>
      <img 
        src={mapImg} 
        alt='part' 
        height={HEIGHT} 
        style={imgStyle}
        ref={imgRef}
        onWheel={handleWheelImage}
        onMouseDown={handleMouseDown}
        onMouseMove={handleMouseMove}
        onMouseUp={handleMouseUp}
      >
      </img>
      <span className={styles.label} style={labelStyle()}></span>
    </div>
  )
}

感謝各位的閱讀,以上就是“react如何實現縮放”的內容了,經過本文的學習后,相信大家對react如何實現縮放這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

林西县| 梁山县| 古交市| 四川省| 安乡县| 万载县| 乐清市| 象山县| 社会| 宁乡县| 广饶县| 洪湖市| 漯河市| 建昌县| 屏山县| 望奎县| 江华| 德阳市| 封丘县| 白水县| 松桃| 文安县| 枞阳县| 井冈山市| 彝良县| 会宁县| 辽源市| 四平市| 香河县| 龙游县| 嘉兴市| 盐山县| 天水市| 潼关县| 青岛市| 五原县| 修文县| 伊春市| 个旧市| 山阴县| 汨罗市|