Skip to main content
June 17, 2019
Answered

Fit Layer To Canvas Keeping Aspect Ratio

  • June 17, 2019
  • 2 replies
  • 6150 views

Hello

I'm currently using the below script to resize a layer to fit the canvas, however I would like to adjust it so it keeps in ratio. It currently stretches the whole layer to fit the canvas which isn't quite what I'm after. I would like it to fit specifically to the width or the height of the canvas depending if the layer content is wider than it is tall or vice-versa. Unfortunately I have zero scripting skills and am at a complete loss on what to adjust. Any help would be fantastic.

var maintainAspectRatio;// set to true to keep aspect ratio 

    if(app.documents.length>0){ 

        app.activeDocument.suspendHistory ('Fit Layer to Canvas', 'FitLayerToCanvas('+maintainAspectRatio+')'); 

    } 

    function FitLayerToCanvas( keepAspect ){// keepAspect:Boolean - optional. Default to false 

        var doc = app.activeDocument; 

        var layer = doc.activeLayer; 

        // do nothing if layer is background or locked 

        if(layer.isBackgroundLayer || layer.allLocked || layer.pixelsLocked 

                                || layer.positionLocked || layer.transparentPixelsLocked ) return; 

        // do nothing if layer is not normal artLayer or Smart Object 

        if( layer.kind != LayerKind.NORMAL && layer.kind != LayerKind.SMARTOBJECT) return; 

        // store the ruler 

        var defaultRulerUnits = app.preferences.rulerUnits; 

        app.preferences.rulerUnits = Units.PIXELS; 

         

        var width = doc.width.as('px'); 

        var height =doc.height.as('px'); 

        var bounds = app.activeDocument.activeLayer.bounds; 

        var layerWidth = bounds[2].as('px')-bounds[0].as('px'); 

        var layerHeight = bounds[3].as('px')-bounds[1].as('px'); 

             

        // move the layer so top left corner matches canvas top left corner 

        layer.translate(new UnitValue(0-layer.bounds[0].as('px'),'px'), new UnitValue(0-layer.bounds[1].as('px'),'px')); 

        if( !keepAspect ){ 

            // scale the layer to match canvas 

            layer.resize( (width/layerWidth)*100,(height/layerHeight)*100,AnchorPosition.TOPLEFT); 

        }else{ 

            var layerRatio = layerWidth / layerHeight; 

            var newWidth = width; 

            var newHeight = ((1.0 * width) / layerRatio); 

            if (newHeight >= height) { 

                newWidth = layerRatio * height; 

                newHeight = height; 

            } 

            var resizePercent = newWidth/layerWidth*100; 

            app.activeDocument.activeLayer.resize(resizePercent,resizePercent,AnchorPosition.TOPLEFT); 

        } 

        // restore the ruler 

        app.preferences.rulerUnits = defaultRulerUnits; 

    } 

This topic has been closed for replies.
Correct answer Stephen Marsh

I just posted this in another topic thread (this code is the opposite, it maintains proportion, the other script code stretches):

 

// FIT LAYER TO CANVAS 
// via https://forums.adobe.com/message/5413957#5413957 
// https://gist.githubusercontent.com/jawinn/ab4df1c33d0743e41fd3/raw/72ff297ae42ed029c86be7644bd021ef4... 
var maintainAspectRatio = true; // set to true to keep aspect ratio, false to stretch/distort to fit   
if (app.documents.length > 0) {
    app.activeDocument.suspendHistory('Fit Layer to Canvas', 'FitLayerToCanvas(' + maintainAspectRatio + ')');
}

function FitLayerToCanvas(keepAspect) { // keepAspect:Boolean - optional. Default to false   
    var doc = app.activeDocument;
    var layer = doc.activeLayer;
    // do nothing if layer is background or locked   
    if (layer.isBackgroundLayer || layer.allLocked || layer.pixelsLocked ||
        layer.positionLocked || layer.transparentPixelsLocked) return;
    // do nothing if layer is not normal artLayer or Smart Object   
    if (layer.kind != LayerKind.NORMAL && layer.kind != LayerKind.SMARTOBJECT) return;
    // store the ruler   
    var defaultRulerUnits = app.preferences.rulerUnits;
    app.preferences.rulerUnits = Units.PIXELS;

    var width = doc.width.as('px');
    var height = doc.height.as('px');
    var bounds = app.activeDocument.activeLayer.bounds;
    var layerWidth = bounds[2].as('px') - bounds[0].as('px');
    var layerHeight = bounds[3].as('px') - bounds[1].as('px');

    // move the layer so top left corner matches canvas top left corner   
    layer.translate(new UnitValue(0 - layer.bounds[0].as('px'), 'px'), new UnitValue(0 - layer.bounds[1].as('px'), 'px'));
    if (!keepAspect) {
        // scale the layer to match canvas   
        layer.resize((width / layerWidth) * 100, (height / layerHeight) * 100, AnchorPosition.TOPLEFT);
    } else {
        var layerRatio = layerWidth / layerHeight;
        var newWidth = width;
        var newHeight = ((1.0 * width) / layerRatio);
        if (newHeight >= height) {
            newWidth = layerRatio * height;
            newHeight = height;
        }
        var resizePercent = newWidth / layerWidth * 100;
        app.activeDocument.activeLayer.resize(resizePercent, resizePercent, AnchorPosition.TOPLEFT);
    }
    // restore the ruler   
    app.preferences.rulerUnits = defaultRulerUnits;
}

