react+gsap实现小熊滑板静止视觉差异效果代码

代码语言:html

所属分类:视觉差异

代码描述:react+gsap实现小熊滑板静止视觉差异效果代码

代码标签: 滑板 静止 视觉 差异 效果

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开


<!DOCTYPE html>
<html lang="en" >

<head>

  <meta charset="UTF-8">
  

<link type="text/css" rel="stylesheet" href="//repo.bfw.wiki/bfwrepo/css/tailwind.2.2.7.css">
  
<style>
*,
*:after,
*:before {
  box-sizing: border-box;
  transform-style: preserve-3d;
}
body {
  background: #233143;
  min-height: 100vh;
  display: grid;
  place-items: center;
  overflow: hidden;
}
img {
  height: 100%;
  -o-object-fit: cover;
     object-fit: cover;
  width: 100%;
}
.parallax-container {
  height: 50vmin;
  width: 50vmin;
  perspective: 50vmin;
  transform: translate3d(0, 0, 50vmin);
}
.parallax {
  transform: rotateX(calc((var(--rx, 0) * var(--range-y, 0)) * 1deg)) rotateY(calc((var(--ry, 0) * var(--range-x, 0)) * 1deg)) rotate(calc((var(--r, 0) * var(--range-x, 0)) * 1deg));
}
.parallax-item {
  left: calc(var(--x, 50) * 1%);
  top: calc(var(--y, 50) * 1%);
  height: calc(var(--height, auto) * 1%);
  width: calc(var(--width, auto) * 1%);
  transform: translate(-50%, -50%) translate3d(calc((var(--mx, 0) * var(--range-x, 0)) * 1%), calc((var(--my, 0) * var(--range-y, 0)) * 1%), calc(var(--mz, 0) * 1vmin)) rotateX(calc((var(--rx, 0) * var(--range-y, 0)) * 1deg)) rotateY(calc((var(--ry, 0) * var(--range-x, 0)) * 1deg)) rotate(calc((var(--r, 0) * var(--range-x, 0)) * 1deg));
}
</style>



</head>

<body>
  <div id="app"></div>


  
      <script type="module">
import React from 'https://cdn.skypack.dev/react';
import T from 'https://cdn.skypack.dev/prop-types';
import gsap from 'https://cdn.skypack.dev/gsap';
import { render } from 'https://cdn.skypack.dev/react-dom';

/**
 * All movements and rotations are based on a decimal scale.
 * 0 - 1 for movement will be 0% - 100% translation
 * 0 - 1 for rotation will be 0deg to 360deg rotation
 *
 * Position is based on relative position to the container in percentage.
 * Z Positioning is a number and the coefficient is defined in the styles.
 */
const DEFAULT_CONFIG = {
  // Starting positions for X and Y
  positionX: 50,
  positionY: 50,
  positionZ: 0,
  // Range of movement in decimal where 1 === 100. Use negative for opposite directions.
  // Range of movement in decimal where 1 === 100. Use negative for opposite directions.
  rotate: 0,
  rotateX: 0,
  rotateY: 0,
  moveX: 0,
  moveY: 0 };


// Range mapping utility
const mapRange = (inputLower, inputUpper, outputLower, outputUpper) => {
  const INPUT_RANGE = inputUpper - inputLower;
  const OUTPUT_RANGE = outputUpper - outputLower;
  return (value) =>
  outputLower + ((value - inputLower) / INPUT_RANGE * OUTPUT_RANGE || 0);
};

const ParallaxContainer = ({ config, children }) => {
  const containerRef = React.useRef(null);
  React.useEffect(() => {
    // Function that updates a CSS coefficient for moving things.
    // Base the center point on the center of the container.
    // Then define a width each side. Default to window width/height.
    const UPDATE = ({ x, y }) => {
      // We are going to normalize -100 to 100 with a range and then use CSS coefficient for updates
      // Can base the range on the position of the container and a distance from it based on screen size.

      // Get the dimensions of the parentNode as the parallax moves and changes dimensions.
      const containerBounds = containerRef.current.parentNode.getBoundingClientRect();
      const centerX = containerBounds.left + containerBounds.width / 2;
      const centerY = containerBounds.top + containerBounds.height / 2;

      const startX = config.coefficientX ?
      centerX - config.coefficientX * window.innerWidth :
      0;
      const endX = config.coefficientX ?
      centerX + config.coefficientX * window.innerWidth :
      window.innerWidth;
      const startY = config.coefficientY ?
      centerY - config.coefficientY * window.innerHeight :
      0;
      const endY = config.coefficientY ?
      centerY + config.coefficientY * window.innerHeight :
      window.innerHeight;

      const POS_X = gsap.utils.mapRange(startX, endX, -100, 100)(x);
      const POS_Y = gsap.utils.mapRange(startY, endY, -100, 100)(y);

      containerRef.current.style.setProperty(
      '--range-x',
      gsap.utils.clamp(-100, 100, POS_X));

      containerRef.current.style.setProperty(
      '--range-y',
      gsap.utils.clamp(-100, 100, POS_Y));

    };
    window.addEventListener('pointermove', UPDATE);
    return () => {
      window.removeEventListener('pointermove', UPDATE);
    };
  }, []);
  return /*#__PURE__*/(
    React.createElement("div", {
      ref: containerRef,
      className: "parallax relative h-full w-full",
      style: {
        '--r': config.rotate,
        '--rx': config.rotateX,
        '--ry': config.rotateY } },

    children));


};

ParallaxContainer.defaultProps = {
  config: {
    rotate: 0,
    rotateX: 0,
    rotateY: 0,
    coefficientX: 0.5,
    coefficientY: 0.5 } };


ParallaxContainer.propTypes = {
  children: T.node,
  config: T.shape({
    rotate: T.number,
    rotateX: T.number,
    rotateY: T.number }) };



const ParallaxItem = ({ children, config }) => {
  const params = { ...DEFAULT_CONFIG, ...config };
  return /*#__PURE__*/(
    React.createElement("div", {
      className: "absolute parallax-item",
      style: {
        '--x': params.positionX,
        '--y': params.positionY,
        '--z': params.positionZ,
        '--r': params.rotate,
        '--rx': params.rotateX,
        '--ry': params.rotateY,
        '--mx': params.moveX,
        '--my': params.moveY,
        '--height': params.height,
        '--width': params.width } },

    children));


};

ParallaxItem.propTypes = {
  children: T.node,
  config: T.shape({
    positi.........完整代码请登录后点击上方下载按钮下载查看

网友评论0