Arjya Shankar Mishra
Arjya Shankar Mishra

Reputation: 21

FabricJs: Draw a grid/array(p*p) of buttons in a FabricJs Canvas

I am trying to draw a grid/array(p*p) of buttons inside a FabricJs canvas. I am able to create the desired grid/array.

But I am unable to draw/place buttons inside the blocks of same height and width.

HTML:

<div>
<canvas id="canvas" width="500" height="500" style="border:1px solid #000000</canvas>
</div>
<button onclick="drawGrid()">Create Grid</button>

Script:

var canvas = new fabric.Canvas('canvas');
var currentCanvasWidth = canvas.width;
var currentcanvasHeight = canvas.height;
var context = canvas.getContext("2d"); 
var gridSize = 50; //decides the value of p(p = currentCanvasWidth/gridSize) ) and the height and width of each block inside the p*p array 

function drawGrid(){

  // Drawing vertical lines
  var x;
  for (x = 0; x <= currentCanvasWidth; x += gridSize) {
      context.moveTo(x + 0.5, 0);
      context.lineTo(x + 0.5, currentcanvasHeight);
  }

  // Drawing horizontal lines
  var y;
  for (y = 0; y <= currentcanvasHeight; y += gridSize) {
      context.moveTo(0, y + 0.5);
      context.lineTo(currentCanvasWidth, y + 0.5);
  }

  gridSize = gridSize;
  context.strokeStyle = "black";
  context.stroke();
} 

Also, I haven't found anything on the html canvas context or FabricJs to create buttons inside grid/array blocks.

Any direction on this approach? or any other approach to create an array of buttons inside FabricJs Canvas.

Here is the Image of my canvas. Basically, I want to create an array of buttons like a TIC-TAC-TOE grid and later filled the buttons with different colors to represent my scene.

Upvotes: 1

Views: 1024

Answers (1)

invernomuto
invernomuto

Reputation: 10211

Probably you should use subclassing and inherit from fabric.rect to make an isolated component, but seems that you are looking for something like the executable snippet below:

var canvas = new fabric.Canvas('c');
canvas.setWidth(301);
canvas.setHeight(301);
canvas.setBackgroundColor("#ffffff", function () { });
for (var i = 0; i < 3; i++) {
    for (var j = 0; j < 3; j++) {
        var gOptions = {
            width: 100,
            height: 100,
            top: 100 * j,
            left: 100 * i,
            hasControls: false,
            stroke: '#000000',
            fill: 'transparent',
            lockMovementX: true,
            lockMovementY: true,
            borderColor: 'transparent',
        };
        var rOptions = {
            width: 100,
            height: 100,
            top: 100 * j,
            left: 100 * i,
            rx: 10,
            ry: 10,
            hasControls: false,
            stroke: '#000000',
            fill: 'transparent',
            lockMovementX: true,
            lockMovementY: true,
            borderColor: 'transparent',
            subType: 'button',
            id: 'button_' + i + '_' + j
    };
        var c = new fabric.Rect(gOptions);
        var r = new fabric.Rect(rOptions);
        r.setGradient('fill', {
            type: 'linear',
            x1: 0,
            y1: -r.height / 2,
            x2: 0,
            y2: r.height / 2,
            colorStops: {
                0: '#fff',
                1: '#eee'
            }
        });
        canvas.add(c);
        canvas.add(r);
    }
}
canvas.on('mouse:over', function (e) {
    if (e.target) {
        if (e.target.get('subType') == 'button') {
            if (canvas.getActiveObject() == e.target) {
                return;
            }
            e.target.setGradient('fill', {
                type: 'linear',
                x1: 0,
                y1: -e.target.height / 2,
                x2: 0,
                y2: e.target.height / 2,
                colorStops: {
                    0: '#eee',
                    1: '#fff'
                }
            });
            canvas.renderAll();
            e.target.hoverCursor = 'pointer';
        }
    }
});
canvas.on('mouse:out', function (e) {
    if (e.target) {
        if (e.target.get('subType') == 'button') {
            if (canvas.getActiveObject() == e.target) {
                return;
            }
            e.target.setGradient('fill', {
                type: 'linear',
                x1: 0,
                y1: -e.target.height / 2,
                x2: 0,
                y2: e.target.height / 2,
                colorStops: {
                    0: '#fff',
                    1: '#eee'
                }
            });
            canvas.renderAll();
            e.target.hoverCursor = 'pointer';
        }
    }
});
canvas.on('object:selected', function (e) {
    canvas.getObjects().forEach(function (item) {
        if (e.target.get('subType') == 'button') {
            item.setGradient('fill', {
                type: 'linear',
                x1: 0,
                y1: -item.height / 2,
                x2: 0,
                y2: item.height / 2,
                colorStops: {
                    0: '#fff',
                    1: '#eee'
                }
            });
            canvas.renderAll();
        }
    });
    if (e.target.get('subType') == 'button') {
        console.log('button ' + e.target.id + ' was clicked');
        e.target.setFill("#cc0000");
    }
});
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.js"></script>
<style>
.snippet-code{
  height: 310px;
}
</style>
<canvas id="c" style=""></canvas>

the bitbucket repository contains a VS2015 solution with a asp.net mvc5 project for a typescript application.

Upvotes: 1

Related Questions