gsap实现8种可调参数的炫酷图片幻灯片转场特效代码

代码语言:html

所属分类:幻灯片

代码描述:gsap实现8种可调参数的炫酷图片幻灯片转场特效代码,结合了ScrollTrigger+ScrambleTextPlugin3

代码标签: gsap 8种 可调 参数 炫酷 图片 幻灯片 转场 特效 代码

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

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

<head>
  <meta charset="UTF-8">
  

<link type="text/css" rel="stylesheet" href="//repo.bfw.wiki/bfwrepo/css/normalize.5.0.css">

  
  
<style>
:root {
  --font-mono: "PP Supply Mono", monospace;
  --font-sans: "PP Neue Montreal", sans-serif;
  --color-text: #fff;
  --content-z: 2;
  --desktop-width: 500px;
  --mobile-width: 300px;
}

@font-face {
  font-family: "PP Neue Montreal";
  src: url("//repo.bfw.wiki/bfwrepo/font/PPNeueMontreal-Variable.woff2")
    format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "PP Supply Mono";
  src: url("//repo.bfw.wiki/bfwrepo/font/PPSupplyMono-Variable.woff2")
    format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html,
body {
  width: 100%;
  height: 100%;
  overflow: hidden;
  font-family: var(--font-sans);
  background: black;
}

img {
  width: 100%;
  height: 100%;
  -o-object-fit: cover;
     object-fit: cover;
  will-change: transform;
}

.tp-dfwv {
  visibility: hidden;
}

.image-slider {
  position: relative;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  opacity: 0;
}

.webgl-canvas {
  display: block;
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
}

/* Corner Text Styles */
.corner-text {
  position: fixed;
  color: white;
  font-family: var(--font-mono);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  line-height: 1.5;
  z-index: 1;
  pointer-events: none;
}

.corner-text div {
  margin-bottom: 4px;
}

.corner-text-top-left {
  top: 2rem;
  left: 2rem;
}

.corner-text-top-right {
  top: 2rem;
  right: 2rem;
  text-align: right;
}

.corner-text-bottom-left {
  bottom: 2rem;
  left: 2rem;
}

.corner-text-bottom-right {
  bottom: 2rem;
  right: 2rem;
  text-align: right;
}

.corner-text-shortcuts {
  top: 50%;
  left: 2rem;
  transform: translateY(-50%);
  font-size: 10px;
  text-align: left;
}

.corner-text-center {
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  height: 80vh;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.featured-image {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 25%;
  height: 50%;
  z-index: var(--content-z);
}

.featured-image-wrapper {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  -webkit-clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%);
          clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%);
  will-change: clip-path;
}

.slide-text {
  position: absolute;
  top: 10%;
  left: 30%;
  transform: translate(-50%, -50%);
  color: var(--color-text);
  z-index: var(--content-z);
}

.slide-number {
  position: relative;
  width: var(--desktop-width);
  height: 20px;
  margin-bottom: 0.5em;
  -webkit-clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
          clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
  overflow: hidden;
}

.slide-number span {
  position: absolute;
  top: 0;
  left: 0;
  color: var(--color-text);
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 400;
  line-height: 1.5;
  transform: translateY(0px);
  will-change: transform;
  margin: 0;
  padding: 0;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

.slide-title {
  position: relative;
  width: var(--desktop-width);
  height: 60px;
  -webkit-clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
          clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
  overflow: hidden;
}

.slide-title h1 {
  position: absolute;
  top: 0;
  left: 0;
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: 48px;
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1.2;
  transform: translateY(0px);
  will-change: transform;
  margin: 0;
  padding: 0;
}

.slide-description {
  position: relative;
  width: var(--desktop-width);
  height: 24px;
  -webkit-clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
          clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
  overflow: hidden;
}

.slide-description p {
  position: absolute;
  top: 0;
  left: 0;
  color: var(--color-text);
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 400;
  line-height: 1.2;
  transform: translateY(0px);
  will-change: transform;
  margin: 0;
  padding: 0;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.slide-paragraph {
  position: absolute;
  bottom: 10%;
  right: 30%;
  transform: translate(50%, -50%);
  color: var(--color-text);
  z-index: var(--content-z);
  width: 460px;
  overflow: hidden;
}

.slide-paragraph-line {
  position: relative;
  width: 100%;
  height: 28px;
  -webkit-clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
          clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
  overflow: hidden;
}

.slide-paragraph-line:last-child {
  margin-bottom: 0;
}

.slide-paragraph-line span {
  position: absolute;
  top: 2px;
  left: 0;
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: 1.25em;
  font-weight: 500;
  line-height: 1.4;
  transform: translateY(0px);
  will-change: transform;
  margin: 0;
  padding: 0;
  white-space: nowrap;
}

@media (max-width: 900px) {
  .featured-image {
    width: 75%;
  }

  .slide-text {
    top: 60%;
    left: 60%;
  }

  .slide-number {
    width: var(--mobile-width);
    height: 18px;
  }

  .slide-number span {
    font-size: 10px;
  }

  .slide-title {
    width: var(--mobile-width);
    height: 50px;
  }

  .slide-title h1 {
    font-size: 36px;
  }

  .slide-description {
    width: var(--mobile-width);
    height: 20px;
  }

  .slide-description p {
    font-size: 12px;
  }

  .slide-paragraph {
    top: 75%;
    right: 20%;
    width: 280px;
    overflow: hidden;
  }

  .slide-paragraph-line {
    height: 24px;
    margin-bottom: 4px;
  }

  .slide-paragraph-line span {
    font-size: 10px;
    line-height: 1.4;
    top: 2px;
  }

  .corner-text {
    font-size: 10px;
  }

  .corner-text-shortcuts {
    font-size: 8px;
  }

  .corner-text-center {
    height: 70vh;
  }
}
</style>

  
  
</head>

<body translate="no">
  <main class="image-slider" role="region" aria-label="Image carousel" data-image-slider-init>
  <canvas class="webgl-canvas" data-webgl-canvas aria-hidden="true"></canvas>

  <!-- Fixed corner and center text -->
  <aside class="corner-text corner-text-top-left" aria-hidden="true">
    <div>ANCIENT</div>
    <div>ONES</div>
    <div>COSMIC</div>
    <div>HORROR</div>
  </aside>

  <aside class="corner-text corner-text-top-right" aria-hidden="true">
    <div>MADNESS</div>
    <div>RISES</div>
  </aside>

  <aside class="corner-text corner-text-bottom-left" aria-hidden="true">
    <div>TENTACLES</div>
    <div>EMERGE</div>

    <div>FROM</div>
    <div>DEPTHS</div>
  </aside>

  <aside class="corner-text corner-text-bottom-right" aria-hidden="true">
    <div>ELDRITCH</div>
    <div>AWAKENS</div>
  </aside>

  <nav class="corner-text corner-text-shortcuts" aria-label="Keyboard shortcuts">
    <p>H - TOGGLE SETTINGS</p>
    <p>1 - DATAMOSH</p>
    <p>2 - PIXEL SORT</p>
    <p>3 - DIGITAL STATIC</p>
    <p>4 - STATIC SWEEP</p>
    <p>5 - GLITCH WIPE</p>
    <p>6 - ANALOG DECAY</p>
    <p>P - CYCLE PRESETS</p>
    <p>+/- INTENSITY</p>
    <p>[ ] SPEED</p>
    <p>R - RESET</p>
  </nav>

  <aside class="corner-text corner-text-center" aria-hidden="true">
    <div>R'LYEH</div>
    <div></div>
    <div>FHTAGN</div>
    <div></div>
    <div></div>
    <div></div>
    <div>CTHULHU</div>
    <div></div>
    <div>THE</div>
    <div>SLEEPER</div>
    <div>STIRS</div>
  </aside>

  <section class="featured-image" data-featured-image>
    <div class="featured-image-wrapper" data-featured-wrapper>
      <img src="//repo.bfw.wiki/bfwrepo/image/5e584482a56eb.png" alt="Awakening Abyss - Eldritch horror scene with cosmic entity emerging from dark abyss" />
    </div>
  </section>

  <header class="slide-text" data-slide-text>
    <div class="slide-number" data-slide-number>
      <span>∅1</span>
    </div>
    <div class="slide-title" data-slide-title>
      <h1>Awakening Abyss</h1>
    </div>
    <div class="slide-description" data-slide-description>
      <p>Eldritch Emergence</p>
    </div>
  </header>

  <div class="slide-paragraph" data-slide-paragraph>
    <div class="slide-paragraph-line" data-paragraph-line-1>
      <span>Archived VHS documentary footage captures the moment</span>
    </div>
    <div class="slide-paragraph-line" data-paragraph-line-2>
      <span>an ancient cosmic entity ruptures frozen silence.</span>
    </div>
  </div>
</main>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/gsap.3.13.0.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/ScrollTrigger.3.13.0.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/ScrambleTextPlugin.3.13.0.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/three.156.js"></script>
      <script  type="module">

import { Pane } from "//repo.bfw.wiki/bfwrepo/js/tweakpane.4.0.3.js";

const preloaderStyle = document.createElement("style");
preloaderStyle.textContent = `
.image-slider, [data-image-slider-init] {
  opacity: 0;
  transition: opacity 1.5s ease-in;
  pointer-events: none;
}

.image-slider.loaded, [data-image-slider-init].loaded {
  opacity: 1;
  pointer-events: auto;
}
`;
document.head.appendChild(preloaderStyle);

function easeInOutSine(t) {
  return -(Math.cos(Math.PI * t) - 1) / 2;
}

function easeInOutCubic(t) {
  return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
}

function smoothstep(edge0, edge1, x) {
  const t = Math.max(0, Math.min(1, (x - edge0) / (edge1 - edge0)));
  return t * t * (3 - 2 * t);
}

function hexToRgb(hex) {
  if (hex.startsWith("#")) {
    return [
    Number.parseInt(hex.slice(1, 3), 16),
    Number.parseInt(hex.slice(3, 5), 16),
    Number.parseInt(hex.slice(5, 7), 16)];

  }
  const match = hex.match(/\d+/g);
  return match ?
  [
  Number.parseInt(match[0]),
  Number.parseInt(match[1]),
  Number.parseInt(match[2])] :

  [255, 255, 255];
}

function interpolateColor(color1, color2, t, opacity = 1) {
  const rgb1 = hexToRgb(color1);
  const rgb2 = hexToRgb(color2);
  const r = Math.round(rgb1[0] + (rgb2[0] - rgb1[0]) * t);
  const g = Math.round(rgb1[1] + (rgb2[1] - rgb1[1]) * t);
  const b = Math.round(rgb1[2] + (rgb2[2] - rgb1[2]) * t);
  return `rgba(${r}, ${g}, ${b}, ${opacity})`;
}

class SliderLoadingManager {
  constructor() {
    this.overlay = null;
    this.canvas = null;
    this.ctx = null;
    this.animationId = null;
    this.startTime = null;
    this.duration = 3000; // 3 seconds
    this.createLoadingScreen();
  }

  createLoadingScreen() {
    this.overlay = document.createElement("div");
    this.overlay.style.cssText = `
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: #000000;
      display: flex;
      justify-content: center;
      align-items: center;
      z-index: 10000;
    `;

    // Create canvas for Line Pulse Wave animation
    this.canvas = document.createElement("canvas");
    this.canvas.width = 300;
    this.canvas.height = 300;

    this.ctx = this.canvas.getContext("2d");
    this.overlay.appendChild(this.canvas);
    document.body.appendChild(this.overlay);

    // Start the Line Pulse Wave animation
    this.startAnimation();
  }

  startAnimation() {
    const centerX = this.canvas.width / 2;
    const centerY = this.canvas.height / 2;
    let time = 0;
    let lastTime = 0;

    const dotRings = [
    { radius: 20, count: 8 },
    { radius: 35, count: 12 },
    { radius: 50, count: 16 },
    { radius: 65, count: 20 },
    { radius: 80, count: 24 }];


    // Red color scheme
    const colors = {
      primary: "#ff0000",
      accent: "#ff6666" };


    const animate = timestamp => {
      if (!this.startTime) this.startTime = timestamp;

      if (!lastTime) lastTime = timestamp;
      const deltaTime = timestamp - lastTime;
      lastTime = timestamp;
      time += deltaTime * 0.001;

      // Clear canvas
      this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);

      // Draw center dot
      this.ctx.beginPath();
      this.ctx.arc(centerX, centerY, 3, 0, Math.PI * 2);
      const rgb = hexToRgb(colors.primary);
      this.ctx.fillStyle = `rgba(${rgb[0]}, ${rgb[1]}, ${rgb[2]}, 0.9)`;
      this.ctx.fill();

      // Draw Line Pulse Wave animation
      dotRings.forEach((ring, ringIndex) => {
        for (let i = 0; i < ring.count; i++) {
          const angle = i / ring.count * Math.PI * 2;
          const radiusPulse = Math.sin(time * 2 - ringIndex * 0.4) * 3;
          const x = centerX + Math.cos(angle) * (ring.radius + radiusPulse);
          const y = centerY + Math.sin(angle) * (ring.radius + radiusPulse);

          const opacityWave =
          0.4 + Math.sin(time * 2 - ringIndex * 0.4 + i * 0.2) * 0.6;
          const isActive = Math.sin(time * 2 - ringIndex * 0.4 + i * 0.2) > 0.6;

          // Draw line from center to point
          this.ctx.beginPath();
          this.ctx.moveTo(centerX, centerY);
          this.ctx.lineTo(x, y);
          this.ctx.lineWidth = 0.8;

          if (isActive) {
            const accentRgb = hexToRgb(colors.accent);
            this.ctx.strokeStyle = `rgba(${accentRgb[0]}, ${accentRgb[1]}, ${
            accentRgb[2]
            }, ${opacityWave * 0.7})`;
          } else {
            const primaryRgb = hexToRgb(colors.primary);
            this.ctx.strokeStyle = `rgba(${primaryRgb[0]}, ${primaryRgb[1]}, ${
            primaryRgb[2]
            }, ${opacityWave * 0.5})`;
          }
          this.ctx.stroke();

          // Draw dot at the end of the line
          this.ctx.beginPath();
          this.ctx.arc(x, y, 2.5, 0, Math.PI * 2);
          if (isActive) {
            const accentRgb = hexToRgb(colors.accent);
            this.ctx.fillStyle = `rgba(${accentRgb[0]}, ${accentRgb[1]}, ${accentRgb[2]}, ${opacityWave})`;
          } else {
            const primaryRgb = hexToRgb(colors.primary);
            this.ctx.fillStyle = `rgba(${primaryRgb[0]}, ${primaryRgb[1]}, ${primaryRgb[2]}, ${opacityWave.........完整代码请登录后点击上方下载按钮下载查看

网友评论0