You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

p5.js绘图应用圆形填充切换按钮双击异常问题及优化咨询

圆形工具填充状态同步问题与优化探讨

更新说明

已定位双击问题的根源:populateOptions函数中按钮的axis初始值为"fill",导致切换颜色后需双击才能切回"nofill"状态。目前通过切换颜色时清空按钮的self.axis解决了问题,但不确定是否为最优方案,寻求更合理的实现方式。

临时实现思路

通过全局变量changedColor标记颜色切换状态,在populateOptions中加入以下逻辑:

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

项目背景

开发大学绘图应用,仅允许使用原生JavaScript与p5.js,采用分文件构造函数设计:

  • ColourPalette构造函数:提供颜色选择功能,选中颜色时设置填充与描边,并调用circleTool.populateOptions()重置按钮状态;
  • CircleTool构造函数:实现圆形绘制功能,选中时生成可切换填充/无填充状态的按钮。

初始问题

当按钮处于「无填充」状态时选择新颜色,ColourPalette会重新启用填充,但按钮状态未同步更新。调用populateOptions()重建按钮后,出现切换颜色后需双击按钮才能切换到无填充状态的问题。曾尝试用全局变量控制状态,但因按钮需重建才能更新状态而无效。

相关代码

ColourPalette构造函数代码

//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构造函数代码

//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');
            }
            
        });
    };
}

内容的提问来源于stack exchange,提问作者AlexSt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 05:03:12