Skip to content

New feature: Ellipse rotation #2935

@MUYUM

Description

@MUYUM

Hi

For one project I need to rotate ellipse. This is currently not supported by jsPDF, therefore I invested some time to extend the code.

It's my first time contributing to jsPDF, therefore I haven't pushed anything to GitHub. It's better if "admin" does it and I will check the changes later.

Current code in jsPDF:

API.__private__.ellipse = API.ellipse = function(x, y, rx, ry, style) {
    if (
      isNaN(x) ||
      isNaN(y) ||
      isNaN(rx) ||
      isNaN(ry) ||
      !isValidStyle(style)
    ) {
      throw new Error("Invalid arguments passed to jsPDF.ellipse");
    }
    var lx = (4 / 3) * (Math.SQRT2 - 1) * rx,
      ly = (4 / 3) * (Math.SQRT2 - 1) * ry;

    moveTo(x + rx, y);
    curveTo(x + rx, y - ly, x + lx, y - ry, x, y - ry);
    curveTo(x - lx, y - ry, x - rx, y - ly, x - rx, y);
    curveTo(x - rx, y + ly, x - lx, y + ry, x, y + ry);
    curveTo(x + lx, y + ry, x + rx, y + ly, x + rx, y);

    putStyle(style);
    return this;
  };

Extended code (ellipse is rotated):

API.__private__.ellipse = API.ellipse = function(x, y, rx, ry, style, phi) {
      if (
        isNaN(x) ||
        isNaN(y) ||
        isNaN(rx) ||
        isNaN(ry) ||
        !isValidStyle(style)
      ) {
        throw new Error("Invalid arguments passed to jsPDF.ellipse");
      }
      var lx = (4 / 3) * (Math.SQRT2 - 1) * rx,
          ly = (4 / 3) * (Math.SQRT2 - 1) * ry;

      var R = (phi || 0) * Math.PI / 180; // Rotation angle (clockwise) converted to Radians

      // Array of points to be rotated
      var P = [
            { X: x + rx, Y: y      },
            { X: x + rx, Y: y - ly },
            { X: x - lx, Y: y - ry },
            { X: x - rx, Y: y + ly },
            { X: x + lx, Y: y + ry },
            { X: x + lx, Y: y - ry },
            { X: x - rx, Y: y - ly },
            { X: x - lx, Y: y + ry },
            { X: x + rx, Y: y + ly },
            { X: x     , Y: y - ry },
            { X: x - rx, Y: y      },
            { X: x     , Y: y + ry },
        ];

      // Rotate ellipse around center (clockwise)
      P.forEach(M =>
      {
          var tX = M.X - x;
          var tY = M.Y - y;

          M.mX = x + tX * Math.cos(R) - tY * Math.sin(R);
          M.mY = y + tX * Math.sin(R) + tY * Math.cos(R);
      });

      // Draw ellipse with curves: Use rotated coordinates
      moveTo (P[0].mX, P[0].mY);
      curveTo(P[1].mX, P[1].mY, P[5].mX, P[5].mY, P[ 9].mX, P[ 9].mY);
      curveTo(P[2].mX, P[2].mY, P[6].mX, P[6].mY, P[10].mX, P[10].mY);
      curveTo(P[3].mX, P[3].mY, P[7].mX, P[7].mY, P[11].mX, P[11].mY);
      curveTo(P[4].mX, P[4].mY, P[8].mX, P[8].mY, P[ 0].mX, P[ 0].mY);

      putStyle(style);
      return this;
    };

Can you please update jsPDF with the extended code. I will have a look afterwards to get idea which parts of the code were changed.

Best regards

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions