告别呆板图形:Rough.js填充器系统如何用算法创造手绘质感

告别呆板图形:Rough.js填充器系统如何用算法创造手绘质感

【免费下载链接】rough 【免费下载链接】rough 项目地址: https://gitcode.com/gh_mirrors/rou/rough

你是否厌倦了UI设计中千篇一律的完美图形?当需要为数据可视化、教育课件或创意设计添加手绘风格时,如何快速实现自然的笔触效果?Rough.js填充器系统通过8种核心算法,让计算机生成的图形瞬间拥有艺术家般的笔触质感。本文将带你深入了解这个强大系统的工作原理,从接口设计到实际应用,掌握用代码创造"不完美美学"的秘诀。

填充器系统的核心架构

Rough.js的填充器系统采用接口驱动设计,所有填充算法都遵循src/fillers/filler-interface.ts定义的统一标准:

export interface PatternFiller {
  fillPolygons(polygonList: Point[][], o: ResolvedOptions): OpSet;
}

这个简洁接口要求所有填充器实现fillPolygons方法,接收多边形顶点数组和配置选项,返回操作集合(OpSet)。这种设计使系统具备高度扩展性,新增填充模式只需实现该接口即可无缝集成。

8种填充算法的家族图谱

系统提供8种各具特色的填充器实现,覆盖从规则图案到随机纹理的广泛需求:

填充器类对应样式名视觉特征核心文件
HachureFillerhachure平行斜线填充hachure-filler.ts
HatchFillercross-hatch交叉斜线填充hatch-filler.ts
ZigZagFillerzigzag锯齿波浪线zigzag-filler.ts
DotFillerdots随机点阵dot-filler.ts
DashedFillerdashed虚线轮廓dashed-filler.ts
ZigZagLineFillerzigzag-line连续折线zigzag-line-filler.ts

这种插件化架构通过src/fillers/filler.ts中的工厂方法实现算法调度:

export function getFiller(o: ResolvedOptions, helper: RenderHelper): PatternFiller {
  let fillerName = o.fillStyle || 'hachure';
  switch (fillerName) {
    case 'zigzag':
      return new ZigZagFiller(helper);
    case 'cross-hatch':
      return new HatchFiller(helper);
    // ...其他填充器实例化逻辑
    default:
      return new HachureFiller(helper);
  }
}

从接口到实现:填充算法的工作原理

以交叉填充(HatchFiller)为例

交叉填充是最常用的手绘风格之一,通过两组相交的平行斜线创造纹理。src/fillers/hatch-filler.ts实现了这一算法,其核心思路是:

  1. 生成第一组与X轴成45°的平行斜线
  2. 生成第二组与X轴成-45°的平行斜线
  3. 通过随机偏移模拟手绘的不完美感
// 简化逻辑示意
class HatchFiller implements PatternFiller {
  fillPolygons(polygonList: Point[][], o: ResolvedOptions): OpSet {
    const ops1 = this.generateHachureLines(polygonList, o, 45);  // 45度线
    const ops2 = this.generateHachureLines(polygonList, o, -45); // -45度线
    return { ops: [...ops1, ...ops2] };
  }
  
  private generateHachureLines(/* 参数 */) {
    // 计算线间距、偏移量和随机抖动
    // 根据多边形边界裁剪线条
    // 返回操作集合
  }
}

锯齿填充(ZigZagFiller)的波形算法

src/fillers/zigzag-filler.ts实现了独特的锯齿波浪效果,通过三角函数生成周期性起伏的线条:

// 简化逻辑示意
class ZigZagFiller implements PatternFiller {
  fillPolygons(polygonList: Point[][], o: ResolvedOptions): OpSet {
    const lines = [];
    for (let y = minY; y < maxY; y += lineSpacing) {
      const line = this.createZigZagLine(y, o);
      const clipped = this.clipToPolygon(line, polygonList);
      lines.push(...clipped);
    }
    return { ops: lines };
  }
  
  private createZigZagLine(y: number, o: ResolvedOptions) {
    const points = [];
    for (let x = minX; x < maxX; x += segmentLength) {
      // 应用正弦函数生成波浪
      const offset = Math.sin(x * frequency) * amplitude;
      points.push({ x, y: y + offset + this.helper.randOffset(y, o) });
    }
    return points;
  }
}

实际应用:5分钟上手填充器系统

基础使用示例

通过Rough.js的SVG渲染器,只需几行代码即可应用填充效果:

<svg id="canvas" width="400" height="400"></svg>
<script src="https://cdn.jsdelivr.net/npm/roughjs@4.5.2/bundled/rough.js"></script>
<script>
  const rc = rough.svg(document.getElementById('canvas'));
  
  // 创建带交叉填充的矩形
  const rect = rc.rectangle(10, 10, 200, 150, {
    fill: 'red',
    fillStyle: 'cross-hatch', // 使用交叉填充
    hachureAngle: 45,         // 主斜线角度
    hachureGap: 10,           // 线间距
    fillWeight: 1.5           // 线条粗细
  });
  
  document.getElementById('canvas').appendChild(rect);
</script>

填充效果对比

不同填充算法在相同参数下产生截然不同的视觉效果,以下是几种常用填充样式的对比(示例来自项目visual-tests/svg目录):

点阵填充(DotFiller)

点阵填充效果

通过src/fillers/dot-filler.ts实现,随机分布的点密度和大小创造出颗粒感,适合表现粗糙材质或阴影效果。

虚线填充(DashedFiller)

虚线填充效果

src/fillers/dashed-filler.ts实现的虚线样式,通过控制线段长度和间距,可模拟手绘草图的轮廓线效果。

交叉填充(HatchFiller)

交叉填充效果

src/fillers/hatch-filler.ts的交叉线条创造出丰富的层次感,常用于技术插图和工程图纸。

高级应用:自定义填充器

Rough.js的接口设计使创建自定义填充器变得简单。假设我们需要实现一种"星点填充",只需创建新的PatternFiller实现:

// 自定义星点填充器示例
class StarFiller implements PatternFiller {
  constructor(private helper: RenderHelper) {}
  
  fillPolygons(polygonList: Point[][], o: ResolvedOptions): OpSet {
    const ops = [];
    // 在多边形内随机生成星形
    for (let i = 0; i < o.fillDensity * 100; i++) {
      const point = this.getRandomPointInPolygon(polygonList);
      const star = this.createStar(point.x, point.y, o);
      ops.push(...this.renderStar(star, o));
    }
    return { ops };
  }
  
  // 其他辅助方法...
}

// 注册自定义填充器
// 注意:实际实现需修改filler.ts中的getFiller方法

结语:不完美中的美学

Rough.js填充器系统通过精妙的算法设计,将计算机的精确性与手绘的有机质感完美结合。从src/fillers/filler-interface.ts的接口定义,到各种填充器的具体实现,整个系统展现了优秀的可扩展性和模块化设计。

无论是数据可视化、教育应用还是创意设计,这些填充算法都能为你的项目注入独特的人文温度。下一步,你可以尝试:

  • 调整src/core.ts中的ResolvedOptions配置,创造新的视觉效果
  • 基于现有填充器修改算法参数,探索更多可能性
  • 实现自定义填充器,扩展系统功能

现在,是时候用这些强大的工具,让你的图形界面告别机械的完美,拥抱手绘的温暖与生命力了。

【免费下载链接】rough 【免费下载链接】rough 项目地址: https://gitcode.com/gh_mirrors/rou/rough

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值