admin管理员组

文章数量:1417691

I'm working on a project where I load an SVG onto the Fabric.js canvas and programmatically add a watermark image inside the SVG. My goal is to embed the watermark only within the main SVG path or content area—not outside or covering the entire bounding box.

Current Behavior:

The watermark is added, but I want to make sure it stays within the main SVG content area and does not cover large portions of the bounding box or render outside the SVG entirely.

Expected Behavior:

The watermark should be placed only within the visible content of the SVG (e.g., inside paths or shapes) and not in empty or padding areas around the SVG.

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Fabric.js Load SVG with Black Paths</title>
  <script src="/[email protected]/dist/index.min.js"></script>
  <style>
    body {
      background-color: #f0f0f0;
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      margin: 0;
    }

    #canvas {
      border: 1px solid #ccc;
    }

    button {
      position: absolute;
      top: 20px;
      left: 20px;
      padding: 10px 20px;
      font-size: 16px;
      cursor: pointer;
    }
  </style>
</head>

<body>

  <canvas id="canvas" width="600" height="600"></canvas>

  <script>
    const canvas = new fabric.Canvas('canvas');

    const svgUrl = '.svg?v=1738307566215'; // Sample SVG URL

    fabric.loadSVGFromURL(svgUrl).then(({
      objects,
      options
    }) => {


      const svgGroup = fabric.util.groupSVGElements(objects, options);
      svgGroup.scaleToWidth(canvas.width * 0.8);
      svgGroup.scaleToHeight(canvas.height * 0.8);
      svgGroup.set({
        angle: 0,
        padding: 0,
        borderColor: '#0069FF',
        peloas: 12,
        cornerSize: 15,
        cornerColor: '#0069FF',
        cornerStyle: 'circle',
        borderScaleFactor: 1.5,
        centeredScaling: false,
        centeredRotation: true,
        transparentCorners: false,
        isLocked: false,
        visible: true,
        clipTo: null,
        lockScalingFlip: true,
        excludeFromExport: false,
        _controlsVisibility: {
          tl: true,
          tr: true,
          br: true,
          bl: true,
          ml: true,
          mt: true,
          mr: true,
          mb: true,
          mtr: true
        },
        element_type: 'SVGShape',
        isSVGElement: true,
        objectCaching: true,
        left: (canvas.width - svgGroup.getScaledWidth()) / 2,
        top: (canvas.height - svgGroup.getScaledHeight()) / 2
      });

      console.log('svgGroup: ', svgGroup);
      canvas.add(svgGroup);
      canvas.renderAll();

      addWatermarkToSvg(svgGroup, '//3c0a13c09cf845ba/proElementWatermark.png?Expires=1832916413&Key-Pair-Id=K2ZIVPTIP2VGHC&Signature=T~Nbyb9Z3gkMBLqhpObfK~bG6kxFgOsSjMqi4GwDQvFrR2EOdBn-NWZgku1qNVX~lDfjblhaz9gjHBPkUlFanw4BNpiRC8XFExmk13jugwEuIGluM3AJEU6U3JqpQDEsQg6wBM1SvUv5Katdfz9YQj-SEhBHnomEbA4UNKpUzPZ5SYVUX22kLiGPxM3TdJS~DpOyYA7SSkNimjFNS~2IINuugRofSSHWKLMxCGTK8aoBSGs2tqwNe5h06cvwgmUpRD8vE4wJc~lyBqU8-5P1DaGvuTSkybHm9jT9NgiJu-gF-PnOBZ~qRopiBhML-JDdPq6KqG3FhV8z14GuIPQ5Aw__').then(() => {
        canvas.renderAll(); // Ensure everything is properly rendered
      }).catch(err => console.error('Error adding watermark:', err));
    });


    function addWatermarkToSvg(svgObject, watermarkUrl) {
      return new Promise((resolve, reject) => {
        fabric.Image.fromURL(watermarkUrl, {
          crossOrigin: 'anonymous'
        }).then((watermark) => {
          svgObject.scaleToHeight(svgObject.height * svgObject.scaleY);
          svgObject.scaleToWidth(svgObject.width * svgObject.scaleX);

          canvas.renderAll();

          const svgBoundingBox = svgObject.getBoundingRect(true);

          // Scale and position the watermark to fit inside the SVG bounding box
          watermark.set({
            left: svgBoundingBox.left,
            top: svgBoundingBox.top + svgBoundingBox.height - watermark.getScaledHeight(),
            opacity: 1,
            selectable: false,
            evented: false,
            height: svgBoundingBox.height,
            width: svgBoundingBox.width,
          });

          // Add the watermark to the canvas
          svgObject.add(watermark);
          resolve(svgObject);
        }).catch((error) => {
          reject(error);
        });
      });
    }
  </script>

</body>

</html>

本文标签: canvasHow to add a watermark inside SVG without covering entire bounding boxStack Overflow