Search code examples
javascriptcanvasmouseeventpaintbox

Box not showing on canvas Javascript


I'm currently creating a software that will be like paint, however I am stuck on getting a box to follow the mouse on the canvas. The purpose of the box is to get it to show where the mouse position is, to show what colour has been selected and to show the size of the brush. I found this piece of code online:

<html>
<head>
<script>
    function m(e){
        var bx = document.getElementById("box");
        bx.style.left = e.pageX;
        bx.style.top = e.pageY;

    }
</script>
</head>

<body onmousemove="m(event)">
    <div id="box" style="background-color:#990000; width:20px; height:20px; position:absolute;" />
</body>

I've tried to implement this into my program, however it doesn't seem to be showing on the canvas...I've changed the function m(e) to fnTrackMouse(event)

I can only use mainly javascript and a bit of html and css. No Jquery please. Here's a section of my program that I'm working on:

<!doctype html>
<html lang="en">
<head>
<style>
...
</style>

<script>
        var oCanvas, oCanvasContext; //declare the global variables used to hold and control the canvas element
        var sFillColour; //create a global variable used to hold the active/selected colour
        var sCanvasColour; //create a global variable used to hold the canvas colour
        var iMouseX, iMouseY; //declare the global variables used to hold the mouse's coordinates
        var iBrushWidth, iBrushHeight; //declare the global variables used to hold the selected brush sizes

        function fnInitialise(iCanvasWidth, iCanvasHeight) {
            //this function is called via the HTML body tag and the onload event
            fnDebugMessage("Running fnInitialise"); //debug message
            oCanvas = document.getElementById("cw1Canvas"); //create a reference to the HTML canvas element
            if (oCanvas.getContext) { //test to see if we can read the canvas' context; if true we have found the canvas
                oCanvas.width=iCanvasWidth; //set the canvas width using the width argument passed to the fnInitialise function
                oCanvas.height=iCanvasHeight; //set the canvas height using the width argument passed to the fnInitialise function
                oCanvasContext = oCanvas.getContext("2d"); //set the context to 2D
                fnDebugMessage("Canvas size, width: " + iCanvasWidth + ", height: " + iCanvasHeight); //debug message, if this message appears in 

                //set some default values`
                sCanvasColour=getComputedStyle(oCanvas).getPropertyValue("background-color"); //this instruction automatically detects the background colour of the cavas and stores it in the global sCanvasColour variable
                fnDebugMessage("Canvas background colour: " + sCanvasColour); //debug message, if this message appears in 

                //let set a default brush size
                iBrushWidth=5;
                iBrushHeight=5;

                //set the canvas size to 550px x 550px
                oCanvas.width=550;
                oCanvas.height=550;

            } else {
                fnDebugMessage("fnInitialise, failed to get the canvas's context"); //debug message, we were unable to get the canvas' context
            }   
        }

        function fnTrackMouse(e) {
            //this function is called "everytime" the user's mouse is moved when over the associated element (in this case the canvas)
            //we have also added the ability for it to accept a parameter (called e, actually we can call it anything but as event is a reserved work "e" makes some sense
            var canvasRect = oCanvas.getBoundingClientRect(); //use this function to dynamically get the size of the canvas and its position
            iMouseX=(e.clientX - canvasRect.left - 3); //modify the original position of the mouse by accounting for the position on the canvas; on the x
            iMouseY=(e.clientY - canvasRect.top - 3); //modify the original position of the mouse by accounting for the position on the canvas; on the y

            var bx = document.getElementById("box");
            bx.style.left = iMouseX;
            bx.style.top = iMouseY;
            fnDebugMessage("Working!"+iMouseX)


            if (e.buttons==1) { //this checks to see if the user is pressing the left mouse button (1 = the left mouse button)
                //the user has pressed the left button - so lets start painting
                fnPaint(iMouseX, iMouseY, iBrushWidth, iBrushHeight); //call the fnPaint function and pass it the coordinates and size to paint
            }

            fnDebugMessage("Tracking mouse: x: " + iMouseX + ", y: "+iMouseY); //update the console to show the mouse position, dont forget, you may need to include an offset to centre the paint effect               

        }
    </script>

</head>
<body onload="fnInitialise(100, 100);">

    <!-- 
        this div block (HTML page divider) is used to hold the entire interactive painting HTML elements 
        the benefit of putting multiple elements in a single container is that if you set the location of the 
        container each of the elements held by the container will move relative to it; move one, move all 
    -->
    <div id="cw1MainContainer">


        <!-- this div block is only used to hold the HTML canvas element -->
        <div id="cw1CanvasContainer">
            <canvas id="cw1Canvas" onmousemove="fnTrackMouse(event);" onkeypress="fnBrushSize(event);"></canvas>
            <div id="box" style="background-color:#990000; width:20px; height:20px; position:absolute;" />
            <!-- 
                by specifing the onmouseover event the canvas will call the "fnTrackMouse" function EVERY time the 
                mouse moves 1 pixel over the canvas.
                by passing the JavaScript "event" we are effectively also passing details about the event, 
                e.g. where the mouse was, what buttons were pressed etc. 
            -->
        </div>
   </div>       

</body>
</html>

I've taken out most of the code that I think was irrelevant to this problem, but if it is necessary, please let me know. Any help would be appreciated. Cheers


Solution

  • There's a little problem with your code.

    Here you're trying to set the position of the bx element according to the mouse position:

        bx.style.left = iMouseX;
        bx.style.top = iMouseY;
    

    Unfortunately this doesn't work unless you append the string px - a short form for pixels.

        bx.style.left = iMouseX+"px";
        bx.style.top = iMouseY+"px";