The versatile custom Swiss Army Knife card for Home Assistant allows you to create your unique visualization using several graphical tools, styling options and animations.
The bar tool is actually a sparkline variant: it displays only the bar values, nothing more.
Adding min/max value labels (positioning is free) would add value to the chart.
(Optional): Suggested Solution
Enabling min and max labels using a flag, or only their relative position.
Position is relative to center of chart. This makes it possible to move the chart, and keep the labels in place.
Assuming:
chart is 80 wide
chart is 40 high
min label at lower left corner:
rx = -40 (is 80/2)
ry = -25 (is 40/2) - 5. Meaning below the chart.
Update @2020.11.10:
The number of decimals is determined by the decimals value for the entity
Styling is done in the usual way: using a style.
For this, the styles section should be extended to be able to format the bar and the labels. Labels can be styled at once, or individually. This means that text-anchor can be set (start, middle, end), which might come in handy!
styles:
bar:
<values>label:
<values>label_min:
<values>label_max:
<values>label_ave:
<values>
The fill and stroke flags in the colorstops/colorlist are not yet supported by the segmented arc: the segarc always uses the color to fill a segment.
It would be nice if these colorstop flags are supported, as it makes the segarc consistent with other tools that do support these flags.
Note:
Segemented arc was already implemented before these colorstop flags where introduced.
(Optional): Suggested Solution
Since issue #48 is created/updated, there are two - non breaking - implementations:
support the fill/stroke flags for the default colorstop/list
support later on the extended colorstopex/listex to get full styling and dark/light theme support
Implement these flags, or even better, implement the new / changed colorstop idea where more styling can be done for each stop (see: #48).
Currently there are two types of coordinates used: one for tools and one for assemblies (of tools):
tools are designed using the default svg viewbox dimensions (200x200) using a 0..100 (percentage) range.
assemblies use the actual viewbox dimensions. These can be variable. Assemblies also use a 0..100 (percentage) range.
At first, percentages, ie relative coordinates seemed the best way to position tools and groups/assemblies. But after creating a lot of examples and building the software, it seems not the best solution:
Two scales might be confusing
While drawing the groups/tools on a grid (paper, Visio, or whatever tool you like), having TWO scales is really confusing
Changing the cards x/y ratio dimensions (1/1, 2/1, etc) results in the movement of the assemblies, as they are relative to the actual size of the card. So extending the card results in having to change all the assembly coordinates
Extending the size of the card was during testing mainly done to put more tools on the card, assuming the other tools won't move, ie stay at their same position! This is currently NOT the case however.
(Optional): Suggested Solution
Use the same - default svg viewbox - to specify positions.
The group will use the same default svg viewbox 0..100 grid (svg is 200x200) reference.
This means that in a 2/1 viewbox (svg 400x200), the group grid range is 0..200x0..100.
Calculations should be changed for assembly coordinates
In the card yaml files, change assembly coordinates depending on the viewbox size.
After using the slider on many views, the incidents where the slider is touched unintentionally is growing 😄
Setting the brightness of a light is not a problem, but changing the thermostat to 23 degrees Celsius is not nice!
Preventing such unintentional interactions would be a nice feature.
(Optional): Suggested Solution
The nicest solution would be a configurable lock of the thumb of the slider where the user should first unlock the slider, before he/she can interact with it.
This solution could be implemented as follows:
show a lock icon on the thumb while the slider is locked
swipe the slider to unlock the slider. This swipe would be at least half of the slider and within a specified amount of time to be recognized as a swipe (left/right for horizontal or up/down on a vertical slider).
the slider is now unlocked for a configurable amount of time, say 5 seconds orso. It keeps being unlocked while dragging the slider and is locked automatically if not
There are enough javascript examples on the internet to recognize a swipe on an element:
Enable only the thumb for touch input. In that case most touches don't do anything, as the user has to move the thumb to the required position.
some setting could be:
input: slider / thumb
The touch area should adapt to the thumb. Default is slider...
Different Suggestion @2022.01.30
If already using the tap_action dragging, then only the thumb should respond. If there are two actions, also a click, then clicking anywhere on the slider also works...
So the user can determine how the slider wil interact...
Add a list of custom fields to the sak card which can be set using JS Templates.
Users can make there own calculations and evaluations, and use those custom fields in tools, just as the standard entities.
Maybe this can also be used in the animations part. No idea...
Practical things that can be solved with this:
light brightness calculation from 0..255 to 0..100%
enable/disable slider based on some other state
pre-calculate slider values
more...
(Optional): Suggested Solution
I have no idea how to implement this, but I know that it is possible.
Should look at Home Assistant source code & custom cards, as some of those use javascript expressions to evaluate or calculate sensor and style values.
Will be a lot of javascript fu I have to learn...
I assume the expression can use:
the current entity
hass values
user values (logged in user)
the custom fields
Update 2020.10.30
A small test seems to work for getting brightness from a light.
Using a new variable that is calculated using javascript.
Now the point is how to exactly implement this.
can be used in toolset meaning used as the input for a tool.
animations can use either entity_index or custom_index orso to have animations run for different inputs. In this way the brightness can be used for a slider, but that slider can also be disabled using the light state itself (on/off).
custom_value: > [[[ if (typeof(entity) === 'undefined') return; if ('brightness' in entity.attributes) { if (entity.attributes && (entity.attributes.brightness <= 255)) { var bri = Math.round(entity.attributes.brightness / 2.55); return (bri ? bri : '0') + '%'; } } ]]]
// testing calculated valueif(this.config.custom_value){constsomeValue=newFunction('states','entity','user','hass',`'use strict'; ${this.config.custom_value.slice(4,-4)}`).call(this,this._parent._hass.states,this._parent.entities[this.config.entity_index],this._parent._hass.user,this._parent._hass,);console.log("BaseTool::set value contains CUSTOM VALUE",this.config.custom_value,someValue);localState=someValue;}
If this can be defined as a real entity, it can be used as a normal entity, so with name, units, etc.
Used within a single card, or toolset?? Putting it in a toolset makes it re-usable, User can use toolset template and get the custom variables for free. Doesn't have to declare them if toolset (template) is used in a card. Much simpler!
custom_entities:
- entity: brightnessvalue: > [[[ if (typeof(entity) === 'undefined') return; if ('brightness' in entity.attributes) { if (entity.attributes && (entity.attributes.brightness <= 255)) { var bri = Math.round(entity.attributes.brightness / 2.55); return (bri ? bri : '0') + '%'; } } ]]]name: "bright it is"unit_of_measurement: "%"icon: mdi:brightnesstrigger_entity: 0#the defined entity that triggers this evaluation. Good for performance?!?!?!?!
Add to toolset which calculates these values on every update, and sets the value for the tools that are using that special custom value?? Or is there a better way??
While observing the animation on the segmented-arc, it appears that the gap between the arcs is partially filled while going from one arc part to the next arc part and vice-versa.
It is not that the full gap is filled temporarily, but just a part of the gap. Must be some calculation going wrong.
Add generic polygon tool. This tool can generate multiple kinds of polygons (regular ones!) using Schläfli symbol to describe and generate the regular polygons:
Add colorstops, colorstopgradients and linear gradients to the segmented-arc, just as the horse-shoe already is capable of.
This will be a lot of work, as you can also color the scale with this.
ColorList
Number of segments equals number of colorlist
Each segment has the same size
Scale is rendered using colorlist
Arc is rendered using colorlist
Colorstop
Number of segments equals number of colorstops
Size of each segment depends on colorstop value
Scale is rendered using colorstops
Arc is rendered using colorstops
Colorstop, segmentcolor = curvalue
Same as colorstop, except:
All arc segments are rendered using last segments colorstop value. Eg. with 3 colorstops (green, yellow, red), and currentvalue is in red, all the segments are drawn in red color.
Colorstop gradients (single color displayed!)
Same as colorstop where segmentcolor = curvalue,, except:
Arc follows gradient of current segment and next segment??. Eg. with 3 colorstops (green, yellow, red) and value in green, color is gradient(green, yellow, %value). Value in yellow, color is gradient(yellow, red, %value). Last, value in red, color is red, as there is no next color. Red remains red...
SimpleGradient (single color displayed!)
Single segment
Two colors (start and end color)
gradientcolor depends on state value + start/end color
Scale is rendered using gradientcolor
Arc is rendered using gradientcolor
(Optional): Suggested Solution
Take the horseshoe as an example, but also check other sources for examples around this. Maybe there are better and easier solutions as the segmented-arc is completely different implemented compared to the horseshoe.
Difficulties with gradients
The segmented arc is constructed using separate path's for each segment. This probably means you can't use any gradient solutions that exactly follow the path:
linear gradients use a fixed angle
unknown if a conical gradient can work, or that requires a full rewrite of the segmented arc to use different solution
Segment color list as an alternative
One alternative to a full gradient are segmented gradients as shown below in the third arc (CPU 31 %):
And with the scale added, and filled using the same color list:
In this case a list of 10 colors is defined in the segmented arc with also 10 segments (must be changed, colorlist defines number of segments) for example.
Each segment gets its own 'fixed' color. Depending on the chosen colorlist, this can look like a nice gradient...
2020.10.13:
First results with some hacking in the creation and rendering of the segmented arc with a colorstop:
Configuration in this case:
show.style = "segmentcolorlist" or "segmentcolors"
segmentcolorlist or segmentcolors:
color1
color2
etc.
OR in segments map:
segments:
colorlist:
color1
color2
etc.
Number of segments is the number of colors in the colorlist. Simple.
Colorstops
The full arc (ie all segments) get the color according to the colorstop. This requires rewriting of the all the segments if a new colorstop is reached or, and that is easier, setting the fill color to the colorstop value.
Segments as colorstops
When using a colorstop list for the creation of the segments, each segment can have its own color. This might already be usable for CPU load, temperature, battery percentage, disk/ram percentage, etc.
In this case the segments can be of different size. Unknown if current implementation can handle this.
But using a separate color for each segment is no problem, as the fill color can be specified using javascript.
Example:
range is 0..100
colorstop 0 = green
colorstop 40 = yellow
colorstop 80 = red
Segment value ranges are
0..40, (40%)
40..80 (40%)
80..100 (20%)
Depending on the size of the full segmented arc (degrees), these segments can be calculated.
Say the arc is 90 degrees, then the segments are:
0.40 * 90 = 36 degrees
0.40 * 90 = 36 degrees
0.20 * 90 = 18 degrees
When using this option, the scale will have the colors according to the colorstops.
Configuration in this case:
show.style = "colorstops"
colorlstops:
00: color1
40: color2
80: color3
Structure
If we use a separate structure under segments for each style, then there is a 1:1 link between them
segments:
simplegradient:
colors:
- color1
- color2dash: 10 (degrees) OR count: 10 (nr of segments)gap: 1
Implementation
// als je ook een colorstop list als segmenten wilt laten zien, dan zul
// je bijv. net als d3 een lijst van segmentgroottes moeten opbouwen.
// standaard dus [20,20,20,15] bijv. zoals in de for loop al gebeurd, maar dan in een array.
// dan dat array laten plotten met gegevens.
//
// dan kun je ook van de colorstop een array maken [40,20,10] bijv. voor kleuren groen, geel, rood bijv.
// dan kun je een schaal neerzetten en zien hoever de waarde eigenlijk is. al bijna in het rood bijv.
The initial idea was to change this definition, but that is a big breaking change and requires changing all the existing views and examples.
Additionally: it hinders the quick release of the public release candidate.
(Optional): Suggested Solution
So, the suggested solution is one that is listed below and used for the lines tool (see issue #55 ), but instead of changing the current colorstop and colorlist types, these extended definitions are implemented in the colorstopex and colorlistex types!
Meaning:
Not a breaking change
Implementation can be postponed after the release candidate.
Merging animations doesn't seem to work. See also #41
This happens only with the switch tool, as this one defines default animations.
Problem is caused by:
The mergeDeep() function concatenates arrays
The function that handles the defined animations to define the style stops when the first match is found.
(Optional): Suggested Solution
This problem can be solved at two locations:
let mergeDeep() check for id's in the array, and merge by id. This means that animations should have an id.
This solutions is generic, and could be used for more arrays...
let the set value() function that handles the animation continue looking for a match in the animations array, and merge each occurrence in the array.
There is no way yet to display random text. It was in the flexible horeseshoe card.
So add this tool and see what functionality can be added to this tool to make it nice:
Basic Implementation (maybe using multiple lines??, ie as an array? But how about styling then??)
Basic Text Styles (bold, italic, etc)
Writing Mode (horizontal, vertical)
Text Outline (yep, using stroke and setting fill to none)
Text Path (text along svg path)
Text Gradient (requires using a def)
Shouldsupport inline styling also, with <tspan> elements as implementation?
And of course: the delta y, to move the next line below the current line. Always in em units.
tool:
type: textlines:
line1:
- content: "this is a test"line2
- dy: 1.2
- content: "another line"
- content: "and this is on the same line"
- content: ", but how would I style each part of this line???"line3
- path: "d = ....."
- content: "this is a test on a path"styles:
lines:
default:
font: xyza;line1:
font: xyza;line2:
font: xyzb;line3:
font: xyzc;text-size: 845739;<for second part of the line ??????? How ???????>
In other words: a line is always an array of tspans. Styling works also: use an array. This conflicts with other tools: styling is NOT an array, but a map. Is inconsistent. Maybe things like line1.1, line1.2 for different lines of content??
This also means that the toolset must be configured in the tools list. This is now a list of tools, and the group properties (xpos, ypos, scale etc.) are 'injected' into the separate tool/widget.
However, to use the svg feature to scale and translate the whole toolset, the toolset must return in the structure of the tools/widgets:
toolsets --> toolset --> tools -> tool.
Each toolset is drawn within an svg group <g> ...tools... </g>
Progress @2020.10.31
Using a hack to get a <g> extra in a toolset, I can scale/transform/skew the group using the Chrome inspector:
Progress @2020.11.03
After some hacking, two versions are required: one for Safari and one for other browser 😬
Would I have expected something else...
Both versions are not yet fully consistent, but that is something for later...
Scaling & rotating seems to work, although rotating is different on Safari and other browsers. Will be fixed later. Scaling is the most important feature. Rotating is more a gimmick...
Since late 2019, Igalia has been working on a new SVG engine, dubbed Layer-Based SVG Engine (LBSE), that will unify the HTML/SVG rendering pipelines in WebCore. This will resolve long-standing design issues of the “legacy” SVG engine and unlock a bunch of new exciting possibilities for Web developers to get creative with SVG. Hardware-accelerated compositing, driven by CSS transform animations, 3D perspective transformations for arbitrary SVG elements, CSS z-index support for all SVG graphics elements, and proper coverage rectangle computations and repaints are just a few highlights of the capabilities the future SVG engine will offer.
In this article, an overview is given about the problems that LBSE aims to solve, and the importance of a performant, well-integrated SVG engine especially for the embedded market. Finally, the current upstreaming status is summarized including an outlook for the year 2023.
If this change lands in Safari (maybe 17.x at the end of this year??), this means:
the SVG rendering engine should conform to standards, ie be compatible to chromium based browsers
full support for the foreignObject (that bug is from 2012!) object, so I can mix HTML with SVG, which would open a lot of possibilities for the Swiss Army Knife card.
hardware acceleration, ie possibly good performance for filters/shadows!
Safari svg problems, workarounds and solutions
Known foreignObject bug
Rendering icons. must calculate position on client window
2020.10.22. Discord via Bram Kragten.
Icons are async loaded. This might be the problem with Safari: a not loaded icon can't be calculated.
Testing shows that after the third render, the icon path can be queried for the path.
Possible Solution:
draw the icon with zero height/width and visibility = hidden.
wait until the icon is loaded (how????), or check with every render if the icon is loaded
draw the icon as intended as an svg path in a viewbox 0 0 24 24.
This should mean that svg stacking is working, scaling is working, and that the icon is not in front anymore of a slider or anything else that should be in front of the icon!!!!
Icon not rendering if no other objects around
Could it be possible to simply use this: https://www.sitepoint.com/how-to-translate-from-dom-to-svg-coordinates-and-back-again/ to get the Safari client coordiantes. Already used for clicks in slider, so use also for this stuff to place icon not on svg coordinates, but xlated to client coords?? Or are these the whole screen, and not the card size coordinates????
use other object, circle or rect behind icon. change color and icon is rendered.
See previous solution for foreignObject. This could also solve this issue I assume
Animation handling
If an animation is stopped/removed on for example an icon, Safari remembers the current position of the icon, where other browsers reset the icon position to the start.
Add a basic switch tool as a very compact button to switch and show on/off values.
This can also be done using existing tools and adding animations depending on the on/off state like `transform: translateX()' to move the thumb, but it is not very user friendly.
(Optional): Suggested Solution
The solution uses standard svg objects, and a predefined animation:
rectangle to draw the track
rectangle to draw the thumb
This means that one can also style rectangle tracks and thumbs. Default is round as the default switch.
animations for on and off to move the thumb and switch the color for the track and thumb.
Note:
If a user wants to change the styling and more, he/she should define the full animation to overwrite the default animation.
Note 2:
There is still a bug in Merge.mergeDeep() which simply concatenates arrays, ie also animations. And the animations stop when a match is found, ie the first animation in the array...
This can be solved either by:
using an id to merge the array elements
continue to find a match in the animation array instead of stopping when a match is found
The tap_action is currently defined under the entities section of the card. This works, but causes some problems for tools attached to these entities (using entity_index: ), but wanting different actions when clicking the tool.
Currently this is solved by using the same entity more than once.
By moving the actions/tap_action to the tool, this problem disappears and makes it very explicit what action a tool results in.
(Optional): Suggested Solution
Move config to tools section, where one can define multiple tap_actions!:
# ------------------------------------------------------------
- type: circleentity_index: 0## Circle is used as button to switch light on/off#user_actions:
tap_action:
haptic: lightactions:
- action: call-serviceservice: light.toggle
Climate example
- type: sliderentity_index: 1## Slider only specifies tap_action in this case. Dragging# does not imply any action.#user_actions:
tap_action:
haptic: lightactions:
- action: call-serviceservice: climate.set_temperatureparameter: temperatureservice_data:
# Override entity_id. Otherwise entity_index is used...entity_id: climate.calenta
Slider with both a click and a drag action.
Slider without a click action only responds to the dragging of the thumb.
- type: sliderentity_index: 0## Slider is used to set brightness percentage#user_actions:
drag_action:
update_interval: 200haptic: selectionactions:
- action: call-serviceservice: light.turn_onparameter: brightness_pcttap_action:
haptic: lightactions:
- action: call-serviceservice: light.turn_onparameter: brightness_pct
Move click handlers from card context to basetool context
The most logical place when moving this to the tools.
The click handler should process the new config and fill the service_data with the right info depending on the specified entity_index, or service_data.
Templating tools makes re-use of toolsets possible. This already shortens the yaml files with a large amount.
It would be nice if the same can be done for colors (colorstops, colorlists)...
Of course, re-use is much better if global sak-templates are implemented, so re-use can take place over cards, instead of (currently) only within a card.
The current implementation uses 1:1 css style syntax, which requires an ';' at the end of each line.
This is also required for the styles: section in yaml.
As any other configuration doesn't need that, it is error prone, especially using templates.
Note: StyleInfo might not be needed using plain js... Just use the styleMap record definition, which is almost the same as the current definitions used, except for the trailing ';' 😄
And oh yes, you can still use the normal syntax: font-family, but use quotes. In that case you don't need the camelCase syntax, which I find confusing to use...
Add card to HACS for easy finding, installation and updating
(Optional): Suggested Solution
Must look at the documentation to make PR for HACS to get it into the default repository.
Overall Steps:
Run local Github action to validate this repository
Make pull request to hacs/default to add this card to HACS (might take a couple of weeks to be included in the HACS repository)
Required changes:
HACS can add files that are located in the /dist folder. This requires structural changes of the system templates SAK is using
Restructure yaml files. Put some in the /dist folder and test current implementation
Last step:
Verify that everything works. So this can be done only after the card is added to HACS. If the configuration changes won't work, another solution must be created...
According to ludeeus, this solution should work though!
Verify install using HACS. Tested using custom repository option!
Some tools can be colored depending on their linked entity state using animations (operators to be precise).
This could also be done - I think - using colorstop lists.
If such a list is attached to for instance a line, icon, state, etc. this list can be checked if the state changes.
In those cases it saves defining an animation with an operator list. Seems easier for the end user??
And if colorstops can be templated (see #14 ), it becomes much easier to implement and use consistently in sak cards.
No 100 lists which must be synchronized with every change...
Moose - A collection of stock photography in a single style. Good for collages. Free for commercial use.
New Old Stock - Vintage photos from the public archives.
Pexels - Free stock photos you can use everywhere.
Pixabay - Over 1.6 million royalty free stock photos and videos shared by our generous community.
reshot - Handpicked, non-stocky images. Yours to use as you wish.
StockSnap - High quality and high resolution stock images free from all copyright restrictions(CC0).
Unsplash - Beautiful, free images and photos that you can download and use for any project.
Stock Videos
Coverr - Download royalty free (for personal and commercial use), unique and beautiful video footage for your website or any project.
Life of Vids - Free videos for personal & commercial uses. New videos added weekly.
Mixkit - Extraordinary HD videos for you to use, completely free of charge.
Pexels Videos - The best free videos shared by the Pexels community.
Videvo - Free HD stock footage & motion graphics for any project.
Icons
Eva Icons - Eva Icons is a pack of more than 480 beautifully crafted Open Source icons for common actions and items.
Evericons - Evericons is a collection of 460+ well-crafted icons for your next project.
Feather icons - Feather is a collection of simply beautiful open source icons. Each icon is designed on a 24x24 grid with an emphasis on simplicity, consistency and readability.
Flaticon - The largest database of free icons available in PNG, SVG, EPS, PSD and BASE 64 formats.
Font Awesome - Get vector icons and social logos on your website with Font Awesome, the web's most popular icon set and toolkit.
Grommet Icons - Iconography for Grommet and React.js
IconBros - 1227+ free icons grouped in 38 collections.
iconmonstr - Discover 4432+ free icons in 307 collections
Icons8 - Get free icons designed to combine perfectly and fit into the style of your design.
Ionicons - Premium designed icons for use in web, iOS, Android, and desktop apps. Support for SVG and web font. Completely open source, MIT licensed and built by the Ionic Framework team.
Material Design icons - Material Design Icons' growing icon collection allows designers and developers targeting various platforms to download icons in the format, color and size they need for any project.
useAnimations - Animated icons in Lottie Framework and After Effects for immediate implementation to your apps or websites.
Fonts
1001FreeFonts - Download 41882 fonts in 21841 families for Windows, Mac and Linux. 1001 Free Fonts offers a huge selection of free fonts. New fonts are added daily.
Archetype - Archetype makes beautiful web typography designs quick and easy to create.
Behance - Behance is a network of sites and services specializing in self-promotion, including consulting, online portfolio sites and many free font resources. All you have to do is to add some clever search filters, such as 'free font'.
Clear Sans - Clear Sans has been recognized as a versatile OpenType font for screen, print, and Web.
Cooper Hewitt - The Typeface created by Chester Jenkins.
Dafont - Archive of freely downloadable fonts. Browse by alphabetical listing, by style, by author or by popularity.
FontPair - Font Pair helps designers pair Google Fonts together. Beautiful Google Font combinations and pairs.
FontSpark - Helping designers discover the perfect font for their next design project.
FontSquirrel - Font Squirrel scours the internet for high quality, legitimately free fonts.
Inter Font Family - Inter is a typeface specially designed for user interfaces.
Google Fonts - Google Fonts is a library of 900 libre licensed fonts, an interactive web directory for browsing the library, and APIs for conveniently using the fonts via CSS and Android.
Type-Scale - Preview and choose the right type scale for your project.
Typewolf - Typewolf helps designers choose the perfect font combination for their next design project
Variable Fonts - A simple resource for finding and trying variable fonts.
Illustrations
Absurb - What about surrealist illustrations for landing pages? Take every user on an individual journey through their own imagination.
Avataaars - Mix and match avatar illustrations. Combine clothes, hair, emotions, accessories, and colors.
Blobmaker - Create organic svg shapes in just a few seconds.
Charco - A set of 16 handcrafted illustrations for your web & app projects by Karthik Srinivas.
Delesign - Use our royalty-free designs for your website, social media, blog, email newsletters, and more.
DrawKit - DrawKit is a collection of free, beautiful, customisable MIT licensed SVG illustrations in two styles
FreePik - More than 3 millions free vectors, PSD, photos and free icons.
Fresh Folk - An illustration library of people and objects
Freellustrations - Download Free illustrations and vector images for website backgrounds and landing pages.
IRA Design - With IRA Design, you can create amazing illustrations, using hand-drawn sketch components, a cool selection of 5 gradients and ai., svg. or png. formats.
Isometric - Free isometric illustrations for designers, startups and companies
Isometric Love - Cute isometric objects for your design.
Humaaans - Mix-&-match illustrations of people with a design library.
Lukasz Adam - Free vector art illustrations and icons. Available for personal and commercial use.
ManyPixels - Each week, discover royalty-free illustrations to power up your projects.
Mixkit - Mixkit is a curated gallery of high-quality videos and art, made by some of the world’s most talented creators, with all content licensed for free.
Open Doodles - Free sketchy illustrations by Pablo Stanley.
Ouch - Free illustrations to class up your project.
Scribbbles - 100+ vectorized scribbbles to spice up your design projects.
Stubborn Generator - Stubborn Generator is a collection of 25 incredibly cool characters.
Undraw - Open-source illustrations for every project you can imagine and create.
Wireframer - Flawless SVG content blocks for your wireframes.
Abduzeedo - The most interesting designs/artworks/concepts curated by Abduzeedo's team to utterly inspire your day.
awwwards. - Awwwards are the Website Awards that recognize and promote the talent and effort of the best developers, designers and web agencies in the world.
Behance - Showcase and discover the latest work from top online portfolios by creative professionals across industries.
CallToIdea - Calltoidea is the unique place where you can find inspiration. A great tool created by a designer for web professionals.
CSS Design Awards - A web design & development award platform for digital folk, UI/UX peeps and inspiring leaders of the web.
DesignMunk - The ultimate hand picked landing page inspirations from around the web.
Deviant Art - DeviantArt is the world's largest online social community for artists and art enthusiasts, allowing people to connect through the creation and sharing of art.
Dribbble - Dribbble is the leading destination to find & showcase creative work and home to the world's best design professionals.
h69 - Landing page colletions & Free resources for designers.
Httpster - Httpster is an inspiration resource showcasing totally rocking websites made by people from all over the world.
Hyperpixel - Discover the latest designs for your own inspiration from our curated list of landing pages.
Inspirationde - Inspirationde is an online source of design inspiration, photography, interior, web design, UI and UX, digital art, illustration, graphic design and much more.
Land-Book - We collect awesome websites to help creatives find inspiration & motivation to do rad stuff.
Lapa Ninja - The best landing page design inspiration from around the web.
Muzli - Muzli is a new-tab Chrome extension that instantly delivers relevant design stories and inspiration.
OnePageLove - One Page Love is a One Page website design gallery showcasing the best Single Page websites, templates and resources.
Pttrns - Pttrns is the finest collection of mobile design patterns, resources and inspiration.
The FWA - Showcasing innovation every day since 2000.
Colorbook - Your hex color information and conversion source. We at colorbook have one mission: we want to give each color its place. Think of it as of a facebook of colors.
ColorBox - Colorbox is a color tool to produce color sets.
Color-hex - Color-hex gives information about colors including color models (RGB,HSL,HSV and CMYK).
Color Designer - Just pick a color, and the app does the rest.
Color Hunt - Color Hunt is a free and open platform for color inspiration with thousands of trendy hand-picked color palettes.
Colorinspire - Curated color inspiration. Free to use for your next project.
Color Lisa - Color palette masterpieces from the world's greatest artists.
Color Quote - Daily dose of color combination and inspirational quote cards for designers and developers.
Color Safe - Empowering designers with beautiful and accessible color palettes based on WCAG Guidelines of text and background contrast ratios.
Color Space - Build beautiful color palettes by entering just one color.
Color Tool - Create, share, and apply color palettes to your UI, as well as measure the accessibility level of any color combination.
DeckRobot - Make consistent corporate slide decks in one click
Google Slides - Create a new presentation and edit it with others at the same time — from your computer, phone or tablet.
Keynote - Keynote is the most powerful presentation app ever designed for a mobile device.
Microsoft PowerPoint - Microsoft PowerPoint is the best presentation software for meetings, industry talks and business proposals.
Prezi - The presentation software that uses motion, zoom, and spatial relationships to bring your ideas to life and make you a great presenter.
Slides - Slides is a place for creating, presenting and sharing presentations. The Slides editor is available right in your browser.
Animation Tools
Adobe After Effects - With After Effects CC, the industry-standard motion graphics and visual effects software, you can take any idea and make it move.
Animator by Haiku - Haiku Animator is the premier solution for creating cross-platform UI animations.
Anime.js - Anime.js is a lightweight Javascript animation library designed to help you make complex animations with ease.
Animista - Animista is a place where you can play with a collection of ready to use CSS animations, tweak them and download only those you will actually use.
Draw.io - A cross-platform simple vector drawing tool. It’ll help you to create all these flowcharts, process diagrams, org charts, UML, ER, and network diagrams just in several minutes.
Lucidchart - A web-based tool for creating diagrams, flow charts, sitemaps.
Miro - Scalable, secure, cross-device and enterprise-ready team collaboration whiteboard for distributed teams.
Overflow - A user flow diagramming tool tailored for designers.
Creative Tools
Poolside FM - FM is an online radio station, playing an infinity pool of summer sounds.
Spring Editor - Stiffness? Damping? Mass? Spring Editor.
Tinkersynth - Tinkersynth is an experimental art project. Create unique designs by manipulating whimsical machines and making serendipitous discoveries.
Currently all widgets are maintained in separate lists per type. This takes a lot of code to maintain.
Furthermore, as the widgets are drawn per type, it is not easy to force a certain drawing order to make sure that some objects are layed out on top of other objects.
Using assemblies to group tools makes this possible. For this, the existing widgets must be changed to classes.
The following widgets (tools) should be migrated to classes:
Entity Area
Badge
Sparkbarchart
Circle
Ellipse
Entity Icon
Horse shoe
Line
Entity Name
Entity State
Range Slider
Segmented Arc
User Svg
(Optional): Suggested Solution
Create base class and separate classes per type of tool that can be displayed on the screen.
Each class takes care of its own initialization, configuration, updates and rendering.
After the first implementation of local templating (see #1), this issue will implement global templating using files. This makes it possible to share templates between cards. The local variant could not do that.
Templating has still the same goal: minimize maintenance and creating a complex card with repeated tools is a lot easier.
If done right, sak templates can be combined with decluttering templates!
The current slider implementation is just a demo-like implementation of a mobile friendly slider.
It has no relation yet with a state entity, has no initial value, nor can it update and configure itself.
(Optional): Suggested Solution
Make a full tool out of this slider:
configuration in yaml
horizontal / vertical
styling
action when released
action when changed (real-time changing light brightness for example)
etc.
runtime stuff
range clipping, say 1,2,3,4,5 and then per 5 orso. Nice for lighting
clip slider value box when at corners. Don't let it slide further, but only change value in box.
The min/max values of the segmented arc are not displayed. It would be nice if this would be possible, of course free placement, and styling.
This could be extended with extra labels like 20%, or 50%.
The thumb of the slider is not correctly positioned if the slider is not set to (50,50) as position.
A (50,50) position leads to a cx/cy of (0,0).
So the actual thumb position seems to assume (0,0) and doesn't calculate the right thumb position in any other situation.
(Optional): Suggested Solution
Adjust thumb position for the actual center position...
The current svg tool supports state images.
Extend the possibilities with:
static images, ie load an external svg file and display it given its height/width as dimensions. Depending on the svg contents, see if colorchanges can be done, depending on state for instance and/or via styles.
embedded svg content. Is about the same as the previous one, but now embedded in the yaml definition
(Optional): Suggested Solution
Some changes are necessary to support these different functions. Some can't be mixed probably, as it gives problems with the animation configuration.
state images are one function
static images / static content I guess the second one, as these overlap in functionality
The units of measurement are always added/shown next to the state value.
In some cases this is not desired: the uoms should either not be displayed, or above or below the state.
Makes this a configuration 'show' option, where default = the old situation.
Every tool can be styled using the styles section.
The segmented arc uses two sections:
styles for the segmented arc itself
styles_bg for the background of the arc
Other tools also will need multiple styles sections to be able to style each part. Some tools already have multiple subsections for styles, so need not to be changed.
Using a zillion style_** sections is not an option.
This must be implemented for all tools. Lot of work, as the yaml views/templates must be changed also:
Area
Badge
Bar
Circle
Horseshoe
Icon
Ellipse
Line
Name
Rectangle
RectEx
SegmentedArc
Slider
State
UserSvg
(Optional): Suggested Solution
The general proposed solution is to make the styles section a map of styling parts. Easy to extent & process.
styles:
front:
fill: red;background:
fill: black;
but also:
styles:
bar:
fill: red;label_min:
fill: black;label_max:
fill: black;
The current animations handling assumes the current entity_index as the state that is processed for getting different animations/styles per state.
In some situations it is very handy if another entity's state can overrule/adjust the styling/animations of the current entity tool.
Examples:
Disable tool depending on state on/off of another entity
Hide tool/toolset depending on state undefined/other of another entity
(Optional): Suggested Solution
Adding an optional entity_index: to the animations is enough.
Note:
Must check the reuse flag. TThat flag takes care of re-using the current/previous state, but was made assuming there is only ONE animation that can determine the styling, which is not true anymore if more than one entity_index can format the styling.
So should the extra state be able to:
overwrite/replace the current animation styling (it is a list, so there can already be a styling)
in 'off' state for entity_index: 1, the on/off states for entity_index: 0 are still applied, ie they change fill color, but can't be clicked on, as pointer-events are disabled. Furthermore, opacity is set to 0.1
in 'on' state for entity_index 1, the tool is enabled again for input
There is currently a discrepancy between the toolset and tool configuration.
The toolset specifies a separate position map with position & dimensions, where the tool uses inline configuration.
Refactor this to use the position map for tools too.
easier for the eye
easier to document
(Optional): Suggested Solution
Easy peasy:
- tool: some exampletype: circleposition:
cx: 50cy: 40radius: 45
Instead of:
- tool: some exampletype: circlecx: 50cy: 40radius: 45
In hass 0.98 everything is rendered perfectly, but since hass 0.110 (change in icon rendering), there are problems.
Problem is described here: home-assistant/frontend/issues/7224, assuming this is a hass frontend issue, and not something that should be changed in this card.
The horse shoe contains animations: if an entity changes from state, you can run an animation on some of the objects (icon, lines circles) using default css animation functionality. This can be defined in the card yaml.
The idea is to implement animations on the swiss army knife also!
You can see how the objects, animations, and entities are linked together:
objects linked to entities using entity_index (index in entities list)
objects linked to animation using separate animation_id
So:
a single entity can trigger multiple animations on several objects.
an object is linked to a single animation! This avoids weird behavior / race conditions / etc.
(Optional): Suggested Solution
1:1 implementation
The sak card uses separate tool objects for each object: the idea is that each object itself handles operations on the object. This means that animations should also be handled by the object/tool itself.
For this:
tool knows the entity_index for which it is linked
the animation is part of the tool config, hence local
the value of that entity is automatically pushed to the tool using its tool.value = function.
in the .value function, the tool can calculate the animation styles itself. These styles will be added to the styles used to redraw the tool during a render action initiated by a changed entity.
There is a simple line tool which can draw a single line. But what about a polyline, or using multiple lines as ONE tool? By supporting the svg polyline, it is easy to also support multiple lines as one object.
So add this tool and see what functionality can be added to this tool to make it nice:
lines
points
multi part styling
(Optional): Suggested Solution
If lines can be made of different parts, one could also style the parts differently. This makes the tool much more usable. However, what about colorstop etc.: they are not yet configured for multi-part tools, which should be if you want to do this. Animations do support multi-part tools already, so for now one should use those...
And this format still doesn't make it possible to have different colors for fill and stroke for instance. The fill and stroke should go into the colorstops itself. Hmmmmmmm. Colorstops with styles and classes??
Currently each tool can define styles in the styles section. These are then defined as inline styles for the SVG element. Those styles overwrite class settings defined in the css stylesheet.
Due to the implementation of the classes section (#49), users can define classes to style a tool.
This requires the tools also to use classes, as otherwise the default (inline) styles keep overwriting the classes!
(Optional): Suggested Solution
Define a class for every tool containing the css styles now defined in javascript and defined in the inline styles section.
Use BEM naming convention.
So for the switch or other compound tools, the classes become:
sak-switch for the switch tool
sak-switch__track for the track part of the switch
sak-switch__thumb for the thumb part of the switch
That is really consistent with the way the styles are organized as switch.track and switch.thumb in yaml/javascript!
Define the css definitions in the sak_templates.yaml file.
See #49 for this.
These css definitions are added to the default css definitions, ie they can overwrite the system/default sak css definitions.
Both font-size and icon-size is currently not consistent with the percentages used for all the other tools.
To make matters worse, some css is also specifying font-sizes, sometimes % font sizes. This results in inconsistent yaml specifications.
For instance:
The font-size for the Name is larger than for the Area, however in the yaml spec this is the opposite:
# Name of entity
- type: namecx: 5cy: 81id: 4entity_index: '[[entity_light]]'styles:
name:
font-size: 1.8emfont-weight: 700text-anchor: start# Area of entity
- type: areaentity_index: 0id: 5cx: 5cy: 91styles:
area:
font-size: 2.4emtext-anchor: start
This is caused by css definitions!
(Optional): Suggested Solution
It is not very difficult, but takes some time to change all the yaml definitions & code:
remove css definitions for font-size in at least the entity__name and entity__area definitions
use a relative font-size of 1em for 1%, ie size is consistent with other tools. This means that with the current svg dimensions (400x400), a value of 1em equals 4px! the ::host font-size must be set to this value!
change all yaml definitions for font-size and icon-size
Javascript templates are currently only supported to implement the custom_value / derived_entity for a tool to process the incoming state value to something else.
Adding javascript templates to the animation section would:
make more animations/dynamic calculations possible
make the current usersvg's image implementation much simpler/shorter
(Optional): Suggested Solution
Animations are 'run' from the tools baseclass set value() method , which is processing the data coming in through set hass().
By implementing javascript templates in this method for animations, makes it fairly easy to implement, as it doesn't impact any other methods and results in generic template support for ALL tool animations.
The current static tool styling and animations sections use a styles section to define css and svg styles. This works ok.
However, one need to specify every single css style for each part, where css/html already defined classes to make this a lot easier.
So add this classes option to:
define classes with true/false (a style map!!) in the classes section and animations section
think about defining the classes in the sak template section, so any user can define its own classes/styles
This one can enable (true) and disable (false) classes. That should be ease to add using some small code refactoring in the render methods.
The system /card classes get a sak- prefix, so no user can overwrite them...
Add classes definitions in the template
So users can define there own classes. These are then added to the styles section.
That is also required for svg filters and other stuff. Not yet done!!!!
NOTE:
The css_extra_definitions section can also define @keyframes for defining own animations!
css_extra_definitions:
- descr: class for whatevercontent: | .whatever { fill: orange-01; stroke-width: 2; stroke: yellow; opacity: 0.2; }
- descr: class for whoevercontent: | .whoever { color: green; align-text: middle; }
IMPORTANT NOTE:
And remember: (inline) styles overwrite the class specifications!!! ALWAYS!!!
This also means that the current inline styles for all tools should be moved to css, as otherwise the class definitions won't work, as they will be overwritten by the predefined inline styles!
Maybe it is possible to have a variable list of entitiesthat can be displayed by extending the card vertically.
In this case one would have to know the size of a single entry and expand the SVG viewBox dynamically.
Situations:
have a list of entities, each entity on a single 'row' of objects
have a group, which can change. Each entity again on a single 'row' of objects.
Describing all the elements of a SAK card, ie all the toolsets and tools can be a lot of yaml. To minimize this makes maintenance and creating a complex card with repeated tools a lot easier.
So the problem to be solved is not on a card level, but on a deeper level. The decluttering template card can't be used for templating assemblies and tools.
(Optional): Suggested Solution
The decluttering card shows how templates can be implemented. The idea is to use that format to be able to template sak-tools as part of sak-toolsets.
A simple test (2020.09.30) shows that this is possible:
Sometimes the colorstops shows a black color at the end of the range although the colorstop value is larger then the maximum value.
The following colorstop should work for a value of 60: it should show orange, but shows black in the segmentedarc. It should even work with an end value of 55: that color should be used for any value larger than 55...
There were two rendering paths for Icons: one for Safari (SVG) and one for Chrome (ForeignObject/SVG). Due to longstanding ForeignObject bugs in Safari, Safari used a different rendering path.
But as the Safari rendering path also works on Chrome, the separate rendering paths become obsolete, so use one and remove all the other stuff...
(Optional): Suggested Solution
Do not only remove Chrome's path, but also all the tests, comments and checks that are now obsolete.
Will be a nice code cleanup!
Note that this issue: home-assistant/frontend#7441 shows the problem, and how to get to the SVG path of the icon, without getting it directly from the database.
Check how performance can be made a bit better. It seems from data from the Chrome inspector that some of the calls are expensive and might result in better overall view switching performance if these parts can be optimized.
For large views with lots of tools small optimizations can result in snappier performance from the users point of view.
Examples:
Totals from sake2 @2020.11.27:
Not all scripting time is from this card of course, but as you can see, the client-width fetch is with 115ms already 4% of the 2835ms scripting time for home assistant, chrome extensions, etc.,
If we look at the urls, we see a better picture, this is detail from the air-quality view:
Here you see this card takes 462ms, so the client-width fetching is about 25% of this time. The other parts, like the stringify's and spread operator also seem relative more expensive now 😬 !
The well known stringify:
The spread operator:
Client size:
The very expensive client rec call used in Icon rendering. This seems hard to cache, as a change in clientwidth (landscape/portrait modus for instance, or changing the client window on a PC) should be detected in that case (an Observer??).
(Optional): Suggested Solution
Format on change
Most parts are always rendered/calculated even if the data is not changed. This applies - I think - in most cases for the styling of a tool. So a changed flag or something might win some performance.
Most of the stringify calls for styles might not be needed in every render() call.
Replace spread operator with deepMerge() call
This call seems to work faster than several spread operator calls.
But this also relates to the fact: has data been changed, so do we need to merge this data AGAIN!
Client-width call still needed?
Is this call still required, if all icons are displayed with their svg path?? If not, this would greatly enhance performance!