Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

How to change the angle of a gradient layer without changing anything else?

New Here ,
Oct 08, 2013 Oct 08, 2013

How to change the angle of a gradient layer without changing anything else?

When I try it myself my whole gradient turns black.

TOPICS
Actions and scripting
1.5K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Guru , Oct 09, 2013 Oct 09, 2013

To add to the above, you can not just set the angle. If you want to use other existing settings you need to get them from the layer. The code in that other thread shows one way to get them.

But if you do not need the existing values for any other reason you can get the descriptor for the layer, make a duplicate of it with all the settings and just overwrite the ones you want to change.

This is one way to just change the angle while keeping the other existing settings.

// helper function for working

...
Translate
Adobe
Community Expert ,
Oct 08, 2013 Oct 08, 2013
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 08, 2013 Oct 08, 2013

How exactly could I use this?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 08, 2013 Oct 08, 2013

First determine the current values then use them with the changes you want.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 09, 2013 Oct 09, 2013

A warning: Mike Hale has used »typeIDToStringID« a couple of times, probably to improve clearness.

If you feed the information back into Action Manager code (recorded with ScriptingListener.plugin) it might be easier to switch the those instances to »typeIDToCharID«.

And to handle varying numbers of Color and Transparency Stops for-clauses based on the length of someObjectName.colorStops and someObjectName.transStops may have to be included.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 09, 2013 Oct 09, 2013

If you want to add to the current gradient angle you could use Mike Hale’s code and instead of »45« use something like this (the function is lifted from Mike’s code).

var newAngle = getGradientAngle()+10;

function getGradientAngle(){

    if(app.documents.length==0 || app.activeDocument.activeLayer.kind != LayerKind.GRADIENTFILL ) return;

    var ref = new ActionReference();

    ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );

    var desc = executeActionGet(ref).getList(charIDToTypeID("Adjs")).getObjectValue(0);

    if(desc.hasKey(charIDToTypeID("Angl"))) theAngle = desc.getDouble(charIDToTypeID("Angl"));

    return theAngle;

};

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Oct 09, 2013 Oct 09, 2013

I think it would be a good thing to add a range check to newAngle. The GUI only uses -180 to 180. Not sure what Photoshop would do with values outside that range, say 200.

Also as the setGradientAdjustmentAngle() function already get the settings from the layer you could save time and code lines by extending that function instead of getting the settings twice. Maybe add an optional increment argument.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 09, 2013 Oct 09, 2013

Good points.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Oct 09, 2013 Oct 09, 2013

To add to the above, you can not just set the angle. If you want to use other existing settings you need to get them from the layer. The code in that other thread shows one way to get them.

But if you do not need the existing values for any other reason you can get the descriptor for the layer, make a duplicate of it with all the settings and just overwrite the ones you want to change.

This is one way to just change the angle while keeping the other existing settings.

// helper function for working with descriptors

function getProperty( psClass, psKey, index ){// integer:Class, integer:key

    var ref = new ActionReference();

    if( psKey != undefined ) ref.putProperty( charIDToTypeID( "Prpr" ), psKey );

    if(index != undefined ){

        ref.putIndex( psClass, index );

    }else{

        ref.putEnumerated( psClass , charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );

    }

    try{

        var desc = executeActionGet(ref);

    }catch(e){ return; }// return on error

    if(desc.count == 0) return;// return undefined if property doesn't exists

    var dataType = desc.getType(psKey);

    switch(dataType){// not all types supported - returns undefined if not supported

        case DescValueType.INTEGERTYPE:

            return desc.getInteger(psKey);

            break;

        case DescValueType.ALIASTYPE:

            return desc.getPath(psKey);

            break;

        case DescValueType.BOOLEANTYPE:

            return desc.getBoolean(psKey);

            break;

        case DescValueType.BOOLEANTYPE:

            return desc.getBoolean(psKey);

            break;

        case DescValueType.UNITDOUBLE:

            return desc.getUnitDoubleValue(psKey);

            break;

        case DescValueType.STRINGTYPE:

            return desc.getString(psKey);

            break;

        case  DescValueType.OBJECTTYPE:

            return desc.getObjectValue(psKey);

            break;

        case  DescValueType.LISTTYPE:

            return desc.getList(psKey);

            break;

        case  DescValueType.ENUMERATEDTYPE:

            return desc.getEnumerationValue(psKey);

            break;

    }

};

function duplicateDescriptor( descriptor ) {

    var newDescriptor = new ActionDescriptor;

    newDescriptor.fromStream( descriptor.toStream() );

    return newDescriptor;

};

function localizeDescriptor( desc ) {

    var stream, pointer, zStringLength, zstring, localized_string, newZStringLength, previousStream, followingStream, newDesc;

    stream = desc.toStream();

    while( true ) {

        pointer = stream.search(/TEXT....\x00\$\x00\$\x00\$/);

        if( pointer === -1 ) {

            break;

        }

        zStringLength = getLongFromStream( stream, pointer + 4 );

        zstring = readUnicode( stream.substr( pointer + 8, ( zStringLength - 1 ) * 2) );

        localized_string = ( localize( zstring ) ) + '\u0000';

        newZStringLength = localized_string.length;

        previousStream = stream.slice( 0, pointer);

        followingStream = stream.slice( pointer + 8 + zStringLength * 2);

        stream = previousStream.concat( 'TEXT', longToString( newZStringLength ), bytesToUnicode( localized_string ), followingStream );

    }

    newDesc = new ActionDescriptor();

    newDesc.fromStream( stream );

    return newDesc;

};

function getShortFromStream( stream, pointer ) {

    var hi, low;

    hi = stream.charCodeAt( pointer ) << 8 ;

    low = stream.charCodeAt( pointer + 1 );

    return hi + low;

};

function getLongFromStream( stream, pointer ) {

    var hi, low;

    hi = getShortFromStream( stream, pointer) << 16;

    low = getShortFromStream( stream, pointer + 2);

    return hi + low;

};

function readUnicode( unicode ) {

    var string = "";

    for( i = pointer = 0; pointer < unicode.length; i = pointer += 2) {

        string +=String.fromCharCode( getShortFromStream( unicode, pointer ) );

    }

    return string;

};

function longToString( longInteger ) {

    var string;

    string = String.fromCharCode( longInteger >>> 24 );

    string += String.fromCharCode( longInteger << 8 >>> 24 );

    string += String.fromCharCode( longInteger << 16 >>> 24 );

    string += String.fromCharCode( longInteger << 24 >>> 24 );

    return string;

};

function bytesToUnicode( bytes ) {

    var unicode = "", char_code, charIndex;

    for( charIndex  = 0; charIndex < bytes.length; charIndex ++ ) {

        char_code = bytes.charCodeAt( charIndex );

        unicode += String.fromCharCode(char_code >> 8 ) +  String.fromCharCode( char_code & 0xff );

    }

    return unicode;

};

function setGradientAdjustmentAngle( angle ) {

    var adjustmentDesc = getProperty( charIDToTypeID("Lyr "), charIDToTypeID( 'Adjs' ) ).getObjectValue(0);

    var newAdjustmentDesc = duplicateDescriptor( adjustmentDesc );

    newAdjustmentDesc.putUnitDouble( charIDToTypeID('Angl'), charIDToTypeID('#Ang'), angle );

   

    var desc = new ActionDescriptor();

        var ref = new ActionReference();

        ref.putEnumerated( stringIDToTypeID('contentLayer'), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );

    desc.putReference( charIDToTypeID('null'), ref );

    desc.putObject( charIDToTypeID('T   '), stringIDToTypeID('gradientLayer'), newAdjustmentDesc);

    executeAction( charIDToTypeID('setd'), desc, DialogModes.NO );

};

var newAngle = 45;

setGradientAdjustmentAngle( newAngle );

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 09, 2013 Oct 09, 2013

Did you include the »Align with layer« setting?

Edit: Excuse me, I see your new code is very much different from the one in the old thread.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Oct 09, 2013 Oct 09, 2013

Weren't we expecting barely average code from Mike, were we?

Tomorrow morning I'll spend a happy hour dribbling over descriptors helper functions - localizeDescriptor is paramount in ActionManager fetish. Hat off!

Davide

www.davidebarranca.com

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 16, 2013 Oct 16, 2013
LATEST

I get an error on line 108: charIDToTypeID is not a function. What am I doing wrong?

NVM FIXED IT

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines