Good scriptable lockscreen widget tutorial and resource?

Now that we can make lockscreen widgets in Scriptable(which is totally awesome by the way). Any good resource or tutorials available out there?

1 Like

Making widgets for the lock screen isnā€™t much different from regular widgets.

There are just some points to consider. Hopefully this list would help.

  • Colours sort of come out as grayscale. Youā€™ll need to experiment which one to use if you want to make them distinguishable from each other
  • Space is limited. Consider the font sizes you use and whenever appropriate, assign a minimumScaleFactor for text content.
  • Thereā€™s native background transparency using the addAccessoryWidgetBackground property of ListWidget.
  • Content of circular widgets are best cantered. But not mandatory of course. You do you.
  • You canā€™t customise sizes and fonts of the inline widget (the one above the clock). Donā€™t even try. Itā€™s best for one liner info.
  • You canā€™t add multiple images on the inline widget. just one and it will appear before the text. Emojis are ok though.
  • WidgetDate where the text dynamically updates every seconds works on the rectangular and circular widgets, but not on the inline widget.

These are the quirks and behaviours Iā€™ve found so far. Iā€™ll update if I find anything else.

Example Widget

7 Likes

Thanks man, really appreciate it! Good to know that making lockscreen widgets is pretty similar to making regular widgets. :grin:

Anyone know if it is possible to create those circles that temperature and fitness are using?
image

Iā€™m no expert in making graphical stuff with scriptable but I see others doing it by making the graphic in a <canvas> element inside a WebView then exporting it from there.

1 Like

Since last week I saw we can add Scriptables in the Lockscreen in the date box. (See my screenshot) Who has used that already? Any examples? :thinking:

So glad I found your post, thanks. I was trying to find changes to the Scriptable docs with the release of lockscreen widget support, and it seems the online docs are not updated (and missing addAccessoryWidgetBackground) while the in-app docs are.

@simonbs if thereā€™s any version history for docs that can be made publicly available that would be much appreciated :pray:


For anyone else interested, I believe these are the only lockscreen-widget-specific changes, all additions to ListWidget:

addAccessoryWidgetBackground: boolean;
presentAccessoryCircular: () => Promise<void>;
presentAccessoryInline: () => Promise<void>;
presentAccessoryRectangular: () => Promise<void>;

I may have missed something though.

Yes, using DrawContext, .strokeEllipse etc.

Hereā€™s a reimplementation of the circular range widget (left) with the temperature widget (right). Transparent masking doesnā€™t seem possible with DrawContext so that would require another approach.

Screenshot 2022-11-22 at 7.35.21 pm

function circularRange(val, min, max, width, height) {
  let context = new DrawContext()
  context.size = new Size(width, height)
  context.respectScreenScale = true
  context.opaque = false
  
  // background
  let rect = new Rect(0, 0, width, height)
  context.setFillColor(Color.black())
  context.fillRect(rect)

  // ring
  let lineWidth = 16
  context.setLineWidth(lineWidth)
  let ring = new Rect(lineWidth/2, lineWidth/2, width - lineWidth, height - lineWidth)
  context.setStrokeColor(Color.gray())
  context.strokeEllipse(ring)

  // mask
  let path = new Path()
  path.move(new Point(width / 2, height / 2))
  let end = Math.PI / 6
  let my = ((1 + Math.tan(end)) / 2) * height
  path.addLine(new Point(0, my))
  path.addLine(new Point(0, height))
  path.addLine(new Point(width, height))
  path.addLine(new Point(width, my))
  context.addPath(path)
  context.setFillColor(Color.black())
  context.fillPath()

  // rounded ends
  let lx = ((1 - Math.cos(end)) / 2) * (width - lineWidth)
  let ly = ((1 + Math.sin(end)) / 2) * (height - lineWidth)
  let lend = new Rect(lx, ly, lineWidth, lineWidth)
  let rx = ((1 + Math.cos(end)) / 2) * (width - lineWidth)
  let rend = new Rect(rx, ly, lineWidth, lineWidth)
  context.setFillColor(Color.gray())
  context.fillEllipse(lend)
  context.fillEllipse(rend)

  // value
  let a = (195 - (val - min) / (max - min) * 210) * Math.PI / 180
  let vx = ((1 + Math.cos(a)) / 2) * (width - lineWidth)
  let vy = ((1 - Math.sin(a)) / 2) * (height - lineWidth)
  let value = new Rect(vx, vy, lineWidth, lineWidth)
  context.setLineWidth(lineWidth * 3/4)
  context.setStrokeColor(Color.black())
  context.strokeEllipse(value)
  context.setFillColor(Color.white())
  context.fillEllipse(value)

  // labels
  context.setTextColor(Color.white())
  context.setFont(Font.mediumSystemFont(72))
  context.setTextAlignedCenter()
  context.drawTextInRect(val.toString(), new Rect(width/4, height/4, width/2, height/2))
  context.setFont(Font.regularSystemFont(32))
  context.setTextAlignedLeft()
  context.drawTextInRect(min.toString(), new Rect(width/5, height * 7/10, width * 3/10, height * 3/10))
  context.setTextAlignedRight()
  context.drawTextInRect(max.toString(), new Rect(width/2, height * 7/10, width * 3/10, height * 3/10))

  return context
}

let widget = new ListWidget()
widget.setPadding(0, 0, 0, -8)
let image = circularRange(16, 6, 18, 175, 175).getImage()
widget.addImage(image)
if (config.runsInAccessoryWidget) {
  Script.setWidget(widget)
} else {
  widget.presentSmall()
}

A couple more

  • config.runsInAccessoryWidget
  • config.widgetFamily adds 3 more values - accessoryRectangular, accessoryInline, and accessoryCircular
1 Like

Thank you for all answers. I have now done a few Lock Screen widgets and will share them here
flopp999/Scriptable (github.com)

Hello,
Please, could someone explain to me the values ā€‹ā€‹195 and 210. It seems that the restitution of the temperature is not always correct
Thanks

These are angles in degrees for positioning the value dot on the arc proportionally between the min and max values. The arc is 210 degrees long and starts at 195 degrees.

2 Likes

Thanks a lot for your explanations !

2 Likes

The widget mode that appears above the clock (is it called ā€œinlineā€?) will automatically prefix the widget with `Weekday Day" (e.g., ā€œSun 22ā€). How do I disable this? I donā€™t need this info, and it takes precious space.

1 Like

I donā€™t think it can be disabled. Itā€™s the same with other widgets, e.g. Things.

Hello,

Strangely, the Color.clear() (on the background ā€˜s rect) is OK with circular widget but not the rectangular one! See screenshot with your widget and mine.
Perhaps, something to do for Simon?

Yes, I would say so. I think the next Scriptable update would be 2.0, with a lot of new stuff to make use of, e.g. SwiftUI.

1 Like

Any idea when that would be? Its been a while now.

Probably a while yet. Hereā€™s a post from October. Simon is surprisingly productive with these hobby projects considering everything else he does (day job, conferences).

2 Likes

Can Someone help me? I want the widget to show on LockScreen but when I press add new widget there is no Option to select Scriptable in list. Appreciate every hint and help.