How to rotate an Icon?

I would like to rotate an icon in my widget. Therefore I tried following code what does not work:

- component: oh-label-card
                  config:
                    icon: f7:compass
                    iconColor: blue
                    item: =(props.directionItem)
                    label: =`${items[props.directionItem].state}`
                    style:
                      transform: rotate(${props.rotationAngle

With the rotationAngle the icon shall rotate in an angle between 0-359°.

Thanks

There are two things here. First, your widget expressions are a little haphazard. It would probably help you to go over the basics of widget expressions:

The style object only applies css style directive directly to the card itself. This means that what you have would turn the whole card, not the icon, but you don’t see any effect because the expression is not correct.

Second, there is no built in property to control the rotation of the icon or icon style. So, you have to add the css yourself using a stylesheet. The difficult part here is that this is a two step process.

The stylesheet property can only be a simple string, it does not get parsed by the expression parser, so for the first step you need to define a css variable in the card’s style object that holds the value you want to use to rotate because you can use expressions in the style object. Your expression is simple. You want the numerical value of a particular item (#'SomeItemName', in this case your item is in a widget variable to it would be #props.directionItem) with the css angle unit ('deg') appended to it:

- component: oh-label-card
  config:
    icon: f7:compass
    iconColor: blue
    item: =props.directionItem
    style:
      --card-icon-rotate: =#props.directionItem + 'deg'

That still won’t do anything because we haven’t used a stylesheet to apply that variable. For the stylesheet we are just adding regular css:

- component: oh-label-card
  config:
    icon: f7:compass
    iconColor: blue
    item: =props.directionItem
    style:
      --card-icon-rotate: =#props.directionItem + 'deg'
    stylesheet: >
      .icon {
        transform: rotate(var(--card-icon-rotate));
      }

image

Other notes:

  1. You don’t need both the label and the item property in the label card. The item property just uses the state of an item to set the card’s label, but if you use both the label property overrides the item property.
  2. items[SomeItemName].state will always return a string version of the item state. The `...` form is a javascript string template which allows you to combine string literals with any variables (written as ${expression result}) into a single string. So =`${items[props.directionItem].state}` is quite redundant as you are using an expression to get a string, and then converting that string into a …string… in order to include it in a …string… that has no other information. That’s why =props.directionItem is sufficient in this case.
1 Like

thanks a lot for the very good explination! Not easy but of course if you know how to do it, it is…

Thank you!

sorry for asking again: It works for f7: icons but when I download a different svn icons and put it in the classic folder, it shows the icon but without rotation.

Do you have an idea why?

Even though all the different icon options are accessed through the same icon property (or oh-icon component, etc.), they are handled differently because of the nature of the icon packs themselves. In the case of the icons served directly from oh through the classic icons folder, the rendered image no longer has the icon class applied to it. This means that the css in the stylesheet which targets anything with the icon class doesn’t apply to that image.

To target the image displayed from an oh served icon you need to change .icon in your stylesheet to .item-media > img:

    stylesheet: >
      .item-media > img {
        transform: rotate(var(--card-icon-rotate));
      }

Thanks a lot - that works without problem!!! Good, that there are experts like you who knows…