To understand how it works we need to approach it step by step as the topic is pretty complex to explain.
However, I am sure you can learn quite a bit when following it step by step.
Sorry, that it took me quite a while but as you can see below the write and analysis need some calm hours to do so on my side
Lets work with this svg named simple.svg (
<svg width="210mm" height="297mm">
<defs id="defs1" />
<g id="element1" openhab="true">
<rect style="fill:#0000ff;fill-rule:evenodd;stroke-width:0.264583" id="rect1" flash="true"
width="36.495762"
height="25.169491"
x="30.203388"
y="31.461863"
/>
</g>
</svg>
- Create an item named Button1 that is a Switch-Item with an ONOFF-State
- Create an item named slider1 that is a Dimmer-item with values from 0-100 which produces a PERCENTAGE state
1) Applying colors based on a ONOFF-State
… and add the following code to the page
config:
embedSvg: true
embedSvgFlashing: true
fixedType: canvas
grid: 10
hideNavbar: true
imageUrl: /static/simple.svg
label: svg_text_sample
layoutType: fixed
screenHeight: 600
screenWidth: 1024
sidebar: false
visibleTo:
- role:administrator
embeddedSvgActions:
element1:
action: toggle
actionCommand: ON
actionCommandAlt: OFF
actionItem: Button2
stateOnColor: "#ff0000"
stateOffColor: "#00ff00"
useProxyElementForState: true
blocks: []
masonry: []
grid: []
canvas:
- component: oh-canvas-layer
config:
preload: true
slots:
default: []
Note that we
- define an actionItem Button2 that is linked to the elememt. The button is of type StateONOFF
- have set both state-colors, one for ON and the other for OFF
- have set useProxyElementForState to true because it is the subelement that is marked with flash=true to which the color should be applied
The result is that the rectangle toggles between red and green it is clicked the item Button2 is toggled between ON and OFF.
The reason is that the svg element is linked to an item that produces ON and OFF states and the colors are chosen by ON and OFF
2) Using a dimmer and applying the percentage as a brightness
Use the following code
config:
embedSvg: true
embedSvgFlashing: true
fixedType: canvas
grid: 10
hideNavbar: true
imageUrl: /static/simple.svg
label: svg_text_sample
layoutType: fixed
screenHeight: 600
screenWidth: 1024
sidebar: false
visibleTo:
- role:administrator
embeddedSvgActions:
element1:
useProxyElementForState: true
stateAsOpacity: true
stateItems:
- slider1
blocks: []
masonry: []
grid: []
canvas:
- component: oh-canvas-layer
config:
preload: true
slots:
default: []
Note that we
- have now us the stateItems section which links the dimmer state to the svg element
- don’t have a clickable element anymore
- now have a state that provides a PERCENTAGE state (not ONOFF!) which produces 0-100
- have set stateAsOpacity to true which applies the values 0 - 100 to the opacity of the blue color of the rectangle
It is important that the “color-change” which in fact is an opacity change is coming from the dimmer
3) How to get a varying color on an element?
The important part is to understand that applying colors is based on an ON/OFF-State. So let’s get back to the first example
config:
embedSvg: true
embedSvgFlashing: true
fixedType: canvas
grid: 10
hideNavbar: true
imageUrl: /static/simple.svg
label: svg_text_sample
layoutType: fixed
screenHeight: 600
screenWidth: 1024
sidebar: false
visibleTo:
- role:administrator
embeddedSvgActions:
element1:
action: toggle
actionCommand: ON
actionCommandAlt: OFF
actionItem: Button2
stateOnColor: "#ff0000"
stateOffColor: "#00ff00"
useProxyElementForState: true
blocks: []
masonry: []
grid: []
canvas:
- component: oh-canvas-layer
config:
preload: true
slots:
default: []
The above is back to a clickable element that switches between red and green because it is controlled by a State-Type ON/OFF.
If the state is ON, the color “#ff0000” is assigned
4) Now we want the color to be dynamically applied, so let’s use the following code
config:
embedSvg: true
embedSvgFlashing: true
fixedType: canvas
grid: 10
hideNavbar: true
imageUrl: /static/simple.svg
label: svg_text_sample
layoutType: fixed
screenHeight: 600
screenWidth: 1024
sidebar: false
visibleTo:
- role:administrator
embeddedSvgActions:
element1:
action: toggle
actionCommand: ON
actionCommandAlt: OFF
actionItem: Button2
stateOnColor: =(items.slider1.state>'50') ? '#ffff00':'#00ffff'
stateOffColor: "#444444"
useProxyElementForState: true
stateItems:
- Button2
- slider1
blocks: []
masonry: []
grid: []
canvas:
- component: oh-canvas-layer
config:
preload: true
slots:
default: []
Note that we
- have added both Button2 and slider1 to the stateItems as they should influence our svg element
- stateOffColor = darkgrey (#444444)
- stateOnColor is chosen dynamically based on the setting of the slider
- if the slide is above 50 we get “#ffff00”, below 50 we get “#00ffff”
The effect is that whenever the button state switches to ON it takes the currently chosen color computed based on the Dimmer-Item together with the formula.
But what happens when we move the slider1? Apparently nothing.
The reason is that even though the state change internally is recognized but is detected as PERCENTAGE.
However, Percentage-States are not ON/OFF-States, so the logic internally that picks the ON/OFF-Color with the formula is not triggered, hence the color is not being applied.
5) Using COLOR-States
Before I come back to this disadvantage, let me explain how dynamic colors can actually work (note that is NOT your usecase).
Use a COLOR-HSB item, for example the color of light, and apply this to the state like so
config:
embedSvg: true
embedSvgFlashing: true
fixedType: canvas
grid: 10
hideNavbar: true
imageUrl: /static/simple.svg
label: svg_text_sample
layoutType: fixed
screenHeight: 600
screenWidth: 1024
sidebar: false
visibleTo:
- role:administrator
embeddedSvgActions:
element1:
action: toggle
actionCommand: ON
actionCommandAlt: OFF
actionItem: thePowerItemOfAnLEDLight
stateOnColor: stateOnColor: "=(items.thePowerItemOfAnLEDLight.state==='ON') ?
items.theColorItemOfAnLEDLight.state: '#aaaaaa'"
stateOffColor: "#444444"
useProxyElementForState: true
stateItems:
- thePowerItemOfAnLEDLight
- theColorItemOfAnLEDLight
blocks: []
masonry: []
grid: []
canvas:
- component: oh-canvas-layer
config:
preload: true
slots:
default: []
Note
- we have the power switch item of the light thePowerItemOfAnLEDLight and Color Item of the light named theColorItemOfAnLEDLight
- the stateOnColor is derived from the item theColorItemOfAnLEDLight in case the Light is ON. When Off, it is just grey.
This will apply the color of the LED strip to the SVG element dynamically when the light is switched on.
But what is the difference?
The important part is theColorItemOfAnLEDLight is of STATE-TYPE HSB (Hue-Saturation-Brightness, essentially a Color-Item).
Color-State-Items are noticed, of course, as Color which triggers Color-assignment to an element.
The logic is
- An HSB item status change is detected
- If that is the case, take the color from the stateOnColor which in this case is a formular and then apply it to the color of the element
Example 3 is different as the State-Type is PERCENT (and not Color), so it doesn’t care about stateOnColor nor does it apply something to the color of the item.
It would though apply the percentage to the opacity, if you switched on StateAsOpacity.
Summary
So, in essence, as far as can currently see, there is no clever way to have your usecase implemented and it seems to be a shortcoming of my current implementation. As soon as I have time I will think about a way how your usecase could be made possible without breaking anything and making the whole topic even more complex.
PS: And yes, I should add all of this to the documentation page 