| 1 |
(function () { |
| 2 |
'use strict'; |
| 3 |
|
| 4 |
var svgNS = 'http://www.w3.org/2000/svg'; |
| 5 |
|
| 6 |
function mkEl(tag, attrs, text) { |
| 7 |
var el = document.createElementNS(svgNS, tag); |
| 8 |
if (attrs) Object.keys(attrs).forEach(function (k) { el.setAttribute(k, attrs[k]); }); |
| 9 |
if (text != null) el.textContent = text; |
| 10 |
return el; |
| 11 |
} |
| 12 |
|
| 13 |
document.querySelectorAll('.bkbg-vc-app').forEach(function (app) { |
| 14 |
var o; |
| 15 |
try { o = JSON.parse(app.dataset.opts || '{}'); } catch (e) { return; } |
| 16 |
|
| 17 |
var values = Array.isArray(o.values) ? o.values : []; |
| 18 |
var centerText = o.centerText || 'Our Values'; |
| 19 |
var size = o.size || 520; |
| 20 |
var orbitRadius = o.orbitRadius || 38; |
| 21 |
var centerRadius = o.centerRadius || 22; |
| 22 |
var iconSize = o.iconSize || 32; |
| 23 |
var labelSize = o.labelSize || 14; |
| 24 |
var descSize = o.descSize || 12; |
| 25 |
var centerTextSize = o.centerTextSize || 20; |
| 26 |
var showDesc = !!o.showDescription; |
| 27 |
var animate = !!o.animate; |
| 28 |
var animDur = o.animateDuration || 800; |
| 29 |
var lineStyle = o.lineStyle || 'dashed'; |
| 30 |
var nodeBg = o.nodeBg || '#6366f1'; |
| 31 |
var centerBg = o.centerBg || '#0f172a'; |
| 32 |
var centerColor = o.centerColor || '#ffffff'; |
| 33 |
var lineColor = o.lineColor || '#cbd5e1'; |
| 34 |
var labelColor = o.labelColor || '#0f172a'; |
| 35 |
var descColor = o.descColor || '#64748b'; |
| 36 |
var sectionBg = o.sectionBg || ''; |
| 37 |
|
| 38 |
if (sectionBg) app.style.background = sectionBg; |
| 39 |
|
| 40 |
var n = values.length; |
| 41 |
if (n === 0) return; |
| 42 |
|
| 43 |
var cx = size / 2; |
| 44 |
var cy = size / 2; |
| 45 |
var OR = (size / 2) * (orbitRadius / 100); |
| 46 |
var CR = (size / 2) * (centerRadius / 100); |
| 47 |
var nodeR = CR * 0.75; |
| 48 |
var dash = lineStyle === 'dashed' ? '6 4' : 'none'; |
| 49 |
|
| 50 |
/* ── Build SVG ── */ |
| 51 |
var svg = mkEl('svg', { |
| 52 |
viewBox: '0 0 ' + size + ' ' + size, |
| 53 |
width: '100%', |
| 54 |
style: 'max-width:' + size + 'px;overflow:visible;display:block;margin:0 auto' |
| 55 |
}); |
| 56 |
|
| 57 |
var nodes = values.map(function (v, i) { |
| 58 |
var angle = (2 * Math.PI * i / n) - Math.PI / 2; |
| 59 |
return { x: cx + OR * Math.cos(angle), y: cy + OR * Math.sin(angle), v: v, angle: angle }; |
| 60 |
}); |
| 61 |
|
| 62 |
/* connector lines */ |
| 63 |
nodes.forEach(function (node, i) { |
| 64 |
var line = mkEl('line', { |
| 65 |
x1: cx, y1: cy, x2: node.x, y2: node.y, |
| 66 |
stroke: lineColor, 'stroke-width': 1.5, |
| 67 |
'stroke-dasharray': dash, opacity: 0.7, |
| 68 |
class: 'bkbg-vc-line' |
| 69 |
}); |
| 70 |
svg.appendChild(line); |
| 71 |
}); |
| 72 |
|
| 73 |
/* orbit ring */ |
| 74 |
svg.appendChild(mkEl('circle', { |
| 75 |
cx: cx, cy: cy, r: OR, |
| 76 |
fill: 'none', stroke: lineColor, 'stroke-width': 1, |
| 77 |
'stroke-dasharray': '4 6', opacity: 0.4 |
| 78 |
})); |
| 79 |
|
| 80 |
/* center circle */ |
| 81 |
svg.appendChild(mkEl('circle', { cx: cx, cy: cy, r: CR, fill: centerBg })); |
| 82 |
var cText = mkEl('text', { |
| 83 |
x: cx, y: cy, |
| 84 |
'text-anchor': 'middle', 'dominant-baseline': 'middle', |
| 85 |
'font-size': centerTextSize, 'font-weight': 700, fill: centerColor, |
| 86 |
'font-family': 'inherit' |
| 87 |
}, centerText); |
| 88 |
svg.appendChild(cText); |
| 89 |
|
| 90 |
/* nodes */ |
| 91 |
nodes.forEach(function (node, i) { |
| 92 |
var g = mkEl('g', { class: 'bkbg-vc-node-g' }); |
| 93 |
if (animate) { |
| 94 |
g.style.setProperty('--vc-cx', cx + 'px'); |
| 95 |
g.style.setProperty('--vc-cy', cy + 'px'); |
| 96 |
g.style.transitionDelay = (i * (animDur / n)) + 'ms'; |
| 97 |
} |
| 98 |
|
| 99 |
/* node circle */ |
| 100 |
var circle = mkEl('circle', { |
| 101 |
cx: node.x, cy: node.y, r: nodeR, |
| 102 |
fill: nodeBg, class: 'bkbg-vc-node-circle' |
| 103 |
}); |
| 104 |
g.appendChild(circle); |
| 105 |
|
| 106 |
/* icon */ |
| 107 |
var _IP = window.bkbgIconPicker; |
| 108 |
var _iType = node.v.iconType || 'custom-char'; |
| 109 |
if (_IP && _iType !== 'custom-char') { |
| 110 |
var _built = _IP.buildFrontendIcon(_iType, node.v.icon, node.v.iconDashicon, node.v.iconImageUrl, node.v.iconDashiconColor); |
| 111 |
if (_built) { |
| 112 |
var fo = document.createElementNS(svgNS, 'foreignObject'); |
| 113 |
fo.setAttribute('x', node.x - nodeR * 0.5); |
| 114 |
fo.setAttribute('y', node.y - nodeR * 0.5); |
| 115 |
fo.setAttribute('width', nodeR); |
| 116 |
fo.setAttribute('height', nodeR); |
| 117 |
var foDiv = document.createElement('div'); |
| 118 |
foDiv.style.cssText = 'width:100%;height:100%;display:flex;align-items:center;justify-content:center;font-size:' + (iconSize * 0.55) + 'px;line-height:1;'; |
| 119 |
foDiv.appendChild(_built); |
| 120 |
fo.appendChild(foDiv); |
| 121 |
g.appendChild(fo); |
| 122 |
} else { |
| 123 |
g.appendChild(mkEl('text', { |
| 124 |
x: node.x, y: node.y, |
| 125 |
'text-anchor': 'middle', 'dominant-baseline': 'middle', |
| 126 |
'font-size': iconSize * 0.55, 'font-family': 'inherit' |
| 127 |
}, node.v.icon || '')); |
| 128 |
} |
| 129 |
} else { |
| 130 |
g.appendChild(mkEl('text', { |
| 131 |
x: node.x, y: node.y, |
| 132 |
'text-anchor': 'middle', 'dominant-baseline': 'middle', |
| 133 |
'font-size': iconSize * 0.55, 'font-family': 'inherit' |
| 134 |
}, node.v.icon || '')); |
| 135 |
} |
| 136 |
|
| 137 |
/* label */ |
| 138 |
var ta = node.x > cx + 5 ? 'start' : node.x < cx - 5 ? 'end' : 'middle'; |
| 139 |
var labelX = node.x + (node.x > cx ? 1 : -1) * (nodeR + 8); |
| 140 |
var labelEl = mkEl('text', { |
| 141 |
x: labelX, y: node.y - (descSize + 2), |
| 142 |
'text-anchor': ta, 'font-size': labelSize, |
| 143 |
'font-weight': 700, fill: labelColor, 'font-family': 'inherit' |
| 144 |
}, node.v.label || ''); |
| 145 |
g.appendChild(labelEl); |
| 146 |
|
| 147 |
/* description */ |
| 148 |
if (showDesc && node.v.description) { |
| 149 |
var descEl = mkEl('text', { |
| 150 |
x: labelX, y: node.y + descSize, |
| 151 |
'text-anchor': ta, 'font-size': descSize, |
| 152 |
fill: descColor, 'font-family': 'inherit' |
| 153 |
}, node.v.description); |
| 154 |
g.appendChild(descEl); |
| 155 |
} |
| 156 |
|
| 157 |
svg.appendChild(g); |
| 158 |
}); |
| 159 |
|
| 160 |
app.appendChild(svg); |
| 161 |
|
| 162 |
/* ── Animate on scroll ── */ |
| 163 |
if (animate) { |
| 164 |
app.classList.add('bkbg-vc-animate'); |
| 165 |
var observer = new IntersectionObserver(function (entries) { |
| 166 |
entries.forEach(function (entry) { |
| 167 |
if (entry.isIntersecting) { |
| 168 |
app.classList.add('bkbg-vc-visible'); |
| 169 |
observer.unobserve(app); |
| 170 |
} |
| 171 |
}); |
| 172 |
}, { threshold: 0.2 }); |
| 173 |
observer.observe(app); |
| 174 |
} |
| 175 |
}); |
| 176 |
}()); |
| 177 |
|