使用 JavaScript 实时更新 HTML Canvas 中可拖动圆形容器的滚动条

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

我正在使用 HTML 和 JavaScript 在画布中开发一个可拖动的圆形容器,但每次用户在容器内滚动时,我很难让滚动条自动更新。尽管容器正确滚动,但滚动条并未实时反映这些变化。如何解决这个问题以确保滚动条与圆形容器内内容的移动正确同步?

const canvas = document.getElementById('canvas');
const container = document.getElementById('container');
const ctx = canvas.getContext('2d');

const resizeCanvas = () => {
    canvas.height = container.clientHeight;
    canvas.width = container.clientHeight;
}

let containerHeight, containerScrollHeight,scrolled, docHeight, scrollPer;

const render = () => {
    containerHeight = container.offsetHeight;
    containerScrollHeight = container.scrollHeight;
    scrolled = container.scrollTop;
    scrollPer = scrolled / (containerScrollHeight - containerHeight);
    
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.lineWidth = 5;
    makeArc('#666666', canvas.width / 2, canvas.height / 2, canvas.height / 2.05, 0, 2 * Math.PI);
    makeArc('#000000', canvas.width / 2, canvas.height / 2, canvas.height / 2.05, ((container.scrollTop - 0.1) * 2) * Math.PI, (container.scrollTop * 2) * Math.PI);
};

const makeArc = (color, one, two, three, four, five) => {
    ctx.beginPath();
    ctx.strokeStyle = color;
    ctx.arc(one, two, three, four, five);
    ctx.stroke();
};


resizeCanvas();
render();
window.addEventListener('resize', function() {
    resizeCanvas();
    render();
});
container.addEventListener('scroll', render);
:root{
  --item-size: 40dvw;
}
*{
  box-sizing: content-box;
}
html {
  scrollbar-width:none;
  -ms-overflow-style:none;
  overflow-y:-moz-scrollbars-none
}
.hide-scrollbar::-webkit-scrollbar {
  width:0;
  display: none
}
body{
  display: flex;
  flex-wrap: wrap;
  flex-direction: column;
  align-content: center;
  justify-content: center;
  align-items: center;
  height: 100vh;
  margin: 0;
  background-color: rgba(185, 212, 235, 0.698);
}
section{
  border-radius: 50%;
  width: calc(var(--item-size) + 5.9px);
  height: calc(var(--item-size) + 5.9px);
  gap: 2px;
  position: relative;
  overflow: hidden;
}
main{
  display: grid;
  grid-auto-flow: row;
  width: 100%;
  height: 100%;
  gap: 2px;
  overflow: scroll;
  scrollbar-width: none;
  scroll-snap-type: y mandatory;
  scroll-behavior: auto;
  position: relative;
  box-sizing: border-box;
}
main>.item{
  background-color: aliceblue;
  border: 3px;
  border-color: black;
  border-style: dashed;
  border-radius: 50%;
  aspect-ratio: 1;
  width: 100%;
  box-sizing: border-box;
  display: flex;
  flex-wrap: wrap;
  align-content: center;
  justify-content: center;
  scroll-snap-align: start;
}
.canvas{
  position: absolute; 
  right: 0px; top: 0px;
  border-radius: 50%;
  pointer-events: none;
}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <h1>Hi</h1>
<section class="scrollbar" id="container">
<main>
  <div class="item">
    <p>hola</p>
  </div>
  <div class="item">
    <p>hola</p>
  </div>
  <div class="item">
    <p>hola</p>
  </div>
</main>
<canvas width="100" height="100" class="canvas" id="canvas"></canvas>
</section>
</body>
</html>

javascript html5-canvas scrollbar
1个回答
0
投票

你的问题不太清楚...
我将重点关注我认为是您的问题,您想要在我眼中创建的“滚动”是随着用户在页面中滚动而增长的圆弧,但实际上什么也没有发生。

  • 您的

    container.addEventListener('scroll', render)
    未触发

  • 我将使用:

    document.addEventListener('wheel', scroll);

参见下面的工作原型

const canvas = document.getElementById('canvas');
const container = document.getElementById('container');
const ctx = canvas.getContext('2d');
let scrollValue = 0.2

const resizeCanvas = () => {
  canvas.height = container.clientHeight;
  canvas.width = container.clientHeight;
  render();
}

const scroll = (e) => {
  scrollValue += (e.deltaY > 0)? 0.5: -0.5
  render()
}

const render = () => {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.lineWidth = 5;
  makeArc('gray', canvas.width/2, canvas.height/2, canvas.height/2.05, 0, 2 * Math.PI);
  makeArc('red' , canvas.width/2, canvas.height/2, canvas.height/2.05, 0, scrollValue);
};

const makeArc = (color, one, two, three, four, five) => {
  ctx.beginPath();
  ctx.strokeStyle = color;
  ctx.arc(one, two, three, four, five);
  ctx.stroke();
};

resizeCanvas();
window.addEventListener('resize', resizeCanvas);
document.addEventListener('wheel', scroll);
:root {
  --item-size: 40dvw;
}

* {
  box-sizing: content-box;
}

html {
  scrollbar-width: none;
  -ms-overflow-style: none;
  overflow-y: -moz-scrollbars-none
}

.hide-scrollbar::-webkit-scrollbar {
  width: 0;
  display: none
}

body {
  display: flex;
  flex-wrap: wrap;
  flex-direction: column;
  align-content: center;
  justify-content: center;
  align-items: center;
  height: 100vh;
  margin: 0;
  background-color: rgba(185, 212, 235, 0.698);
}

section {
  border-radius: 50%;
  width: calc(var(--item-size) + 5.9px);
  height: calc(var(--item-size) + 5.9px);
  gap: 2px;
  position: relative;
  overflow: hidden;
}

main {
  display: grid;
  grid-auto-flow: row;
  width: 100%;
  height: 100%;
  gap: 2px;
  overflow: scroll;
  scrollbar-width: none;
  scroll-snap-type: y mandatory;
  scroll-behavior: auto;
  position: relative;
  box-sizing: border-box;
}

main>.item {
  background-color: aliceblue;
  border: 3px;
  border-color: black;
  border-style: dashed;
  border-radius: 50%;
  aspect-ratio: 1;
  width: 100%;
  box-sizing: border-box;
  display: flex;
  flex-wrap: wrap;
  align-content: center;
  justify-content: center;
  scroll-snap-align: start;
}

.canvas {
  position: absolute;
  right: 0px;
  top: 0px;
  border-radius: 50%;
  pointer-events: none;
}
<body>
  <section class="scrollbar" id="container">
    <main>
      <div class="item">
        <p>aaa</p>
      </div>
      <div class="item">
        <p>bbb</p>
      </div>
      <div class="item">
        <p>ccc</p>
      </div>
      <div class="item">
        <p>ddd</p>
      </div>
      <div class="item">
        <p>eee</p>
      </div>
      <div class="item">
        <p>fff</p>
      </div>
    </main>
    <canvas width="100" height="100" class="canvas" id="canvas"></canvas>
  </section>
</body>

© www.soinside.com 2019 - 2024. All rights reserved.