在 html 中添加多个 p5.js 画布

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

我目前正在使用实例模式构建一个网站,该网站有多个 p5.js 画布和我自己的图像,因此我可以在 html 页面上获得多个画布。但是,我认为我的语法不正确。

// first sketch
var sketch1 = function (p) {
  const NUM_IMGS = 4;
  imgs = [];
  let currentImg = 0;
  p.preload = function () {
    for (let i = 0; i < NUM_IMGS; i++) {
      imgs[1] = p.loadImage("images/mag.png");
      imgs[2] = p.loadImage("images/outfits.png");
      imgs[3] = p.loadImage("images/photographer1.png");
      imgs[4] = p.loadImage("images/photographer2.png");
    }
  };

  p.setup = function () {
    const sketch1 = p.createCanvas(450, 300);
  };
  setupButtons();
};

p.draw = function () {
  p.image(imgs[currentImg], 0, 0);
};

const setupButtons = (_) => {
  previous = p.createButton("⏪");
  previous.position(p.width * 0.6 - 100, p.height);

  previous.mouseClicked((_) => {
    if (p.currentImg > 0) p.currentImg--;
  });

  next = p.createButton("⏩");
  next.position(p.width * 0.3 + 100, p.height);

  next.mouseClicked((_) => {
    if (p.currentImg < p.imgs.length - 1) p.currentImg++;
  });
};

// second sketch
var sketch2 = function (p) {
  let y;
  let z;
  let a;

  let switcher;

  let currentImage;

  p.preload = function () {
    y = p.loadImage("girls.png");
    z = p.loadImage("bow.png");
    a = p.loadImage("rose.png");
    b = p.loadImage("reds.png");
  };

  p.setup = function () {
    p.createCanvas(250, 300);

    switcher = createButton("see my pics");
    switcher.position(900, 1200);

    switcher.mousePressed(changeImg);
  };

  p.draw = function () {};

  p.changeImg = function () {
    if (currentImage == y) currentImage = z;
    else if (currentImage == z) currentImage = a;
    else if (currentImage == a) currentImage = b;
    else {
      currentImage = y;
    }

    image(currentImage, 0, 0, 250, 300);
  };
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.min.js"></script>

我收到错误消息“p is not defined”。我似乎无法让 p5 激活“实例模式”使用此代码作为参考并使用此代码作为参考

javascript p5.js
1个回答
0
投票

忠告:慢点!这段代码看起来像是一口气写出来的,盲目地希望/假设它会起作用。如果没有,就没有明显的调试入口点,因为复杂性已经远远超出了您的理解范围。

更好的策略是慢慢编码,一旦做出任何更改就运行代码以验证它是否仍然有效。如果它不起作用,您将确切地知道如何修复它,因为您只做了一个小改动。

从简单、最小的示例开始,例如文档中的 p5 实例模式示例,然后只有在您彻底测试代码以说服自己它有效后才构建。两个链接的草图都是非实例模式幻灯片。与其尝试让实例模式、2 个草图和幻灯片逻辑同时运行,不如一次专注于一个目标。从让显示单个图像的单个实例开始工作。然后把它做成幻灯片。然后添加第二个草图。如果这些步骤太大,请将问题离散化为更小的步骤,这些步骤是可实现和可验证的。

你可以把编程想象成探索一个满是坑的黑屋子。如果你不情愿地冲进去,你就会掉进坑里。如果你走得慢,测试你前面的下一步,你就会安全地到达目标。


这是我注意到的一些错误的列表:

  • p.draw
    setupButtons
    在全球范围内,导致您的主要错误。这些需要在 p5 实例闭包内,在那里它们可以访问
    p
    参数。如果您使用 autoformatter(我已经为您在问题代码上运行了一个),您可能已经看到了这一点。
  • 您的代码缺少对
    new p5(sketch1)
    的调用以初始化实例。
  • 关于何时在变量前使用
    p.
    的困惑。如果您拥有该变量,并且它是在您的草图闭包中使用
    let
    声明的,请不要在前面添加
    p.
    p.
    只是用来指代p5库中的一段数据。例子:
    • p.changeImg
      应该是
      const changeImg
    • p.imgs
      应该是
      imgs
    • p.currentImg
      应该是
      currentImg
    • createButton("see my pics");
      应该是
      p.createButton("see my pics");
  • for (let i = 0; i < NUM_IMGS; i++) {
    除了将相同的图像一遍又一遍地加载到索引 1、2、3、4 之外什么都不做。
  • 数组是 0 索引的,但是
    imgs[0]
    从未设置过。
  • setupButtons();
    应从 p5 的
    setup
    函数中调用,以便正确初始化实例。
  • 到处都是全局变量。这些可能导致非常微妙的错误——本质上,来自一个闭包的数据泄漏到另一个闭包中,造成严重破坏。始终使用
    let
    const
    严格限定变量范围。示例包括
    next
    previous
    imgs
    linter 会告诉你这些错误。在脚本顶部添加
    "use strict";
    也很有帮助。
  • changeImg
    在数组更易于管理时使用单独的变量。
  • currentImage
    从未在草图 2 中初始化。

这里的代码远非完美,但解决了上述大部分问题。我已经移动了几个位置并添加了虚拟图像以使示例可以运行。我希望你能从这里调整到你想要的。

// first sketch
var sketch1 = function (p) {
  const imgs = [];
  let currentImg = 0;

  p.preload = function () {
    imgs[0] = p.loadImage("http://placekitten.com/450/300");
    imgs[1] = p.loadImage("http://placekitten.com/450/301");
    imgs[2] = p.loadImage("http://placekitten.com/450/302");
    imgs[3] = p.loadImage("http://placekitten.com/450/303");
  };

  p.setup = function () {
    const sketch1 = p.createCanvas(450, 300);
    setupButtons();
  };

  const setupButtons = () => {
    const previous = p.createButton("⏪");
    previous.position(10, 10);

    previous.mouseClicked(() => {
      if (currentImg > 0) currentImg--;
    });

    const next = p.createButton("⏩");
    next.position(40, 10);
    next.mouseClicked(() => {
      if (currentImg < imgs.length - 1) currentImg++;
    });
  };

  p.draw = function () {
    p.image(imgs[currentImg], 0, 0);
  };
};

// second sketch
var sketch2 = function (p) {
  let images;
  let switcher;
  let currentImage = 0;

  p.preload = function () {
    images = [
      p.loadImage("http://placekitten.com/250/300"),
      p.loadImage("http://placekitten.com/250/301"),
      p.loadImage("http://placekitten.com/250/302"),
      p.loadImage("http://placekitten.com/250/303"),
    ]
  };

  p.setup = function () {
    p.createCanvas(250, 300);

    switcher = p.createButton("see my pics");
    switcher.position(90, 120);
    switcher.mousePressed(changeImg);

    p.noLoop();
  };

  const changeImg = function () {
    p.image(images[currentImage], 0, 0, 250, 300);
    currentImage = (currentImage + 1) % images.length;
  };
};

new p5(sketch1);
new p5(sketch2);
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/p5.min.js"></script>

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