mirror of
https://github.com/Doodle3D/Doodle3D-Core.git
synced 2024-11-16 02:57:56 +01:00
59 lines
1.8 KiB
JavaScript
59 lines
1.8 KiB
JavaScript
|
import { SHAPE_CACHE_LIMIT } from '../constants/general.js';
|
||
|
import { Text } from '@doodle3d/cal';
|
||
|
import { POTRACE_OPTIONS } from '../constants/d2Constants.js';
|
||
|
import * as POTRACE from '@doodle3d/potrace-js';
|
||
|
import ClipperShape from '@doodle3d/clipper-js';
|
||
|
import { shapeToVectorShape } from './vectorUtils.js';
|
||
|
import memoize from 'memoizee';
|
||
|
|
||
|
const MARGIN = 200;
|
||
|
|
||
|
export const createText = memoize(createTextRaw, { max: SHAPE_CACHE_LIMIT });
|
||
|
export function createTextRaw(text, size, family, style, weight) {
|
||
|
if (text === '') return [];
|
||
|
|
||
|
const { width, height, canvas } = createTextCanvas(text, size, family, style, weight);
|
||
|
|
||
|
// TODO merge with potrace in flood fill trace reducer
|
||
|
const paths = POTRACE.getPaths(POTRACE.traceCanvas(canvas, POTRACE_OPTIONS));
|
||
|
|
||
|
const halfWidth = width / 2;
|
||
|
const halfHeight = height / 2;
|
||
|
const pathsOffset = paths.map(path => path.map(({ x, y }) => ({
|
||
|
x: (x - halfWidth) / 10,
|
||
|
y: (y - halfHeight) / 10
|
||
|
})));
|
||
|
|
||
|
const shapes = new ClipperShape(pathsOffset, true, true, false)
|
||
|
.fixOrientation()
|
||
|
.seperateShapes()
|
||
|
.map(shape => shape.mapToLower())
|
||
|
.map(shapeToVectorShape);
|
||
|
|
||
|
return shapes;
|
||
|
}
|
||
|
|
||
|
const textContext = new Text();
|
||
|
export function createTextCanvas(text, size, family, style, weight) {
|
||
|
textContext.size = size;
|
||
|
textContext.family = family;
|
||
|
textContext.style = style;
|
||
|
textContext.weight = weight;
|
||
|
|
||
|
const canvas = document.createElement('canvas');
|
||
|
const context = canvas.getContext('2d');
|
||
|
|
||
|
const width = Math.ceil(textContext.measure(context, text)) + 2 * MARGIN;
|
||
|
const height = size + 2 * MARGIN;
|
||
|
|
||
|
canvas.width = width;
|
||
|
canvas.height = height;
|
||
|
|
||
|
context.fillStyle = 'white';
|
||
|
context.fillRect(0, 0, width, height);
|
||
|
|
||
|
textContext.drawText(context, text, MARGIN, height / 2);
|
||
|
|
||
|
return { width, height, canvas };
|
||
|
}
|