更新:没关系,我找到了强制双击的漏洞.因为按钮的轴已经被设置为"填充",所以我需要在按钮上点击两次才能变回"无填充",所以我现在所做的就是清空按钮的自轴,每次我改变 colored颜色 ,使它完美地工作.这可能不是最好的方法,但它奏效了.如果你有什么更好的办法,请告诉我.

我的方法基于这个全局变量,当我在ColorPalette中单击另一种 colored颜色 时,该变量将变为True,我将此变量放入opolateOptions中,因此当从ColorPalette调用它时,它首先运行并清除按钮的状态:

if (changedColor) {
     self.axis = "";
     changedColor = false;
} 

我正在为大学的一个绘图应用程序项目工作,我只被允许使用p5.js的香草Java脚本.我在不同的文件中有不同的构造函数,例如ColourPalette,用户在其中 Select 一种 colored颜色 (该 colored颜色 的填充在该构造函数中声明),另一个CircleTool构造函数,我在其中创建一个椭圆,当 Select 该工具时,会出现一个按钮,可以在已填充/未填充之间切换.

现在我的问题是,切换按钮一开始工作没有问题,但当我 Select 一个新的 colored颜色 ,而按钮是"未填充"时,填充内部 colored颜色 调色板再次启用,但我的按钮没有更新,所以我想到了每次我更改 colored颜色 时从CircleTool调用panateOptions()函数,因为这将重新创建处于"已填充"状态的按钮.但这样做的问题是,当我更改 colored颜色 时,我现在需要单击该按钮两次,直到未填充生效,请参见以下代码:

colored颜色 构造器:这就是我每次 Select 新 colored颜色 时调用populateOptions()函数的地方,这样我的按钮每次都会重置为fill状态

//Displays and handles the colour palette.
function ColourPalette() {
    //a list of web colour strings
    this.colours = ["black", "silver", "gray", "white", "maroon", "red", "purple",
        "orange", "pink", "fuchsia", "green", "lime", "olive", "yellow", "navy",
        "blue", "teal", "aqua"
    ];
    //make the start colour be black
    this.selectedColour = "black";

    var self = this;

    var colourClick = function() {
        //remove the old border
        var current = select("#" + self.selectedColour + "Swatch");
        current.style("border", "0");

        //get the new colour from the id of the clicked element
        var c = this.id().split("Swatch")[0];

        //set the selected colour and fill and stroke
        self.selectedColour = c;
        fill(c);
        stroke(c);
        circleTool.unselectTool();
        circleTool.populateOptions();
        //add a new border to the selected colour
        this.style("border", "2px solid blue");
    }

    //load in the colours
    this.loadColours = function() {
        //set the fill and stroke properties to be black at the start of the programme
        //running
        fill(this.colours[0]);
        stroke(this.colours[0]);

        //for each colour create a new div in the html for the colourSwatches
        for (var i = 0; i < this.colours.length; i++) {
            var colourID = this.colours[i] + "Swatch";

            //using JQuery add the swatch to the palette and set its background colour
            //to be the colour value.
            var colourSwatch = createDiv()
            colourSwatch.class('colourSwatches');
            colourSwatch.id(colourID);

            select(".colourPalette").child(colourSwatch);
            select("#" + colourID).style("background-color", this.colours[i]);
            colourSwatch.mouseClicked(colourClick)
        }

        select(".colourSwatches").style("border", "2px solid blue");
    };
    //call the loadColours function now it is declared
    this.loadColours();
}

CircleTool构造函数:这是panateOptions函数所在的位置,按钮是在这里被控制的.

//Tool to draw circles
function CircleTool() {
    this.name = "circleTool";
    this.icon = "/assets/circle.jpg";

    var startMouseX = -1;
    var startMouseY = -1;
    var drawing = false;
    this.draw = function() {
        //Function to draw the circle
        if(mouseIsPressed) {
            if(startMouseX == -1) {
                drawing = true;
                startMouseX = mouseX;
                startMouseY = mouseY;
                loadPixels();
            }    
            else {
                updatePixels();
                ellipse(startMouseX,startMouseY,dist(startMouseX,startMouseY,mouseX,mouseY));
            }        
        }
        else if(drawing) {
            drawing = false;
            startMouseX = -1;
            startMouseY = -1;
        }
    }
    //This will clear the button from the canvas when circleTool is unselected
    this.unselectTool = function() {
        updatePixels();
        //clear options
        select(".options").html("");
    };
    //adds a button and click handler to the options area. When clicked
    //toggle the fill of the circle
    this.populateOptions = function() {
        select(".options").html(
            "<button id='circleButton'>Filled Circle</button>");
        //  //click handler
        select("#circleButton").mouseClicked(function() {
            var button = select("#" + this.elt.id);            
            if (self.axis == "fill") {
                self.axis = "notFill";
                
                button.html('Filled Circle');   
                fill(colourP.selectedColour);             
            }
            else {                
                self.axis = "fill";
                self.lineOfSymmetry = width / 2;
                noFill();
                button.html('Not Filled');
            }
            
        });
    };
}

为了消除需要点击按钮两次才能使unfilled生效的问题,我试图用一个全局变量来控制所有这些filled/unfilled,但它不起作用,因为即使我用布尔值控制按钮的状态,按钮也不会更新它的状态,除非我再次调用populateOptions函数.

我只想要这个按钮来控制和切换我的圆圈的填充状态,我不确定如何处理这个问题,似乎是一个简单的问题,但不能解决它.

推荐答案

也许您可以通过查看下面的示例获得一些完成项目的 idea .该演示将基于Circle类创建一个圆形数组,然后允许用户使用ColorPicker更改每个圆形的 colored颜色 .绘制圆圈的方法是在按住Shift键的情况下拖动鼠标以创建一个以圆圈为中心的边界正方形.随后的点击测试是通过判断鼠标坐标来查看它们是否落在边框内(出于演示目的而显示).其他技术也可以用来判断鼠标指针是否落在圆圈内,例如毕达哥拉斯定理.要使用演示,请使用以下步骤:

  1. 首先点击窗口以激活它.
  2. 按住Shift键,然后单击窗口位置并拖动鼠标以创建一个正方形.松开鼠标按钮后,圆圈将添加到数组中并显示.
  3. 转到ColorPicker并 Select 所需的 colored颜色 .
  4. 单击要 Select 的圆.
  5. 单击ColorPicker旁边的按钮进行更改.

第二个示例显示如何构造切换按钮.

let crc = [];
let shiftDown = false;
let x, y, x1, y1;
let w, h;
let selectedCrc;
let myPicker;

class Circle {
  constructor(xpos, ypos, diam, fillColor) {
    this.x = xpos;
    this.y = ypos;
    this.d = diam;
    this.bkgrnd = fillColor;
    this.selected = false;
  }

  display() {
    for (let i = 0; i < crc.length; i++) {
      fill(crc[i].bkgrnd);
      circle(crc[i].x, crc[i].y, crc[i].d);
    }
  }
}

function setup() {
  createCanvas(800, 800);
  background(209);
  myPicker = createColorPicker("deeppink");
  myPicker.position(width - 100, 10);
  let button = createButton("change color of selected circle");
  button.position(width - 320, 15);
  button.mousePressed(() => {
    if (crc[selectedCrc].selected) {
      crc[selectedCrc].bkgrnd = myPicker.color();
      fill(crc[selectedCrc].bkgrnd);
      circle(crc[selectedCrc].x, crc[selectedCrc].y, crc[selectedCrc].d);
    }
  });
}

function draw() {
  for (let i = 0; i < crc.length; i++) {
    crc[i].display();
  }
}

function mousePressed() {
  if (shiftDown) {
    x = mouseX;
    y = mouseY;
  }
  print("x:" + mouseX + ",y:" + mouseY);
  for (let i = 0; i < crc.length; i++) {   
    // Reconstruct bounding rectangle from circle coordinates and diameter
    if (
      mouseX >= crc[i].x - crc[i].d / 2 &&
      mouseX <= crc[i].x + crc[i].d / 2 &&
      mouseY >= crc[i].y - crc[i].d / 2 &&
      mouseY <= crc[i].y + crc[i].d / 2
    ) {
      print("isInCircleRect =", i);
      crc[i].selected = true;
      selectedCrc = i;
      print("selectedCircle id =", selectedCrc);
    } else {
      crc[i].selected = false;
      print("unselectedCircle =", i);
    }
  }
}

function mouseDragged() {
  if (shiftDown) {
    x1 = mouseX;
    y1 = mouseY;

    w = x1 - x;
    h = y1 - y;
  }
}

function mouseReleased() {
  if (shiftDown) {
    x1 = mouseX;
    y1 = mouseY;
    diam = x1 - x;
    w = x1 - x;
    h = y1 - y;
    // center circle in bounding rectangle
    crc.push(new Circle(x + w / 2, y + w / 2, diam, color(255)));
    // display bounding rectangle
    noFill();
    rect(x, y, w, w);
  }
  diam = 0; // reset to zero
  print(crc);
}

function keyPressed() {
  if (keyCode == SHIFT) {
    shiftDown = true;
  }
  print("shiftDown = ", shiftDown);
}

function keyReleased() {
  if (keyCode == SHIFT) {
    shiftDown = false;
  }
  print("shiftDown = ", shiftDown);
}

Toggle Button Demo

var btnState = false;
let colorPicker;

function setup() {
  createCanvas(400, 400);
  background(209);
  fill(0);
  circle(200, 200, 100);
  myPicker = createColorPicker('deeppink');
  myPicker.position(110, 10);
  let button = createButton("fill/unfill");
  button.position(20, 10);
  // Use button to change circle's color.
  button.mousePressed(() => {
    if (!btnState) {
      btnState = true;
      fill(255);
      circle(200, 200, 100);
    } else {
      btnState = false;
      fill(myPicker.value());
      circle(200, 200, 100);
    }
  });
}

function draw() {
}

Javascript相关问答推荐

foreach循环中的Typescript字符串索引

容器如何更改默认插槽中子项的显示?

获取表格的左滚动位置

如何访问Json返回的ASP.NET Core 6中的导航图像属性

过滤对象数组并动态将属性放入新数组

django无法解析余数:[0] from carray[0]'

有没有可能使滑动img动画以更快的速度连续?

函数返回与输入对象具有相同键的对象

XSLT处理器未运行

在执行异步导入之前判断模块是否已导入()

WP Bootstrap NavWaker:下拉菜单一次打开所有下拉菜单

如何在Node.js中排除导出的JS文件

如何在和IF语句中使用||和&;&;?

将Auth0用户对象存储在nextjs类型脚本的Reaction上下文中

P5JS-绘制不重叠的圆

bootstrap S JS赢得了REACT中的函数/加载

P5play SecurityError:无法从';窗口';读取命名属性';Add';:阻止具有源的帧访问跨源帧

需要刷新以查看Mern堆栈应用程序中的更改

如何调整下拉内容,使其不与其他元素重叠?

react :图表负片区域不同 colored颜色