Resize rectangle in Paper.js
Asked Answered
W

2

5

I have a very ordinary rectangle created in Paper.js and I'd like to resize it, but I can't find any obvious ways to do it.

var rect = new Rectangle([0, 0],[width,height]);
rect.center = mousePoint;
var path = new Path.Rectangle(rect, 4);
path.fillColor = fillColor;
path.meta = fillColor;

There's a scale transformation method, but it's not really for mouse interaction and my goal is to create a handle that can resize a component.

Whitethroat answered 21/4, 2015 at 1:37 Comment(0)
G
4

You can calculate the scaling by dividing the intended width/height of your rectangle with the current width/height of your rectangle.

Then you can use that scaling 'coefficient' to apply the scaling.

Based on your code above, you can get the current width/height of your rectangle by using: rect.bounds.width and rect.bounds.height

Here's a function you can use

var rectangle = new Shape.Rectangle({
    from: [0, 0],
    to: [100, 50],
    fillColor: 'red'
});


function resizeDimensions(elem,width,height){
    //calc scale coefficients and store current position
    var scaleX = width/elem.bounds.width;
    var scaleY = height/elem.bounds.height;
    var prevPos = new Point(elem.bounds.x,elem.bounds.y);

    //apply calc scaling
    elem.scale(scaleX,scaleY);

    //reposition the elem to previous pos(scaling moves the elem so we reset it's position);
    var newPos = prevPos + new Point(elem.bounds.width/2,elem.bounds.height/2);
    elem.position = newPos;
}


resizeDimensions(rectangle,300,200)

And here's the Sketch for it.

Be aware that the above function will also reposition the element at it's previous position but it will use top-left positioning. Paper.js uses the element's center to position them so I'm clarifying this so it doesn't cause confusion

Garnishee answered 21/4, 2015 at 4:22 Comment(3)
Thank you very much. I just realized that there's a Shape object. I can call rectangle.set({ size: [200,200] }) and it works fine, but this is not the case for Path.rectangle.Whitethroat
I counter a problem with this solution. When I change the width to 0, then change it back, the scaleX is Infinity.Ironwork
Good answer after this one.Confounded
D
18

Note that PaperJS has three different kinds of Rectangles:

  • Rectangle — This is the basic type (data structure) that defines a rectangle. Basically, top-left point, width, and height. (Nothing is displayed on the screen.) This kind of rectangle can be resized by setting its size property, for instance:

    let rect;
    const originalSize = [50, 50];
    const newSize = [100, 100];
    
    rect = new Rectangle([10, 50], originalSize);
    rect.size = newSize;
    
  • Path.Rectangle — This is a method for generating a list of Segments that make up a rectangular-shaped Path. This does get displayed, but a Path lacks methods associated with a rectangle. For instance, a Path.Rectangle has no size property (so trying to modify it has no effect). To resize a Path you can use the scale() method as another answer proposes, or modify its Segments:

    rect = new Path.Rectangle([210, 50], originalSize);
    rect.strokeColor = "red";
    rect.strokeWidth = 3;
    
    rect.segments[0].point = rect.segments[0].point.add([-25, 25]);  // lower left point
    rect.segments[1].point = rect.segments[1].point.add([-25, -25]); // upper left point
    rect.segments[2].point = rect.segments[2].point.add([25, -25]);  // upper right point
    rect.segments[3].point = rect.segments[3].point.add([25, 25]);  // lower right point
    
    
  • Shape.Rectangle — This kind of rectangle gets displayed and exposes properties about its shape, such as size. To resize a Shape.Rectangle you can modify its size property directly:

    rect = new Shape.Rectangle([410, 50], originalSize)
    rect.strokeColor = "blue"
    rect.strokeWidth = 3
    
    rect.size = newSize
    

Most likely, if you want to draw a rectangle and modify its properties after the fact, the rectangle you are looking for is Shape.Rectangle.

Here is a Sketch that lets you play around with the different kinds of rectangles.

Diarist answered 1/8, 2019 at 4:23 Comment(1)
This answer is better than the accepted one. Maybe there wasn't such shapes in the 2015 version...Confounded
G
4

You can calculate the scaling by dividing the intended width/height of your rectangle with the current width/height of your rectangle.

Then you can use that scaling 'coefficient' to apply the scaling.

Based on your code above, you can get the current width/height of your rectangle by using: rect.bounds.width and rect.bounds.height

Here's a function you can use

var rectangle = new Shape.Rectangle({
    from: [0, 0],
    to: [100, 50],
    fillColor: 'red'
});


function resizeDimensions(elem,width,height){
    //calc scale coefficients and store current position
    var scaleX = width/elem.bounds.width;
    var scaleY = height/elem.bounds.height;
    var prevPos = new Point(elem.bounds.x,elem.bounds.y);

    //apply calc scaling
    elem.scale(scaleX,scaleY);

    //reposition the elem to previous pos(scaling moves the elem so we reset it's position);
    var newPos = prevPos + new Point(elem.bounds.width/2,elem.bounds.height/2);
    elem.position = newPos;
}


resizeDimensions(rectangle,300,200)

And here's the Sketch for it.

Be aware that the above function will also reposition the element at it's previous position but it will use top-left positioning. Paper.js uses the element's center to position them so I'm clarifying this so it doesn't cause confusion

Garnishee answered 21/4, 2015 at 4:22 Comment(3)
Thank you very much. I just realized that there's a Shape object. I can call rectangle.set({ size: [200,200] }) and it works fine, but this is not the case for Path.rectangle.Whitethroat
I counter a problem with this solution. When I change the width to 0, then change it back, the scaleX is Infinity.Ironwork
Good answer after this one.Confounded

© 2022 - 2024 — McMap. All rights reserved.