Skip to content

Commit

Permalink
📝 Change hover tooltips to click, add copy buttons
Browse files Browse the repository at this point in the history
Remove color name and hex code from graphic
Add color name to tooltip
Add copy buttons for each data line
Add copy button on color name that copies all data lines
  • Loading branch information
rekognizecode committed Oct 29, 2024
1 parent ce2d4db commit f6862a7
Show file tree
Hide file tree
Showing 2 changed files with 296 additions and 263 deletions.
288 changes: 218 additions & 70 deletions docs/_static/colorTooltips.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,115 +73,263 @@ function rgbToCMYK(r,g,b){
}

const CSS_UNIT = "px";
const HEIGHT_OFFSET = -150;
const HEIGHT_OFFSET = 160;
const svg = document.querySelector('svg');
const svgRect = svg.getBoundingClientRect();

const copySVG = `
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-copy" width="44" height="44" viewBox="0 0 24 24" stroke-width="1.5" stroke="#000000" fill="none" stroke-linecap="round" stroke-linejoin="round">
<title>Copy to clipboard</title>
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<rect x="8" y="8" width="12" height="12" rx="2"></rect>
<path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path>
</svg>
`
const copyAllSVG = `
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-copy all" width="70" height="16" viewBox="0 0 70 16" fill="none" stroke-linecap="round" stroke-linejoin="round">
<title>Copy all to clipboard</title>
<text x="2" y="12" stroke-width="0.3" font-size="10" style="font-weight='100'; font-family='SegoeUI', 'Segoe UI'">Copy all</text>
<g transform="scale(0.75 0.75) translate(26 6)" stroke-width="1.5">
<rect x="40" y="2" width="12" height="12" rx="2"></rect>
<path d="M48 2v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path>
</g>
</svg>`;

const checkSVG = `
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-check" width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" stroke="#28a745" fill="none" stroke-linecap="round" stroke-linejoin="round">
<title>Copied!</title>
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M5 12l5 5l10 -10"></path>
</svg>`;

const checkAllSVG = `
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-check all" width="70" height="16" viewBox="0 0 70 16" fill="none" stroke-linecap="round" stroke-linejoin="round">
<title>Copied!</title>
<text y="12" font-size="10" style="font-weight='200'; font-family='SegoeUI', 'Segoe UI'">All copied</text>
<g transform="scale(0.75 0.75) translate(58 0)" stroke-width="1.5" stroke="#28a745">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M5 12l5 5l10 -10" stroke-width="1.5"></path>
</g>
</svg>`;

function copyToClipboard(text, button) {
navigator.clipboard.writeText(text).then(() => {
button.innerHTML = checkSVG;

setTimeout(() => {
button.innerHTML = copySVG;
}, 2000);
}).catch((err) => {
console.error('Failed to copy text: ', err);
});
}
function copyAllToClipboard(text, button) {
navigator.clipboard.writeText(text).then(() => {
button.innerHTML = checkAllSVG;

setTimeout(() => {
button.innerHTML = copyAllSVG;
}, 2000);
}).catch((err) => {
console.error('Failed to copy text: ', err);
});
}


