You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
160 lines
4.1 KiB
160 lines
4.1 KiB
import { fabric } from "fabric";
|
|
|
|
fabric.perfLimitSizeTotal = 134217728;
|
|
fabric.maxCacheSideLimit = 65536;
|
|
|
|
export default class Board {
|
|
constructor(id) {
|
|
this.id = id;
|
|
this.state = {a: 32};
|
|
|
|
this.containerElement = document.getElementById(id);
|
|
if (this.containerElement == null) {
|
|
throw new Error(`Container ${this.id} not found`)
|
|
}
|
|
|
|
this.canvasElement = document.createElement("canvas");
|
|
this.containerElement.appendChild(this.canvasElement);
|
|
|
|
this.canvas = new fabric.Canvas(this.canvasElement, {backgroundColor: "#555"});
|
|
|
|
this.gridGroup = new fabric.Group();
|
|
this.canvas.add(this.gridGroup);
|
|
|
|
this.gridOptions = {
|
|
enabled: true,
|
|
size: 64,
|
|
hightlightInterval: 8,
|
|
lineColor: "#444",
|
|
highlightColor: "#333",
|
|
};
|
|
|
|
this.setupPanning();
|
|
}
|
|
|
|
destroy() {
|
|
this.canvasElement.remove();
|
|
}
|
|
|
|
resize(width, height) {
|
|
this.canvas.setHeight(height);
|
|
this.canvas.setWidth(width);
|
|
|
|
this.redrawGrid();
|
|
this.moveGrid();
|
|
|
|
this.canvas.renderAll();
|
|
}
|
|
|
|
redrawGrid() {
|
|
const {enabled, size, hightlightInterval, lineColor, highlightColor} = this.gridOptions;
|
|
|
|
for (const obj of this.gridGroup.getObjects().slice()) {
|
|
this.gridGroup.remove(obj);
|
|
}
|
|
if (!enabled) {
|
|
return;
|
|
}
|
|
|
|
const wCount = Math.ceil((this.canvas.getWidth() / this.canvas.getZoom()) / size) + (hightlightInterval * 2);
|
|
const hCount = Math.ceil((this.canvas.getHeight() / this.canvas.getZoom()) / size) + (hightlightInterval * 2);
|
|
|
|
const width2 = wCount * (size);
|
|
const height2 = hCount * (size);
|
|
|
|
this.gridGroup.set("left", 0);
|
|
this.gridGroup.set("top", 0);
|
|
this.gridGroup.set("width", width2);
|
|
this.gridGroup.set("height", height2);
|
|
this.gridGroup.set("selectable", false);
|
|
this.gridGroup.set("hoverCursor", "default");
|
|
|
|
for (let i = 0; i <= wCount; ++i) {
|
|
let x = i * size;
|
|
let line = new fabric.Line([x, 0, x, height2], {stroke: lineColor, strokeWidth: 2, selectable: false});
|
|
|
|
if (i % hightlightInterval == 0) {
|
|
line.set("stroke", highlightColor);
|
|
}
|
|
|
|
this.gridGroup.addWithUpdate(line);
|
|
}
|
|
|
|
for (let i = 0; i <= hCount; ++i) {
|
|
let y = i * size;
|
|
let line = new fabric.Line([0, y, width2, y], {stroke: lineColor, strokeWidth: 2, selectable: false});
|
|
|
|
if (i % hightlightInterval == 0) {
|
|
line.set("stroke", highlightColor);
|
|
}
|
|
|
|
this.gridGroup.addWithUpdate(line);
|
|
}
|
|
}
|
|
|
|
moveGrid() {
|
|
const size = this.gridOptions.size * this.gridOptions.hightlightInterval;
|
|
const [x, y] = this.canvas.viewportTransform.slice(4).map(n => -n);
|
|
const xOffset = (x % size) + size;
|
|
const yOffset = (y % size) + size;
|
|
|
|
this.gridGroup.set("left", x - xOffset);
|
|
this.gridGroup.set("top", y - yOffset);
|
|
this.gridGroup.setCoords();
|
|
|
|
console.log(this.gridGroup);
|
|
}
|
|
|
|
setupPanning() {
|
|
const parent = this;
|
|
|
|
this.canvas.on('mouse:wheel', ({e}) => {
|
|
if (e.shiftKey === false) {
|
|
return;
|
|
}
|
|
|
|
let delta = e.deltaY;
|
|
let zoom = this.canvas.getZoom();
|
|
zoom = zoom - delta/1000;
|
|
if (zoom > 5) {
|
|
zoom = 5;
|
|
}
|
|
if (zoom < 0.25) {
|
|
zoom = 0.25;
|
|
}
|
|
|
|
this.canvas.setZoom(zoom);
|
|
this.redrawGrid();
|
|
this.moveGrid();
|
|
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
})
|
|
|
|
this.canvas.on('mouse:down', function(opt) {
|
|
var evt = opt.e;
|
|
if (evt.shiftKey === true) {
|
|
this.isDragging = true;
|
|
this.selection = false;
|
|
this.lastPosX = evt.clientX;
|
|
this.lastPosY = evt.clientY;
|
|
}
|
|
});
|
|
this.canvas.on('mouse:move', function(opt) {
|
|
if (this.isDragging) {
|
|
var e = opt.e;
|
|
this.viewportTransform[4] += e.clientX - this.lastPosX;
|
|
this.viewportTransform[5] += e.clientY - this.lastPosY;
|
|
this.requestRenderAll();
|
|
this.lastPosX = e.clientX;
|
|
this.lastPosY = e.clientY;
|
|
|
|
parent.moveGrid();
|
|
}
|
|
});
|
|
this.canvas.on('mouse:up', function(opt) {
|
|
this.isDragging = false;
|
|
this.selection = true;
|
|
});
|
|
}
|
|
}
|