Rough.js: как заставить компьютер рисовать «от руки»

Слишком простая, ровная графика может быстро надоедать. Простой способ внести приятную шероховатость – библиотека Rough.js

Rough.js – небольшая графическая библиотека (< 9 кБ в gzip), позволяющая рисовать на JavaScript в скетчевом стиле, делать графику, как бы сделанную от руки. Библиотека определяет примитивы для рисования линий, кривых, дуг, многоугольников, кругов и эллипсов. Она также поддерживает рисование путей SVG. В середине января вышел релиз 4.0, в этой публикации мы постараемся соединить известные данные и нововведения.

Rough.js работает как с Canvas, так и с SVG.

Rough.js: как заставить компьютер рисовать «от руки»

Установка

Устанавливаем из менеджера пакетов:

 npm install --save roughjs 

Используем в коде:

 import rough from 'roughjs'; 

Примеры использования

Полная документация API Rough.js доступна на Github.

Приведём несколько примеров.

Прямоугольник

Rough.js: как заставить компьютер рисовать «от руки»
 const rc = rough.canvas(document.getElementById('canvas'));
rc.rectangle(10, 10, 200, 200); // x, y, ширина, высота 

Для SVG-варианта:

 const rc = rough.svg(svg);
let node = rc.rectangle(10, 10, 200, 200); // x, y, ширина, высота
svg.appendChild(node); 

Линии и эллипсы

Rough.js: как заставить компьютер рисовать «от руки»
 rc.circle(80, 120, 50); // centerX, centerY, диаметр
rc.ellipse(300, 100, 150, 80); // centerX, centerY, ширина, высота
rc.line(80, 120, 300, 100); // x1, y1, x2, y2 

Заполнение

Rough.js: как заставить компьютер рисовать «от руки»
 rc.circle(50, 50, 80, { fill: 'red' }); // fill with red hachure
rc.rectangle(120, 15, 80, 80, { fill: 'red' });
rc.circle(50, 150, 80, { fill: "rgb(10,150,10)", fillWeight: 3 // thicker lines for hachure
});
rc.rectangle(220, 15, 80, 80, { fill: 'red', hachureAngle: 60, // angle of hachure, hachureGap: 8
});
rc.rectangle(120, 105, 80, 80, { fill: 'rgba(255,0,200,0.2)', fillStyle: 'solid' // solid fill
}); 

Стили заливки могут быть: штриховкой (по умолчанию), сплошной, зигзагообразной, поперечной штриховкой, точками, солнечными лучами, пунктирной или зигзагообразной линией

Rough.js: как заставить компьютер рисовать «от руки»

Стиль зарисовки

Rough.js: как заставить компьютер рисовать «от руки»
 rc.rectangle(15, 15, 80, 80, { roughness: 0.5, fill: 'red' });
rc.rectangle(120, 15, 80, 80, { roughness: 2.8, fill: 'blue' });
rc.rectangle(220, 15, 80, 80, { bowing: 6, stroke: 'green', strokeWidth: 3 }); 

Пути SVG

Rough.js: как заставить компьютер рисовать «от руки»
 rc.path('M80 80 A 45 45, 0, 0, 0, 125 125 L 125 80 Z', { fill: 'green' });
rc.path('M230 80 A 45 45, 0, 1, 0, 275 125 L 275 80 Z', { fill: 'purple' });
rc.path('M80 230 A 45 45, 0, 0, 1, 125 275 L 125 230 Z', { fill: 'red' });
rc.path('M230 230 A 45 45, 0, 1, 1, 275 275 L 275 230 Z', { fill: 'blue' }); 

Примеры посложнее

Rough.js: как заставить компьютер рисовать «от руки»
 const rc = rough.canvas(document.getElementById('canvas')); //line and rectangle
