(P5js) 尝试将两个草图相互组合但一直失败

(P5js) Trying to combine two sketches to each other but keep failing

我正在尝试制作最终草图,最终目标基本上是有一个输入框,在其中提交一个单词,然后逐个字母地获取单词的拼写。 我制作了两个草图,一个是输入框,一个是拼写,但我已经尝试了多次,但我似乎无法将两个草图结合起来。 值得一提的是代码。

let input, button, visualization;
var img;

function setup() {
  // create canvas
  createCanvas(600 , 600);
  

  input = createInput();
  input.position(20, 65);

  button = createButton('submit');
  button.position(input.x + input.width, 65);
  button.mousePressed(visualize);

  visualization = createElement('h2', 'Type a word to get its spelling');
  visualization.position(20, 5);

  textAlign(CENTER);
  textSize(50);
}

function visualize() {
  const word = input.value();
  visualization.html('This is the spelling of ' + word + '!');
  input.value('');
}

对于输入框。

var sourceText = 'word';
var curIndex = 0;
function setup() {
  createCanvas(400, 400);
  frameRate(3);
}
function draw() {
  background(50);
  fill(255);
  textSize(144);
  textAlign(CENTER, CENTER);
  text(
    sourceText.substring(curIndex, curIndex+1),
    width/2, height/2);
  curIndex++;
  if (curIndex > sourceText.length) {
    curIndex = 0;
  }
}

用于拼写可视化。

与其使用两个 canvas,不如创建 graphics buffers! The code below will creates only one canvas with two buffers of width = canvas_width and height = canvas_height/2! These buffurs are drawn as image objects!

另请注意,在设置函数中我使用了 noLoop 以防止 draw() 函数每秒执行 60 次。通过使用 noLoop()draw() 函数将只执行一次!当您使用静态 canvases 时,使用 noLoop() 函数是一种很好的做法。在您的情况下,您希望输入位于 canvas 内,因此您必须使用它来防止在 canvas 上重新加载并允许系统捕获您的输入。

带按钮 stop loop 的矩形仅供测试!您可以删除它,或者进行实验并了解它是如何工作的!请记住 draw() 函数只被调用一次,因此当程序执行时矩形具有随机颜色。

现在,visualize() 函数使用 loop() function which enables the draw() function to be executed on 60FPS by default! This is required because you want to update the canvas once a new letter is added! You may choose your own algorithm to implement this but that the main idea of how to solve your problem! This function will use setInterval() & clearInterval() 并且它由代码顶部定义的毫秒控制!

PS:

  • 实施时请考虑大文本,因为它会超出 canvas。您可以检查文本位置是否大于 canvas_width 并防止这种情况发生(即将文本位置重置为新行)
  • 考虑无效输入
  • 考虑显示文本中未添加 space 字符。你可以使用 \s 来解决这个问题。
  • ...以及更多

var topBuffer;
var botttomBuffer;
let input;
let displayDiv;
var secondsPerLetter = 1 * 1000; //1 second * 1000 milliseconds

function setup() {
  noLoop(); //FPS = 0 (draw function is used once only after setup())
  textAlign(CENTER);
  textSize(50);
  
  // create canvas and buffers
  const canvas = createCanvas(800 , 600);
  topBuffer = createGraphics(width, height/2);
  botttomBuffer = createGraphics(width, height/2);
  
  // Draw on your buffers however you like
  drawTopBuffer();
  drawBottomBuffer();
  
  // Paint the off-screen buffers onto the main canvas
  image(topBuffer, 0, 0);
  image(botttomBuffer, 0, 300);
  
}


function draw(){
  fill(random(255),random(255),random(255))
  rect(width-100,height/2-100,100,100)
}

function drawTopBuffer() {
    topBuffer.background(200);
    topBuffer.fill(0);
    topBuffer.textSize(32);
    topBuffer.text("Input a word to be spelled:", 50, 50);
  
    input = createInput();
    input.position(20, height/4-60);
    input.style("width","740px");
    input.style("height","40px");
    input.style("font-size","40px");
  

    var button = createButton('submit');
    button.position(20, 145);
    button.style("width","750px");
    button.style("height","40px");
    button.style("font-size","30px");
  
    button.mousePressed(visualize);
  
    var button2 = createButton('Stop loop()');
    button2.position(width-90, 240);
    button2.mousePressed(noLoop);
}

function drawBottomBuffer() {
    botttomBuffer.background(160);
    botttomBuffer.fill(0);
    botttomBuffer.textSize(32);
  
    botttomBuffer.text("Spelling word:", 50, 50);
    
  
    displayDiv = createElement("div");
    displayDiv.id = "myDisplayDiv";
    displayDiv.position(20, height/2+100);
    displayDiv.style("width", "10px");
    displayDiv.style("height","500px");
    displayDiv.style("font-size","40px");
    displayDiv.style("display","inline-flex");
}

function visualize() {
  
  loop();
  var infoLabel = createElement('h2', 'You typed: \"' + input.value() + '\"');
  infoLabel.position(20, 205);
  
  let str = input.value().split('');
  
  const interval = setInterval(() => {
        
    var p = createElement("p", str[0] + " ");
    
    p.parent(displayDiv);
    
    str = str.slice(1); //Move to next letter

    if (!str.length) {
      clearInterval(interval);
      noLoop(); //STOP LOOP
    }
  }, secondsPerLetter);
}
html, body {
  margin: 0;
  padding: 0;
}
canvas {
  display: block;
}
<!DOCTYPE html>
<html>
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/p5.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/addons/p5.dom.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/addons/p5.sound.min.js"></script>
    <link rel="stylesheet" type="text/css" href="style.css">
    <meta charset="utf-8" />

  </head>
  <body>
    <script src="sketch.js"></script>
  </body>
</html>