mirror of
https://github.com/slidevjs/rough-notation.git
synced 2026-01-14 17:44:21 +01:00
@@ -10,6 +10,8 @@ export interface Rect {
|
||||
}
|
||||
|
||||
export type RoughAnnotationType = 'underline' | 'box' | 'circle' | 'highlight' | 'strike-through' | 'crossed-off';
|
||||
export type FullPadding = [number, number, number, number];
|
||||
export type RoughPadding = number | [number, number] | FullPadding;
|
||||
|
||||
export interface RoughAnnotationConfig {
|
||||
type: RoughAnnotationType;
|
||||
@@ -18,7 +20,7 @@ export interface RoughAnnotationConfig {
|
||||
animationDelay?: number; // default = 0
|
||||
color?: string; // defaults to currentColor
|
||||
strokeWidth?: number; // default based on type
|
||||
padding?: number; // defaults to 5px
|
||||
padding?: RoughPadding; // defaults to 5px
|
||||
iterations?: number; // defaults to 2
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Rect, RoughAnnotationConfig, SVG_NS, DEFAULT_ANIMATION_DURATION } from './model.js';
|
||||
import { Rect, RoughAnnotationConfig, SVG_NS, DEFAULT_ANIMATION_DURATION, FullPadding } from './model.js';
|
||||
import { ResolvedOptions, OpSet } from 'roughjs/bin/core';
|
||||
import { line, rectangle, ellipse } from 'roughjs/bin/renderer';
|
||||
|
||||
@@ -29,16 +29,42 @@ const highlightOptions = JSON.parse(JSON.stringify(defaultOptions));
|
||||
highlightOptions.roughness = 3;
|
||||
highlightOptions.disableMultiStroke = true;
|
||||
|
||||
function parsePadding(config: RoughAnnotationConfig): FullPadding {
|
||||
const p = config.padding;
|
||||
if (p || (p === 0)) {
|
||||
if (typeof p === 'number') {
|
||||
return [p, p, p, p];
|
||||
} else if (Array.isArray(p)) {
|
||||
const pa = p as number[];
|
||||
if (pa.length) {
|
||||
switch (pa.length) {
|
||||
case 4:
|
||||
return [...pa] as FullPadding;
|
||||
case 1:
|
||||
return [pa[0], pa[0], pa[0], pa[0]];
|
||||
case 2:
|
||||
return [...pa, ...pa] as FullPadding;
|
||||
case 3:
|
||||
return [...pa, pa[1]] as FullPadding;
|
||||
default:
|
||||
return [pa[0], pa[1], pa[2], pa[3]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return [5, 5, 5, 5];
|
||||
}
|
||||
|
||||
export function renderAnnotation(svg: SVGSVGElement, rect: Rect, config: RoughAnnotationConfig, animationGroupDelay: number) {
|
||||
const opList: OpSet[] = [];
|
||||
let strokeWidth = config.strokeWidth || 2;
|
||||
const padding = (config.padding === 0) ? 0 : (config.padding || 5);
|
||||
const padding = parsePadding(config);
|
||||
const animate = (config.animate === undefined) ? true : (!!config.animate);
|
||||
const iterations = config.iterations || 2;
|
||||
|
||||
switch (config.type) {
|
||||
case 'underline': {
|
||||
const y = rect.y + rect.h + padding;
|
||||
const y = rect.y + rect.h + padding[2];
|
||||
for (let i = 0; i < iterations; i++) {
|
||||
if (i % 2) {
|
||||
opList.push(line(rect.x + rect.w, y, rect.x, y, singleStrokeOptions));
|
||||
@@ -60,10 +86,10 @@ export function renderAnnotation(svg: SVGSVGElement, rect: Rect, config: RoughAn
|
||||
break;
|
||||
}
|
||||
case 'box': {
|
||||
const x = rect.x - padding;
|
||||
const y = rect.y - padding;
|
||||
const width = rect.w + (2 * padding);
|
||||
const height = rect.h + (2 * padding);
|
||||
const x = rect.x - padding[3];
|
||||
const y = rect.y - padding[0];
|
||||
const width = rect.w + (padding[1] + padding[3]);
|
||||
const height = rect.h + (padding[0] + padding[2]);
|
||||
for (let i = 0; i < iterations; i++) {
|
||||
opList.push(rectangle(x, y, width, height, singleStrokeOptions));
|
||||
}
|
||||
@@ -91,11 +117,10 @@ export function renderAnnotation(svg: SVGSVGElement, rect: Rect, config: RoughAn
|
||||
break;
|
||||
}
|
||||
case 'circle': {
|
||||
const p2 = padding * 2;
|
||||
const width = rect.w + (2 * p2);
|
||||
const height = rect.h + (2 * p2);
|
||||
const x = rect.x - p2 + (width / 2);
|
||||
const y = rect.y - p2 + (height / 2);
|
||||
const width = rect.w + (padding[1] + padding[3]);
|
||||
const height = rect.h + (padding[0] + padding[2]);
|
||||
const x = rect.x - padding[3] + (width / 2);
|
||||
const y = rect.y - padding[0] + (height / 2);
|
||||
const fullItr = Math.floor(iterations / 2);
|
||||
const singleItr = iterations - (fullItr * 2);
|
||||
for (let i = 0; i < fullItr; i++) {
|
||||
|
||||
Reference in New Issue
Block a user