前端图片旋转查看效果

image
image

其实就是多张图片切换,low~

import {
  FC,
  ReactElement,
  useRef,
  useEffect,
  useCallback,
  useState,
  useMemo,
} from "react";
import axios from "axios";
import { log } from "../../../utils/logger";
import { ContentContainer } from "../../../constants/LayoutStyled";

const ImageVideo: FC = (): ReactElement => {
  const timeout = useMemo(() => 50, []);
  const imageProperty = useMemo(() => "sourceIndex", []);
  const canvas = useRef(null);
  const [sources, setSources] = useState([]);
  const image = useRef(new Image());
  const dragOrigin = useRef<{ origin: number }>({ origin: 0 });
  const Timer = useRef<{ timer: NodeJS.Timeout | null }>({ timer: null });

  const toggleSource = useCallback(
    (nextIndex: number) => {
      const eImage = image.current;
      eImage.setAttribute(imageProperty, nextIndex.toString());
      eImage.src = sources[nextIndex];
    },
    [sources, imageProperty]
  );

  const autoRotate = useCallback(
    (startIndex = 1): void => {
      const nextIndex = startIndex <= sources.length ? startIndex : 0;
      toggleSource(nextIndex);
      Timer.current.timer = setTimeout(() => {
        autoRotate(nextIndex + 1);
      }, timeout);
    },
    [sources, toggleSource, timeout]
  );

  const drawDefaultImage = useCallback(() => {
    const ctx = canvas.current!.getContext("2d");
    const imgSrc =
      "https://media.emeralds.com/stone/E1526/video360/E1526-video360-001-Medium.jpg?1";
    const eImage = image.current;
    eImage.onload = () => {
      ctx!.drawImage(eImage, 0, 0, 365, 365);
    };
    eImage.setAttribute(imageProperty, "0");
    eImage.src = imgSrc;
  }, [imageProperty]);

  const handleClearTimeout = useCallback(() => {
    clearTimeout(Timer.current.timer as NodeJS.Timeout);
    Timer.current.timer = null;
  }, []);

  useEffect(() => {
    drawDefaultImage();
    getSource();

    return handleClearTimeout;
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  useEffect(() => {
    if (sources.length) {
      log("start");
      autoRotate();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [sources]);

  const getSource = useCallback(async () => {
    let i = 1;
    const source: string[] = [];

    while (i <= 261) {
      const url = `https://media.emeralds.com/stone/E1526/video360/E1526-video360-${i
        .toString()
        .padStart(3, "0")}-Medium.jpg?1`;
      await axios
        .get(url, { responseType: "blob" })
        .then((response: any) => {
          const imgSrc = window.URL.createObjectURL(response.data);
          source.push(imgSrc);
        })
        .catch(() => {});
      i++;
    }
    if (source.length) {
      setSources(() => source);
      log("source length:", source.length);
    }
  }, []);

  const onMouseMove = useCallback(
    ({ clientX }) => {
      const eImage = image.current;
      const currentSourceIndex = Number(eImage.getAttribute(imageProperty));
      const nextIndex =
        clientX > dragOrigin.current.origin
          ? currentSourceIndex - 1
          : currentSourceIndex + 1;
      const shouldIndex =
        nextIndex <= sources.length && nextIndex >= 0
          ? nextIndex
          : nextIndex < 0
          ? sources.length
          : 0;
      toggleSource(shouldIndex);
      dragOrigin.current.origin = clientX;
    },
    [image, toggleSource, sources, dragOrigin, imageProperty]
  );

  const onMouseDown = useCallback(
    ({ clientX }) => {
      dragOrigin.current.origin = clientX;
      handleClearTimeout();
      canvas.current!.addEventListener("mousemove", onMouseMove);
    },
    [onMouseMove, canvas, handleClearTimeout]
  );

  const cancelDrag = useCallback(() => {
    if (!Timer.current.timer) {
      log("cancel", Timer.current.timer);
      canvas.current!.removeEventListener("mousemove", onMouseMove);
      const sourceIndex = image.current.getAttribute(imageProperty);
      autoRotate(Number(sourceIndex) + 1);
    }
  }, [onMouseMove, canvas, image, autoRotate, imageProperty, Timer]);

  return (
    
      
    
  );
};

export default ImageVideo;

你可能感兴趣的:(前端图片旋转查看效果)