Search code examples
javascriptpluginssketchappsketch-3

Implement shadow on the object from my predefine shadows in Sketch


I am not pro in javascript but I want to implement shadow on the object from my predefine shadows but the code is not working:

      var selection = context.selection;
      for (var i=0; i < selection.count(); i++){
        var layer = selection.objectAtIndex(i)

           if (layer.isEmpty) UI.message('No layers selected!');
           else {
                var sha_0 = [];
                var sha_1 = [
                color: '#00000024',
                 x: 0,
                 y: 1,
                 blur: 1,
                 spread: 0
                ]
                var sha_2 = [
                color: '#00036024',
                 x: 0,
                 y: 1,
                 blur: 1,
                 spread: 0
                ]
                var options = ['0dp', '1dp', '2dp'];
                var selectDialog = sketch.UI.getSelectionFromUser("Please select shadow depth:", options);
                if (selected == 0) {
                layer.forEach(function (e) {
                   e.style.shadows = sha_0;
                 });
               } else if (selected == 1) {
                 layer.forEach(function (e) {
                   e.style.shadows = sha_1;
                 });
               } else if (selected == 2) {
                 layer.forEach(function (e) {
                   e.style.shadows = sha_2;
                 });
               }
           }
      }

Solution

  • The methods you need to call belonging to the UI library are asynchronous. They rely on the user performing some action before the code can continue. In Javascript this requires either a callback function or the use of async/await with Promises. The specific method you're using: sketch.UI.getSelectionFromUser is depricated in favor of the new UI.getInputFromUser method as you can find here.

    For example:

    UI.getInputFromUser(
      "What's your favorite design tool?",
      {
        type: UI.INPUT_TYPE.selection,
        possibleValues: ['Sketch', 'Paper'],
      },
      (err, value) => {
        if (err) {
          // most likely the user canceled the input
          return
        }
      }
    )
    

    Thus, your code will look something like this:

    // selected layers via document object per docs
    var selection = document.selectedLayers;
    // iterate directly over the selection layers
    selection.forEach(layer => {
      // These shadows are objects, not arrays, so changed [] to {}
      var sha_0 = [];
      var sha_1 = [{
        color: '#00000024',
        x: 0,
        y: 1,
        blur: 1,
        spread: 0
      }]
      var sha_2 = [{
        color: '#00036024',
        x: 0,
        y: 1,
        blur: 1,
        spread: 0
      }]
      var options = ['0dp', '1dp', '2dp'];
      // Use the newer getInputFromUser method
      UI.getInputFromUser(
        "Please select shadow depth:",
        {
          type: UI.INPUT_TYPE.selection,
          possibleValues: options,
        },
        (err, value) => {
          if (err) {
            // most likely the user canceled the input
            return
          }
          switch (value) {
            case options[0]:
              layer.style.shadows = sha_0;
              break;
            case options[1]:
              layer.style.shadows = sha_1;
              break;
            case options[2]:
              layer.style.shadows = sha_2;
              break;
          }
        }
      )
    })
    

    Your code could possibly be simplified more, but that should get you moving again.