Novice
Novice

Reputation: 401

How to put control inside a HTML5 canvas drawing?

I have a requirement that I want a input control/dropdown inside my canvas drawing. It goes like I want to take some input from user from canvas. On my canvas there are some boxes and each box can be drag and drop, once it is drop at some place then our user my modify them (by providing some input by typing or by choosing it from dropdown). So far I am able to draw boxes and make the dragable and dropable, here is the JS fiddle for the same -

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>

currently there are three dragable boxes and I want to put controls inside them. and when they are dropped somewhere then also those input controls should be inside that box.

I have no idea how to put a control inside a canvas drawing, I understand that DOM element can't come inside the Canvas. So I have to create some glimpse of input control or dropdown by drawing them, but how ?

Thanks in advance.

Upvotes: 0

Views: 881

Answers (1)

dwana
dwana

Reputation: 413

Simply said a canvas is an editable image, you could create everything yourself. But that would require to write all the animation for every element. Like when you click on one of the inputboxes (same as drag) a line starts blinking indicating you can type, this line should reposition when you type/delete. If you want a drop down, you should program the collapse/open function, the blue selected value, etc...

So if your elements somewhat resemble basic form elements, I would go for a more DOM-minded solution. For example 2 div next to eachother, 1 empty and 1 filled with the form elements. And when a user drags an element to the empty div you add a copy to it's DOM with javascript. (You can re-use alot of code if you put divs over the current canvas)

Upvotes: 1

Related Questions