javascript 为什么JS只能在一个盒子上工作?

cidc1ykv  于 5个月前  发布在  Java
关注(0)|答案(2)|浏览(71)

此问题在此处已有答案

What do querySelectorAll and getElementsBy* methods return?(12个回答)
2天前关闭。
我从codepen中提取了这个JS片段并将其应用到我的网站上。我希望水彩效果在div中,但它似乎只适用于第一个。
我尝试使用const canvas = document.querySelectorAll('.see-more');,但这使它更糟,不工作。

//watercolor effect on see more//

  const canvas = document.querySelector('.see-more');
  console.log(canvas);
  //canvas.width = 300;
  //canvas.height = 150;
  const cx = canvas.getContext('2d');
  cx.globalCompositeOperation = 'source-over';
  cx.imageSmoothingEnabled = true;
  cx.imageSmoothingQuality = 'low';
  const palette = [
    //[255, 255, 255],
    //[83, 159, 162], //turqoise//
    //[114, 177, 164], //green
    [171, 204, 177],
    //mint
    //[196, 219, 180], //light green//
    [221, 160, 221],
    //plum//
    [255, 192, 203],
    //pink//
    [0, 255, 255],
    //neon blue//
    [255, 255, 0] //yellow//
    //[212, 226, 182] //bright green
  ];

  const gradients = palette.map(([r, g, b]) => {
    const gradient = cx.createRadialGradient(0, 0, 1, 0, 0, 50);
    gradient.addColorStop(0, `rgba(${r},${g},${b},1)`);
    gradient.addColorStop(1, `rgba(${r},${g},${b},0)`);
    return gradient;
  });
  const watercolors = [];
  class Watercolor {
    constructor(time) {
      const colorIndex = Math.floor(Math.random() * palette.length);
      this.color = gradients[colorIndex];
      this.radius = 50;
      this.x = Math.random() * canvas.width;
      this.y = Math.random() * canvas.height;
      this.dx = Math.random() * 2 - 1;
      this.dy = Math.random() * 2 - 1;
      this.startTime = time;
      this.currentTime = time;
      this.duration = Math.ceil(Math.random() * 5000);
    }
    update(time) {
      this.currentTime = time;
      if (this.currentTime - this.startTime >= this.duration) {
        return false;
      }
      this.x += this.dx;
      this.y += this.dy;
      return true;
    }
    render(cx) {
      cx.save();
      cx.globalAlpha = (this.currentTime - this.startTime) / this.duration;
      cx.translate(this.x, this.y);
      cx.beginPath();
      cx.arc(0, 0, this.radius, 0, Math.PI * 2);
      cx.fillStyle = this.color;
      cx.fill();
      cx.restore();
    }
  }
  let frameId;
  function frame(time) {
    const multiplier = 0.25;
    const expectedWidth = Math.floor(canvas.clientWidth * multiplier);
    if (canvas.width !== expectedWidth) {
      canvas.width = expectedWidth;
    }
    const expectedHeight = Math.floor(canvas.clientHeight * multiplier);
    if (canvas.height !== expectedHeight) {
      canvas.height = expectedHeight;
    }
    if (watercolors.length < 2) {
      watercolors.push(new Watercolor(time));
    }
    for (let index = watercolors.length - 1; index >= 0; index--) {
      const watercolor = watercolors[index];
      if (!watercolor.update(time)) {
        console.log(watercolors.splice(index, 1));
      }
    }
    for (const watercolor of watercolors) {
      watercolor.render(cx);
    }
    frameId = window.requestAnimationFrame(frame);
  }
  function start() {
    frameId = window.requestAnimationFrame(frame);
  }
  function stop() {
    window.cancelAnimationFrame(frameId);
  }
  start();
.sec {
  padding-top: 200px;
  padding-bottom: 200px;
}

.cont {
  max-width: 1440px;
  padding-right: 30px;
  padding-left: 30px;
}

.see-more-wrap {
  position: relative;
  overflow: hidden;
  width: 40%;
  margin-left: 10px;
  //border-style: solid;
  //border-width: 1px;
  background-color: @swatch_76b6399f;
  text-decoration: none;
}
<section class="sec"><div class="w-layout-blockcontainer cont w-container"><div><a href="#" class="see-more-wrap w-inline-block"><div><h3 class="h3-copy">More work?</h3><div class="mar-btm-10px">Discover the collection of our previous projects.</div></div><div class="pos-abs w-embed"><canvas class="see-more" width="137" height="18"></canvas>

<style>
  .see-more {
    width: 100%;
    height: 100%;
    display: flex;
  }

  .see-more {
    filter: blur(20px) contrast(2);
  }
</style></div></a><a href="#" class="see-more-wrap w-inline-block"><div><h3 class="h3-copy">More work?</h3><div class="mar-btm-10px">Discover the collection of our previous projects.</div></div><div class="pos-abs w-embed"><canvas class="see-more"></canvas>

<style>
  .see-more {
    width: 100%;
    height: 100%;
    display: flex;
  }

  .see-more {
    filter: blur(20px) contrast(2);
  }
</style></div></a></div></div></section>
efzxgjgh

efzxgjgh1#

我让它工作,但它是一个很多的工作,基本上,我们改变了querySelectorquerySelectorAll,然后运行一个for循环的所有画布。至于变化,基本上,我的范围画布存在通过传递参数,使每个画布函数运行在其各自的画布!

//watercolor effect on see more//
let frameId;
const watercolors = [];
const palette = [
  //[255, 255, 255],
  //[83, 159, 162], //turqoise//
  //[114, 177, 164], //green
  [171, 204, 177],
  //mint
  //[196, 219, 180], //light green//
  [221, 160, 221],
  //plum//
  [255, 192, 203],
  //pink//
  [0, 255, 255],
  //neon blue//
  [255, 255, 0] //yellow//
  //[212, 226, 182] //bright green
];

const getGradients = (canvas) => palette.map(([r, g, b]) => {
  const cx = canvas.getContext('2d');
  const gradient = cx.createRadialGradient(0, 0, 1, 0, 0, 50);
  gradient.addColorStop(0, `rgba(${r},${g},${b},1)`);
  gradient.addColorStop(1, `rgba(${r},${g},${b},0)`);
  return gradient;
});

class Watercolor {
  constructor(time, canvas) {
    const colorIndex = Math.floor(Math.random() * palette.length);
    const gradientsArr = getGradients(canvas);
    this.color = gradientsArr[colorIndex];
    this.radius = 50;
    this.x = Math.random() * canvas.width;
    this.y = Math.random() * canvas.height;
    this.dx = Math.random() * 2 - 1;
    this.dy = Math.random() * 2 - 1;
    this.startTime = time;
    this.currentTime = time;
    this.duration = Math.ceil(Math.random() * 5000);
  }
  update(time) {
    this.currentTime = time;
    if (this.currentTime - this.startTime >= this.duration) {
      return false;
    }
    this.x += this.dx;
    this.y += this.dy;
    return true;
  }
  render(cx) {
    cx.save();
    cx.globalAlpha = (this.currentTime - this.startTime) / this.duration;
    cx.translate(this.x, this.y);
    cx.beginPath();
    cx.arc(0, 0, this.radius, 0, Math.PI * 2);
    cx.fillStyle = this.color;
    cx.fill();
    cx.restore();
  }
}

const canvases = document.querySelectorAll('.see-more');
if (canvases && canvases.length) {
  canvases.forEach((canvas) => {
    //canvas.width = 300;
    //canvas.height = 150;
    const cx = canvas.getContext('2d');
    cx.globalCompositeOperation = 'source-over';
    cx.imageSmoothingEnabled = true;
    cx.imageSmoothingQuality = 'low';
    start(canvas);
  });
}

function start(canvas) {
  frameId = window.requestAnimationFrame(frame.bind(this, canvas));
}

function stop() {
  window.cancelAnimationFrame(frameId);
}


function frame(canvas, time) {
  const cx = canvas.getContext('2d');
  const multiplier = 0.25;
  const expectedWidth = Math.floor(canvas.clientWidth * multiplier);
  if (canvas.width !== expectedWidth) {
    canvas.width = expectedWidth;
  }
  const expectedHeight = Math.floor(canvas.clientHeight * multiplier);
  if (canvas.height !== expectedHeight) {
    canvas.height = expectedHeight;
  }
  if (watercolors.length < 2) {
    watercolors.push(new Watercolor(time, canvas));
  }
  for (let index = watercolors.length - 1; index >= 0; index--) {
    const watercolor = watercolors[index];
    if (!watercolor.update(time)) {
      watercolors.splice(index, 1);
    }
  }
  for (const watercolor of watercolors) {
    watercolor.render(cx);
  }
  frameId = window.requestAnimationFrame(frame.bind(this, canvas));
}
.sec {
  padding-top: 200px;
  padding-bottom: 200px;
}

.cont {
  max-width: 1440px;
  padding-right: 30px;
  padding-left: 30px;
}

.see-more-wrap {
  position: relative;
  overflow: hidden;
  width: 40%;
  margin-left: 10px;
  //border-style: solid;
  //border-width: 1px;
  background-color: @swatch_76b6399f;
  text-decoration: none;
}
<section class="sec">
  <div class="w-layout-blockcontainer cont w-container">
    <div>
      <a href="#" class="see-more-wrap w-inline-block">
        <div>
          <h3 class="h3-copy">More work?</h3>
          <div class="mar-btm-10px">Discover the collection of our previous projects.</div>
        </div>
        <div class="pos-abs w-embed"><canvas class="see-more" width="137" height="18"></canvas>

          <style>
            .see-more {
              width: 100%;
              height: 100%;
              display: flex;
            }
            
            .see-more {
              filter: blur(20px) contrast(2);
            }
          </style>
        </div>
      </a>
      <a href="#" class="see-more-wrap w-inline-block">
        <div>
          <h3 class="h3-copy">More work?</h3>
          <div class="mar-btm-10px">Discover the collection of our previous projects.</div>
        </div>
        <div class="pos-abs w-embed"><canvas class="see-more"></canvas>

          <style>
            .see-more {
              width: 100%;
              height: 100%;
              display: flex;
            }
            
            .see-more {
              filter: blur(20px) contrast(2);
            }
          </style>
        </div>
      </a>
    </div>
  </div>
</section>
rpppsulh

rpppsulh2#

当前方法的问题是document. querySelectorAll('. see-more')仅选择与指定选择器匹配的第一个元素。要解决此问题,您应该使用document.querySelectorAll('. see-more')并在其返回的NodeList上重新选择。
以下是如何修改代码以使用类将效果应用于所有canvas元素的方法。
选择所有画布元素:使用document.querySelectorAll('. see-more')获取所有画布元素。
遍历每个画布元素:使用循环遍历每个画布元素,并对每个元素应用水彩效果。
将效果应用于每个画布:对于每个画布元素,您需要创建一个单独的上下文并应用水彩效果。
下面是代码的修改版本:

// Select all canvas elements
    const canvases = document.querySelectorAll('.see-more');

   // Function to start the watercolor effect on a canvas
   function startWatercolorEffect(canvas) {
const cx = canvas.getContext('2d');
cx.globalCompositeOperation = 'source-over';
cx.imageSmoothingEnabled = true;
cx.imageSmoothingQuality = 'low';
// ... rest of your watercolor effect setup ...

function frame(time) {
    // ... your frame logic ...
    frameId = window.requestAnimationFrame(frame);
}

function start() {
    frameId = window.requestAnimationFrame(frame);
}

start();

字符串
}

// Apply the effect to each canvas
    canvases.forEach(canvas => {
    startWatercolorEffect(canvas);
   });

相关问题