简体   繁体   中英

unable to draw more then 1 shape on html5 canvas

here i have a program that draw a polygon on canvas. problem is it draw 1 polygon only.i cannot seems to solve the problem as why i am only able to draw 1 polygon. After i finish drawing my first shape the cursor move over canvas and nothing happens.

<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div id="board">
<canvas id="canvas" width="300" height="300" style="border: 1px solid black;"></canvas>
        <br /><br />
        <input type="button" value="Save" onclick="save();" />&nbsp;
        <input type="button" value="reset" onclick="reset(); " />&nbsp;
        Couleur : <select id="color" onchange="changeColor(this.options[this.selectedIndex].value);">
            <option value="red" selected="selected">Red</option>
            <option value="blue" selected="selected">Blue</option>
            <option value="green" selected="selected">green</option>
            <option value="black" selected="selected">black</option>
            <option value="yellow" selected="selected">yellow</option>
        </select>
</p>
</div><!-- END board -->
</body>
</html>

<style>
body {
        margin: 0;      
}

#board {
        margin: 0 auto;
        width: 500px;   
}

#myCanvas {
        border: 3px dotted #000;        
}
</style>

<script type="text/JavaScript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js?ver=1.4.2"></script>
<script type="text/javascript">
var END_CLICK_RADIUS = 5;
            //the max number of points of your poygon
            var MAX_POINTS = 8;

            var mouseX = 0;
            var mouseY = 0;
            var isStarted = false;
            var points = null;

            var canvas = null;
            var ctx = null;
            window.onload = function() {
                canvas = document.getElementById("canvas");
                ctx = canvas.getContext("2d");
                changeColor("red");
                canvas.addEventListener("click", function(e) {
                    var x = e.clientX-canvas.offsetLeft;
                    var y = e.clientY-canvas.offsetTop;
                    if(isStarted) {
                        //drawing the next line, and closing the polygon if needed
                        if(Math.abs(x - points[0].x) < END_CLICK_RADIUS && Math.abs(y - points[0].y) < END_CLICK_RADIUS) {
                            isStarted = false;
                        } else {
                            points[points.length] = new Point(x, y);
                            if(points.length >= MAX_POINTS) {
                                isStarted = false;
                            }
                        }
                    } else if(points == null) {
                        //opening the polygon
                        points = new Array();
                        points[0] = new Point(x, y);
                        isStarted = true;
                    }
                }, false);

                //we just save the location of the mouse
                canvas.addEventListener("mousemove", function(e) {
                    mouseX = e.clientX - canvas.offsetLeft;
                    mouseY = e.clientY - canvas.offsetTop;
                }, false);

                //refresh time
                setInterval("draw();", 100);
            }

            //changes the color of the draw
            function changeColor(color) {
                ctx.strokeStyle = color;
            }

            //object representing a point
            function Point(x, y) {
                this.x = x;
                this.y = y;
            }

            //resets the application
            function reset() {
                isStarted = false;
                points = null;
            }

            //alerts the point list
            function save() {
                if(points == null) {
                    alert("nothing to save");
                } else {
                    var s = "";
                    for(var a in points) {
                        //inversing y axis by (canvas.height - points[a].y)
                        s += "(" + points[a].x + "," + (canvas.height - points[a].y) + ")\n";
                    }
                    alert(s);
                }
            }

            //draws the current chape
            function draw() {
                ctx.clearRect(0, 0, canvas.width, canvas.height);

                ctx.beginPath();

                if(points != null && points.length > 0) {
                    ctx.moveTo(points[0].x, points[0].y);

                    for(i = 1 ; i < points.length ; i++) {
                        ctx.lineTo(points[i].x, points[i].y);
                    }

                    if(isStarted) {
                        ctx.lineTo(mouseX, mouseY);
                    } else {
                        ctx.lineTo(points[0].x, points[0].y);
                    }
                }

                ctx.stroke();
            }
</script>

Consider the data storage and the flow of your code.

A shape is an array of points which is built from click to click. After intervals of 100 milliseconds the shape so far is drawn. The shape is drawn by clearing the canvas and drawing all the points in the array so the only shape that can be drawn is the one stored in the points array.

The conditions for opening a new polygon are

  1. isStarted is false

  2. points == null

isStarted is set to false when the polygon is completed but points is not set to null.

PROBLEM setting points to null wipes out the shape just completed.

SOLUTION an array of shapes.

Also you do not need to draw at set intervals you can draw on the click of the mouse.

Try out the suggestion below.

<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div id="board">
<canvas id="canvas" width="300" height="300" style="border: 1px solid black;"></canvas>
        <br /><br />
        <input type="button" value="Save" onclick="save();" />&nbsp;
        <input type="button" value="reset" onclick="reset(); " />&nbsp;
        Couleur : <select id="color" onchange="changeColor(this.options[this.selectedIndex].value);">
            <option value="red" selected="selected">Red</option>
            <option value="blue" selected="selected">Blue</option>
            <option value="green" selected="selected">green</option>
            <option value="black" selected="selected">black</option>
            <option value="yellow" selected="selected">yellow</option>
        </select>
</p>
</div><!-- END board -->
</body>
</html>

<style>
body {
        margin: 0;      
}

#board {
        margin: 0 auto;
        width: 500px;   
}

#myCanvas {
        border: 3px dotted #000;        
}
</style>

<script type="text/JavaScript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js?ver=1.4.2"></script>
<script type="text/javascript">
var END_CLICK_RADIUS = 5;
            //the max number of points of your poygon
            var MAX_POINTS = 8;

            var mouseX = 0;
            var mouseY = 0;
            var isStarted = false;
            var points = null;
            var shapes=new Array();

            var canvas = null;
            var ctx = null;
            window.onload = function() {
                canvas = document.getElementById("canvas");
                ctx = canvas.getContext("2d");
                changeColor("red");
                canvas.addEventListener("click", function(e) {
                    var x = e.clientX-canvas.offsetLeft;
                    var y = e.clientY-canvas.offsetTop;                    
                    if(isStarted) {
                        //drawing the next line, and closing the polygon if needed
                        if(Math.abs(x - points[0].x) < END_CLICK_RADIUS && Math.abs(y - points[0].y) < END_CLICK_RADIUS) {
                            isStarted = false;
                            points[points.length] = new Point(points[0].x, points[0].y); //stores closing point
                            shapes.push(points); //pushes the array points into the array shapes
                        } else {
                            points[points.length] = new Point(x, y);
                            if(points.length >= MAX_POINTS) {
                                isStarted = false;
                                points[points.length] = new Point(points[0].x, points[0].y); //stores closing point
                                shapes.push(points);
                            }
                        }
                    } else {                        
                        //opening the polygon
                        points = new Array();
                        points[0] = new Point(x, y);
                        isStarted = true;
                    }
                    draw();
                }, false);

                //we just save the location of the mouse
                canvas.addEventListener("mousemove", function(e) {
                    mouseX = e.clientX - canvas.offsetLeft;
                    mouseY = e.clientY - canvas.offsetTop;
                }, false);

                //refresh time
                setInterval("draw();", 100);
            }

            //changes the color of the draw - CURRENTLY SAME FOR ALL SHAPES
            function changeColor(color) {
                ctx.strokeStyle = color;
            }

            //object representing a point
            function Point(x, y) {
                this.x = x;
                this.y = y;
            }

            //resets the application
            function reset() {
                isStarted = false;
                points = null;
            }

            //alerts the point list - NOTE UPDATE THIS FUNCTION TO SAVE ALL SHAPES
            function save() {
                if(points == null) {
                    alert("nothing to save");
                } else {
                    var s = "";
                    for(var a in points) {
                        //inversing y axis by (canvas.height - points[a].y)
                        s += "(" + points[a].x + "," + (canvas.height - points[a].y) + ")\n";
                    }
                    alert(s);
                }
            }

            //draws the current shape
            function draw() {
                var prevpoints;
                ctx.clearRect(0, 0, canvas.width, canvas.height);

                ctx.beginPath();

                //draws polygon under construction
                if(points != null && points.length > 0) {
                    ctx.moveTo(points[0].x, points[0].y);

                    for(i = 1 ; i < points.length ; i++) {
                        ctx.lineTo(points[i].x, points[i].y);
                    }

                    if(isStarted) {
                        ctx.lineTo(mouseX, mouseY);
                    } else {
                        ctx.lineTo(points[0].x, points[0].y);
                    }
                }

                // draws previous shapes in any exist
                for (var j = 0; j<shapes.length; j++) {
                    prevpoints=shapes[j];
                    ctx.moveTo(prevpoints[0].x, prevpoints[0].y);

                    for(i = 1 ; i < prevpoints.length ; i++) {
                        ctx.lineTo(prevpoints[i].x, prevpoints[i].y);
                    }
                }

                ctx.stroke();
            }
</script>

NOTE I have made NO changes to the save function you will need to take into account that there are several shapes

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM