// Glintpane hub page: live 9-slice builder, icon browser and UI piece gallery. © 2026 CyberMax. (function () { 'use strict'; var $ = function (s) { return document.querySelector(s); }; var KIT = null; var SCALE = 0.25; // same SliceScale the Luau module uses var COLORS = ['green', 'blue', 'red', 'gold', 'purple', 'orange', 'pink', 'cyan', 'grey']; var SWATCH = { green: '#52D66A', blue: '#3FA9FF', red: '#FF4D5E', gold: '#FFC531', purple: '#A66BFF', orange: '#FF8A33', pink: '#FF6FB5', cyan: '#39E0E0', grey: '#C3CAD8' }; var state = { color: 'green', icon: 'play', mono: false, tint: '#ffffff', cat: 'All', q: '' }; function toast(msg) { var t = $('#toast'); t.textContent = msg; t.classList.add('on'); setTimeout(function () { t.classList.remove('on'); }, 2200); } // Apply a kit piece to an element as CSS border-image with the module's SliceCenter and SliceScale. function slice(el, piece) { var m = KIT.piece_meta[piece]; var url = 'img/ui/' + piece + '.png'; if (!m.slice) { el.style.borderImage = 'none'; el.style.background = 'url(' + url + ') center/contain no-repeat'; return; } var x0 = m.slice[0], y0 = m.slice[1], x1 = m.slice[2], y1 = m.slice[3]; var t = y0, r = m.w - x1, b = m.h - y1, l = x0; el.style.borderStyle = 'solid'; el.style.borderWidth = (t * SCALE) + 'px ' + (r * SCALE) + 'px ' + (b * SCALE) + 'px ' + (l * SCALE) + 'px'; el.style.borderImage = 'url(' + url + ') ' + t + ' ' + r + ' ' + b + ' ' + l + ' fill stretch'; el.dataset.piece = piece; } function iconSrc(name, mono) { return 'img/' + (mono ? 'mono' : 'color') + '/' + name + '.png'; } function setButtonIcon() { var img = $('#gbtn-icon'); if (state.mono) { img.style.visibility = 'hidden'; var tinted = $('#gbtn-tint'); if (!tinted) { tinted = document.createElement('span'); tinted.id = 'gbtn-tint'; tinted.className = 'tint'; img.after(tinted); } tinted.style.webkitMaskImage = tinted.style.maskImage = 'url(' + iconSrc(state.icon, true) + ')'; tinted.style.backgroundColor = state.tint; img.style.display = 'none'; tinted.style.display = ''; } else { var t2 = $('#gbtn-tint'); if (t2) t2.style.display = 'none'; img.style.display = ''; img.style.visibility = ''; img.src = iconSrc(state.icon, false); } } function buildBuilder() { var btn = $('#gbtn'); var hovering = false; function show(s) { slice(btn, 'button-' + state.color + '-' + s); btn.dataset.state = s; } btn.addEventListener('pointerenter', function () { hovering = true; show('hover'); }); btn.addEventListener('pointerleave', function () { hovering = false; show('normal'); }); btn.addEventListener('pointerdown', function () { show('pressed'); }); btn.addEventListener('pointerup', function () { show(hovering ? 'hover' : 'normal'); }); btn.addEventListener('click', function () { toast('Clicked! In Roblox: button.Activated:Connect(...)'); }); show('normal'); slice($('#panel'), 'panel-light'); slice($('#track'), 'bar-track'); slice($('#fill'), 'bar-fill-green'); slice($('.pill'), 'bar-track'); var rar = [['common', 'egg'], ['uncommon', 'pet'], ['rare', 'sword'], ['epic', 'crystal'], ['legendary', 'crown'], ['mythic', 'diamond']]; $('#slots').innerHTML = rar.map(function (r) { return '
' + r[1] + '' + r[0] + '
'; }).join(''); document.querySelectorAll('#slots .slot').forEach(function (s) { slice(s, 'slot-' + s.dataset.r); }); $('#colors').innerHTML = COLORS.map(function (c) { return ''; }).join(''); $('#colors').addEventListener('click', function (e) { var b = e.target.closest('[data-c]'); if (!b) return; state.color = b.dataset.c; document.querySelectorAll('#colors .sw').forEach(function (x) { x.classList.toggle('on', x === b); }); show('normal'); slice($('#fill'), 'bar-fill-' + (['green', 'blue', 'red', 'gold', 'purple'].indexOf(state.color) >= 0 ? state.color : 'green')); }); $('#t-text').addEventListener('input', function (e) { $('#gbtn-text').textContent = e.target.value || ' '; }); $('#t-width').addEventListener('input', function (e) { btn.style.width = e.target.value + 'px'; }); var all = []; Object.keys(KIT.categories).forEach(function (c) { all = all.concat(KIT.categories[c]); }); $('#t-icon').innerHTML = all.map(function (n) { return '' + n + ''; }).join(''); $('#t-icon').addEventListener('change', function (e) { state.icon = e.target.value; setButtonIcon(); }); $('#t-mono').addEventListener('change', function (e) { state.mono = e.target.checked; setButtonIcon(); }); $('#t-tint').addEventListener('input', function (e) { state.tint = e.target.value; if (!state.mono) { state.mono = true; $('#t-mono').checked = true; } setButtonIcon(); }); $('#t-bar').addEventListener('input', function (e) { var v = +e.target.value; $('#fill').style.width = v + '%'; $('#fill').style.display = v > 0 ? '' : 'none'; }); $('#fill').style.width = '65%'; btn.style.width = '240px'; } function renderIcons() { var mono = $('#mono-all').checked; var names = []; Object.keys(KIT.categories).forEach(function (c) { if (state.cat === 'All' || state.cat === c) names = names.concat(KIT.categories[c]); }); var q = state.q.trim().toLowerCase(); if (q) names = names.filter(function (n) { return n.indexOf(q) >= 0; }); $('#icons').innerHTML = names.map(function (n) { return '
' + n + ' icon
' + n + (KIT.sampler.indexOf(n) >= 0 ? ' FREE' : '') + '
'; }).join('') || '

No icon matches. Try "coin", "egg" or "arrow".

'; } function buildIcons() { var cats = ['All'].concat(Object.keys(KIT.categories)); $('#cats').innerHTML = cats.map(function (c) { var n = c === 'All' ? KIT.icons : KIT.categories[c].length; return ''; }).join(''); $('#cats').addEventListener('click', function (e) { var b = e.target.closest('[data-cat]'); if (!b) return; state.cat = b.dataset.cat; document.querySelectorAll('#cats .chip').forEach(function (x) { x.classList.toggle('on', x === b); }); renderIcons(); }); $('#q').addEventListener('input', function (e) { state.q = e.target.value; renderIcons(); }); $('#mono-all').addEventListener('change', renderIcons); $('#light-bg').addEventListener('change', function (e) { $('#icons').classList.toggle('light', e.target.checked); }); renderIcons(); } function buildPieces() { var groups = {}; Object.keys(KIT.piece_meta).forEach(function (k) { var g = KIT.piece_meta[k].group; (groups[g] = groups[g] || []).push(k); }); $('#pieces').innerHTML = Object.keys(groups).map(function (g) { return '

' + g + ' ' + groups[g].length + '

' + groups[g].map(function (k) { var m = KIT.piece_meta[k]; return '
' + k + '
' + k + '
'; }).join('') + '
'; }).join(''); } $('#btn-free').addEventListener('click', function () { toast('Free sampler downloading: 12 icons + the green button.'); }); fetch('kit.json').then(function (r) { return r.json(); }).then(function (kit) { KIT = kit; buildBuilder(); buildIcons(); buildPieces(); document.body.dataset.ready = '1'; }); })();