absoluteInfluenceRect removed in Sketch 96

We’ve relied on the absoluteInfluenceRect method in our script to import from Sketch, but it seems that method was removed in Sketch 96. Is there a replacement for it?

Indeed this method has been removed in 96, we’ve moved influence rect calculations into the rendering engine, out of the model, so it deliberately doesn’t know anymore how far rendering attributes extend beyond the frame (for shadows and the like).

It was always a rough approximation, so one thing you can do is take the alignmentRect yourself and expand that if there’s a shadow or outer border etc.

If you don’t care about how far the shadows and borders poke out you should just use the alignmentRect methods without modification,

1 Like

Thanks for the info. We do care about how far shadows/borders poke out, because we use this rect to set the MSExportRequest.rect property and want to make sure that the export includes the layer’s shadows and borders.

I just came across this answer that describes how to use influenceRectForBoundsInDocument as a replacement for for absoluteInfluenceRect. This solution seems to work for us.

1 Like

And influenceRectForBoundsInDocument is gone now in Sketch 97. Basically, what Pieter said: they’re moving all drawing-related calculations to the rendering layer that doesn’t know about nothing but pixels, while the model layer doesn’t know anything about those pixels (which may not even be rendered yet).

I’ve been experimenting with a few different approaches to calculating an influence rect that would match absoluteInfluenceRect/influenceRectForBoundsInDocument results and here’s what seems to be passing all of my tests so far:

  1. Let the rendering engine do the work and calculate the actual renderable area for the layer. This area is basically a trimmed influence rect already (because empty areas are not rendered and thus not accounted for when calculating the image rendition size). So you may even stop here if that’s what you need.
    let request = MSExportRequest.exportRequestsFromLayerAncestry_(layer.ancestry()).firstObject()
    // NOTE: In order to let MSExporter run the actual rect calculations,
    // `request.rect` must be `NSZeroRect` (which is almost always
    // the case if you're creating an export request this way unless
    // your layer is a slice which has a pre-defined influence rect anyway).
    // request.setRect_(NSZeroRect)
    // This will trigger internal rendering and influence rect calculation machinery...
    let exporter = MSExporter.exporterForRequest_colorSpace_(request, nil)
    _= exporter.trimmedBounds()
    // ... that will assign the resulting rect to our request instance
    let trimmedRenderableRect = request.rect()
  2. Now, I personally am not satisfied with a trimmed influence rect, I need a full one that is equal to pre-Sketch 96 absoluteInfluenceRect which is (AFAIK) never smaller than a layer’s frame. So how do we compensate for the trimmed whitespace lost (if any)? Why not combine both the actual renderable area of a layer and its known frame?
    function absoluteRectForLayer(layer) {
        // assuming layer is not MSPage
        return layer.parentObject().convertRect_toCoordinateSpace_(layer.frame().rect(), nil)
    let absoluteInfluenceRect = NSUnionRect(trimmedRenderableRect, absoluteRectForLayer(layer));

Apart from being written in Objective-C, the actual code I use in my plugin also covers a few additional cases (e.g. restoring trimmed whitespace from a child layer of a detached symbol instance if this child layer was partially outside of this symbol’s bounds, etc), but those are minor and I only support them so I don’t have to update my tests cases :sweat_smile: