mirror of
https://github.com/rough-stuff/rough.git
synced 2026-01-15 01:18:26 -05:00
148 lines
5.7 KiB
JavaScript
148 lines
5.7 KiB
JavaScript
import { RoughGenerator } from './generator';
|
|
import { RoughRenderer } from './renderer';
|
|
const hasDocument = typeof document !== 'undefined';
|
|
export class RoughSVG {
|
|
constructor(svg, config) {
|
|
this.svg = svg;
|
|
this.gen = new RoughGenerator(config || null, this.svg);
|
|
}
|
|
get generator() {
|
|
return this.gen;
|
|
}
|
|
static createRenderer() {
|
|
return new RoughRenderer();
|
|
}
|
|
get defs() {
|
|
if (hasDocument) {
|
|
if (!this._defs) {
|
|
const doc = this.svg.ownerDocument || document;
|
|
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;
|
|
}
|
|
line(x1, y1, x2, y2, options) {
|
|
const d = this.gen.line(x1, y1, x2, y2, options);
|
|
return this.draw(d);
|
|
}
|
|
rectangle(x, y, width, height, options) {
|
|
const d = this.gen.rectangle(x, y, width, height, options);
|
|
return this.draw(d);
|
|
}
|
|
ellipse(x, y, width, height, options) {
|
|
const d = this.gen.ellipse(x, y, width, height, options);
|
|
return this.draw(d);
|
|
}
|
|
circle(x, y, diameter, options) {
|
|
const d = this.gen.circle(x, y, diameter, options);
|
|
return this.draw(d);
|
|
}
|
|
linearPath(points, options) {
|
|
const d = this.gen.linearPath(points, options);
|
|
return this.draw(d);
|
|
}
|
|
polygon(points, options) {
|
|
const d = this.gen.polygon(points, options);
|
|
return this.draw(d);
|
|
}
|
|
arc(x, y, width, height, start, stop, closed = false, options) {
|
|
const d = this.gen.arc(x, y, width, height, start, stop, closed, options);
|
|
return this.draw(d);
|
|
}
|
|
curve(points, options) {
|
|
const d = this.gen.curve(points, options);
|
|
return this.draw(d);
|
|
}
|
|
path(d, options) {
|
|
const drawing = this.gen.path(d, options);
|
|
return this.draw(drawing);
|
|
}
|
|
draw(drawable) {
|
|
const sets = drawable.sets || [];
|
|
const o = drawable.options || this.gen.defaultOptions;
|
|
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;
|
|
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;
|
|
break;
|
|
}
|
|
case 'path2Dpattern': {
|
|
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;
|
|
}
|
|
opsToPath(drawing) {
|
|
return this.gen.opsToPath(drawing);
|
|
}
|
|
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;
|
|
path.style.strokeWidth = fweight + '';
|
|
path.style.fill = 'none';
|
|
return path;
|
|
}
|
|
}
|