javascript - 画布事件监听器切换参数状态
问题描述
您好我正在尝试向画布元素添加交互性。下面你可以看到电动帆布。我想知道如何在开关上添加鼠标单击事件侦听器以打开和关闭它。是否可以在单击时将开关打开参数从 true 更改为 false ?我可以定义一个特定的位置并在该位置捕获鼠标单击事件,但是任何人都应该使用这个电路来创建他的电路,所以不可能给开关一个预定义的位置
/*Basic Circuit symbol toolset, still alot missing
credit to: https://stackoverflow.com/users/434421/mindoftea*/
class Circuit {
constructor(name="canvas", ix=50, iy=50) {
this.canvas = document.getElementById(name);
this.ctx = canvas.getContext("2d");
this.d = 0;
this.ix = ix;
this.iy = iy;
this.cx = ix;
this.cy = iy;
this.dx = 1;
this.dy = 0;
this.px = 0;
this.py = 0;
this.pd = 0;
this.pdx = 0;
this.pdy = 0;
this.ctx.beginPath();
this.ctx.moveTo(this.cx, this.cy);
}
start(ix=10, iy=10) {
this.d = 0;
this.ix = ix;
this.iy = iy;
this.cx = ix;
this.cy = iy;
this.dx = 1;
this.dy = 0;
this.px = 0;
this.py = 0;
this.pd = 0;
this.pdx = 0;
this.pdy = 0;
this.ctx.beginPath();
this.ctx.moveTo(this.cx, this.cy);
}
finish(close=true) {
if (close) {
this.ctx.lineTo(this.ix, this.iy);
}
this.ctx.stroke();
}
save() {
this.px = this.cx;
this.py = this.cy;
this.pd = this.d;
this.pdx = this.dx;
this.pdy = this.dy;
}
restore() {
this.cx = this.px;
this.cy = this.py;
this.d = this.pd;
this.dx = this.pdx;
this.dy = this.pdy;
this.ctx.moveTo(this.cx, this.cy);
}
newelement(len=50) {
this.ctx.save();
this.ctx.translate(this.cx, this.cy);
this.ctx.rotate(this.d*Math.PI/2);
if (this.dx < -0.5 ) {
this.ctx.rotate(Math.PI);
this.ctx.translate(-len, 0);
}
this.ctx.moveTo(0,0);
}
endelement(len=50) {
this.ctx.restore();
this.cx += this.dx * len;
this.cy += this.dy * len;
this.ctx.moveTo(this.cx,this.cy);
}
wire(len=50) {
this.newelement(len);
this.ctx.lineTo(len,0);
this.endelement(len);
}
drawWire(len=50) {
this.cx += this.dx * len;
this.cy += this.dy * len;
this.ctx.lineTo(this.cx, this.cy);
}
power(len=50, n=2, label="") {
var space = 5;
var wl = (len - (2*n-1)*space)/2;
this.newelement(len);
this.ctx.lineTo(wl,0);
this.ctx.fillText(label, wl, 4*space);
while (n--) {
this.ctx.moveTo(wl+space*(2*n+1), -space);
this.ctx.lineTo(wl+space*(2*n+1), space);
this.ctx.moveTo(wl+space*(2*n), -2*space);
this.ctx.lineTo(wl+space*(2*n), 2*space);
}
this.ctx.moveTo(len-wl, 0);
this.ctx.lineTo(len,0);
this.endelement(len);
}
drawPower(len=50, n=2, label="") {
var space = 5;
var wl = (len - (2*n-1)*space)/2;
this.drawWire(wl);
this.ctx.fillText(label, this.cx + 30 * this.dy, this.cy + 30 * this.dx);
while (n--) {
this.ctx.moveTo(this.cx + 15 * this.dy, this.cy + 15 * this.dx);
this.ctx.lineTo(this.cx - 15 * this.dy, this.cy - 15 * this.dx);
this.cx += this.dx * space;
this.cy += this.dy * space;
this.ctx.moveTo(this.cx + 2*space * this.dy, this.cy + 2*space * this.dx);
this.ctx.lineTo(this.cx - 2*space * this.dy, this.cy - 2*space * this.dx);
if (n != 0) {
this.cx += this.dx * space;
this.cy += this.dy * space;
}
}
this.ctx.moveTo(this.cx, this.cy);
this.drawWire(wl);
}
capacitor(len=50, label="") {
var space=5;
var hh = space*1.8;
var cl = (len-space)/2;
this.newelement(len);
this.ctx.lineTo(cl,0);
this.ctx.fillText(label, cl, hh+10)
this.ctx.moveTo(cl, -hh);
this.ctx.lineTo(cl, hh);
this.ctx.moveTo(cl+space, -hh);
this.ctx.lineTo(cl+space, hh);
this.ctx.moveTo(cl+space, 0);
this.ctx.lineTo(len,0);
this.endelement(len);
}
drawCapacitor(len=50, label="") {
var space=5;
var cl = (len-space)/2;
this.drawWire(cl);
this.ctx.fillText(label, this.cx + 20 * this.dy, this.cy + 20 * this.dx )
this.ctx.moveTo(this.cx + 10 * this.dy, this.cy + 10 * this.dx);
this.ctx.lineTo(this.cx - 10 * this.dy, this.cy - 10 * this.dx);
this.cx += this.dx * space;
this.cy += this.dy * space;
this.ctx.moveTo(this.cx + 10 * this.dy, this.cy + 10 * this.dx);
this.ctx.lineTo(this.cx - 10 * this.dy, this.cy - 10 * this.dx);
this.ctx.moveTo(this.cx, this.cy);
this.drawWire(cl);
}
inductor(len=50, n=4, label="") {
var xs, ys;
xs = 1;
ys = 2;
var space = 6;
var wl = (len-(n+1)*space)/2;
this.newelement(len);
this.ctx.lineTo(wl, 0);
this.ctx.fillText(label, wl, 25);
this.ctx.scale(xs, ys);
while (n--) {
this.ctx.moveTo(wl+space*(n+2), 0);
this.ctx.arc(wl+space*(n+1), 0, space, 0, Math.PI, 1);
this.ctx.moveTo(wl+space*(n), 0);
if (n>0) {
this.ctx.arc(wl+space*(n+1/2), 0, space/2, Math.PI,0, 1);
}
}
this.ctx.scale(1/xs, 1/ys);
this.ctx.moveTo(len-wl,0);
this.ctx.lineTo(len,0);
this.endelement(len);
}
drawInductor(len=50, n=4, label="") {
var xs, ys;
xs = 1 + Math.abs(this.dy);
ys = 1 + Math.abs(this.dx);
var space = 6;
var wl = (len-n*space)/2;
this.drawWire(len);
this.ctx.fillText(label, this.cx+(10+space)*this.dy, this.cy+(10+space)*this.dx)
this.cx += this.dx * space;
this.cy += this.dy * space;
this.ctx.scale(xs, ys);
while (n--) {
//ctx.moveTo(x/xs+5*Math.abs(dx),y/ys+5*dy);
this.ctx.moveTo(this.cx / xs + space * Math.abs(this.dx), this.cy / ys + space * this.dy);
this.ctx.arc(this.cx / xs, this.cy / ys, space, Math.PI / 2 * this.dy, Math.PI + Math.PI / 2 * this.dy, 1);
this.cx += space * this.dx;
this.cy += space * this.dy;
if (n != 0) {
if (this.dx >= 0) {
this.ctx.moveTo(this.cx / xs - space * this.dx, this.cy / ys - space * this.dy);
}
this.ctx.moveTo(this.cx / xs - space * this.dx, this.cy / ys - space * this.dy);
this.ctx.arc(this.cx / xs - space / 2 * this.dx, this.cy / ys - space / 2 * this.dy, 1.5, Math.PI + Math.PI / 2 * this.dy, Math.PI / 2 * this.dy, 1);
}
}
this.ctx.moveTo(this.cx / xs - 1.75 * this.dx, this.cy / ys - 1.75 * this.dy);
this.ctx.scale(1 / xs, 1 / ys);
this.ctx.lineTo(this.cx, this.cy);
this.drawWire(len);
}
trimmer(len=50, label="") {
//capacitor
var space=5;
var hh = space * 1.8;
var cl = (len-space)/2;
var size=1.4*hh;
var psize = size*Math.cos(Math.PI/4);
this.newelement(len);
//draw capacitor
this.ctx.moveTo(0,0);
this.ctx.lineTo(cl,0);
this.ctx.fillText(label, cl, hh+10)
this.ctx.moveTo(cl, -hh);
this.ctx.lineTo(cl, hh);
this.ctx.moveTo(cl+space, -hh);
this.ctx.lineTo(cl+space, hh);
this.ctx.moveTo(cl+space, 0);
this.ctx.lineTo(len,0);
var x = len/2-psize;
var y = 0+psize;
this.ctx.moveTo(x,y);
var x1 = len/2+psize;
var y1 = 0-psize;
this.ctx.lineTo(x1,y1);
//short line
psize /= 3;
x = x1-psize;
y = y1-psize;
this.ctx.moveTo(x,y);
x = x1+psize;
y = y1+psize;
this.ctx.lineTo(x,y);
this.endelement(len);
}
drawTrimmer(len=50, label="") {
var size=12;
var psize = size*Math.cos(Math.PI/4);
var x = this.cx+len/2*this.dx;
var y = this.cy+len/2*this.dy;
var x1 = x-psize*Math.abs(this.dx-this.dy);
var y1 = y+psize*Math.abs(this.dy-this.dx);
this.ctx.moveTo(x1,y1);
x1 = x+psize*Math.abs(this.dx-this.dy);
y1 = y-psize*Math.abs(this.dy-this.dx);
this.ctx.lineTo(x1,y1);
//short line
psize /= 3;
x = x1-psize*Math.abs(this.dx-this.dy);
y = y1-psize*Math.abs(this.dy-this.dx);
this.ctx.moveTo(x,y);
x = x1+psize*Math.abs(this.dx-this.dy);
y = y1+psize*Math.abs(this.dy-this.dx);
this.ctx.lineTo(x,y);
this.ctx.moveTo(this.cx, this.cy);
this.drawCapacitor(len, label);
}
resistor(len=50, n=5, style=1, label="") {
var size = 5;
var wl = (len-(n+1)*size)/2;
this.newelement(len);
this.ctx.lineTo(wl,0);
this.ctx.fillText(label, wl, size+15);
if (style == 1) {
var x = wl+size;
var y = -size;
while (n--) {
this.ctx.lineTo(x,y);
this.ctx.lineTo(x,y+2*size);
x += size;
}
this.ctx.lineTo(len-wl, 0);
} else {
this.ctx.rect(wl,-size, size*(n+1), 2*size);
}
this.ctx.moveTo(len-wl, 0);
this.ctx.lineTo(len,0);
this.endelement(len);
}
drawResistor(len=50, n=5, style=1, label="") {
var size = 5;
var wl = (len-(n+1)*size)/2;
this.drawWire(wl);
this.ctx.fillText(label, this.cx+this.dy*(size+15), this.cy+this.dx*(size+15));
if (style == 1) {
this.cx += this.dx * size;
this.cy += this.dy * size;
while (n--) {
this.ctx.lineTo(this.cx - size * this.dy, this.cy - size * this.dx);
this.ctx.lineTo(this.cx + size * this.dy, this.cy + size * this.dx);
this.cx += size * this.dx;
this.cy += size * this.dy;
}
this.ctx.lineTo(this.cx, this.cy);
} else {
this.ctx.rect(this.cx-size*this.dy, this.cy-size*this.dx, size*(n+1)*this.dx+2*size*this.dy, size*(n+1)*this.dy+2*size*this.dx);
this.cx += this.dx * size*(n+1);
this.cy += this.dy * size*(n+1) ;
this.ctx.moveTo(this.cx, this.cy);
}
this.drawWire(wl);
}
drawSwitch(len=50, open=true, label="S") {
var size=len/2;
var wl = (len-size)/2;
this.drawWire(wl);
var x = this.cx;
var y = this.cy;
this.ctx.fillText(label, x - 15*this.dy, y+15*this.dx);
//this.ctx.arc(x,y,2, 0, Math.PI*2);
x += size*this.dx;
y += size*this.dy;
if (open) {
this.ctx.lineTo(x-size/2*this.dy, y-size/2*this.dx);
} else {
this.ctx.lineTo(x, y);
}
this.ctx.arc(this.cx, this.cy, 2, 0, Math.PI*2);
this.ctx.moveTo(x, y);
this.ctx.arc(x,y, 2,0, Math.PI*2);
this.ctx.moveTo(x, y);
this.cx = x;
this.cy = y;
this.drawWire(wl);
}
switch(len=50, open=true, label="S") {
var size=len/2;
var circle = 2;
var wl = (len-size)/2;
this.newelement(len);
this.ctx.lineTo(wl,0);
this.ctx.moveTo(wl+circle,0);
this.ctx.fillText(label, wl+circle, circle+15);
this.ctx.arc(wl+circle,0, circle, 0, Math.PI*2);
this.ctx.moveTo(wl+size-circle, 0);
this.ctx.arc(wl+size-circle,0,circle, 0, Math.PI*2);
this.ctx.moveTo(wl+circle,-circle);
if (open) {
this.ctx.lineTo(wl+size, -circle-size/2);
} else {
this.ctx.lineTo(wl+size, -circle);
}
this.ctx.moveTo(len-wl,0);
this.ctx.lineTo(len,0);
this.endelement(len);
}
turnClockwise() {
this.d++;
this.dx = Math.cos(Math.PI/2 * this.d);
this.dy = Math.sin(Math.PI/2 * this.d);
}
turnCounterClockwise() {
this.d--;
this.dx = Math.cos(Math.PI/2 * this.d);
this.dy = Math.sin(Math.PI/2 * this.d);
}
}
var cc = new Circuit("canvas",100, 100);
cc.ctx.lineWidth = 2;
cc.start(100, 300);
cc.wire();
cc.power(50, 2, "E");
cc.resistor(50,4,1,"R");
cc.switch(50,false)
//cc.wire();
//cc.turnCounterClockwise();
cc.capacitor(50,"C");
cc.trimmer(50,"T");
cc.wire();
cc.turnClockwise();
//cc.wire();
cc.trimmer(50,"T");
cc.inductor(50, 4, "Inductor");
cc.wire();
cc.turnClockwise();
//cc.wire();
cc.capacitor(50,"CC");
//cc.trimmer(50,"T2");
cc.inductor(50,5,"Ind");
//cc.wire();
cc.resistor(50,4,2,"R");
cc.switch();
cc.save();
cc.turnCounterClockwise();
cc.wire(20);
cc.turnClockwise();
cc.resistor(50,6,1,"R6");
cc.turnClockwise();
cc.wire(20);
cc.restore();
cc.turnClockwise();
cc.wire(20);
cc.turnCounterClockwise();
cc.resistor(50,5,1,"R5");
cc.turnCounterClockwise();
cc.wire(20);
cc.turnClockwise();
cc.wire();
cc.resistor(50,4,1,"R");
cc.turnClockwise();
cc.wire();
//cc.drawSwitch(50,false, "S3");
cc.power(50, 1, "E2");
cc.finish();
cc.start(100,250);
cc.wire();
cc.capacitor();
cc.turnClockwise();
cc.wire(20);
cc.turnCounterClockwise();
cc.capacitor();
cc.turnCounterClockwise();
cc.wire(20);
cc.save();
cc.wire(20);
cc.turnCounterClockwise();
cc.capacitor();
cc.turnCounterClockwise();
cc.wire(20);
cc.restore();
cc.turnClockwise();
cc.wire();
cc.turnCounterClockwise();
cc.wire(20);
cc.switch();
cc.wire(20);
cc.turnCounterClockwise();
cc.resistor();
cc.wire();
cc.trimmer();
cc.inductor();
cc.turnCounterClockwise();
cc.power();
cc.finish();
<canvas style="position:fixed;top:0;left:0;border:1px;" width="500" height="500" id="canvas">
解决方案
- 为您的交换机创建一个注册表。它存储边界框和状态。
- 计算每个开关在创建时的位置和大小(这样您就可以获得边界框的 x1,y1 和 x2,y2)。
- 在创建时通过“注册”方法将每个交换机输入到注册表中。
- 为画布创建 Click 或 MouseUp 处理程序。在 Click 或 MouseUp 时,通过“handleClick”方法将鼠标的位置报告给注册表。
- 如果报告给注册表的鼠标位置在开关的边界框内,请切换该开关(图形和功能)。
像这样的东西:
class SwitchRegister {
var x1, x2, y1, y2; // float
var state; // boolean
constructor(x1, y1, x2, y2, state) {
this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2;
this.state = new Boolean(state);
}
}
class SwitchRegistry {
var registers; // array of SwitchRegister
register(x1, y1, x2, y2, state) {
this.registers[this.registers.length] = new SwitchRegister(x1, y1, x2, y2, state);
}
handleClick(x, y) {
for (i = 0; i < this.registers.length; i++) {
if (x >= this.registers[i].x1 && x <= this.registers[i].x2
&& y >= this.registers[i].y1 && y <= this.registers[i].y2) {
this.registers[i].state = !this.registers[i].state; // toggle state
// redraw the switch
// toggle its function within the sim
}
}
}
}
推荐阅读
- optimization - 如何减少二进制变量整数线性规划的总和
- c# - 如何在 ASP.NET Core 的 Startup.cs 中注册 RoleManager
- r - ggplot - 面板边框交替黑白矩形
- apache-kafka - 如何使用kafka和faust检查是否在给定时间段内发送了新记录
- django - Django将对象传递给新模板
- jenkins - OWASP ZAP 无法测试 API
- database - PHPSpreadsheet - 如何从 PHPSpreadsheet 创建一个 zip 文件?
- android - 选择 Android 库的构建变体的 Gradle 脚本
- sql - 插入覆盖目录的问题
- ios - Swift curl --用户帖子