Canvas 的视差效果和延迟 - 使用 JavaScript 加载的图像

问题描述 投票:0回答:1

使用 Canvas,我可以将图像加载到 main.js 文件中来实现视差效果。视差效果很好 草稿代码在这里:https://github.com/bengabo/parallax-image 我的问题是我想延迟图像“layer_9_1.png”的显示,但是当我编写延迟时,它会应用于所有图像。我尝试了一个函数,一个条件......但没有任何作用。每次,它都适用于所有图像。

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="stylesheet" type="text/css" href="/style.css" />
    <meta name="author" content="Benjamin Gaboury" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0, user-scalable=no"
    />
    <title>Interactive parallax illo</title>
  </head>
  <body>
    <div class="image-container">
      <canvas class="canvas" id="canvas" width="900" height="1200"></canvas>
      <div class="loading-screen" id="loading">Loading...</div>
    </div>
    <script type="text/javascript" src="/main.js"></script>
  </body>
</html>
body {
  box-sizing: border-box;
  margin: 0;
  height: 100%;
  background-color: #ffffff;
  display: flex;
  justify-content: center;
  align-items: center;
  font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
}

.image-container {
  display: flex;
  height: 100%;
  width: 100%;
  max-width: 100%;
  position: relative;
}

.canvas {
  width: auto;
  max-width: 100%;
  max-height: 100%;
  display: block;
  margin: auto;
  background-color: rgb(255, 255, 255);
}

.loading-screen {
  position: absolute;
  width: 100%;
  height: 100%;
  background: white;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  visibility: visible;
  opacity: 1;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  line-height: 40px;
  transition: 0.25s ease all 0.75s;
  color: #999;
  transform: translateZ(50px);
}

.loading-screen.hidden {
  visibility: hidden;
  opacity: 0;
}
let ctx = canvas.getContext("2d");

// Loading screen
let loading_screen = document.getElementById("loading");

/**
 * Images loader
 */
let loaded = false;
let load_counter = 0;

let background = new Image();
let stars_01 = new Image();
let stars_02 = new Image();
let stars_03 = new Image();
let shadows = new Image();
let mask = new Image();
let planets = new Image();
let stars_04 = new Image();
let title = new Image();

let layers_list = [
  {
    image: background,
    src: "/layer_1_1.png",
    z_index: -2,
    position: { x: 0, y: 0 },
    blend: null,
    opacity: 1,
    maxOffsetX: 100,
    maxOffsetY: 100,
    delay: 0,
  },
  {
    image: stars_01,
    src: "/layer_2_1.png",
    z_index: -1.8,
    position: { x: 0, y: 0 },
    blend: null,
    opacity: 1,
    delay: 0,
  },
  {
    image: stars_02,
    src: "/layer_3_1.png",
    z_index: -1.5,
    position: { x: 0, y: 0 },
    blend: "overlay",
    opacity: 0.7,
    delay: 0,
  },
  {
    image: stars_03,
    src: "/layer_4_1.png",
    z_index: -1.25,
    position: { x: 0, y: 0 },
    blend: "overlay",
    opacity: 0.8,
    delay: 0,
  },
  {
    image: shadows,
    src: "/layer_5_1.png",
    z_index: -0.75,
    position: { x: 0, y: 0 },
    blend: "multiply",
    opacity: 1,
    maxOffsetX: 100,
    maxOffsetY: 100,
    delay: 0,
  },
  {
    image: mask,
    src: "/layer_6_1.png",
    z_index: 0,
    position: { x: 0, y: 0 },
    blend: null,
    opacity: 1,
    delay: 0,
  },
  {
    image: planets,
    src: "/layer_7_1.png",
    z_index: 0.25,
    position: { x: 0, y: 0 },
    blend: null,
    opacity: 1,
    delay: 0,
  },
  {
    image: stars_04,
    src: "/layer_8_1.png",
    z_index: 1.25,
    position: { x: 0, y: 0 },
    blend: null,
    opacity: 0.8,
    maxOffsetX: 100,
    maxOffsetY: 100,
    delay: 0,
  },
  {
    image: title,
    src: "/layer_9_1.png",
    z_index: 1.5,
    position: { x: canvas.width, y: 0 },
    blend: null,
    opacity: 1,
    maxOffsetX: 120,
    maxOffsetY: 100,
    delay: 2000,
  },
];

const hideLoading = () => {
  loading_screen.classList.add("hidden");
};

layers_list.forEach((layer, index) => {
  layer.image.onload = () => {
    load_counter += 1;
    if (load_counter >= layers_list.length) {
      hideLoading();
      requestAnimationFrame(drawCanvas);
    }
  };

  layer.image.src = layer.src;
});

let getOffset = (layer) => {
  let touch_multip = 0.1;
  let touch_offset_x = pointer.x * layer.z_index * touch_multip;
  let touch_offset_y = pointer.y * layer.z_index * touch_multip;

  // Limit movement based on maxOffsetX and maxOffsetY
  if (touch_offset_x > layer.maxOffsetX) {
    touch_offset_x = layer.maxOffsetX;
  }
  if (touch_offset_x < -layer.maxOffsetX) {
    touch_offset_x = -layer.maxOffsetX;
  }
  if (touch_offset_y > layer.maxOffsetY) {
    touch_offset_y = layer.maxOffsetY;
  }
  if (touch_offset_y < -layer.maxOffsetY) {
    touch_offset_y = -layer.maxOffsetY;
  }

  let offset = {
    x: touch_offset_x,
    y: touch_offset_y,
  };

  return offset;
};
const drawCanvas = () => {
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  // const rotate_x = pointer.y * 0.15 + motion.y * 1.2;
  // const rotate_y = pointer.x * 0.15 + motion.x * 1.2;
  // const transform_string =
  //   "rotateX(" + rotate_x + "deg), rotateY(" + rotate_y + "deg)";
  // canvas.style.transform = transform_string;
  layers_list.forEach((layer, index) => {
    layer.position = getOffset(layer);
    // Blend modes
    layer.blend
      ? (ctx.globalCompositeOperation = layer.blend)
      : (ctx.globalCompositeOperation = "normal");
    // Opacity
    ctx.globalAlpha = layer.opacity;
    ctx.drawImage(layer.image, layer.position.x, layer.position.y);
  });
  requestAnimationFrame(drawCanvas);
};

/**
 * Mouse ctrl
 */
let moving = false;

let pointer_init = {
  x: 0,
  y: 0,
};

let pointer = {
  x: 0,
  y: 0,
};

const pointerStart = (event) => {
  moving = true;

  if (event.type === "touchstart") {
    pointer_init.x = event.touches[0].clientX;
    pointer_init.y = event.touches[0].clientY;
  } else if (event.type === "mousedown") {
    pointer_init.x = event.clientX;
    pointer_init.y = event.clientY;
  }
};
canvas.addEventListener("touchstart", pointerStart);
canvas.addEventListener("mousedown", pointerStart);

const pointerMmove = (event) => {
  event.preventDefault();
  if (moving === true) {
    let current_x = 0;
    let current_y = 0;
    if (event.type === "touchemove") {
      current_x = event.touches[0].clientX;
      current_y = event.touches[0].clientY;
    } else if (event.type === "mousemove") {
      current_x = event.clientX;
      current_y = event.clientY;
    }
    pointer.x = current_x - pointer_init.x;
    pointer.y = current_y - pointer_init.y;
  }
};

window.addEventListener("touchmove", pointerMmove);
window.addEventListener("mousemove", pointerMmove);
canvas.addEventListener("touchmove", (event) => {
  event.preventDefault();
});
canvas.addEventListener("mousemove", (event) => {
  event.preventDefault();
});

window.addEventListener("touchend", (event) => {
  endGesture();
});
window.addEventListener("mouseup", (event) => {
  endGesture();
});

const endGesture = () => {
  moving = false;
  pointer.x = 0;
  pointer.y = 0;
};
javascript html css canvas settimeout
1个回答
0
投票

可能通过

setTimeout
解决您的问题。您可以在超时时间内加载图像并点击
layer.delay

我像这样编辑了你的部分代码:

layers_list.forEach((layer, index) => {
    setTimeout(() => {
        layer.image.onload = () => {
            load_counter += 1;
            if (load_counter >= layers_list.length) {
                hideLoading();
                requestAnimationFrame(drawCanvas);
            }
        };
        layer.image.src = layer.src;
    }, layer.delay);
});
© www.soinside.com 2019 - 2024. All rights reserved.