gpt4 book ai didi

javascript - 如何在一个 Canvas 上启用绘制和删除多个元素?

转载 作者:可可西里 更新时间:2023-11-01 13:25:39 28 4
gpt4 key购买 nike

我正在尝试为乒乓球运动图形编写生成器。我希望它为练习的每个集会显示一个表格,上面有箭头显示球的移动路径和比赛区域的矩形。

现在它看起来像这样:https://codepen.io/graNite/pen/grqXOo

您可以添加新表格,删除最后一个表格,并在第一个表格的同一 Canvas 层上绘制两个固定箭头。

我想要启用的是通过单击并拖动在每个表上绘制箭头*,然后右键单击它们将其删除。

*(就像它们是在 drawArrows 函数中绘制的一样)

执行此操作的最佳方法是什么?

我已经为箭头实现了一个 Canvas 层,甚至可以为每个表上的每个箭头都这样做,但是如果我右键单击它以删除它,我如何访问中间层中的箭头?

HTML

<button onclick="addTable()">Add table</button>
<button onclick="removeTable()">Remove table</button>
<button onclick="drawArrow(50, 50, 150, 250)">Draw arrow</button>
<button onclick="drawArrow(50, 300, 180, 20)">Draw arrow2</button>
</br>
<div id="tables">
</div>

CSS

body {
background-color: #982439;
}

#table {
padding: 10px;
}

canvas {
position: absolute;
}

JS

function drawTable(table) {
"use strict";
var draw = table.getContext("2d");
draw.shadowBlur = 20;
draw.shadowColor = 'rgba(0,0,0,0.3)'; // shadow
draw.fillStyle = "#2e3f73"; // table
draw.fillRect(35.25, 20, 152.5, 274);
draw.fillStyle = "#ffffff"; // lines
draw.fillRect(111.35, 20, 0.3, 274); // middle line
draw.fillRect(35.25, 20, 2, 274); // lift side
draw.fillRect(185.75, 20, 2, 274); // right side
draw.fillRect(35.25, 20, 152.5, 2); // top base line
draw.fillRect(35.25, 292, 152.5, 2); // bottom base line
draw.fillRect(20, 156, 183, 2); // net
}

function addTable() {
"use strict";
var container = document.createElement("div"),
table = document.createElement("canvas"),
arrowLayer = document.createElement("canvas"),
width = 223,
height = 314;


container.appendChild(table);
container.appendChild(arrowLayer);
container.style.width = width + "px";
container.style.height = height + "px";
container.style.display = "inline-block";
document.getElementById("tables").appendChild(container);

table.width = width;
table.height = height;
table.className = "table";
table.style.zIndex = "0";
drawTable(table);

arrowLayer.width = width;
arrowLayer.height = height;
arrowLayer.className = "arrow";
arrowLayer.style.zIndex = "1";
arrowLayer.id = "arrow1";
}

function removeTable() {
"use strict";
var child = document.getElementById("tables").lastChild;
child.parentNode.removeChild(child);
}

function drawArrow(start_x, start_y, end_x, end_y) {
"use strict";
    var draw = document.getElementById('arrow1').getContext('2d'),
angle = Math.atan((end_y - start_y) / (end_x - start_x)),
length = Math.sqrt(Math.pow((end_x - start_x), 2) + Math.pow((end_y - start_y), 2));

// set colors and style
draw.strokeStyle = "#ffb900";
draw.fillStyle = "#ffb900";
draw.lineWidth = 9;

// draw arrow line
draw.beginPath();
draw.translate(start_x, start_y);
draw.moveTo(0, 0);
draw.rotate(angle);
draw.lineTo(length - 23, 0); // note: arrowhead is 24px long and total arrow is line+head
draw.stroke();
draw.moveTo(-start_x, -start_y);

// draw arrow head
draw.beginPath();
draw.moveTo(length, 0);
draw.lineTo(length - 24, -7.5); // ^ see note above
draw.lineTo(length - 24, 7.5);
draw.fill();

//reset context
draw.rotate(-angle);
draw.moveTo(-start_x, -start_y);
draw.translate(-start_x, -start_y);
}

最佳答案

良好的界面设计

高质量的界面不应该有丑陋的按钮,它应该直观易用。应该始终有反馈(光标、突出显示、翻转效果)。这些效果不是为了展示,而是为了提供用户与应用程序交互所需的信息。因此,FX 不必是主要的,只要足以让用户看到一切正常,什么是可点击的,什么是不可点击的。

我本来打算在没有帮助的情况下添加它,因为它应该有意义,但我已经添加了帮助以防万一。我们对界面的使用都有不同的方法。

更新:我添加了更多代码。现在仅在使用帮助功能之前显示帮助。一旦使用帮助不显示。

通过代码在我认为需要的地方(基本上所有地方)添加了注释

代码

表在数组 tableArray 中。使用返回表对象的 addTable() 添加表。表默认为非事件 table.active=false。要激活,请在表格上单击鼠标或 table.active = true; table.draw(); 箭头在数组 table.arrows 中为 {x:?,y?,xx:?,yy:?,highlight:false} 删除使用数组拼接或通过接口(interface)。要删除表格,请将其停用 table.active = false;(或单击关闭)它将保留在 DOM 中,直到调用 updateTables()。 (当用户鼠标点击更新关闭时自动调用)

总会有一个可见的非事件表,可用于添加事件表。

数组中的每个表都有完成其任务所需的一切。鼠标事件、渲染事件、关闭等

每个表格都以全帧速率呈现(当它具有内部鼠标焦点时),因此您可以根据需要添加漂亮的动画。当鼠标不在 Table 上时,它不会更新,除非您调用 table.draw() 函数。

代码有点乱,有点失控。常量定义了大多数东西(在代码的顶部)。表格、关闭图标和空表格是预呈现的。根据需要呈现箭头和帮助。

使用

单击空表以添加(激活)。单击事件表关闭图标以关闭。单击拖动添加箭头,在箭头附近单击鼠标右键删除。鼠标附近的箭头将突出显示。

Note The number of tables has no restriction. This is not a good idea and you should limit the number of tables. Also there is a bit of a layout issue when added tables cause page scroll bars to appear. Removing tables does not revert to what was. As I do not know what you want I left that for you to sort out.

Also added GLOBAL_SCALE const that is applied to all constants just for the fun of it so it is a little smaller that the original

// contains an array of tables.
var tableArray = [];

// App constants all up top
const GLOBAL_SCALE = 0.7;
const SHOW_HELP = true; // set to false to have the help turned off
const SHADOW = 'rgba(0,0,0,0.8)';
const WHITE = "white";
const TABLE_REFRESH_DELAY = 50; // Time in millisecond befor updating DOM for table add and remove
const FONT = {
face : "px Arial",
size : Math.max(10,18 * GLOBAL_SCALE),
fill : WHITE,
};
const TABLE = {
width : 223 * GLOBAL_SCALE, // size of table
height : 314 * GLOBAL_SCALE,
tables : document.getElementById("tables"),
image : { // table image styles
shadow : SHADOW,
shadowBlur : 20 * GLOBAL_SCALE,
fill : "#2e3f73",
lines : WHITE,
font : FONT,
cursor : "default",
},
empty : { // empty table styles
inset : 30 * GLOBAL_SCALE, // amount box is inset
lines : 'rgba(255,255,255,0.5)',
lineWidth : 8 * GLOBAL_SCALE,
shadow : SHADOW,
shadowBlur : 20 * GLOBAL_SCALE,
font : FONT,
cursor : "pointer",
highlightAmount : 0.3, // amount to highlight empty table when mouse over 0 none 1 full
},
arrow : { // arrow styles
width : 15 * GLOBAL_SCALE, // arrow width
shadow : SHADOW,
shadowBlur : 10 * GLOBAL_SCALE,
// custom cursor
cursor : "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADcAAAAVCAYAAADiv3Z7AAACtUlEQVRYha2Ye1NTMRDFf/KqLY/SlvIolAJFqSKOoqI4o+P3/1LXP3oi23XvTUrpzJm52Zxs9mRzczeFl/u9KkDp2FV5xb/IURT42hIoGbcsp1hMGrxegw1hU9gCWsDrDFriWrTc2FYDL/K1qZiS2KywdRO0DcAiTdIBtoEdYFfYC7Arzo7426a96+B53n/idBTDlha7VmAStiGyD9wjiegCPWAAHABDg0NhqL6B0BcGZpyF5fQM98D52lcc7SaBXlhbArrGeRTQEDgCKoNzwdsq4Aw4BUZqn8qWeGOhMryRGWt9jrRwfSMwbdF/72F6SFuxLXLPORppwspMPgYq+0v93mb63rh2OFbPU9sO5hlrcXtKRstnz2atxXwb9oCqEhYmWrRdR4F6mxdQIzqyfWjwOQOutMgHzF+RlL0FcTZrXaV77MU4YZ+EXIC/InuTuIL+B809Ay6UvX3mZ4TdmgviOiIdARPgxooywr4BX4TGbRkFvoo40/4MvHPi/HtXK+5CKxOJ+y6BXwsC/ePav18gcz+AeyeuS2ZbenFN2zJlLxuUa4fbtIkTtFfOnBfzENjum8TZbWQ4j5nt9jPgPEY+KXzn1ng6UPaYnz7p+1JphW7R6WVsM6FS/x1Ph41d5dT+KB+3at/JVrn+9/Jf6fnWjEm4ofC0jD4Fhxo4kZOpwxVwaTBl/g17q4lnDjfqnxp/17IlXMt+qYxc6NnyLafoO1f3ER8Cxyx+xG3lcKL+E9N/pknPtTATPY/VNwr8nbFYvRw7nDj+qWzZCsVnr6T8snVfj//rv1SaRbVlPxhj0Wf+/lhE3MTL1paRwFzh7Kv2qMqPbgUR3/vsOET+l7oVWIElV56Su9ky9znvczPjf+n7nBUZ3YKjW/FzbuO5MXV/U6x8E68TmrP5vuf+h1IaT5b7F+ZaSjBzrT+rAAAAAElFTkSuQmCC') 10 11, pointer",
fill : "#ffb900",
highlight : "#ffdc44",
lineWidth : 1,
line : "#ffdc44",
lineHigh : "#ffed55",
head : 30 * GLOBAL_SCALE, // arrow head width
minSize : 5, // min size arrow can be if smaller then arrow is not created
},
DOM : { // variouse dom setting for table canvas and div tags
display : "inline-block",
canvasClass : "table",
zIndex : 1,
},
closeIcon : { // styles for reandering and display close icon
size : 32 * GLOBAL_SCALE,
fill : "red",
lines : WHITE,
lineWidth : Math.max(1,2 * GLOBAL_SCALE),
shadow : SHADOW,
shadowBlur : 20 * GLOBAL_SCALE,
cursor : "pointer",
pos : {
x : 1, // as fractions
y : 0,
}
},
help : { // text help
empty : "Click here to|add a new table".split("|"),
active : "Click to drag arrows".split("|"),
activeArrow : "Right click on arrow|to remove it".split("|"),
closeTable : "To close table|move to top right|click Close Icon".split("|"),
}
}
const MOUSE = { // event contains a list of mouse event to listen to
buttonMasks : [1, 2, 4, 6, 5, 3],
events : "mousemove,mousedown,mouseup,mouseout,mouseover,contextmenu".split(","),
}; // contextmenu is included as that needs to be blocked for right button events

