Widget Examples

Err, sorry. You use an enhanced version, please wait a minute…

1 Like

Thanks for looking into this for me. Yeah there’s some random stuff I added in that I don’t think has any function, hopefully, I didn’t make it too messy! I’m not too experienced with this stuff.

All I tried to do was edit the updated one you posted by adding the small section to add the date up top, make it a large widget, change the background, and reformat how the info is shown in terms of the weather (move feels like up, current temp + desc on the right side, and remove seconds from time updated).

Hmm not really clean but you might add a

widget.setPadding(0, 16, 30, 16) after let widget = ...

and then a widget.addSpacer(30) after your date text block to see if it fits your needs.

Edit: The setPadding pattern is (top, left, bottom, right) in pixels.

1 Like

Aha, that did it! Once I did that and changed new Point(x , x) and it’s perfect! Thank you, I spent way too long trying to figure this out myself I had to make a post for some assistance. I appreciate it :slight_smile:

Thank you @egamez and @mzeryck for this wonderful widget that I use daily now :blush:

Learning another program language is so neat!

added wind speed and cardinal arrows.
Wind gusts if there are any.
True or false to show HI and Low for the day instead of updated time.
Also Alerts image if there is an weather alert out. (I added this and saw you added same icon for cached weather. :joy: )
You can click alert icon and will take you to whatever webpage you put in to see the alerts.

Here’s a pic of the alerts before I edited more and switched over to SFSymbols.

P.S. Still learning forums and GitHub so I will let y’all know when I get it uploaded.

Thanks again for the wonderful weather widget :blush:

Here is the code. Hopefully this works.

3 Likes

may i have change the background image choice mode? because i want let the desk look colorful,but i don’t know how to do it…

First off, thanks for @mzeryck for sharing the “invisible” widget code to emulate transparent backgrounds.
Inspired by that code, I created a module to make it easier to pull the necessary wallpaper “slices”. The module handles both light and dark mode. As long as you make slices for both modes, your widgets will follow every time you switch modes.

How to Use

Setup

Download both scripts. Then run the No Background Config script. This should guide you on how to create the slices that can be used for your widgets.

Your Widget

There are different ways to get the wallpaper slice that you need to set for your widget background.

  1. By getting the actual image for a specific position.
const nobg = importModule('no-background.js')
const widget = new ListWidget();
widget.backgroundImage = await nobg.getSlice('small-top-left')

Valid slice names are:

  • small-top-left / small-top-right
  • small-middle-left / small-middle-right
  • small-bottom-left / small-bottom-right
  • medium-top / medium-middle / medium-bottom,
  • large-top / large-bottom.
  1. Getting the path of the image for a specific position.
const nobg = importModule('no-background.js')
const widget = new ListWidget();

const bgpath = nobg.getPathForSlice('small-top-left')
widget.backgroundImage = Image.fromFile(bgpath)
  1. By storing the position for a widget and pulling that using a widgetID as a key. The key can be the name of the script or maybe pass the parameter when adding the widget on your home screen.
const widgetID = "mywidget"
const nobg = importModule('no-background.js')

// store the widget position by calling this statement
// await nobg.chooseBackgroundSlice(widgetID)

const widget = new ListWidget();
widget.backgroundImage = await nobg.getSliceForWidget(widgetID)

You can find examples on the Github Repo.

Hope you find this useful.

12 Likes

Nice addition but have a look at the siplified SFSymol tweak again. Now we can use @egamez new for loop to get the ‘night’ bool and simplify all other SFSymbol related parts:

This is deprecated, we don’t need to call extra sunrise/sunset data:

// Prepare for the SFSymbol request by getting sunset/sunrise times.
const date = new Date()
const sunData = await new Request("https://api.sunrise-sunset.org/json?lat=" + LAT + "&lng=" + LON + "&formatted=0&date=" + date.getFullYear() + "-" + (date.getMonth()+1) + "-" + date.getDate()).loadJSON();

We can grab the ‘night’ boolean straight from @egamez’s fix:

// 'Night' boolean for line graph and SFSymbols
var night = (hourData.dt > hourDay.sunset || hourData.dt < hourDay.sunrise)

Then this:

// The next three lines were modified for SFSymbol support.
const condition = i==0?weatherData.current.weather[0].id:hourData.weather[0].id
const condDate = i==0?weatherData.current.dt:hourData.dt
drawImage(symbolForCondition(condition,condDate), spaceBetweenDays * i + 34, 161 - (50*delta));

simplifies to this:

// Next 2 lines SFSymbols tweak 
const condition = i==0?weatherData.current.weather[0].id:hourData.weather[0].id
drawImage(symbolForCondition(condition), spaceBetweenDays * i + 34, 161 - (50*delta)); //40, 165

And this

// This function returns an SFSymbol image for a weather condition.
function symbolForCondition(cond,condDate) {
  // get sunrise and sunset
  const sunrise = new Date(sunData.results.sunrise).getTime()
  const sunset = new Date(sunData.results.sunset).getTime()
  const timeValue = condDate * 1000
  // Is it night at the provided date?
  const night = (timeValue < sunrise) || (timeValue > sunset)
  // Define our symbol equivalencies.
  let symbols = {
    // Thunderstorm
    "2": function() {
      return "cloud.bolt.rain.fill"
    },
(...)

…turns into this and will always match the new fixed line-graph values:

// SFSymbol function
function symbolForCondition(cond){
  // Define our symbol equivalencies.
  let symbols = {
  // Thunderstorm
    "2": function(){
      return "cloud.bolt.rain.fill"
    },
(...)
2 Likes

Thank you very much,may i have the small-bottom-right widgets complete code,(also to thanks for @eqsOne for sharing the widget code )i like it very much,image ,i want make it’s background change

do you need it for the weather widget? if so do this:

  widget.backgroundColor = backgroundColor;  // <-- look for this line

  // add these lines
  var bgImage = await nobg.getSlice('small-bottom-right')
  if (bgImage) {
    var rect = new Rect(0,0,(config.widgetFamily == "small") ? contextSize : mediumWidgetWidth, contextSize)
    drawContext.drawImageInRect(bgImage,rect)
  }

but if you need it for another widget, use this code

const nobg = importModule('no-background.js')
const widget = new ListWidget();
widget.backgroundImage = await nobg.getSlice('small-bottom-right')

// widget content code goes here
widget.addSpacer()
let text = widget.addText('Hello Scriptable')
text.textColor = Color.white()
text.centerAlignText()
widget.addSpacer()
// end of widget content code

if (config.runsInWidget) {
  Script.setWidget(widget)
} else {
  await widget.presentSmall()
}
Script.complete()
1 Like

Thank you for your help😊
I will go back and edit it later on in evening.
Have a great day :grin:

Hey eqsOne, thank you for sharing your Code! I wanted to adopt this to our City and found the following page:

Here you can add the ID (for Example Mainz ist 163) of your City an get the numbers you need. But I don’t know how to get the Data from the tr / td: Bildschirmfoto 2020-10-21 um 18.03.49|308x62
Can you help me? So we can use the Script for every City / State.

Thank you :slight_smile:

yep,thank you very much` i just add the code for the weather widegt,but it can’t work,

,if you have all compelete code ,may i have one all?

there are so many versions of the weather script, I’m not sure which one you use.
to fix your error, add this line on the top of the script

const nobg = importModule('no-background.js')

Hi, I don’t know you managed to get the covid data from this form (if I enter 163 into the ID field, I only get some geometry data). However, I do know that one can select “JSON” in the bottom of the form (the default is “HTML” which should give you an easily parsable format.

If you insist on <tr><td> …: You have to use JavaScript DOM methods like in the original Covid script from @eqsOne. Something along the lines

let table = document.getElementById("COVID-Tabelle"); /* if it has an ID... */
let tr = table.getElementsByTagName("TR");
tr.forEach(row => {
  let td = tr.getElementsByTagName("TD");
 ...
})

Which is a pain… So if JSON works, use it.
Oh, and please tell me how to get the actual covid data with this form :wink: Thanks in advance

Hmm, your reference uses a rest api, no need to scratch the data from html if you just want to display the cases entry for Mainz i.e.

It loads much quicker by using a simple json request. Change the url into something like this and then just grab the ‘cases’ entry from the response.

@schm_and Here’s a quick snippet to show what I mean, this loads in just a second:

//* Mainz - Cases *//

let widget = new ListWidget()
widget.setPadding(16, 16, 16, 16)

const spc = 3
let time = new Date().getHours()

var night = (time >= 19 || time < 7)

//Title Text
let titleTxt = widget.addText("Mainz")
titleTxt.font= Font.boldSystemFont(17)
titleTxt.leftAlignText()
widget.addSpacer()

//Value Text
let vlFnt = Font.semiboldSystemFont(27)

//Untertitel Textstyle
let ptFnt = Font.systemFont(18)
let ptCol

//Hintergrund
if (night) {
  titleTxt.textColor = Color.lightGray()
  ptCol = Color.gray()
  const gradient = new LinearGradient()
  gradient.locations = [0, 1]
  gradient.colors = [
    new Color("192331"),
    new Color("222222")
  ]
  widget.backgroundGradient = gradient
}
else {
  titleTxt.textColor = Color.darkGray()
  ptCol = Color.darkGray()
}

await loadSite()

if (!config.runsInWidget) widget.presentSmall()
Script.setWidget(widget)
Script.complete()

async function loadSite() {
  //Source: Robert Koch-Institut, dl-de/by-2-0
  let url='https://services7.arcgis.com/mOBPykOjAyBO2ZKk/arcgis/rest/services/RKI_Landkreisdaten/FeatureServer/0/query?where=&objectIds=163&outFields=GEN,cases&geometry=&geometryType=esriGeometryPoint&inSR=4326&spatialRel=esriSpatialRelWithin&returnGeometry=false&outSR=4326&f=json'
  let req = new Request(url)
  let dta = await req.loadJSON()
  let res = dta.features[0].attributes
  let cases = res.cases+""
  
//**************************
  //Fälle Text
  if (res != null) {
    let tx2 = widget.addText(cases)
      tx2.leftAlignText()
      tx2.font = vlFnt
      tx2.textColor = Color.red()
  }
  //Fälle Untertitel
  let tx1 = widget.addText("Fälle")
  tx1.textColor = ptCol
  tx1.font= ptFnt
  tx1.leftAlignText()
  widget.addSpacer(spc)
}
1 Like

I tried this with the weather widget, but my log says ‘image does not exists’ but the files are there. Do you have any idea whats wrong?

thanks!

Post #412 shows @egamez’s fixed original. The one in #414 is the same with a revised version of @mzeryck’s FSymbol tweak added.

Could u help me again?it doesn’t work…

It is about #406 version。。。