mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
working trilium canvas note
This commit is contained in:
parent
2a2c82cd29
commit
22363f5b74
@ -13,11 +13,12 @@ img.src = deleteIcon;
|
||||
* const canvasState = new CanvasState();
|
||||
* canvasState.on('selecting', ()=>{});
|
||||
* canvasState.activate('selecting');
|
||||
Inspiration: https://stackoverflow.com/a/53917410
|
||||
https://developer.mozilla.org/en-US/docs/Web/API/EventTarget
|
||||
Inspiration: https://stackoverflow.com/a/53917410
|
||||
https://developer.mozilla.org/en-US/docs/Web/API/EventTarget
|
||||
*/
|
||||
class CanvasState extends EventTarget {
|
||||
constructor(initialState) {
|
||||
super();
|
||||
this.states = {
|
||||
IDLE: 'idle',
|
||||
INTERACTING: 'interacting',
|
||||
@ -99,6 +100,9 @@ class InfiniteCanvas {
|
||||
this.resetZoom = this.resetZoom.bind(this);
|
||||
this.cropCanvas = this.cropCanvas.bind(this);
|
||||
this.placeTextBox = this.placeTextBox.bind(this);
|
||||
this.getInfiniteCanvas = this.getInfiniteCanvas.bind(this);
|
||||
this.setInfiniteCanvas = this.setInfiniteCanvas.bind(this);
|
||||
this.overrideFabric = this.overrideFabric.bind(this);
|
||||
}
|
||||
|
||||
overrideFabric() {
|
||||
@ -178,6 +182,55 @@ class InfiniteCanvas {
|
||||
return self;
|
||||
}
|
||||
|
||||
/**
|
||||
* prepares object that has width, scale and height of current view
|
||||
* @returns {{canvas: *, width: *, lastScale: number, height: *}}
|
||||
*/
|
||||
getInfiniteCanvas() {
|
||||
const canvas = this.$canvas;
|
||||
const canvasContent = canvas.toJSON();
|
||||
console.log('Canvas JSON', canvasContent);
|
||||
const payload = {
|
||||
width: this.width,
|
||||
height: this.height,
|
||||
lastScale: this.lastScale,
|
||||
canvas: canvasContent,
|
||||
};
|
||||
return payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* load infinite canvas json into canvas
|
||||
* @param infiniteCanvasState
|
||||
*/
|
||||
async setInfiniteCanvas(infiniteCanvasState) {
|
||||
const self = this;
|
||||
const canvasContainer = this.$canvasContainer;
|
||||
const {lastScale, width, height, canvas} = infiniteCanvasState;
|
||||
|
||||
// console.log('sICJSON', payload, canvasContainer);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const savedCanvas = canvas;
|
||||
if (savedCanvas) {
|
||||
this.$canvas.loadFromJSON(savedCanvas, function() {
|
||||
console.log('loaded?');
|
||||
self.width = self.scaledWidth = parseInt(width, 10);
|
||||
self.height = self.scaledHeight = parseInt(height, 10);
|
||||
self.lastScale = lastScale;
|
||||
self.$canvas.setWidth(self.width);
|
||||
self.$canvas.setHeight(self.height);
|
||||
self.$canvasContainer.width(self.width).height(self.height);
|
||||
self.$canvas.renderAll();
|
||||
resolve();
|
||||
});
|
||||
} else {
|
||||
console.log('payload empty?');
|
||||
reject('payload empty?');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} direction [top, left, right, bottom]
|
||||
@ -205,7 +258,7 @@ class InfiniteCanvas {
|
||||
}
|
||||
|
||||
let newWidth = this.scaledWidth,
|
||||
newHeight = this.scaledHeight;
|
||||
newHeight = this.scaledHeight;
|
||||
|
||||
if (direction === 'top' || direction === 'bottom') {
|
||||
newHeight = this.scaledHeight + distance;
|
||||
@ -246,7 +299,10 @@ class InfiniteCanvas {
|
||||
// place text box independent of touch type
|
||||
if (this.activatePlaceTextBox) {
|
||||
if (fabricEvent && fabricEvent.absolutePointer) {
|
||||
this.placeTextBox(fabricEvent.absolutePointer.x, fabricEvent.absolutePointer.y);
|
||||
this.placeTextBox(
|
||||
fabricEvent.absolutePointer.x,
|
||||
fabricEvent.absolutePointer.y,
|
||||
);
|
||||
this.activatePlaceTextBox = false;
|
||||
return;
|
||||
}
|
||||
@ -284,13 +340,13 @@ class InfiniteCanvas {
|
||||
placeTextBox(x, y) {
|
||||
const canvas = this.$canvas;
|
||||
canvas.add(
|
||||
new fabric.IText('Tap and Type', {
|
||||
fontFamily: 'Arial',
|
||||
// fontWeith: '200',
|
||||
fontSize: 15,
|
||||
left: x,
|
||||
top: y,
|
||||
}),
|
||||
new fabric.IText('Tap and Type', {
|
||||
fontFamily: 'Arial',
|
||||
// fontWeith: '200',
|
||||
fontSize: 15,
|
||||
left: x,
|
||||
top: y,
|
||||
}),
|
||||
);
|
||||
canvas.isDrawingMode = false;
|
||||
}
|
||||
@ -333,8 +389,8 @@ class InfiniteCanvas {
|
||||
console.log('panstart', e);
|
||||
|
||||
if (
|
||||
e.pointerType === 'touch' &&
|
||||
!this.drawWithTouch // pointertype mouse and canvas state mouse-drag
|
||||
e.pointerType === 'touch' &&
|
||||
!this.drawWithTouch // pointertype mouse and canvas state mouse-drag
|
||||
) {
|
||||
canvas.isDrawingMode = false;
|
||||
canvas.isDragging = true;
|
||||
@ -454,14 +510,14 @@ class InfiniteCanvas {
|
||||
/**
|
||||
* Crop the canvas to the surrounding box of all elements on the canvas
|
||||
*
|
||||
Learnings: we must NOT use fabric.Group, since this messes with items and then
|
||||
SVG export is scwed. Items coordinates are not set correctly!
|
||||
fabric.Group(items).aCoords does NOT work.
|
||||
Therefore we need to get bounding box ourselves
|
||||
Note: Or maybe we can use group, destroy and readd everything afterwards:
|
||||
http://fabricjs.com/manage-selection
|
||||
https://gist.github.com/msievers/6069778#gistcomment-2030151
|
||||
https://stackoverflow.com/a/31828460
|
||||
Learnings: we must NOT use fabric.Group, since this messes with items and then
|
||||
SVG export is scwed. Items coordinates are not set correctly!
|
||||
fabric.Group(items).aCoords does NOT work.
|
||||
Therefore we need to get bounding box ourselves
|
||||
Note: Or maybe we can use group, destroy and readd everything afterwards:
|
||||
http://fabricjs.com/manage-selection
|
||||
https://gist.github.com/msievers/6069778#gistcomment-2030151
|
||||
https://stackoverflow.com/a/31828460
|
||||
*/
|
||||
async cropCanvas() {
|
||||
console.log('cropCanvas');
|
||||
|
@ -9,7 +9,7 @@ import _debounce from './canvas-note-utils/lib/lodash.debounce.js';
|
||||
const TPL = `
|
||||
<div id="parentContainer" class="note-detail-canvas-note note-detail-printable"
|
||||
style=" /*resize: both;*/
|
||||
overflow:auto; width: 100%; height: 80%; background-color: rgba(255,248,230,0.58); border: 1px double #efefef;">
|
||||
overflow:auto; width: 100%; height: 70%; background-color: rgba(255,248,230,0.58); border: 1px double #efefef;">
|
||||
<div id="canvasContainer" style="width: 1500px; height: 1500px;">
|
||||
<canvas id="c" class="canvasElement" style="border:1px solid #aaa; width: 1500px; height: 1500px"></canvas>
|
||||
</div>
|
||||
@ -25,7 +25,6 @@ const TPL = `
|
||||
<button id="pen-2" class="btn btn-info"><i class='bx bx-pencil' style="border-left: 3px solid red"></i></button>
|
||||
<button id="pen-3" class="btn btn-info"><i class='bx bx-pencil' style="border-left: 3px solid green"></i></button>
|
||||
<button id="pen-4" class="btn btn-info"><i class='bx bx-pencil' style="border-left: 3px solid blue"></i></button>
|
||||
<br />
|
||||
<button id="marker-1" class="btn btn-info"><i class='bx bx-pen' style="border-left: 7px solid yellow"></i></button>
|
||||
<button id="marker-2" class="btn btn-info"><i class='bx bx-pen' style="border-left: 7px solid wheat"></i></button>
|
||||
<button id="marker-3" class="btn btn-info"><i class='bx bx-pen'
|
||||
@ -61,6 +60,9 @@ export default class CanvasNoteTypeWidget extends TypeWidget {
|
||||
super();
|
||||
|
||||
this.initCanvas = this.initCanvas.bind(this);
|
||||
this.saveData = this.saveData.bind(this);
|
||||
this.getContent = this.getContent.bind(this);
|
||||
this.doRefresh = this.doRefresh.bind(this);
|
||||
}
|
||||
static getType() {
|
||||
return "canvas-note";
|
||||
@ -74,6 +76,14 @@ export default class CanvasNoteTypeWidget extends TypeWidget {
|
||||
.then(() => {
|
||||
console.log("fabric.js-loaded")
|
||||
this.initCanvas();
|
||||
})
|
||||
.then(async () => {
|
||||
const noteComplement = await this.tabContext.getNoteComplement();
|
||||
if (this.infiniteCanvas && noteComplement.content) {
|
||||
const content = JSON.parse(noteComplement.content || "");
|
||||
await this.infiniteCanvas.setInfiniteCanvas(content);
|
||||
}
|
||||
this.canvas.on('after:render', _debounce(this.saveData, 1000));
|
||||
});
|
||||
|
||||
return this.$widget;
|
||||
@ -82,8 +92,9 @@ export default class CanvasNoteTypeWidget extends TypeWidget {
|
||||
async doRefresh(note) {
|
||||
// get note from backend and put into canvas
|
||||
const noteComplement = await this.tabContext.getNoteComplement();
|
||||
if (this.canvas && noteComplement.content) {
|
||||
this.canvas.loadFromJSON(noteComplement.content);
|
||||
if (this.infiniteCanvas && noteComplement.content) {
|
||||
const content = JSON.parse(noteComplement.content || "");
|
||||
await this.infiniteCanvas.setInfiniteCanvas(content);
|
||||
}
|
||||
console.log('doRefresh', note, noteComplement);
|
||||
}
|
||||
@ -92,9 +103,9 @@ export default class CanvasNoteTypeWidget extends TypeWidget {
|
||||
* Function gets data that will be sent via spacedUpdate.scheduleUpdate();
|
||||
*/
|
||||
getContent() {
|
||||
const content = JSON.stringify(this.__canvas.toJSON());
|
||||
const content = this.infiniteCanvas.getInfiniteCanvas();
|
||||
console.log('gC', content);
|
||||
return content;
|
||||
return JSON.stringify(content);
|
||||
}
|
||||
|
||||
saveData() {
|
||||
@ -110,6 +121,7 @@ export default class CanvasNoteTypeWidget extends TypeWidget {
|
||||
|
||||
this.infiniteCanvas = myCanvas.initFabric();
|
||||
this.canvas = this.infiniteCanvas.$canvas;
|
||||
// this.canvas.clear();
|
||||
|
||||
this.canvas.setWidth(myCanvas.width);
|
||||
this.canvas.setHeight(myCanvas.height);
|
||||
|
Loading…
x
Reference in New Issue
Block a user