var helpItemsUsed = {
empty : false,
active : false,
activeArrow : false,
closeTable : false,
};
const turnOffHelp = function(){
helpItemsUsed.empty = true;
helpItemsUsed.active = true;
helpItemsUsed.activeArrow = true;
helpItemsUsed.closeTable = true;
};
if(!SHOW_HELP){turnOffHelp();};
// returns distance of point p to line segment x, y,xx,yy
const distFromLine = function(px,py,x,y,xx,yy){
var vx,vy,pvx,pvy,lx,ly,u;
vx = xx - x;
vy = yy - y;
pvx = px - x;
pvy = py - y;
u = (pvx * vx + pvy * vy)/(vy * vy + vx * vx);
if(u >= 0 && u <= 1){
lx = vx * u;
ly = vy * u;
return Math.sqrt(Math.pow(ly - pvy,2) + Math.pow(lx - pvx,2));
}
// closest point past ends of line so get dist to closest end
return Math.min(
Math.sqrt(Math.pow(xx - px,2)+ Math.pow(yy - py,2)),
Math.sqrt(Math.pow(x - px,2)+ Math.pow(y - py,2))
);
}
// set up functions create images and do other general setup
function setupContext(ctx,descript){ // sets common context settings
ctx.shadowBlur = descript.shadowBlur;
ctx.shadowColor = descript.shadow;
ctx.strokeStyle = descript.lines;
ctx.fillStyle = descript.fill;
ctx.lineWidth = descript.lineWidth;
ctx.lineCap = "round";
if(descript.font){
ctx.font = descript.font.size + descript.font.face;
}
}
function createTableImage() { // create image of table but why write a comment when the function tells it all???
var table = document.createElement("canvas");
table.width = TABLE.width;
table.height= TABLE.height;
var ctx = table.getContext("2d");
setupContext(ctx,TABLE.image);
var scaleX = table.width / 223; /// get the scale compared to original layout
var scaleY = table.height / 314; /// get the scale compared to original layout
ctx.fillStyle = TABLE.image.fill;
ctx.fillRect(35.25 * scaleX, 20 * scaleY, 152.5 * scaleX, 274 * scaleY);
ctx.fillStyle = TABLE.image.lines; // lines
ctx.fillRect(111.35 * scaleX, 20 * scaleY, 0.3, 274 * scaleY); // middle line
ctx.fillRect(35.25 * scaleX, 20 * scaleY, 2, 274 * scaleY); // lift side
ctx.fillRect(185.75 * scaleX, 20 * scaleY, 2, 274 * scaleY); // right side
ctx.fillRect(35.25 * scaleX, 20 * scaleY, 152.5 * scaleX, 2); // top base line
ctx.fillRect(35.25 * scaleX, 292 * scaleY, 152.5 * scaleX, 2); // bottom base line
ctx.fillRect(20 * scaleX, 156 * scaleY, 183 * scaleX, 2); // net
return table
}

function createEmptyImage() { // empty table image
var i = TABLE.empty.inset;
var image = document.createElement("canvas");
var w = image.width = TABLE.width;
var h = image.height = TABLE.height;
var ctx = image.getContext("2d");
setupContext(ctx,TABLE.empty);
ctx.strokeRect(i, i, w - i * 2, h - i * 2);
ctx.beginPath();
ctx.moveTo(i * 2, i * 2);
ctx.lineTo(w - i * 2, h - i * 2);
ctx.moveTo(i * 2, h - i * 2);
ctx.lineTo(w - i * 2, i * 2);
ctx.stroke();
return image
}
function createCloseImage() { // create close icon
var S = TABLE.closeIcon.size;
var s = S * 0.5;
var c = s * 0.4; // cross dist from center
var sb = TABLE.closeIcon.shadowBlur;
var l = TABLE.closeIcon.lineWidth;
var image = document.createElement("canvas");
// Image must include shadowblur
image.width = S+sb; // add blur to size
image.height= S+sb;
var ctx = image.getContext("2d");
setupContext(ctx,TABLE.closeIcon);
ctx.beginPath();
var cx = s + sb / 2; // add half blur to get center
var cy = s + sb / 2;
ctx.arc(cx, cy, s - l, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.moveTo(cx - c, cy - c)
ctx.lineTo(cx + c, cy + c)
ctx.moveTo(cx - c, cy + c)
ctx.lineTo(cx + c, cy - c)
ctx.stroke();
return image
}
// create the images
var tableImage = createTableImage();
var closeIcon = createCloseImage();
var emptyTableImage = createEmptyImage();


// draws a arrow a is the arrow object
function drawArrow(ctx,a){
var s = TABLE.arrow; // get arrow style
var vx,vy;
var x,y;
x = a.x;
y = a.y;
vx = a.xx-x;
vy = a.yy-y;
var dir = Math.atan2(vy,vx);
var len = Math.sqrt(vx * vx + vy * vy);
// ctx.save();
ctx.setTransform(1,0,0,1,x,y);
ctx.rotate(dir);
var w = s.width/2;
var h = Math.min(len,s.head); // ensure arrow head no bigger than arrow length
h /=2;
if(a.highlight){
ctx.fillStyle = s.highlight;
ctx.strokeStyle = s.lineHigh;
}else{
ctx.fillStyle = s.fill;
ctx.strokeStyle = s.line;
}
ctx.lineWidth = s.lineWidth;
ctx.save();
ctx.shadowBlur = s.shadowBlur;
ctx.shadowColor = s.shadow;
ctx.beginPath();
ctx.moveTo(0,-w/2);
ctx.lineTo(len-h-h,-w);
ctx.lineTo(len-h-h,-h);
ctx.lineTo(len,0);
ctx.lineTo(len-h-h,h);
ctx.lineTo(len-h-h,w);
ctx.lineTo(0,w/2);
ctx.closePath();
ctx.fill();
ctx.stroke();
ctx.restore();
}

// display help text for table
function drawHelpText(ctx,text,style){
ctx.font = style.font.size + style.font.face;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
var i,len;
len = text.length;
var y = ctx.canvas.height / 2 - len * style.font.size * 1.2;
var yy = y + 1;
ctx.strokeStyle = "#000";
ctx.lineWidth = 2;
for(i = 0; i < len; i++){
ctx.strokeText(text[i], ctx.canvas.width / 2 + 1, yy);
yy += TABLE.empty.font.size * 1.2;
}
ctx.fillStyle = style.font.fill;
for(i = 0; i < len; i++){
ctx.fillText(text[i], ctx.canvas.width / 2, y);
y += TABLE.empty.font.size * 1.2;
}

}
//------------------------------------------------------------
// functions for table
function drawClose(){ // draws close icon. Fades in the close mouse is
var ctx = this.ctx;
var w = closeIcon.width;
var grow = w * 0.1;
var x = (this.width - w) * TABLE.closeIcon.pos.x ;
var y = (this.height - w) * TABLE.closeIcon.pos.y ;

x += w/2; // get icon center
y += w/2;
var dist = Math.sqrt(Math.pow(this.mouse.x - x, 2) + Math.pow(this.mouse.y - y, 2));
if(dist < TABLE.closeIcon.size / 2){
this.mouseOverClose = true;
}else{
this.mouseOverClose = false;
}
x -= w/2; // back to icon top left
y -= w/2;
ctx.globalAlpha = 1-(Math.min(100,(dist - w * 2)) / 100);
if(this.mouseOverClose){
ctx.drawImage(closeIcon,x-grow,y-grow,w + grow * 2,w + grow * 2);
}else{
ctx.drawImage(closeIcon,x,y);
}
ctx.globalAlpha = 1;
}
function drawEmpty(){ // draw empty table and handle click on empty table
var ctx = this.ctx;
ctx.drawImage(emptyTableImage,0,0);
if(this.mouse.over){
ctx.globalCompositeOperation = "lighter";
ctx.globalAlpha = TABLE.empty.highlightAmount;
ctx.drawImage(emptyTableImage,0,0);
ctx.globalAlpha = 1;
ctx.globalCompositeOperation = "source-over";

if(!helpItemsUsed.empty){ // show help is the help action has not yet been done
drawHelpText(ctx,TABLE.help.empty,TABLE.empty);
}
this.cursor = TABLE.empty.cursor;
if(this.mouse.button & 1){ // bit field
this.buttonDown = true;
}else if( this.buttonDown){
this.active = true;
setTimeout(addTable,TABLE_REFRESH_DELAY);
this.buttonDown = false;
helpItemsUsed.empty = true; // flag this help as not needed as user has complete that task
}
}else{
this.cursor = "default";
}
}
function drawTable(){ // darw the table all states
var ctx = this.ctx;
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
if(this.active){
ctx.drawImage(tableImage,0,0);
if(this.mouse.over){
if(!this.dragging){ // Dont draw close icon while draggin
this.drawCloseIcon();
}
if(this.mouseOverClose && ! this.dragging){ // if not dragging and mouse over close
this.cursor = TABLE.closeIcon.cursor; // set cursor
if(this.mouse.button & 1){ // bit field is mouse left down
this.buttonDown = true;
}else if(this.buttonDown){ // only close if mouse moves up while over close.
this.active = false;
helpItemsUsed.closeTable = true;
this.buttonDown = false;
setTimeout(updateTables,TABLE_REFRESH_DELAY);
}
}else{ // not over close
// if near a arrow and mouse button right is down delete the arrow
if(this.closestArrowIndex > -1 && (this.mouse.button & 4) === 4){ // but field Only button right down
this.arrows.splice(this.closestArrowIndex,1);
this.closestArrowIndex = -1;
this.mouse.button = 0; // turn mouse click off
helpItemsUsed.activeArrow = true; // flag arrow delete help as used

}else // if not near line or close then check for mouse left
if(this.mouse.button & 1){ // bit field if down start dragging new arroe
if(!this.dragging){ // Start of drag create arrow
this.arrows.push({
x: this.mouse.x,
y: this.mouse.y,
xx : this.mouse.x,
yy : this.mouse.y,
});
this.currentArrow = this.arrows[this.arrows.length-1];
this.dragging = true;

}else{ // during drag move arrow endpoint
helpItemsUsed.active = true; // flag arrow help as used
this.currentArrow.xx = this.mouse.x;
this.currentArrow.yy = this.mouse.y;
}
}else{ // mouse up
if(this.dragging){ // is dragging then must be a arrow
// if arrow added is smaller than 2 pixels then remove it;
if(Math.abs(this.currentArrow.xx-this.currentArrow.x) < TABLE.arrow.minSize && Math.abs(this.currentArrow.y-this.currentArrow.yy) < TABLE.arrow.minSize){
this.arrows.length -= 1;
}
this.currentArrow = null;
this.dragging = false;
}
}
this.cursor = TABLE.image.cursor; // set cursor tp table standard
}
}
if(this.closestArrowIndex > -1 && ! this.dragging){ // is mouse near arrow
this.cursor = TABLE.arrow.cursor; // yes set cursor for arrow

}
// find arrow closest to mouse
var minDist = TABLE.arrow.width; // this sets the max distance mouse can be for it to highlight an arrow
var dist = 0;
this.closestArrowIndex = -1;
for(var i = 0; i < this.arrows.length; i++){ // test all arrow
var a = this.arrows[i];
drawArrow(ctx,a); // draw the arrow
a.highlight = false; // turn off highlight
dist = distFromLine(this.mouse.x,this.mouse.y,a.x,a.y,a.xx,a.yy); // get distance from mouse
if(dist < minDist){ // is closer than any other arrow
this.closestArrowIndex = i; // yes remember the index
minDist = dist;
}
}
if(this.closestArrowIndex > -1 && this.mouse.over){ // is a arror close to mouse
this.arrows[this.closestArrowIndex].highlight = true; // highlight it
}

ctx.setTransform(1,0,0,1,0,0); // reset transform after arrows drawn
// show help
if(this.mouse.over){
if(this.arrows.length === 0 && !helpItemsUsed.active){
drawHelpText(ctx,TABLE.help.active,TABLE.image);
}else
if(this.closestArrowIndex > -1 && !helpItemsUsed.activeArrow){
drawHelpText(ctx,TABLE.help.activeArrow,TABLE.image);
}else
if(this.closestArrowIndex === -1 && !helpItemsUsed.closeTable){
drawHelpText(ctx,TABLE.help.closeTable,TABLE.image);
}
}
}else{
this.drawEmpty();
}
}
// renders a table. Stops rendering if the mouse is not over
function tableUpdate(){
if(this.mouse.over){
this.updating = true;
requestAnimationFrame(this.update);
}else{
this.buttonDown = false; // turn of button if dragged off
this.div.style.cursor = "default";
this.updating = false;
this.draw(); // draw another time. This alows for the visual state to be correct
}
this.draw();
this.div.style.cursor = this.cursor;
}
// Mousecallback starts a table rendering if not allready doing so.
function mouseInOutCallback(){
if(this.mouse.over){
if(!this.updating){
this.update();
}
}else{
this.div.style.cursor = "default";
}
}
// function to handle mouse events
function mouseEvent(e) {
var m =this; // lazy programer short cut
var t = e.type;
var bounds = m.element.getBoundingClientRect();
m.x = e.clientX - bounds.left;
m.y = e.clientY - bounds.top;
if (t === "mousedown") {
m.button |= MOUSE.buttonMasks[e.which-1];
} else if (t === "mouseup") {
m.button &= MOUSE.buttonMasks[e.which + 2];
} else if (t === "mouseout") {
m.button = 0;
m.over = false;
m.table.mouseOver();
} else if (t === "mouseover") {
m.over = true;
m.table.mouseOver();
}
e.preventDefault();
}
// create the mouse inteface for a table
function createMouse(table){
var mouse = {
x : 0,
y : 0,
over : false,
table : table,
element : table.div,
button : 0,
};
mouse.event = mouseEvent.bind(mouse);
mouse.start = function(){
MOUSE.events.forEach( n => { this.element.addEventListener(n, this.event); } );
}
mouse.remove = function(){
MOUSE.events.forEach( n => { this.element.removeEventListener(n, this.event); } );
}
return mouse;
}
function createAddTable(){ // Creates a table. Tables default in inactive
var table = {};
var div = document.createElement("div");
div.style.width = TABLE.width+ "px";
div.style.height = TABLE.height + "px";
div.style.display = TABLE.DOM.display;
var canvas = document.createElement("canvas");
canvas.width = TABLE.width;
canvas.height = TABLE.height;
canvas.className = TABLE.DOM.tableClass
canvas.style.zIndex = TABLE.DOM.zIndex;
var ctx = canvas.getContext("2d");
table.div = div;
table.canvas = canvas;
table.ctx = ctx;
table.arrows = [];
table.width = TABLE.width;
table.height = TABLE.height;
table.mouseOverClose = false
table.drawCloseIcon = drawClose;
table.draw = drawTable;
table.dragging = false;
table.active = false;
table.update = tableUpdate.bind(table);
table.mouseOver = mouseInOutCallback; // called by mouseEvent when mouse over out
table.drawEmpty = drawEmpty.bind(table);
table.dead = false; // when removed and not needed it is dead and can then be removed from table array
table.updating = false; // true is animation requests are happening
div.appendChild(canvas); // add canvas
table.mouse = createMouse(table);
table.draw();
return table;
}
function removeTable(table){ // remove table from dom
table.mouse.remove(); // deactivate moue events
TABLE.tables.removeChild(table.div); // remove from DOM
table.dead = true;// flag as dead to be removed from table array
}
function addTable(){ // Adds a table to table array and DOM
var table = createAddTable(); // create new table
TABLE.tables.appendChild(table.div); // add to the dom
table.mouse.start(); // start the mouse
tableArray.push(table); // add to table array
return table;
}
function updateTables(){ // Updates tables. Removes any dead tables from table array
var closeTables = [];
closeTables = tableArray.filter(t => !t.active);
while(closeTables.length > 1){
removeTable(closeTables.shift());
}
for(var i = 0; i < tableArray.length; i ++){
if(tableArray[i].dead){
tableArray.splice(i,1);
i -= 1;
}
}
}
addTable();
body {
background-color: #982439;
}

#table {
padding: 10px;
}

canvas {
position: absolute;
}
<div id="tables">
</div>

关于javascript - 如何在一个 Canvas 上启用绘制和删除多个元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38942605/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com