createSlider() 函数在 canvas 之外创建滑块。如何将滑块定位在 canvas 内?

The createSlider() function creates the slider outside of the canvas. How to position the slider inside the canvas?

我正在尝试使用 p5.js 在 canvas 中实现一个滑块。如果网页正文中没有 HTML 元素,则 canvas 和滑块位于网页的左上角。

但是,当我更改 canvas 的位置时,滑块不会停留在 canvas 内。 position 方法设置滑块绝对相对于网页的位置。

如何设置滑块在 canvas 中的位置?

这是复制问题的最低限度代码。

<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>p5.js example</title>
    <style> body {padding: 0; margin: 0;} </style>
    <script src="../p5.min.js"></script>
    <script src="../addons/p5.dom.min.js"></script>
    <script src="../addons/p5.sound.min.js"></script>
    <script src="sketch.js"></script>
  </head>
  <body>
      <div>
          <p><object width="150" height="150" vspace="100"></object> 
            This is some text. This is some text. This is some text.</p>
      </div>
  </body>
</html>

sketch.js 文件是:

var slider;
function setup() {
  slider = createSlider(0, 255, 100);
  slider.position(10, 10);
  slider.style('width', '80px');
}

function draw() {
  var val = slider.value();
  background(val);
}

p5.js' createSlider() 函数创建一个 <input /> range HTML element,它不同于用于呈现其他方法的 <canvas/> 元素。

您可以将绝对定位与 z-index 结合使用,使 canvas 具有较低的 z-index 和具有较高 z-index 的滑块(在 [=39= 之上) ]), 两者都具有您需要的绝对位置。

如果您确实希望在 canvas 元素内呈现滑块,您可以使用 p5.js 绘图函数和 mouse/touch 事件来滚动自己的滑块 class,但是它不会像使用 <input /> 范围 HTML 元素那样 CPU 有效。

这是移植到 p5.js:

Processing > Examples > Topics > GUI > Scrollbar 示例

/**
 * Scrollbar. 
 * 
 * Move the scrollbars left and right to change the positions of the images. 
 */

let slider;

function setup() {
  createCanvas(640, 360);
  noStroke();
  
  slider = new HScrollbar(0, height/2-8, width, 16, 16);
}

function draw() {
  background(255);
  
  fill(0);
  text("slider position: " + slider.getPos().toFixed(2),width/2,height/3);
  
  slider.update();
  slider.display();
}


class HScrollbar {
  constructor(xp, yp, sw, sh, l) {
    this.swidth = sw;
    this.sheight = sh;
    let widthtoheight = sw - sh;
    this.ratio = sw / widthtoheight;
    this.xpos = xp;
    this.ypos = yp-this.sheight/2;
    this.spos = this.xpos + this.swidth/2 - this.sheight/2;
    this.newspos = this.spos;
    this.sposMin = this.xpos;
    this.sposMax = this.xpos + this.swidth - this.sheight;
    this.loose = l;
    this.over = false;
    this.locked = false;
  }

  update() {
    if (this.overEvent()) {
      this.over = true;
    } else {
      this.over = false;
    }
    if (mouseIsPressed && this.over) {
      this.locked = true;
    }
    if (!mouseIsPressed) {
      this.locked = false;
    }
    if (this.locked) {
      this.newspos = constrain(mouseX-this.sheight/2, this.sposMin, this.sposMax);
    }
    if (abs(this.newspos - this.spos) > 1) {
      this.spos = this.spos + (this.newspos-this.spos)/this.loose;
    }
  }

  overEvent() {
    if (mouseX > this.xpos && mouseX < this.xpos+this.swidth &&
       mouseY > this.ypos && mouseY < this.ypos+this.sheight) {
      return true;
    } else {
      return false;
    }
  }

  display() {
    noStroke();
    fill(204);
    rect(this.xpos, this.ypos, this.swidth, this.sheight);
    if (this.over || this.locked) {
      fill(0, 0, 0);
    } else {
      fill(102, 102, 102);
    }
    rect(this.spos, this.ypos, this.sheight, this.sheight);
  }

  getPos() {
    // Convert spos to be values between
    // 0 and the total width of the scrollbar
    return this.spos * this.ratio;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.min.js"></script>

请检查: CSlider - Canvas p5.js 的滑块,支持 scale(),主要支持标准 p5 滑块调用: https://editor.p5js.org/Comissar/sketches/IHUYuzjR