Skip to content

Commit

Permalink
fix: store whiteboard paths as point array
Browse files Browse the repository at this point in the history
  • Loading branch information
Anapher committed Jul 9, 2021
1 parent 722e67d commit e83b204
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
#pragma warning disable 8618

using System.Collections.Generic;
using Newtonsoft.Json.Linq;

namespace Strive.Core.Services.WhiteboardService.CanvasData
{
public record CanvasPath : CanvasObject
{
public IReadOnlyList<JValue[]> Path { get; set; }
public IReadOnlyList<CanvasPoint> Path { get; set; }
}
}
35 changes: 35 additions & 0 deletions src/Web/WebSPA/Client/src/features/whiteboard/path-cache.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { uncompressPathData } from './path-compression';
import { CanvasObject, VersionedCanvasObject, WhiteboardCanvas } from './types';

export default class PathCache {
private uncompressedPaths = new Map<string, CanvasObject>();

public preprocess(canvas: WhiteboardCanvas): WhiteboardCanvas {
const requiredPathIds = Object.fromEntries(Array.from(this.uncompressedPaths.keys()).map((x) => [x, false]));

const uncompressPath = (obj: VersionedCanvasObject) => {
requiredPathIds[obj.id] = true;

let cached: any = this.uncompressedPaths.get(obj.id);
if (!cached) {
cached = uncompressPathData(obj.data);
this.uncompressedPaths.set(obj.id, cached);
}

return { ...obj, data: { ...obj.data, path: cached } };
};

const result = {
...canvas,
objects: canvas.objects.map((x) => (x.data.type === 'path' ? uncompressPath(x) : x)),
};

for (const [id, used] of Object.entries(requiredPathIds)) {
if (!used) {
this.uncompressedPaths.delete(id);
}
}

return result;
}
}
18 changes: 12 additions & 6 deletions src/Web/WebSPA/Client/src/features/whiteboard/path-compression.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
import { fabric } from 'fabric';
import simplify from 'simplify-js';
import { Point } from './types';

/**
* Compress the path by simplifying the points
* @param data the path data
*/
export function compressPathData(data: any): void {
const simplifiedPoints = simplify(data.path.map((x: any) => ({ x: x[1], y: x[2] })));
data.path = simplifiedPoints;
}

/**
* Uncompress path data
* @param data the compressed data
*/
export function uncompressPathData(data: any): any {
const points = data.path as Point[];
const brush = new fabric.PencilBrush();
const path = brush.convertPointsToSVGPath(simplifiedPoints.map(({ x, y }) => new fabric.Point(x, y)));

console.log(path);

data.path = fixPathGetInstructions(path);
const path = brush.convertPointsToSVGPath(points.map(({ x, y }) => new fabric.Point(x, y)));
return fixPathInstructions(path);
}

/**
* Return the path data for fabric js
* @param segments the input segments, something like ["M ", 60.4315, " ", 10.205996948242188, " ", "Q ", 60.4325, ...]
*/
function fixPathGetInstructions(segments: string[]): (string | number)[][] {
function fixPathInstructions(segments: string[]): (string | number)[][] {
if (segments.length === 0) return [];

const result = new Array<(string | number)[]>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default class PencilTool extends WhiteboardToolBase {
configureCanvas(canvas: Canvas) {
super.configureCanvas(canvas);

(canvas.freeDrawingBrush as any).decimate = 5;
(canvas.freeDrawingBrush as any).decimate = 2;
canvas.isDrawingMode = true;
canvas.defaultCursor = 'default';
this.lastUpdateIndex = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import _ from 'lodash';
import { TypedEmitter } from 'tiny-typed-emitter';
import { applyObjectConfig, deleteObject, getId, isLiveObj, objectToJson } from './fabric-utils';
import LiveUpdateControl, { getUpdateControl } from './live-update-handler';
import PathCache from './path-cache';
import {
CanvasLiveAction,
CanvasObjectPatch,
Expand Down Expand Up @@ -37,6 +38,7 @@ export default class WhiteboardController extends TypedEmitter<WhiteboardControl
{ type: CanvasLiveAction['type']; updateControl: LiveUpdateControl<CanvasLiveAction> }
>();
private throttledLiveUpdate: _.DebouncedFunc<(update: CanvasLiveAction) => void> | undefined;
private pathCache = new PathCache();

constructor(canvas: HTMLCanvasElement, initialTool: WhiteboardTool, initialOptions: WhiteboardToolOptions) {
super();
Expand Down Expand Up @@ -74,6 +76,8 @@ export default class WhiteboardController extends TypedEmitter<WhiteboardControl
}

public updateCanvas(canvas: WhiteboardCanvas) {
canvas = this.pathCache.preprocess(canvas);

if (!this.currentVersion) {
this.fc.loadFromJSON(
{
Expand Down

0 comments on commit e83b204

Please sign in to comment.