简体   繁体   English

如何创建可以修改其原始函数调用的对象

[英]How to create an object that can modify its original function call

I am trying to create a button object which can run a class function (show() in this case) that will change the button's color.我正在尝试创建一个按钮对象,该对象可以运行将更改按钮颜色的类函数(在本例中为 show())。 The problem is I can only do this by calling show() repeatedly each time the color changes.问题是我只能通过每次颜色改变时重复调用 show() 来做到这一点。 The result is a ton of buttons being drawn on the screen, but I would like to only draw the button once.结果是在屏幕上绘制了大量按钮,但我只想绘制一次按钮。 Is there a way around this?有没有解决的办法? (Note: I have the button x position increasing to show the buttons being created) (注意:我让按钮 x 位置增加以显示正在创建的按钮)

 let canvas = document.getElementById("JScanvas"), c = canvas.getContext("2d"); let mousePosition = { x: 0, y: 0 }; // ignore, a few functions I might need for this to run function buildRect(fillColor, outlineColor, outlineSize, x, y, w, h) { if (fillColor && outlineColor) { c.beginPath(); c.rect(x, y, w, h); c.fillStyle = fillColor; c.fill(); c.lineWidth = outlineSize; c.strokeStyle = outlineColor; c.stroke(); } else if (fillColor && !outlineColor) { c.beginPath(); c.rect(x, y, w, h); c.fillStyle = fillColor; c.fill(); } else if (!fillColor && outlineColor) { c.beginPath(); c.rect(x, y, w, h); c.lineWidth = outlineSize; c.strokeStyle = outlineColor; c.stroke(); } } function write(str, x, y, color, txtSize, font) { let size = txtSize.toString(); c.font = size + "px" + " " + font; c.fillStyle = color; c.fillText(str, x, y); } // end of useless functions class button { // mouse is {canvs: canvas, mClicked: t/f, mPosition: mousePosition{x, y}} constructor(name, order, btnColor, x, y, w, h, txtColor, txtSize, m, f) { this.name = name; this.order = order; this.btnColor = btnColor; this.x = x; this.y = y; this.w = w; this.h = h; this.txtColor = txtColor; this.txtSize = txtSize; this.m = m; this.f = f; //change color when mouse over button this.m.canvs.addEventListener("mousemove", (event) => { console.log("hello there"); if (this.x < this.m.mPosition.x && this.m.mPosition.x < this.x + this.w && this.y < this.m.mPosition.y && this.m.mPosition.y < this.y + this.h) { if (this.btnColor[0] != "grey") { this.btnColor[0] = "grey"; this.x += 50; this.show(); } else { this.btnColor[0] = "red"; this.x += 50; this.show(); } } }); } show() { if (!this.btnColor[0] && !this.btnColor[0]) { buildRect("transparent", false, 1, this.x, this.y, this.w, this.h); } else if (!this.btnColor[0]) { buildRect(false, this.btnColor[1], 1, this.x, this.y, this.w, this.h); } else if (!this.btnColor[1]) { buildRect(this.btnColor[0], false, 1, this.x, this.y, this.w, this.h); } else { buildRect(this.btnColor[0], this.btnColor[1], 1, this.x, this.y, this.w, this.h); } c.fillStyle = this.txtColor; let theString = String(this.txtSize) + "px Arial"; c.font = theString; let width = Math.round(c.measureText(c.fillText(this.name, -1000, 0)).width); if (width > this.w) { let center = this.x + (this.w / 2); let newSize = this.w / width; c.font = String(this.txtSize * newSize); let newWidth = Math.round(newSize * width); c.textAlign = "center"; c.textBaseline = "middle"; c.fillText(this.name, this.x + (this.w / 2), this.y + (this.h / 2)); } else { c.textAlign = "center"; c.textBaseline = "middle"; c.fillText(this.name, this.x + (this.w / 2), this.y + (this.h / 2)); } } clickButton(mouseX, mouseY) { if (mouseX >= this.x && mouseX <= this.x + this.w && mouseY >= this.y && mouseY <= this.y + this.h) { return true; } else { return false; } } runf() { this.f(); } } //getting mouse position function getMousePos(canvas, evt) { const rect = canvas.getBoundingClientRect(); return { x: evt.clientX - rect.left, y: evt.clientY - rect.top }; } canvas.addEventListener("mousemove", (evt) => { let r = getMousePos(canvas, event); mousePosition.x = rx, mousePosition.y = ry; }); let mouse = { canvs: canvas, mClicked: false, mPosition: mousePosition }; //button object to call: ("red" is the color of the button I am trying to change to grey) let cookie = new button("cookie", 1, ["red", false], 50, 100, 150, 50, "black", 30, mouse, 2); cookie.show();
 <!DOCTYPE html> <html> <head> <title>Playground</title> </head> <body> <canvas width="1500" height="1500" id="JScanvas"></canvas> </body> </html>

I think you have over complicated your code...我认为您的代码过于复杂...

Here is a simple example where we change the color when the mouse is over the rectangle这是一个简单的例子,当鼠标在矩形上时我们改变颜色

 let canvas = document.getElementById("canvas") let c = canvas.getContext("2d"); class button { constructor(color, x, y, w, h) { this.color = color; this.x = x; this.y = y; this.w = w; this.h = h; } draw(mouse) { c.beginPath(); c.rect(this.x, this.y, this.w, this.h); if (mouse.x >= this.x && mouse.x <= this.x + this.w && mouse.y >= this.y && mouse.y <= this.y + this.h) { c.fillStyle = "gray"; } else { c.fillStyle = this.color; } c.fill(); } } function getMousePos(evt) { if (!evt) return { x: 0, y: 0 } const rect = canvas.getBoundingClientRect(); return { x: evt.clientX - rect.left, y: evt.clientY - rect.top }; } let buttons = [] buttons.push(new button("red", 50, 100, 40, 20)) buttons.push(new button("blue", 100, 50, 40, 20)) canvas.addEventListener("mousemove", mainDraw); function mainDraw(evt) { let mouse = getMousePos(evt) c.clearRect(0, 0, canvas.width, canvas.height); buttons.forEach((btn) => { btn.draw(mouse) }) } mainDraw()
 <canvas id="canvas" width="150" height="150"></canvas>

As you can see there is only one addEventListener and it is outside the class button, the logic is simple, we clean the entire canvas and draw everything on every event... that is how games do it, I'm sure that will work for what you are doing too.正如你所看到的,只有一个 addEventListener 并且它在类按钮之外,逻辑很简单,我们清理整个画布并在每个事件上绘制所有内容......游戏就是这样做的,我相信这会起作用你也在做什么。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM