从零开始学 Fabric.js-01 (画一个矩形,矩形内填充图片)。

从零开始学 Fabric.js-01 (画一个矩形,矩形内填充图片)。

前言

2024 年我几乎没怎么碰过 Fabric.js,工作中遇到问题都是临时抱佛脚------翻文档、搜答案、解决问题。这样学下来,知识点零散得像一盘散沙,没个系统。所以,我决定从头开始,跟着官方文档,结合小案例,重新梳理 Fabric.js,把基础打牢。这次,我假装自己是小白,从零起步,和你一起探索这个有趣的 Canvas 库!

今日小案例:矩形填充图片

目标很简单:画一个矩形,把图片填充进去,但不创建新的 Fabric 对象。换句话说,就是让矩形直接用图片作为填充效果,而不是叠加一个独立的图片对象。

第一步:画一个矩形

先搭个基本框架,创建一个 Canvas 和矩形试试水。

html 复制代码
<canvas id="canvas" width="300" height="300"></canvas>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/index.js"></script>
<script>
  const canvas = new fabric.Canvas('canvas');
  const rect = new fabric.Rect({
    width: 100,  // 宽度
    height: 100, // 高度
    left: 100,   // 距左边距离
    top: 100,    // 距顶部距离
    fill: 'red'  // 填充红色
  });
  canvas.add(rect); // 别忘了加到画布上
</script>

运行后,Canvas 上出现一个红色矩形,位置居中,简单明了。但目标是用图片填充,红色只是占位,咱们继续。

第二步:尝试填充图片

直觉告诉我,把 fill: 'red' 改成图片 URL(比如 'https://example.com/image.jpg')应该行得通。结果一跑,报错!翻了下文档才发现,fabric.Rectfill 属性不支持直接填图片地址,得用特殊方法。

第三步:发现 fabric.Pattern

查阅 Fabric.js 官方文档(fabricjs.com/docs),`fill... 可以接受 fabric.Pattern 对象,而 fabric.Pattern 是专门用来处理图案填充的。它需要一个"源"(source),可以是图片或另一个 Canvas。思路清晰了:先把图片画到一个临时 Canvas 上,再用 fabric.Pattern 把这个 Canvas 填充到矩形。

fabric.Pattern 用法
javascript 复制代码
const pattern = new fabric.Pattern({
  source: canvas1, // 一个画了图片的 Canvas
  repeat: 'no-repeat' // 不重复填充
});

第四步:完整实现

把图片加载到临时 Canvas,再填充到矩形,代码如下:

html 复制代码
<canvas id="canvas" width="300" height="300"></canvas>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/index.js"></script>
<script>
  // 封装加载图片的 Promise
  function loadImage(url) {
    return new Promise((resolve) => {
      const img = new Image();
      img.src = url;
      img.onload = () => resolve(img);
    });
  }

  const canvas = new fabric.Canvas('canvas');
  const imgUrl = 'https://p3-passport.byteacctimg.com/img/user-avatar/3a7164e8729a54bf8a5e51a7c2bb6157~300x300.image';

  loadImage(imgUrl).then(img => {
    // 创建临时 Canvas
    const canvas1 = document.createElement('canvas');
    canvas1.width = 100;  // 匹配矩形尺寸
    canvas1.height = 100;
    const ctx = canvas1.getContext('2d');
    ctx.drawImage(img, 0, 0, 100, 100); // 画图并缩放到 100x100

    // 创建图案
    const pattern = new fabric.Pattern({
      source: canvas1,
      repeat: 'no-repeat'
    });

    // 定义矩形并填充图案
    const rect = new fabric.Rect({
      width: 100,
      height: 100,
      left: 100,
      top: 100,
      fill: pattern
    });

    canvas.add(rect); // 添加到画布
  });
</script>
在线 Demo

代码解析

  1. 加载图片 :用 loadImage 函数异步加载图片,确保图片 ready 后再操作。
  2. 临时 Canvas :创建 canvas1,用原生 2D 上下文把图片画上去,尺寸与矩形一致。
  3. 图案填充fabric.Patterncanvas1 转为填充图案,repeat: 'no-repeat' 保证不平铺。
  4. 矩形渲染 :把 pattern 赋值给 fill,矩形就有了图片效果。

小结与反思

  • 收获 :学会了 fabric.Pattern 的用法,理解了 Fabric.js 的填充机制。
  • 坑点:直接填图片 URL 不行,得转成 Canvas 或图案对象。
相关推荐
持久的棒棒君3 小时前
npm安装electron下载太慢,导致报错
前端·electron·npm
渔舟唱晚@5 小时前
大模型数据流处理实战:Vue+NDJSON的Markdown安全渲染架构
vue.js·大模型·数据流
crary,记忆5 小时前
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
前端·webpack·angular·angular.js
漂流瓶jz6 小时前
让数据"流动"起来!Node.js实现流式渲染/流式传输与背后的HTTP原理
前端·javascript·node.js
SamHou06 小时前
手把手 CSS 盒子模型——从零开始的奶奶级 Web 开发教程2
前端·css·web
我不吃饼干6 小时前
从 Vue3 源码中了解你所不知道的 never
前端·typescript
开航母的李大6 小时前
【中间件】Web服务、消息队列、缓存与微服务治理:Nginx、Kafka、Redis、Nacos 详解
前端·redis·nginx·缓存·微服务·kafka
Bruk.Liu6 小时前
《Minio 分片上传实现(基于Spring Boot)》
前端·spring boot·minio
鱼樱前端7 小时前
Vue3+d3-cloud+d3-scale+d3-scale-chromatic实现词云组件
前端·javascript·vue.js
q_19132846957 小时前
基于Springboot+Vue的办公管理系统
java·vue.js·spring boot·后端·intellij idea