rc.rectangle(10, 10, 100, 100);
rc.rectangle(140, 10, 100, 100, { fill: 'rgba(255,0,0,0.2)', fillStyle: 'solid', roughness: 2
});
rc.rectangle(10, 130, 100, 100, { fill: 'red', stroke: 'blue', hachureAngle: 60, hachureGap: 10, fillWeight: 5, strokeWidth: 5
}); // ellipse and circle
rc.ellipse(350, 50, 150, 80);
rc.ellipse(610, 50, 150, 80, { fill: 'blue'
});
rc.circle(480, 50, 80, { stroke: 'red', strokeWidth: 2, fill: 'rgba(0,255,0,0.3)', fillStyle: 'solid'
}); //overlapping circles
rc.circle(480, 150, 80, { stroke: 'red', strokeWidth: 4, fill: 'rgba(0,255,0,1)', fillWeight: 4, hachureGap: 6
});
rc.circle(530, 150, 80, { stroke: 'blue', strokeWidth: 4, fill: 'rgba(255,255,0,1)', fillWeight: 4, hachureGap: 6
}); // linearPath and polygon
rc.linearPath([[690, 10], [790, 20], [750, 120], [690, 100]], { roughness: 0.7, stroke: 'red', strokeWidth: 4
});
rc.polygon([[690, 130], [790, 140], [750, 240], [690, 220]]);
rc.polygon([[690, 250], [790, 260], [750, 360], [690, 340]], { stroke: 'red', strokeWidth: 4, fill: 'rgba(0,0,255,0.2)', fillStyle: 'solid'
});
rc.polygon([[690, 370], [790, 385], [750, 480], [690, 460]], { stroke: 'red', hachureAngle: 65, fill: 'rgba(0,0,255,0.6)'
}); // arcs
rc.arc(350, 200, 200, 180, Math.PI, Math.PI * 1.6);
rc.arc(350, 300, 200, 180, Math.PI, Math.PI * 1.6, true);
rc.arc(350, 300, 200, 180, 0, Math.PI / 2, true, { stroke: 'red', strokeWidth: 4, fill: 'rgba(255,255,0,0.4)', fillStyle: 'solid'
});
rc.arc(350, 300, 200, 180, Math.PI / 2, Math.PI, true, { stroke: 'blue', strokeWidth: 2, fill: 'rgba(255,0,255,0.4)'
}); // draw sine curve
let points = [];
for (let i = 0; i < 20; i++) { // 4pi - 400px let x = (400 / 20) * i + 10; let xdeg = (Math.PI / 100) * x; let y = Math.round(Math.sin(xdeg) * 90) + 500; points.push([x, y]);
}
rc.curve(points, { roughness: 1.2, stroke: 'red', strokeWidth: 3
}); 
Rough.js: как заставить компьютер рисовать «от руки»
 const rc = rough.canvas(document.getElementById('canvas'), { async: true, options: { simplification: 0.2, roughness: 0.65 }
});
const width = 960, height = 500;
const projection = d3.geo.albersUsa().scale(1070).translate([width / 2, height / 2]);
const path = d3.geo.path().projection(projection);
const randomColor = () => { let r = `rgb(${Math.round(Math.random() * 255)}, ${Math.round(Math.random() * 255)}, ${Math.round(Math.random() * 255)})`; return r;
}
const randomAngle = () => { return (Math.random() > 0.5 ? -1 : 1) * (1 + Math.random() * 88);
}
const randomStyle = () => { return (Math.random() > 0.5 ? 'solid' : '');
}
d3.json("./us.json", async (error, us) => { if (error) throw error; let topo = topojson.feature(us, us.objects.states).features; for (let feature of topo) { rc.path(path(feature), { fill: randomColor(), fillStyle: randomStyle(), hachureAngle: randomAngle() }); }
}); 

Появилось в версии 4.0: задание seed для случайных чисел

Многие пользователи просили эту функцию. Rough.js вычисляет фигуры, генерируя много случайных смещений. В результате каждый рендер создает уникальную нарисованную от руки форму. Однако в некоторых случаях это нежелательное поведение, и приложение может захотеть сохранить форму даже при разных размерах.

API теперь позволяет пользователю передавать начальное значение, которое используется для генерации предсказуемой последовательности случайных чисел. Предоставление семян не является обязательным.

 const seed = rough.newSeed();
rc.rectangle(10, 10, 200, 200, { fill: 'red', seed });
rc.rectangle(240, 10, 250, 250, { fill: 'blue', seed }); 
Rough.js: как заставить компьютер рисовать «от руки»

Заполнение

 rc.rectangle(240, 10, 250, 250, { stroke: 'none', fill: 'blue' }); 
Rough.js: как заставить компьютер рисовать «от руки»

Ещё примеры:

  1. Wired elements – набор элементов на основе Rough.js.

Желательно построить публикацию в духе «пример кода – пример рисунка». https://github.com/pshihn/rough https://github.com/pshihn/rough/wiki

proglib.io

Добавить комментарий

Ваш e-mail не будет опубликован.

17 − 14 =