mirror of
https://github.com/rough-stuff/rough.git
synced 2026-01-20 03:37:55 -05:00
109 lines
4.5 KiB
JavaScript
109 lines
4.5 KiB
JavaScript
import { RoughRenderer } from './renderer';
|
|
const hasDocument = typeof document !== 'undefined';
|
|
export class RoughSVGBase {
|
|
constructor(svg) {
|
|
this.svg = svg;
|
|
}
|
|
static createRenderer() {
|
|
return new RoughRenderer();
|
|
}
|
|
get defs() {
|
|
const doc = this.svg.ownerDocument || (hasDocument && document);
|
|
if (doc) {
|
|
if (!this._defs) {
|
|
const dnode = doc.createElementNS('http://www.w3.org/2000/svg', 'defs');
|
|
if (this.svg.firstChild) {
|
|
this.svg.insertBefore(dnode, this.svg.firstChild);
|
|
}
|
|
else {
|
|
this.svg.appendChild(dnode);
|
|
}
|
|
this._defs = dnode;
|
|
}
|
|
}
|
|
return this._defs || null;
|
|
}
|
|
draw(drawable) {
|
|
const sets = drawable.sets || [];
|
|
const o = drawable.options || this.getDefaultOptions();
|
|
const doc = this.svg.ownerDocument || (hasDocument && document);
|
|
const g = doc.createElementNS('http://www.w3.org/2000/svg', 'g');
|
|
for (const drawing of sets) {
|
|
let path = null;
|
|
switch (drawing.type) {
|
|
case 'path': {
|
|
path = doc.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
path.setAttribute('d', this.opsToPath(drawing));
|
|
path.style.stroke = o.stroke;
|
|
path.style.strokeWidth = o.strokeWidth + '';
|
|
path.style.fill = 'none';
|
|
break;
|
|
}
|
|
case 'fillPath': {
|
|
path = doc.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
path.setAttribute('d', this.opsToPath(drawing));
|
|
path.style.stroke = 'none';
|
|
path.style.strokeWidth = '0';
|
|
path.style.fill = o.fill || null;
|
|
break;
|
|
}
|
|
case 'fillSketch': {
|
|
path = this.fillSketch(doc, drawing, o);
|
|
break;
|
|
}
|
|
case 'path2Dfill': {
|
|
path = doc.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
path.setAttribute('d', drawing.path || '');
|
|
path.style.stroke = 'none';
|
|
path.style.strokeWidth = '0';
|
|
path.style.fill = o.fill || null;
|
|
break;
|
|
}
|
|
case 'path2Dpattern': {
|
|
if (!this.defs) {
|
|
console.error('Cannot render path2Dpattern. No defs/document defined.');
|
|
}
|
|
else {
|
|
const size = drawing.size;
|
|
const pattern = doc.createElementNS('http://www.w3.org/2000/svg', 'pattern');
|
|
const id = `rough-${Math.floor(Math.random() * (Number.MAX_SAFE_INTEGER || 999999))}`;
|
|
pattern.setAttribute('id', id);
|
|
pattern.setAttribute('x', '0');
|
|
pattern.setAttribute('y', '0');
|
|
pattern.setAttribute('width', '1');
|
|
pattern.setAttribute('height', '1');
|
|
pattern.setAttribute('height', '1');
|
|
pattern.setAttribute('viewBox', `0 0 ${Math.round(size[0])} ${Math.round(size[1])}`);
|
|
pattern.setAttribute('patternUnits', 'objectBoundingBox');
|
|
const patternPath = this.fillSketch(doc, drawing, o);
|
|
pattern.appendChild(patternPath);
|
|
this.defs.appendChild(pattern);
|
|
path = doc.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
path.setAttribute('d', drawing.path || '');
|
|
path.style.stroke = 'none';
|
|
path.style.strokeWidth = '0';
|
|
path.style.fill = `url(#${id})`;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if (path) {
|
|
g.appendChild(path);
|
|
}
|
|
}
|
|
return g;
|
|
}
|
|
fillSketch(doc, drawing, o) {
|
|
let fweight = o.fillWeight;
|
|
if (fweight < 0) {
|
|
fweight = o.strokeWidth / 2;
|
|
}
|
|
const path = doc.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
path.setAttribute('d', this.opsToPath(drawing));
|
|
path.style.stroke = o.fill || null;
|
|
path.style.strokeWidth = fweight + '';
|
|
path.style.fill = 'none';
|
|
return path;
|
|
}
|
|
}
|