p5.j​​s代码不会抛出错误,但在点击鼠标时不会加载

时间:2016-06-07 14:02:35

标签: javascript canvas mouseevent p5.js

我正在分析总统候选人的演讲。我有一个包含以下变量的数据文件:

> names(cl.context)
[1] "id"        "category"  "statement" "nchar"     "polarity" 

statement变量由每个属于三个category的句子填充。 polarity范围从-1到1,反映句子是否具有正偏差,中性或负偏差 我在p5中尝试做的是当用户在画布中单击鼠标时,按类别显示语句,随机x,y放置。这些陈述本身根据其极性着色 我终于达到了开发者控制台不会抛出任何错误并绘制画布的程度。但是当我在画布中单击时,没有任何反应。没有陈述。
我对JavaScript很陌生,因为它没有抛出错误信息,我无法解决问题所在。希望在这里提供一些建议。

我的p5代码:

var clContext;
var x;
var y;

const STATEMENTS = 118, CATEGORY = 3, QTY = STATEMENTS/CATEGORY | 0,
      POLARITY = 3,
      statements = Array(STATEMENTS), inds = Array(CATEGORY), polarity = Array(POLARITY);

      //load the table of Clinton's words and frequencies
function preload() {
        clContext = loadTable("cl_context.csv", "header");
      }

function setup() {
  createCanvas(647, 400);
  background(51);
  // Calling noStroke once here to avoid unecessary repeated function calls
  noStroke();
  // iterate over the table rows
  for(var i=0; i<clContext.getRowCount(); i++){
      //- Get data out of the relevant columns for each row -//
      var inds = clContext.get(i, "category");
      var statements = clContext.get(i, "statement");
      var polarity = clContext.get(i, "polarity")
    }

  for (let i = 0; i < statements; randomCategoryStates(i++));
  // create your Statement object and add to
  // the statements array for use later
  inds[i] = new Statement();


    console.info(inds);
}

function draw() {
  if(mouseClicked == true){
  for(var i=0; i<inds.length; i++) {
      inds[i].display();
  }
}
}

function mouseClicked() {
  if((mouseX < width) && (mouseY < height)) {
      randomCategoryStates(~~random(CATEGORY));
      redraw();
      return false;
  }

}

// Function to display statements by a random category with each mouse click
function randomCategoryStates(group) {
  let idx = inds[group], rnd;
  while ((rnd = ~~random(QTY)) == idx);
  inds[group] = rnd;
}

// Function to align statements, categories, and polarity
function Statement() {
  this.x = x;
  this.y = y;
  this.xmax = 10;
  this.ymax = 4;
  this.cat = inds;
  this.statement = statements;
  this.polarity = polarity;
  // set a random x,y position for each statement
  this.dx = (Math.random()*this.xmax) * (Math.random() < .5 ? -1 : 1);
  this.dy = (Math.random()*this.ymax) * (Math.random() < .5 ? -1 : 1);
}
// Attach pseudo-class methods to prototype;
// Maps polarity to color and x,y to random placement on canvas
Statement.prototype.display = function() {
  this.x += this.dx;
  this.y += this.dy;
  var cols = map(this.polarity == -1, 205, 38, 38);
  var cols = map(this.polarity == 0, 148, 0, 211);
  var cols = map(this.polarity == 1, 0, 145, 205);
  fill(cols);
  textSize(14);
  text(this.statement, this.x, this.y);
};  

编辑:让我感到困惑的一件事是,我在处理论坛上使用此代码获得的帮助并没有在{{mouseClicked()函数中调用draw函数1}}函数,所以我补充说。不完全确定我是否正确地做了或者甚至是必要的。

1 个答案:

答案 0 :(得分:1)

你的代码有很多。我将尝试通过所有事情,没有特别的顺序:

为什么需要这些变量?

var x;
var y;

我知道您认为您正在使用它们将位置传递给Statement,但您从未设置过这些变量!让我们暂时摆脱它们,因为它们没有做任何事情。这会导致代码出错,但我们会在一秒钟内修复此错误。

看看这个循环:

for(var i=0; i<clContext.getRowCount(); i++){
      //- Get data out of the relevant columns for each row -//
      var inds = clContext.get(i, "category");
      var statements = clContext.get(i, "statement");
      var polarity = clContext.get(i, "polarity")
    }

您在此处阅读CSV文件,但之后您无法对这些变量进行任何操作。然后你用这个来跟进:

for (let i = 0; i < statements; randomCategoryStates(i++));
  // create your Statement object and add to
  // the statements array for use later
  inds[i] = new Statement();

注意循环之后的分号!这意味着inds[i] = new Statement()行在外面循环,这没有任何意义。我也不知道你在randomCategoryStates(i++)部分做了什么。

您需要将所有这些组合成一个循环:

  for (var i = 0; i < clContext.getRowCount(); i++) {
    var category = clContext.get(i, "category");
    var statement = clContext.get(i, "statement");
    var polarity = clContext.get(i, "polarity")
    inds[i] = new Statement();
  }

