public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Dominik Csapak <d.csapak@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH widget-toolkit v5 1/1] add tag related helpers
Date: Fri,  8 Apr 2022 09:45:19 +0200	[thread overview]
Message-ID: <20220408074530.1212056-5-d.csapak@proxmox.com> (raw)
In-Reply-To: <20220408074530.1212056-1-d.csapak@proxmox.com>

helpers to
* generate a color from a string consistently
* generate a html tag for a tag
* related css classes

contrast is calculated according to SAPC draft:
https://github.com/Myndex/SAPC-APCA

which is likely to become a w3c guideline in the future and seems
to be a better algorithm for this

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 src/Utils.js         | 70 ++++++++++++++++++++++++++++++++++++++++++++
 src/css/ext6-pmx.css | 45 ++++++++++++++++++++++++++++
 2 files changed, 115 insertions(+)

diff --git a/src/Utils.js b/src/Utils.js
index 6a03057..09085d8 100644
--- a/src/Utils.js
+++ b/src/Utils.js
@@ -1272,6 +1272,76 @@ utilities: {
 	    .map(val => val.charCodeAt(0)),
 	);
     },
+
+    stringToRGB: function(string) {
+	let hash = 0;
+	if (!string) {
+	    return hash;
+	}
+	string += 'prox'; // give short strings more variance
+	for (let i = 0; i < string.length; i++) {
+	    hash = string.charCodeAt(i) + ((hash << 5) - hash);
+	    hash = hash & hash; // to int
+	}
+
+	let alpha = 0.7; // make the color a bit brighter
+	let bg = 255; // assume white background
+
+	return [
+	    (hash & 255)*alpha + bg*(1-alpha),
+	    ((hash >> 8) & 255)*alpha + bg*(1-alpha),
+	    ((hash >> 16) & 255)*alpha + bg*(1-alpha),
+	];
+    },
+
+    rgbToCss: function(rgb) {
+	return `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`;
+    },
+
+    // optimized & simplified SAPC function
+    // https://github.com/Myndex/SAPC-APCA
+    getTextContrastClass: function(rgb) {
+	    const blkThrs = 0.022;
+	    const blkClmp = 1.414;
+
+	    // linearize & gamma correction
+	    let r = (rgb[0]/255)**2.4;
+	    let g = (rgb[1]/255)**2.4;
+	    let b = (rgb[2]/255)**2.4;
+
+	    // relative luminance sRGB
+	    let bg = r*0.2126729 + g*0.7151522 + b*0.0721750;
+
+	    // black clamp
+	    bg = bg > blkThrs ? bg : bg + (blkThrs - bg) ** blkClmp;
+
+	    // SAPC with white text
+	    let contrastLight = bg ** 0.65 - 1;
+	    // SAPC with black text
+	    let contrastDark = bg ** 0.56 - 0.046134502;
+
+	    if (Math.abs(contrastLight) >= Math.abs(contrastDark)) {
+		return 'light';
+	    } else {
+		return 'dark';
+	    }
+    },
+
+    getTagElement: function(string, color_overrides) {
+	let rgb = color_overrides?.[string] || Proxmox.Utils.stringToRGB(string);
+	let bgcolor = Proxmox.Utils.rgbToCss(rgb);
+	let style = `background-color: ${bgcolor};`;
+	let cls;
+	if (rgb.length > 3) {
+	    let fgcolor = Proxmox.Utils.rgbToCss([rgb[3], rgb[4], rgb[5]]);
+	    style += `color: ${fgcolor}`;
+	    cls = "proxmox-tag-dark";
+	} else {
+	    let txtCls = Proxmox.Utils.getTextContrastClass(rgb);
+	    cls = `proxmox-tag-${txtCls}`;
+	}
+	return `<span class="${cls}" style="${style}">${string}</span>`;
+    },
 },
 
     singleton: true,
diff --git a/src/css/ext6-pmx.css b/src/css/ext6-pmx.css
index 2516578..4448751 100644
--- a/src/css/ext6-pmx.css
+++ b/src/css/ext6-pmx.css
@@ -6,6 +6,51 @@
     background-color: LightYellow;
 }
 
+.proxmox-tags-full .proxmox-tag-light,
+.proxmox-tags-full .proxmox-tag-dark {
+    border-radius: 3px;
+    padding: 1px 6px;
+    margin: 0px 1px;
+}
+
+.proxmox-tags-circle .proxmox-tag-light,
+.proxmox-tags-circle .proxmox-tag-dark {
+    margin: 0px 1px;
+    position: relative;
+    top: 2px;
+    border-radius: 6px;
+    height: 12px;
+    width: 12px;
+    display: inline-block;
+    color: transparent !important;
+    overflow: hidden;
+}
+
+.proxmox-tags-none .proxmox-tag-light,
+.proxmox-tags-none .proxmox-tag-dark {
+    display: none;
+}
+
+.proxmox-tags-dense .proxmox-tag-light,
+.proxmox-tags-dense .proxmox-tag-dark {
+    width: 6px;
+    margin-right: 1px;
+    display: inline-block;
+    color: transparent !important;
+    overflow: hidden;
+    vertical-align: bottom;
+}
+
+.proxmox-tags-full .proxmox-tag-light {
+    color: #fff;
+    background-color: #383838;
+}
+
+.proxmox-tags-full .proxmox-tag-dark {
+    color: #000;
+    background-color: #f0f0f0;
+}
+
 .x-mask-msg-text {
     text-align: center;
 }
-- 
2.30.2





  parent reply	other threads:[~2022-04-08  7:46 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-08  7:45 [pve-devel] [PATCH cluster/widget-toolkit/manager v5] add tags to ui Dominik Csapak
2022-04-08  7:45 ` [pve-devel] [PATCH cluster v5 1/3] add CFS_IPC_GET_GUEST_CONFIG_PROPERTIES method Dominik Csapak
2022-04-08 10:05   ` Matthias Heiserer
2022-04-08  7:45 ` [pve-devel] [PATCH cluster v5 2/3] Cluster: add get_guest_config_properties Dominik Csapak
2022-04-08  7:45 ` [pve-devel] [PATCH cluster v5 3/3] datacenter.cfg: add option for tag-tree-style and tag-colors Dominik Csapak
2022-04-08  7:45 ` Dominik Csapak [this message]
2022-04-08  7:45 ` [pve-devel] [PATCH manager v5 01/11] api: /cluster/resources: add tags to returned properties Dominik Csapak
2022-04-08  7:45 ` [pve-devel] [PATCH manager v5 02/11] api: /version: add 'tag-colors' and 'tag-tree-style' Dominik Csapak
2022-04-08  7:45 ` [pve-devel] [PATCH manager v5 03/11] ui: parse and save tag color overrides from /version Dominik Csapak
2022-04-08  7:45 ` [pve-devel] [PATCH manager v5 04/11] ui: tree/ResourceTree: collect tags on update Dominik Csapak
2022-04-08  7:45 ` [pve-devel] [PATCH manager v5 05/11] ui: add form/TagColorGrid Dominik Csapak
2022-04-08 11:39   ` Matthias Heiserer
2022-04-08  7:45 ` [pve-devel] [PATCH manager v5 06/11] ui: dc/OptionView: add editors for tag settings Dominik Csapak
2022-04-08  7:45 ` [pve-devel] [PATCH manager v5 07/11] ui: add form/Tag Dominik Csapak
2022-04-08  7:45 ` [pve-devel] [PATCH manager v5 08/11] ui: add form/TagEdit.js Dominik Csapak
2022-04-08  7:45 ` [pve-devel] [PATCH manager v5 09/11] ui: {lxc, qemu}/Config: show Tags and make them editable Dominik Csapak
2022-04-08  7:45 ` [pve-devel] [PATCH manager v5 10/11] ui: tree/ResourceTree: show Tags in tree Dominik Csapak
2022-04-08  7:45 ` [pve-devel] [PATCH manager v5 11/11] ui: form/GlobalSearchField: display tags and allow to search for them Dominik Csapak
2022-04-08 12:15 ` [pve-devel] [PATCH cluster/widget-toolkit/manager v5] add tags to ui Matthias Heiserer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220408074530.1212056-5-d.csapak@proxmox.com \
    --to=d.csapak@proxmox.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal