Skip to content

Commit 875e725

Browse files
committed
added new icons and updated file structure and UI to add more products.
1 parent d54c1aa commit 875e725

29 files changed

Lines changed: 558 additions & 30 deletions

app.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ function renderHome() {
123123
<div class="hero-orb orb-3"></div>
124124
<div class="hero-glass">
125125
<div class="hero-logo-row">
126-
<img src="browserstack-icon.svg" alt="BrowserStack" class="hero-logo" />
126+
<img src="icons/browserstack-icon.svg" alt="BrowserStack" class="hero-logo" />
127127
<span class="hero-brand">BrowserStack</span>
128128
</div>
129129
<h1 class="hero-title">Welcome to the <span class="hero-grad">Demo Hub</span></h1>

data.js

Lines changed: 15 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

extract-icons.js

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
const fs = require('fs');
2+
const path = require('path');
3+
const dir = '/Users/yashdalwani/Documents/BrowserStack-Demo-Hub';
4+
const svg = fs.readFileSync(path.join(dir, 'product-section-color-icons-v6.svg'), 'utf8');
5+
6+
// 1. Parse all gradient definitions
7+
const gradDefs = {};
8+
const gradDefRe = /<linearGradient id="(paint\d+_linear_1013_98)"[\s\S]*?<\/linearGradient>/g;
9+
let m;
10+
while ((m = gradDefRe.exec(svg)) !== null) {
11+
const id = m[0].match(/id="(paint\d+_linear_1013_98)"/)[1];
12+
gradDefs[id] = m[0];
13+
}
14+
15+
// 2. Parse gradient y-positions to identify icon groups
16+
const gradYRe = /<linearGradient id="(paint\d+_linear_1013_98)" x1="[\d.]+?" y1="([\d.]+?)"/g;
17+
const grads = [];
18+
while ((m = gradYRe.exec(svg)) !== null) grads.push({ id: m[1], y: parseFloat(m[2]) });
19+
20+
const iconGroups = [];
21+
let group = [grads[0]];
22+
for (let i = 1; i < grads.length; i++) {
23+
if (grads[i].y - grads[i - 1].y > 20) { iconGroups.push(group); group = [grads[i]]; }
24+
else group.push(grads[i]);
25+
}
26+
iconGroups.push(group);
27+
28+
// 3. Collect all drawable elements with their position in the SVG
29+
const elemRe = /<(path|ellipse|circle|rect)(\s[^>]*)\/>/g;
30+
const allElems = [];
31+
while ((m = elemRe.exec(svg)) !== null) {
32+
allElems.push({ tag: m[0], pos: m.index });
33+
}
34+
35+
// 4. For each icon group, find the SVG slice between first and last element referencing its paints
36+
const iconNames = [
37+
'icon-01', 'icon-02', 'icon-03', 'icon-04-lca', 'icon-05', 'icon-06',
38+
'icon-07', 'icon-08', 'icon-09', 'icon-10', 'icon-11', 'icon-12',
39+
'icon-13', 'icon-14-live', 'icon-15', 'icon-16', 'icon-17', 'icon-18',
40+
'icon-19', 'icon-20', 'icon-21', 'icon-22', 'icon-23'
41+
];
42+
43+
fs.mkdirSync(path.join(dir, 'icons'), { recursive: true });
44+
45+
iconGroups.forEach((grp, idx) => {
46+
const paintIds = new Set(grp.map(g => g.id));
47+
const minY = Math.min(...grp.map(g => g.y));
48+
const nextMinY = idx + 1 < iconGroups.length
49+
? Math.min(...iconGroups[idx + 1].map(g => g.y))
50+
: 1677;
51+
const iconY = Math.max(0, minY - 14);
52+
const iconH = Math.min(44, nextMinY - iconY);
53+
54+
// Find positions of elements referencing this icon's paints
55+
const myElems = allElems.filter(e => {
56+
for (const pid of paintIds) {
57+
if (e.tag.includes(pid)) return true;
58+
}
59+
return false;
60+
});
61+
62+
if (myElems.length === 0) {
63+
console.log(`⚠ ${iconNames[idx]}: no elements found`);
64+
return;
65+
}
66+
67+
const firstPos = myElems[0].pos;
68+
const lastElem = myElems[myElems.length - 1];
69+
const lastPos = lastElem.pos + lastElem.tag.length;
70+
71+
// Grab all elements in the SVG between firstPos and lastPos (includes white overlays)
72+
const sliceElems = allElems.filter(e => e.pos >= firstPos && e.pos <= lastPos);
73+
74+
// Collect gradient defs for this icon
75+
const prefix = 'i' + (idx + 1);
76+
let defsOut = grp.map(g => (gradDefs[g.id] || '')).join('\n ')
77+
.replace(/paint(\d+)_linear_1013_98/g, prefix + '_p$1');
78+
let contentOut = sliceElems.map(e => e.tag).join('\n ')
79+
.replace(/paint(\d+)_linear_1013_98/g, prefix + '_p$1');
80+
81+
const out = [
82+
'<svg xmlns="http://www.w3.org/2000/svg" width="44" height="44" viewBox="0 0 44 ' + iconH.toFixed(1) + '" fill="none">',
83+
' <defs>',
84+
' ' + defsOut,
85+
' </defs>',
86+
' <g transform="translate(0,' + (-iconY).toFixed(1) + ')">',
87+
' ' + contentOut,
88+
' </g>',
89+
'</svg>'
90+
].join('\n');
91+
92+
const fname = path.join(dir, 'icons', iconNames[idx] + '.svg');
93+
fs.writeFileSync(fname, out);
94+
console.log('✓ ' + iconNames[idx] + '.svg (' + sliceElems.length + ' elems, y=' + iconY.toFixed(0) + ')');
95+
});

icons/icon-01.svg

Lines changed: 26 additions & 0 deletions
Loading

icons/icon-02.svg

Lines changed: 21 additions & 0 deletions
Loading

icons/icon-03.svg

Lines changed: 16 additions & 0 deletions
Loading

icons/icon-04-lca.svg

Lines changed: 11 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)