但这仍然没有任何意义,因为您永远不会将这些变量传递到您的Statement课程中。所以,让我们来看看。

我只是添加一些评论:

function Statement() {
  this.x = x; //when do you ever set the value of x?
  this.y = y; //when do you ever set the value of y?
  this.cat = inds; //cat is the array that holds all statements? What??
  this.statement = statements; //statement is the statements array, but nothing is ever added to that array?
  this.polarity = polarity; //when do you ever set the value of polarity?

正如您所看到的,您在这里所做的事情并没有多大意义。你需要改变这个构造函数,以便它需要参数,然后你需要传递这些参数。像这样:

function Statement(category, polarity, statement) {
  this.category = category;
  this.statement = statement;
  this.polarity = polarity;
}

现在我们已经有了,我们可以将for循环中的行更改为:

inds[i] = new Statement(category, statement, polarity);

但这仍然没有意义。为什么你有单独的数组用于语句,类别和极性?你只是想要一个使用Statement类的实例来保存它们的数组吗?因此,让我们摆脱indspolarity变量,因为它们不能用于任何事情。

然后我们将该行更改为:

statements[i] = new Statement(category, polarity, statement);

我们还必须更改仍在使用inds变量的其他地方,但我们还有其他问题。

让我们从您的draw()功能开始:

function draw() {
  if (mouseClicked == true) {
    for (var i = 0; i < statements.length; i++) {
      statements[i].display();
    }
  }
}

所以我猜你只想在按下鼠标时显示任何内容,没有按下鼠标时什么都不显示?我不确定这是否合理,但没关系。即便如此,此代码也没有意义,因为 mouseClicked是一个函数,而不是一个变量。要确定是否按下了鼠标,您需要使用{{3}变量,你不需要== true部分。

if (mouseIsPressed) {

我不知道这两个函数应该做什么:

function mouseClicked() {
  if ((mouseX < width) && (mouseY < height)) {
    randomCategoryStates(~~random(CATEGORY));
    redraw();
    return false;
  }
}

// Function to display statements by a random category with each mouse click
function randomCategoryStates(group) {
  let idx = statements[group],
    rnd;
  while ((rnd = ~~random(QTY)) == idx);
  statements[group] = rnd;
}

有更简单的方法可以获取随机数据。我现在要删除它们,因为它们比它们值得更麻烦。我们可以稍后返回并添加随机逻辑。

现在,让我们看一下display()课程中的Statement函数:

Statement.prototype.display = function() {
  this.x += this.dx;
  this.y += this.dy;
  var cols = map(this.polarity == -1, 205, 38, 38);
  var cols = map(this.polarity == 0, 148, 0, 211);
  var cols = map(this.polarity == 1, 0, 145, 205);
  fill(cols);
  textSize(14);
  text(this.statement, this.x, this.y);
};

我们从未真正声明xydxdy变量,因此我们将它们添加到构造函数中:

  this.x = random(width);
  this.y = random(height);
  this.dx = random(-5, 5);
  this.dy = random(-5, 5);

返回display()功能,这些行没有任何意义:

  var cols = map(this.polarity == -1, 205, 38, 38);
  var cols = map(this.polarity == 0, 148, 0, 211);
  var cols = map(this.polarity == 1, 0, 145, 205);

为什么要将相同的变量声明3次?为什么要尝试将布尔值映射到数值?这没有任何意义。现在,让我们摆脱这些界限并简化你的逻辑:

  if(this.polarity == -1){
    fill(255, 0, 0);
  }
  else if(this.polarity == 1){
    fill(0, 255, 0);
  }
  else{
    fill(0, 0, 255);
  }

这将使负极性为红色,正极性为绿色,中性极性为蓝色。

现在我们有了这个,我们实际上可以运行代码。当您按住鼠标时,您将看到您的语句随机显示和移动。但是,他们会快速填满您的屏幕,因为您无法清除旧框架。 每当您要清除旧框架时,都需要调用background()函数。我们可能会在draw()函数的开始处或{{1}内部执行此操作。在for循环之前的语句。

if(mouseIsPressed)

如果您进行了所有这些更改,那么您将有一个正常工作的计划。我愿意打赌它仍然没有完全符合您的要求。 您必须开始更简单。您的代码有点混乱,而且这是尝试一次编写整个程序而不是测试小的结果一次一块。 这就是我们要求mouseIsPressed的原因,因为调试这样的事情是非常痛苦的。你需要开始将目标缩小到更小的部分。

例如,如果你现在想要这样做,那么一次只出现一个语句,重新开始,只有一个简单的示例草图,它只显示一个硬编码语句。在您尝试将其集成到主程序之前,完美地运行。如果您希望按类别排序语句,那么重新开始使用更简单的示例草图,它只显示基于类别的语句,而不需要任何额外的逻辑。这样,如果您对某些特定内容有疑问,可以发布这些小代码,这将更容易为您提供帮助。

祝你好运。