Back to Code List
javascript

Simple Grid

This grid was the first step into making a drag and drop system that would snap to grid points. For now, mouseover events will find the nearest snap point and place a dot.

   index.html

<!DOCTYPE html>
<html>
<head>
    <script type="text/javascript" src="grid.js"></script>
</head>
<body>
    <canvas id="content"></canvas>
</body>
</html>

<script type="text/javascript">
    //// init new grid
    var newGrid = new gridRender({
        canvasId:'content',
        canvasWidth:500,
        canvasHeight:500,
        cellWidth:30,
        cellHeight:30,
        lineWidth:1,
        backgroundColor:'#dddddd',
        lineColor:'#cccccc'
    });
    //// init mouse movements.
    initMouseMove();
</script>
    

   grid.js

//// start: add prototypes for js array item
    if (!Array.prototype.forEach)
    {
      Array.prototype.forEach = function(fun /*, thisp*/)
      {
        var len = this.length;
        if (typeof fun != "function")
          throw new TypeError();

        var thisp = arguments[1];
        for (var i = 0; i < len; i++)
        {
          if (i in this)
            fun.call(thisp, this[i], i, this);
        }
      };
    }

    /*if (!Array.prototype.binarySearch) {
            Array.prototype.binarySearch = function binarySearch(value){
                var items=this;
                
                var startIndex  = 0,
                    stopIndex   = items.length - 1,
                    middle      = Math.floor((stopIndex + startIndex)/2);
    
                while(items[middle] != value && startIndex < stopIndex){
                    //adjust search area
                    if (value < items[middle]){
                        stopIndex = middle - 1;
                    } else if (value > items[middle]){
                        startIndex = middle + 1;
                    }
    
                    //recalculate middle
                    middle = Math.floor((stopIndex + startIndex)/2);
                }
                // return closest item
                return items[middle];
            }
        }*/
//// end prototype additions


//// begin class definition
    var gridRender = function (params) {
        var setup = {
            canvas: document.getElementById(params.canvasId),
                    
            setCanvas: function () {
                this.canvas.width = params.canvasWidth;
                this.canvas.height = params.canvasHeight;
                this.canvas.style.backgroundColor = params.backgroundColor;
            },
            drawGrid: function () {
                this.xArray = [], this.yArray = [];
                var cellWidth = params.cellWidth, cellHeight = params.cellHeight;
                var canvasWidth = params.canvasWidth, canvasHeight = params.canvasHeight;
                var context = this.canvas.getContext("2d");
                
                for(i=0; i<canvasWidth; i+=cellWidth) {
                    this.xArray.push(i);
                }
                for(i=0; i<canvasHeight; i+=cellHeight) {
                    this.yArray.push(i);
                }
                
                context.lineWidth = params.lineWidth;
                context.strokeStyle = params.lineColor;
                this.xArray.forEach(function(item){
                    if (item !== 0 && item !== canvasWidth) {
                        context.moveTo(item, 0);
                        context.lineTo(item, canvasHeight);
                        context.stroke();
                    }
                });
                this.yArray.forEach(function(item){
                    if (item !== 0 && item !== canvasHeight) {
                        context.moveTo(0, item);
                        context.lineTo(canvasWidth, item);
                        context.stroke();
                    }
                });
            },
            getNearestXY: function (itemX,itemY) {
                var x = Math.round(itemX/params.cellWidth)*params.cellWidth;
                var y = Math.round(itemY/params.cellHeight)*params.cellHeight;
                return [x,y];
            },
            drawDot: function (x,y) {
                var context = this.canvas.getContext("2d")
                context.beginPath();
                context.arc(x,y,2,0,2*Math.PI,false);
                context.fillStyle = "#000000";
                context.fill();
                context.strokeStyle = "#000000";
                context.stroke();
            }
        
        };
        
        setup.setCanvas();
        setup.drawGrid();
        
        return setup;
    }
//// end class definition


//// start mouse movement items
    function initMouseMove(e) {
        var canvas = document.getElementById('content');
        var canvasX = canvas.offsetLeft;
        var canvasY = canvas.offsetTop;
        
        canvas.onclick = mouseClick;
        canvas.onmousemove = function(e) {
			var p = getCoords(e); // Get info for finger i
				var closestXY = newGrid.getNearestXY(p.x,p.y);
				newGrid.drawDot(closestXY[0],closestXY[1]);
        };
        
        var stuff = [];
		// add event for touch devices
        canvas.ontouchmove = function(e) {
            /*if (evt.touches.length == 1) {
				var touch = evt.touches[0];
                var x = touch.pageX-canvasX;
                var y = touch.pageY-canvasY;
                var closestXY = newGrid.getNearestXY(x,y);
                newGrid.drawDot(closestXY[0],closestXY[1]);
            }*/
			for (var i = 1; i <= e.touches.length; i++) {
				var p = getCoords(e.touches[i - 1]); // Get info for finger i
				var closestXY = newGrid.getNearestXY(p.x,p.y);
				//newGrid.drawDot(closestXY[0],closestXY[1]);
			}
        };
        
        function mouseClick(evt) {
            var x = getCoords(evt)-canvasX;
            var y = getCoords(evt)-canvasY;
            var closestXY = newGrid.getNearestXY(x,y);
            newGrid.drawDot(closestXY[0],closestXY[1]);
        }
		
		function getCoords(e) {
			if (e.offsetX) {
				// Works in Chrome / Safari (except on iPad/iPhone)
				return { x: e.offsetX, y: e.offsetY };
			}
			else if (e.layerX) {
				// Works in Firefox
				return { x: e.layerX, y: e.layerY };
			}
			else {
				// Works in Safari on iPad/iPhone
				return { x: e.pageX - canvasX, y: e.pageY - canvasY };
			}
		}
    }
//// end mouse movement items