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