function addCircleHints() {
const circles = document.querySelectorAll("circle")
const circles = document.querySelectorAll("circle");
const nameDiv = document.getElementById("name");
let activeCircle = null;
let tooltip = null;

for (let i = 0; i < circles.length; i++) {
const circle = circles[i];
function hideTooltip() {
nameDiv.style.opacity = 0;
nameDiv.innerHTML = null;
activeCircle = null;
}

function showTooltip(circle, r, g, b) {

const colorInfo = [
`Hex: ${rgbToHexCode(r, g, b)}`,
`RGB: ${r}, ${g}, ${b}`,
`HSV: ${rgbToHSV(r, g, b).join(', ')}`,
`CMYK: ${rgbToCMYK(r, g, b).join(', ')}`,
`Vividness: ${calculateVividness(r, g, b)}`,
`Kontrast weiß: ${rgbToWhiteContrast(r, g, b)}`,
`Kontrast schwarz: ${rgbToBlackContrast(r, g, b)}`
];

let pantoneSet = false;
if (circle.parentElement.hasAttribute('serif:id')) {
let serifs = circle.parentElement.getAttribute('serif:id');
if(serifs.includes("Pantone")) {
colorInfo.push(serifs.split("|")[1]);
pantoneSet = true;
}
colorInfo.unshift(serifs.split("|")[0]);
}

const circleBBox = circle.getBoundingClientRect();
const circleX = circleBBox.left + svgRect.left + (circleBBox.width / 2);
const circleY = circleBBox.top + svgRect.top + window.scrollY;

nameDiv.style.left = (circleX - 85) + 'px';
nameDiv.style.top = pantoneSet ? (circleY - HEIGHT_OFFSET - 35) + 'px' : (circleY - HEIGHT_OFFSET - 15) + 'px';

const tooltipContent = colorInfo.map((info, index) => {
if (index === 0) {
return `<div>${info} <button class="all copy-all-button">${copyAllSVG}</button></div>`;
}
return `<div>${info} <button class="copy-button">${copySVG}</button></div>`;
}).join("");

nameDiv.innerHTML = tooltipContent;
document.querySelector(".copy-all-button").addEventListener("click", function () {
copyAllToClipboard(colorInfo.join("\n"), this);
});

document.querySelectorAll(".copy-button").forEach((button, index) => {
button.addEventListener("click", function () {
copyToClipboard(colorInfo[index], this);
});
});

const nameDiv = document.getElementById("name");
nameDiv.style.opacity = 1;
nameDiv.style.borderColor = `rgb(${r},${g},${b})`;

activeCircle = circle;
tooltip = document.getElementById("name");
}

document.addEventListener('click', (event) => {
if (activeCircle && !activeCircle.contains(event.target) && !tooltip.contains(event.target)) {
hideTooltip();
}
});

for (let i = 0; i < circles.length; i++) {
const circle = circles[i];
const style = circle.getAttribute('style');
if (style) {

if (style) {
const colorMatch = style.match(/fill:rgb\((\d+),(\d+),(\d+)\)/);
if (colorMatch) {
const r = colorMatch[1];
const g = colorMatch[2];
const b = colorMatch[3];
const hsv = rgbToHSV(r, g, b);
const vividness = calculateVividness(r, g, b);
const whiteContrast = rgbToWhiteContrast(r, g, b);
const blackContrast = rgbToBlackContrast(r, g, b);
const [c, m, y, k] = rgbToCMYK(r, g, b);
const hex = rgbToHexCode(r, g, b);
let colorId = `Hex: ${hex} RGB: ${r}, ${g}, ${b} HSV: ${hsv[0]}, ${hsv[1]}, ${hsv[2]} CMYK: ${c}, ${m}, ${y}, ${k} Vividness: ${vividness} Kontrast weiß: ${whiteContrast} Kontrast schwarz: ${blackContrast}`;
circle.setAttribute('id', colorId);
circle.addEventListener("mouseover", () => {
window.onmousemove = function (j) {

const x = j.clientX - svgRect.left;
const y = j.clientY - svgRect.top + window.scrollY;

nameDiv.style.top = (y + HEIGHT_OFFSET) + CSS_UNIT;
nameDiv.style.left = x - 75 + CSS_UNIT;

const [_, r, g, b] = colorMatch;

circle.addEventListener("click", (event) => {
event.stopPropagation();

if (activeCircle === circle && !tooltip.contains(event.target)) {
hideTooltip();
} else {
showTooltip(circle, r, g, b);
}
document.getElementById("namep").innerText = circle.id.split(" ").join("\n");
nameDiv.style.opacity = 1;
nameDiv.style.borderColor = `rgb(${r},${g},${b})`
});
}

} else {
circle.setAttribute('id', `circle_${i}`);
}

circle.addEventListener("mouseleave", () => {
document.getElementById("name").style.opacity = 0;
});
};
}
}
addCircleHints();

function addSquareHints() {
const squares = document.querySelectorAll("rect");
const nameDiv = document.getElementById("name");
let activeSquare = null;
let tooltip = null;

for (let i = 0; i < squares.length; i++) {
const square = squares[i];
function hideTooltip() {
nameDiv.style.opacity = 0;
nameDiv.innerHTML = null;
activeSquare = null;
}

const nameDiv = document.getElementById("name");
function showTooltip(square, r, g, b) {

const colorInfo = [
`Hex: ${rgbToHexCode(r, g, b)}`,
`RGB: ${r}, ${g}, ${b}`,
`HSV: ${rgbToHSV(r, g, b).join(', ')}`,
`CMYK: ${rgbToCMYK(r, g, b).join(', ')}`,
`Vividness: ${calculateVividness(r, g, b)}`,
`Kontrast weiß: ${rgbToWhiteContrast(r, g, b)}`,
`Kontrast schwarz: ${rgbToBlackContrast(r, g, b)}`
];

let pantoneSet = false;
let pantone = "";
if (square.parentElement.hasAttribute('serif:id')) {
pantone = square.parentElement.getAttribute('serif:id');
pantoneSet = true;
let serifs = square.parentElement.getAttribute('serif:id');
if(serifs.includes("Pantone")) {
colorInfo.push(serifs.split("|")[1]);
pantoneSet = true;
}
colorInfo.unshift(serifs.split("|")[0]);
}

const squareBBox = square.getBoundingClientRect();
const squareX = squareBBox.left + svgRect.left + (squareBBox.width / 2);
const squareY = squareBBox.top + svgRect.top + window.scrollY;

nameDiv.style.left = (squareX - 85) + 'px';
nameDiv.style.top = pantoneSet ? (squareY - HEIGHT_OFFSET - 20) + 'px' : (squareY - HEIGHT_OFFSET) + 'px';

const tooltipContent = colorInfo.map((info, index) => {
if (index === 0) {
return `<div>${info} <button class="all copy-all-button">${copyAllSVG}</button></div>`;
}
return `<div>${info} <button class="copy-button">${copySVG}</button></div>`;
}).join("");

nameDiv.innerHTML = tooltipContent;
document.querySelector(".copy-all-button").addEventListener("click", function () {
copyAllToClipboard(colorInfo.join("\n"), this);
});

document.querySelectorAll(".copy-button").forEach((button, index) => {
button.addEventListener("click", function () {
copyToClipboard(colorInfo[index], this);
});
});

nameDiv.style.opacity = 1;
nameDiv.style.borderColor = `rgb(${r},${g},${b})`;

activeSquare = square;
tooltip = document.getElementById("name");
}

document.addEventListener('click', (event) => {
if (activeSquare && !activeSquare.contains(event.target) && !tooltip.contains(event.target)) {
hideTooltip();
}
});

for (let i = 0; i < squares.length; i++) {
const square = squares[i];
const style = square.getAttribute('style');
if (style) {

if (style) {
const colorMatch = style.match(/fill:rgb\((\d+),(\d+),(\d+)\)/);
if (colorMatch) {
const r = colorMatch[1];
const g = colorMatch[2];
const b = colorMatch[3];
const hsv = rgbToHSV(r, g, b);
const vividness = calculateVividness(r, g, b);
const whiteContrast = rgbToWhiteContrast(r, g, b);
const blackContrast = rgbToBlackContrast(r, g, b);
const [c, m, y, k] = rgbToCMYK(r, g, b);
const hex = rgbToHexCode(r, g, b);
let colorId = `Hex: ${hex} RGB: ${r}, ${g}, ${b} HSV: ${hsv[0]}, ${hsv[1]}, ${hsv[2]} CMYK: ${c}, ${m}, ${y}, ${k} Vividness: ${vividness} Kontrast weiß: ${whiteContrast} Kontrast schwarz: ${blackContrast}`;
if(pantoneSet)
colorId += ` ${pantone}`;
square.setAttribute('id', colorId);
square.addEventListener("mouseover", () => {
window.onmousemove = function (j) {

const x = j.clientX - svgRect.left;
const y = j.clientY - svgRect.top + window.scrollY;

nameDiv.style.top = pantoneSet ? (y + HEIGHT_OFFSET - 20) + CSS_UNIT : (y + HEIGHT_OFFSET) + CSS_UNIT;
nameDiv.style.left = x - 75 + CSS_UNIT;

const [_, r, g, b] = colorMatch;

square.addEventListener("click", (event) => {
event.stopPropagation();

if (activeSquare === square && !tooltip.contains(event.target)) {
hideTooltip();
} else {
showTooltip(square, r, g, b);
}
document.getElementById("namep").innerText = square.id.split(" ").join("\n");
nameDiv.style.opacity = 1;
nameDiv.style.borderColor = `rgb(${r},${g},${b})`;
});
}
} else {
square.setAttribute('id', `square_${i}`);
}

square.addEventListener("mouseleave", () => {
nameDiv.style.opacity = 0;
});
};
}
}
addSquareHints();
Loading

0 comments on commit f6862a7

Please sign in to comment.