Reputation: 21
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
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