2 replies

schroef
Inspiring
February 1, 2020

Does anyone know how i can reset scale to 100%. Im trying make simple script, but the resize function works with percentage, so simply using 100 doesnt do anything. I cant find the reference for this in the scripting documents. Neither does there exist a simple function "reset scale" or "reset transformation". At least not that i know of

Stephen Marsh
Community Expert
Community Expert
December 17, 2022
quote

Does anyone know how i can reset scale to 100%.


By @schroef

 

@schroef – I know that this is an old post, however, your activity has now brought it to my attention... If you were referring to resetting a smart object transformation:

 

// Reset the SO transform
var idplacedLayerResetTransforms = stringIDToTypeID("placedLayerResetTransforms");
executeAction(idplacedLayerResetTransforms, undefined, DialogModes.NO);
Stephen Marsh
Community Expert
Stephen MarshCommunity ExpertCorrect answer
Community Expert
June 17, 2019

I just posted this in another topic thread (this code is the opposite, it maintains proportion, the other script code stretches):

 

// FIT LAYER TO CANVAS 
// via https://forums.adobe.com/message/5413957#5413957 
// https://gist.githubusercontent.com/jawinn/ab4df1c33d0743e41fd3/raw/72ff297ae42ed029c86be7644bd021ef4... 
var maintainAspectRatio = true; // set to true to keep aspect ratio, false to stretch/distort to fit   
if (app.documents.length > 0) {
    app.activeDocument.suspendHistory('Fit Layer to Canvas', 'FitLayerToCanvas(' + maintainAspectRatio + ')');
}

function FitLayerToCanvas(keepAspect) { // keepAspect:Boolean - optional. Default to false   
    var doc = app.activeDocument;
    var layer = doc.activeLayer;
    // do nothing if layer is background or locked   
    if (layer.isBackgroundLayer || layer.allLocked || layer.pixelsLocked ||
        layer.positionLocked || layer.transparentPixelsLocked) return;
    // do nothing if layer is not normal artLayer or Smart Object   
    if (layer.kind != LayerKind.NORMAL && layer.kind != LayerKind.SMARTOBJECT) return;
    // store the ruler   
    var defaultRulerUnits = app.preferences.rulerUnits;
    app.preferences.rulerUnits = Units.PIXELS;

    var width = doc.width.as('px');
    var height = doc.height.as('px');
    var bounds = app.activeDocument.activeLayer.bounds;
    var layerWidth = bounds[2].as('px') - bounds[0].as('px');
    var layerHeight = bounds[3].as('px') - bounds[1].as('px');

    // move the layer so top left corner matches canvas top left corner   
    layer.translate(new UnitValue(0 - layer.bounds[0].as('px'), 'px'), new UnitValue(0 - layer.bounds[1].as('px'), 'px'));
    if (!keepAspect) {
        // scale the layer to match canvas   
        layer.resize((width / layerWidth) * 100, (height / layerHeight) * 100, AnchorPosition.TOPLEFT);
    } else {
        var layerRatio = layerWidth / layerHeight;
        var newWidth = width;
        var newHeight = ((1.0 * width) / layerRatio);
        if (newHeight >= height) {
            newWidth = layerRatio * height;
            newHeight = height;
        }
        var resizePercent = newWidth / layerWidth * 100;
        app.activeDocument.activeLayer.resize(resizePercent, resizePercent, AnchorPosition.TOPLEFT);
    }
    // restore the ruler   
    app.preferences.rulerUnits = defaultRulerUnits;
}
June 17, 2019

This is perfect, thank you so much!

Stephen Marsh
Community Expert
Community Expert
June 19, 2019

Glad to be of help.