javascript - 如何将控件放入 HTML5 Canvas 绘图中?

标签 javascript html canvas

我有一个要求,我想在我的 Canvas 绘图中添加一个输入控件/下拉菜单。就像我想从 Canvas 上获取用户的一些输入一样。在我的 Canvas 上有一些框,每个框都可以拖放,一旦将其拖放到某个位置,我们的用户就可以修改它们(通过键入或从下拉列表中选择提供一些输入)。到目前为止,我已经能够绘制盒子并使其可拖动和可放置,这是相同的 JS fiddle -

http://jsfiddle.net/akki166786/wa52f9pm/

    <script type="text/javascript">
            window.onload = function(){
                draw();
            }
        </script>
    <body style="margin: 0;padding:0;clear:both; cursor: pointer">
        <canvas id="canvas" tabindex="1" style="float:left" ></canvas>
        <div id="plainEnglish" tabindex="2" style="float: left;"></div>
    </body>

<script>
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");

c.width = 600;
c.height = 300;

//My mouse coordinates
var x,y;
c.addEventListener("mousedown",down);
c.addEventListener("mousemove",move);
c.addEventListener("mouseup",up);

var r = 0;

function counter() {
 r++;
 console.log(r);
}

//I'll save my boxes in this array
var myBoxes = new Array();

// Those boxes which I have moved to droppable area of the canvas.
var myDroppedBoxes = new Array();

//This function describes what a box is.
//Each created box gets its own values
function box(x,y,w,h,rgb,text) {
    this.x = x,
    this.y = y;
    this.xS = x; //saving x
    this.yS = y; //saving y
    this.w = w;
    this.h = h;
    this.rgb = rgb;
    this.text = text;

    //to determine if the box is being draged
    this.draging = false;
    this.isBeingDragged = false;
}

//Let's make some boxes!!
myBoxes[0] = new box(20,20,75,20,"#6AA121","First");
myBoxes[1] = new box(20,50,75,20,"#6AA121", "Second");
myBoxes[2] = new box(20,80,75,20,"#6AA121","third");

//here we draw everything
function draw() {
    ctx.clearRect(0,0,c.width,c.height);
    //Dropable area
    ctx.fillStyle="red";
    ctx.fillRect(c.width/2,0,c.width,c.height);

    //Boxes!
    for (var i = 0; i<myBoxes.length; i++) {
        var b = myBoxes[i];
        if (b.draging) { //box on the move
            //Also draw it on the original spot
            ctx.fillStyle=b.rgb; 
            ctx.fillRect(b.xS,b.yS,b.w,b.h);
            ctx.strokeRect(b.xS,b.yS,b.w,b.h);
            ctx.font = "14px Arial";
            ctx.strokeText(b.text, b.xS + 5 , b.yS + 15);
        }

        ctx.fillStyle=b.rgb;
        ctx.fillRect(b.x,b.y,b.w,b.h);
        ctx.strokeRect(b.x,b.y,b.w,b.h);
        ctx.font = "14px Arial";
        ctx.strokeText(b.text, b.x + 5 , b.y + 15);
    }

    for(var i = 0; i< myDroppedBoxes.length; i++) {
        var b = myDroppedBoxes[i];
        ctx.fillStyle=b.rgb;
        ctx.fillRect(b.x,b.y,b.w,b.h);
        ctx.strokeRect(b.x,b.y,b.w,b.h);
        ctx.font = "14px Arial";
        ctx.strokeText(b.text, b.x + 5 , b.y + 15);
    }


}


function down(event) {
    event = event || window.event;
    x = event.pageX - c.offsetLeft,
    y = event.pageY - c.offsetTop;

    for (var i = 0; i<myBoxes.length; i++) {
        var b = myBoxes[i];
        if (x>b.xS && x<b.xS+b.w && y>b.yS && y<b.yS+b.h) {
            myBoxes[i].draging = true;
            myBoxes[i].isBeingDragged = true;
        }

    }

    for (var i = 0; i<myDroppedBoxes.length; i++) {
        var b = myDroppedBoxes[i];
        if (x>b.x && x<b.x + b.w && y>b.y && y<b.y + b.h) {
            b.draging = true;
            b.isBeingDragged = true;
        }

    }
    draw();
}

