Run »
<html lang="en"> <head> <meta charset="UTF-8"> <title>变形幻灯片插件</title> <style> *, *:before, *:after { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: 'Roboto', Helvetica, Arial, sans-serif; background: #000; } .distorted-gallery { --transition-time: 800; overflow: hidden; position: relative; height: 100vh; -webkit-perspective: 1000px; perspective: 1000px; -webkit-transform-style: preserve-3d; transform-style: preserve-3d; } .distorted-gallery__image { position: absolute; left: 50%; top: 50%; width: 46.6666666667vh; height: 70vh; margin-left: -23.3333333333vh; margin-top: -35vh; -o-object-fit: cover; object-fit: cover; -o-object-position: 50% 50%; object-position: 50% 50%; opacity: 0; -webkit-transition-timing-function: ease-in-out; transition-timing-function: ease-in-out; will-change: transform, opacity; } .distorted-gallery__image.s--left { -webkit-transform-origin: 0 50%; transform-origin: 0 50%; -webkit-transform: rotateX(-8deg) rotateY(-35deg) translate3d(-170%, 0, -30px) scale(2, 0.7); transform: rotateX(-8deg) rotateY(-35deg) translate3d(-170%, 0, -30px) scale(2, 0.7); } .distorted-gallery__image.s--right { -webkit-transform-origin: 100% 50%; transform-origin: 100% 50%; -webkit-transform: rotateX(8deg) rotateY(35deg) translate3d(170%, 0, -30px) scale(2, 0.7); transform: rotateX(8deg) rotateY(35deg) translate3d(170%, 0, -30px) scale(2, 0.7); } .distorted-gallery__image.s--prev { opacity: 0; -webkit-transition: all 560ms; transition: all 560ms; } .distorted-gallery__image.s--prev-left { -webkit-transform-origin: 0 100%; transform-origin: 0 100%; -webkit-transform: rotate(-5deg) translate3d(-50%, 30%, 0); transform: rotate(-5deg) translate3d(-50%, 30%, 0); } .distorted-gallery__image.s--prev-right { -webkit-transform-origin: 100% 100%; transform-origin: 100% 100%; -webkit-transform: rotate(5deg) translate3d(50%, 30%, 0); transform: rotate(5deg) translate3d(50%, 30%, 0); } .distorted-gallery__image.s--active { opacity: 1; -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); -webkit-transition: opacity 320ms 160ms ease-in, -webkit-transform 640ms 160ms cubic-bezier(0.97, 0.13, 0.34, 1.15); transition: opacity 320ms 160ms ease-in, -webkit-transform 640ms 160ms cubic-bezier(0.97, 0.13, 0.34, 1.15); transition: transform 640ms 160ms cubic-bezier(0.97, 0.13, 0.34, 1.15), opacity 320ms 160ms ease-in; transition: transform 640ms 160ms cubic-bezier(0.97, 0.13, 0.34, 1.15), opacity 320ms 160ms ease-in, -webkit-transform 640ms 160ms cubic-bezier(0.97, 0.13, 0.34, 1.15); } .distorted-gallery.s--no-transition .distorted-gallery__image { -webkit-transition: all 0s 0s; transition: all 0s 0s; } .distorted-gallery__control { z-index: 100; position: absolute; left: 50px; top: 50%; width: 50px; height: 50px; margin-top: -25px; border-radius: 50%; background: rgba(255, 255, 255, 0.4); cursor: pointer; } .distorted-gallery__control:before { content: ''; position: absolute; left: 50%; top: 50%; width: 20px; height: 20px; margin-left: -10px; margin-top: -10px; border: 2px solid #000; border-bottom: none; border-right: none; -webkit-transform: translateX(5px) rotate(-45deg); transform: translateX(5px) rotate(-45deg); } .distorted-gallery__control--right { left: auto; right: 50px; } .distorted-gallery__control--right:before { -webkit-transform: translateX(-5px) rotate(135deg); transform: translateX(-5px) rotate(135deg); } .footer-link { z-index: 100; position: absolute; left: 5px; bottom: 5px; font-size: 16px; color: #fff; } .footer-link img { width: 32px; vertical-align: top; } .footer-link--twitter { left: auto; right: 5px; } </style> </head> <body> <div id="app"> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/classnames/2.2.6/index.min.js"></script> <script id="rendered-js"> function _defineProperty(obj, key, value) {if (key in obj) {Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true });} else {obj[key] = value;}return obj;}class DistortedGallery extends React.PureComponent { constructor(props) { super(props);_defineProperty(this, "runAutochangeTO", () => { this.changeTO = setTimeout(() => { this.changeImages(); this.runAutochangeTO(); }, this.AUTOCHANGE_TIME); });_defineProperty(this, "runAnimatingTO", () => { this.animatingTO = setTimeout(() => this.setState({ noTransition: true, prevImgLeft: -1, prevImgRight: -1 }, () => { const layoutTrigger = this.galleryRef.offsetTop; this.setState({ noTransition: false, isAnimating: false }); }), this.transitionTime); });_defineProperty(this, "getLimitIndex", () => this.props.images.length - 1);_defineProperty(this, "getImgIndex", targetIndex => { const limitIndex = this.getLimitIndex(); if (targetIndex < 0) return limitIndex; if (targetIndex > limitIndex) return 0; return targetIndex; });_defineProperty(this, "changeImages", (back = false) => { window.clearTimeout(this.changeTO); if (this.state.isAnimating) return; const change = back ? -1 : 1; this.setState(st => { const activeImg = this.getImgIndex(st.activeImg + change); return { isAnimating: true, activeImg: activeImg, leftImg: this.getImgIndex(activeImg - 1), rightImg: this.getImgIndex(activeImg + 1), ...(back ? { prevImgRight: st.activeImg } : { prevImgLeft: st.activeImg }) }; }, this.runAnimatingTO); });this.changeTO = null;this.animatingTO = null;this.AUTOCHANGE_TIME = 4000;this.transitionTime = 1000; // default value, updated in DidMount this.state = { isAnimating: false, activeImg: 0, leftImg: this.getLimitIndex(), rightImg: 1, prevImgLeft: -1, prevImgRight: -1, noTransition: false };}componentWillUnmount() {window.clearTimeout(this.changeTO);window.clearTimeout(this.animatingTO);}componentDidMount() {this.transitionTime = Number(getComputedStyle(this.galleryRef).getPropertyValue('--transition-time')); //this.runAutochangeTO(); }render() { return ( React.createElement("div", { className: classNames( 'distorted-gallery', { 's--no-transition': this.state.noTransition }), ref: _gal => {this.galleryRef = _gal;} }, React.createElement("div", { className: "distorted-gallery__images" }, this.props.images.map((src, i) => React.createElement("img", { className: classNames( 'distorted-gallery__image', { 's--active': i === this.state.activeImg, 's--left': i === this.state.leftImg, 's--right': i === this.state.rightImg, 's--prev': i === this.state.prevImgLeft || i === this.state.prevImgRight, 's--prev-left': i === this.state.prevImgLeft, 's--prev-right': i === this.state.prevImgRight }), src: src, alt: `Cute Cat №${i + 1}` }))), React.createElement("div", { className: "distorted-gallery__control", onClick: () => this.changeImages(true) }), React.createElement("div", { className: "distorted-gallery__control distorted-gallery__control--right", onClick: () => this.changeImages() }))); }} const NUM_OF_IMAGES = 7; const images = Array.from(Array(NUM_OF_IMAGES).keys()).map((i) => `/images/${i + 1}.jpg`); ReactDOM.render(React.createElement(DistortedGallery, { images: images }), document.querySelector('#app')); </script> </body> </html>