117 lines
7.4 KiB
JavaScript
117 lines
7.4 KiB
JavaScript
// ------------------------------------------------------------------------
|
|
// lens-overlay.js - Returns an SVG string for the event overlay inside
|
|
// the big ScopeReticle.
|
|
//
|
|
// Rendered INSIDE the lens clip path, BELOW the glass shine/shade layers.
|
|
// cx, cy = lens centre coords; lensR = lens radius.
|
|
//
|
|
// To add a new overlay for an event: add another 'if (...)' block below
|
|
// that matches by event.emoji or event.id and returns an SVG fragment
|
|
// string. Return null when no overlay applies.
|
|
// ------------------------------------------------------------------------
|
|
|
|
export function getLensOverlaySVG(event, cx, cy, lensR) {
|
|
if (!event) return null;
|
|
const id = event.id;
|
|
|
|
if (event.emoji === '☄️') {
|
|
return [
|
|
'<g opacity="0.55" clip-path="url(#scope-lens-clip)">',
|
|
'<line x1="' + (cx-60) + '" y1="' + (cy-50) + '" x2="' + (cx-20) + '" y2="' + (cy-20) + '" stroke="#ffe8a0" stroke-width="1.5" stroke-linecap="round" opacity="0.9"/>',
|
|
'<line x1="' + (cx-40) + '" y1="' + (cy-70) + '" x2="' + (cx+5) + '" y2="' + (cy-30) + '" stroke="#fff0c0" stroke-width="1" stroke-linecap="round" opacity="0.7"/>',
|
|
'<line x1="' + (cx+30) + '" y1="' + (cy-60) + '" x2="' + (cx+65) + '" y2="' + (cy-25) + '" stroke="#ffe8a0" stroke-width="1.8" stroke-linecap="round" opacity="0.8"/>',
|
|
'<line x1="' + (cx-10) + '" y1="' + (cy-40) + '" x2="' + (cx+30) + '" y2="' + (cy-5) + '" stroke="#fff0c0" stroke-width="0.9" stroke-linecap="round" opacity="0.65"/>',
|
|
'<line x1="' + (cx-70) + '" y1="' + (cy-20) + '" x2="' + (cx-35) + '" y2="' + (cy+10) + '" stroke="#ffe8a0" stroke-width="1.2" stroke-linecap="round" opacity="0.6"/>',
|
|
'</g>',
|
|
].join('');
|
|
}
|
|
|
|
if (id.includes('solar-eclipse')) {
|
|
const cx_ = cx, cy_ = cy - 20;
|
|
return '<g clip-path="url(#scope-lens-clip)">'
|
|
+ '<radialGradient id="corona-glow" cx="' + cx_ + '" cy="' + cy_ + '" r="38" gradientUnits="userSpaceOnUse">'
|
|
+ '<stop offset="0%" stop-color="rgba(255,220,100,0)" />'
|
|
+ '<stop offset="55%" stop-color="rgba(255,220,100,0.55)" />'
|
|
+ '<stop offset="100%" stop-color="rgba(255,180,40,0)" /></radialGradient>'
|
|
+ '<circle cx="' + cx_ + '" cy="' + cy_ + '" r="38" fill="url(#corona-glow)" opacity="0.8" />'
|
|
+ '<circle cx="' + cx_ + '" cy="' + cy_ + '" r="18" fill="rgba(5,2,15,0.88)" /></g>';
|
|
}
|
|
|
|
if (id.includes('lunar-eclipse')) {
|
|
const cx_ = cx, cy_ = cy - 30;
|
|
return '<g clip-path="url(#scope-lens-clip)">'
|
|
+ '<radialGradient id="blood-moon-glow" cx="' + cx_ + '" cy="' + cy_ + '" r="30" gradientUnits="userSpaceOnUse">'
|
|
+ '<stop offset="0%" stop-color="rgba(180,30,10,0.7)" />'
|
|
+ '<stop offset="100%" stop-color="rgba(120,10,5,0)" /></radialGradient>'
|
|
+ '<circle cx="' + cx_ + '" cy="' + cy_ + '" r="30" fill="url(#blood-moon-glow)" />'
|
|
+ '<circle cx="' + cx_ + '" cy="' + cy_ + '" r="16" fill="rgba(160,25,10,0.75)" />'
|
|
+ '<circle cx="' + cx_ + '" cy="' + cy_ + '" r="16" fill="none" stroke="rgba(220,60,20,0.5)" stroke-width="1.5" /></g>';
|
|
}
|
|
|
|
if (event.emoji === '🪐' && event.id.includes('conjunction')) {
|
|
return '<g clip-path="url(#scope-lens-clip)" opacity="0.65">'
|
|
+ '<circle cx="' + (cx+20) + '" cy="' + (cy-35) + '" r="10" fill="rgba(210,185,130,0.7)" />'
|
|
+ '<ellipse cx="' + (cx+20) + '" cy="' + (cy-35) + '" rx="18" ry="4.5" fill="none" stroke="rgba(200,170,100,0.65)" stroke-width="2.5" /></g>';
|
|
}
|
|
|
|
if (event.emoji === '🔴') {
|
|
return '<g clip-path="url(#scope-lens-clip)" opacity="0.6">'
|
|
+ '<circle cx="' + (cx+30) + '" cy="' + (cy-30) + '" r="7" fill="rgba(200,80,40,0.75)" />'
|
|
+ '<circle cx="' + (cx-20) + '" cy="' + (cy-45) + '" r="5" fill="rgba(220,160,80,0.7)" /></g>';
|
|
}
|
|
|
|
if (id === 'stargazing') {
|
|
const pts = [[cx-50,cy-55,1.8],[cx+40,cy-65,1.4],[cx-20,cy-70,1.0],[cx+65,cy-40,1.6],[cx-60,cy-30,1.2],[cx+50,cy-55,1.0],[cx-35,cy-45,1.4],[cx+20,cy-50,1.8],[cx-75,cy-50,1.0]];
|
|
const dots = pts.map(function(s){return '<circle cx="'+s[0]+'" cy="'+s[1]+'" r="'+s[2]+'" fill="rgba(255,255,255,0.9)" />';}).join('');
|
|
return '<g clip-path="url(#scope-lens-clip)" opacity="0.7">' + dots + '</g>';
|
|
}
|
|
|
|
if (id === 'perfect-sunset') {
|
|
return '<g clip-path="url(#scope-lens-clip)" opacity="0.5">'
|
|
+ '<radialGradient id="sunset-lens-glow" cx="' + cx + '" cy="' + (cy+20) + '" r="' + lensR + '" gradientUnits="userSpaceOnUse">'
|
|
+ '<stop offset="0%" stop-color="rgba(255,120,20,0.7)" />'
|
|
+ '<stop offset="50%" stop-color="rgba(255,60,10,0.25)" />'
|
|
+ '<stop offset="100%" stop-color="rgba(200,20,0,0)" /></radialGradient>'
|
|
+ '<circle cx="' + cx + '" cy="' + cy + '" r="' + lensR + '" fill="url(#sunset-lens-glow)" /></g>';
|
|
}
|
|
|
|
if (id === 'heat-spike') {
|
|
return '<g clip-path="url(#scope-lens-clip)" opacity="0.35">'
|
|
+ '<path d="M ' + (cx-lensR+10) + ' ' + (cy+30) + ' Q ' + (cx-20) + ' ' + (cy+15) + ' ' + (cx+20) + ' ' + (cy+30) + ' Q ' + (cx+60) + ' ' + (cy+45) + ' ' + (cx+lensR-10) + ' ' + (cy+30) + '" fill="none" stroke="rgba(255,120,20,0.6)" stroke-width="2" />'
|
|
+ '<path d="M ' + (cx-lensR+10) + ' ' + (cy+45) + ' Q ' + (cx-10) + ' ' + (cy+30) + ' ' + (cx+30) + ' ' + (cy+45) + ' Q ' + (cx+65) + ' ' + (cy+60) + ' ' + (cx+lensR-10) + ' ' + (cy+45) + '" fill="none" stroke="rgba(255,100,10,0.5)" stroke-width="2" /></g>';
|
|
}
|
|
|
|
if (id === 'wet') {
|
|
const sl = [-55,-30,-5,20,45,65].map(function(x){
|
|
return '<line x1="' + (cx+x) + '" y1="' + (cy-lensR+10) + '" x2="' + (cx+x-15) + '" y2="' + (cy+lensR-10) + '" stroke="rgba(140,180,220,0.6)" stroke-width="1" stroke-linecap="round" />';
|
|
}).join('');
|
|
return '<g clip-path="url(#scope-lens-clip)" opacity="0.45">' + sl + '</g>';
|
|
}
|
|
|
|
if (id === 'wind') {
|
|
const wl = [-30,5,40].map(function(y){
|
|
return '<path d="M ' + (cx-lensR+12) + ' ' + (cy+y) + ' q 40 -14 80 0 q 30 10 ' + (lensR-10) + ' -2" fill="none" stroke="rgba(170,200,230,0.55)" stroke-width="1.5" stroke-linecap="round" />';
|
|
}).join('');
|
|
return '<g clip-path="url(#scope-lens-clip)" opacity="0.45">' + wl + '</g>';
|
|
}
|
|
|
|
if (id === 'storm') {
|
|
// Driving rain streaks plus a forked lightning bolt.
|
|
const sl = [-55,-30,-5,20,45,65].map(function(x){
|
|
return '<line x1="' + (cx+x) + '" y1="' + (cy-lensR+10) + '" x2="' + (cx+x-22) + '" y2="' + (cy+lensR-10) + '" stroke="rgba(140,180,220,0.55)" stroke-width="1" stroke-linecap="round" />';
|
|
}).join('');
|
|
const bolt = '<path d="M ' + (cx+6) + ' ' + (cy-lensR+18) + ' L ' + (cx-14) + ' ' + (cy+8) + ' L ' + (cx-2) + ' ' + (cy+8) + ' L ' + (cx-18) + ' ' + (cy+lensR-14) + ' L ' + (cx+18) + ' ' + (cy-2) + ' L ' + (cx+4) + ' ' + (cy-2) + ' Z" fill="rgba(255,224,120,0.7)" stroke="rgba(255,200,60,0.8)" stroke-width="1" stroke-linejoin="round" />';
|
|
return '<g clip-path="url(#scope-lens-clip)" opacity="0.5">' + sl + bolt + '</g>';
|
|
}
|
|
|
|
if (id === 'frost') {
|
|
const fc = [[-50,40],[0,55],[50,40],[-30,65],[30,65]].map(function(p){
|
|
var dx=p[0], dy=p[1];
|
|
return '<g transform="translate(' + (cx+dx) + ',' + (cy+dy) + ')"><line x1="-6" y1="0" x2="6" y2="0" stroke="rgba(180,220,255,0.8)" stroke-width="1" /><line x1="0" y1="-6" x2="0" y2="6" stroke="rgba(180,220,255,0.8)" stroke-width="1" /><line x1="-4" y1="-4" x2="4" y2="4" stroke="rgba(180,220,255,0.7)" stroke-width="0.8" /><line x1="4" y1="-4" x2="-4" y2="4" stroke="rgba(180,220,255,0.7)" stroke-width="0.8" /></g>';
|
|
}).join('');
|
|
return '<g clip-path="url(#scope-lens-clip)" opacity="0.5">' + fc + '</g>';
|
|
}
|
|
|
|
return null;
|
|
}
|