function move(event) {
    event = event || window.event;
    x = event.pageX - c.offsetLeft,
    y = event.pageY - c.offsetTop;

    for (var i = 0; i<myBoxes.length; i++) {
        var b = myBoxes[i];
        if (b.draging && b.isBeingDragged) {
            myBoxes[i].x = x;
            myBoxes[i].y = y;

            if (b.x>c.width/2) {
            var length = myDroppedBoxes.length ;
                myDroppedBoxes[length] = new box(x,y,b.w,b.h,b.rgb,b.text);
                myDroppedBoxes[length].draging = true;
                myDroppedBoxes[length].isBeingDragged = true;
                b.x = b.xS;
                b.y = b.yS;
                b.isBeingDragged = false;
            }
        }
    }

    for (var i = 0; i<myDroppedBoxes.length; i++) {
        var b = myDroppedBoxes[i];
        if (b.draging && b.isBeingDragged) {
            b.x = x;
            b.y = y;
        }
    }
    draw();
}
function up(event) {
    event = event || window.event;
    x = event.pageX - c.offsetLeft,
    y = event.pageY - c.offsetTop;

    for (var i = 0; i< myBoxes.length; i++) {
        var b = myBoxes[i];
        if (b.draging && b.isBeingDragged) {
            //Let's see if the rectangle is inside the dropable area
            if (b.x < c.width/2) {
                myBoxes[i].x = b.xS;
                myBoxes[i].y = b.yS;
                myBoxes[i].draging = false;
                b.isBeingDragged = false;
            }

        }
    }

    for (var i = 0; i< myDroppedBoxes.length; i++) {
        var b = myDroppedBoxes[i];
        if ( b.isBeingDragged) {
            //Let's see if the rectangle is inside the dropable area
            if (b.x>c.width/2) {
                b.x = x;
                b.y = y;
                clubLegos(b);
                plainTextMaker();
                b.isBeingDragged = false;
            }
            else {
                //No it's not, sending it back to its original spot   
               myDroppedBoxes.splice(i,1);
            }

        }

    }
    draw();
}

function clubLegos(b) {
    // this loop is for checking that the box is lying near to which other box.
    for(var j = 0; j < myDroppedBoxes.length; j++) {  
        var z =  myDroppedBoxes[j];
        if(!z.isBeingDragged) {
                if(((x > z.x) && (x < (z.x + z.w))) && ((y > (z.y - 15)) && (y < (z.y + z.h + 10)))) {
                    b.x = z.x;
                    if( (y - z.y) >= 0) {
                        b.y = (z.y + z.h);
                        console.log("inside if " + y + " " + z.y);
                    }
                    else {
                    console.log("inside else " +  y + " " + z.y);
                        b.y = (z.y - z.h);
                    }


                }
        }
    }
}

function plainTextMaker() {
    plainEnglishDiv =  document.getElementById("plainEnglish");
    plainEnglishDiv.innerHTML = "<h3>Here I am generating some plain text based on each drag and drop</h3>";
}

</script>
</html>

目前有三个可拖动的框,我想将控件放入其中。当它们被放到某个地方时,这些输入控件也应该位于该框中。

我不知道如何将控件放入 Canvas 绘图中,我知道 DOM 元素不能进入 Canvas 。因此,我必须通过绘制输入控件或下拉菜单来创建一些输入控件或下拉菜单的一瞥,但如何实现?

提前致谢。

最佳答案

简单地说, Canvas 是一个可编辑的图像,您可以自己创建一切。但这需要为每个元素编写所有动画。就像当您单击其中一个输入框(与拖动相同)时,一条线开始闪烁,指示您可以输入,当您输入/删除时,该线应该重新定位。如果你想要一个下拉菜单,你应该对折叠/打开功能、蓝色选定值等进行编程...

因此,如果您的元素有点类似于基本表单元素,我会选择更注重 DOM 的解决方案。例如,2 个 div 彼此相邻,1 个为空,1 个填充有表单元素。当用户将一个元素拖动到空 div 时,您可以使用 javascript 将一个副本添加到它的 DOM 中。 (如果将 div 放在当前 Canvas 上,则可以重复使用大量代码)

关于javascript - 如何将控件放入 HTML5 Canvas 绘图中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31269928/

相关文章:

javascript - 如何使用 Javascript 选择所有具有特定文本内容的 anchor 标记?

java - Swing JLayeredPane 未在调用 PaintAll 时绘制所有元素

javascript - 从存储在对象中的回调调用函数,在数组中

javascript - 多选下拉列表未显示

javascript - 试图在用户将鼠标悬停在图像上时显示 div?

javascript - Chart.js 使用 X 轴时间动态更新图表

javascript - 将图像调整为屏幕高度但保持比例

html - 本地 HTML5 页面/DIV 的屏幕截图

javascript - 使用光标位置单击图像时显示 div

javascript - 如何将一系列img标签添加到数组中?