mirror of
git://f0xx.org/android_cast
synced 2026-07-29 05:17:39 +03:00
sync 4
This commit is contained in:
@@ -1,18 +1,23 @@
|
|||||||
/**
|
/**
|
||||||
* Hub landing globe — orthographic Canvas2D (globe3d=1).
|
* Hub landing globe — orthographic Canvas2D (globe3d=1).
|
||||||
* Matches globe3d=0: sample hub SVG disks in body-fixed ortho coords (N-up via bodyToTex).
|
* Phase 1: E–W parallels only (SVG hub ellipses → body → Y-rotation → canvas stroke).
|
||||||
* Mercator-flat lon/lat fill only where the ortho disk has no paint (rotation wrap).
|
* Phase 2 (after confirm): N–S meridians from SVG.
|
||||||
*/
|
*/
|
||||||
export const GLOBE_VIEW = { imgW: 1920, imgH: 1080, cx: 720, cy: 560, r: 322, rim: 330 };
|
export const GLOBE_VIEW = { imgW: 1920, imgH: 1080, cx: 720, cy: 560, r: 322, rim: 330 };
|
||||||
|
|
||||||
const AUTO_SPIN_RAD_S = 0.035;
|
const AUTO_SPIN_RAD_S = 0.035;
|
||||||
const DRAG_ROTATION_PER_PX = 0.004;
|
const DRAG_ROTATION_PER_PX = 0.004;
|
||||||
const OCEAN_FALLBACK = { r: 22, g: 38, b: 60 };
|
const OCEAN_FALLBACK = { r: 22, g: 38, b: 60 };
|
||||||
const FRONT_Z = 0.02;
|
const FRONT_Z = 0.04;
|
||||||
const RASTER_SCALE = 2;
|
const RASTER_SCALE = 2;
|
||||||
const GRID_PARALLELS = [0, 0.521, -0.521];
|
const AXIS_STEPS = 160;
|
||||||
const GRID_MERIDIAN_SPACING = Math.PI / 6;
|
|
||||||
const GRID_LINE_RAD = 0.018;
|
/** Same ellipses as hub-logo-fragment-globe-grid-overlay.svg (E–W / parallel to equator). */
|
||||||
|
const HUB_EW_PARALLELS = [
|
||||||
|
{ cx: 720, cy: 560, rx: 318, ry: 11, width: 7.5, bright: true },
|
||||||
|
{ cx: 720, cy: 392, rx: 260, ry: 39, width: 7.5, bright: false },
|
||||||
|
{ cx: 720, cy: 728, rx: 260, ry: 39, width: 7.5, bright: false },
|
||||||
|
];
|
||||||
|
|
||||||
function hubAsset(rel, build) {
|
function hubAsset(rel, build) {
|
||||||
const link = document.querySelector('link[href*="hub.css"]');
|
const link = document.querySelector('link[href*="hub.css"]');
|
||||||
@@ -103,18 +108,125 @@ function inverseRotateY(nx, ny, nz, rotY) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Map view body → hub disk coords (globe3d=0, N-up artwork). */
|
|
||||||
function bodyToTex(body) {
|
function bodyToTex(body) {
|
||||||
return { x: body.x, y: -body.y, z: body.z };
|
return { x: body.x, y: -body.y, z: body.z };
|
||||||
}
|
}
|
||||||
|
|
||||||
function texLonLat(tex) {
|
function bodyToView(body, rotY) {
|
||||||
|
const cosR = Math.cos(rotY);
|
||||||
|
const sinR = Math.sin(rotY);
|
||||||
return {
|
return {
|
||||||
lon: Math.atan2(tex.x, tex.z),
|
x: body.x * cosR + body.z * sinR,
|
||||||
lat: Math.asin(Math.max(-1, Math.min(1, tex.y))),
|
y: body.y,
|
||||||
|
z: -body.x * sinR + body.z * cosR,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Hub disk pixel → unit-sphere body (front hemisphere, matches globe3d=0). */
|
||||||
|
function hubPixelToBody(hpX, hpY) {
|
||||||
|
const texX = (hpX - GLOBE_VIEW.cx) / GLOBE_VIEW.r;
|
||||||
|
const texY = (GLOBE_VIEW.cy - hpY) / GLOBE_VIEW.r;
|
||||||
|
const rr = texX * texX + texY * texY;
|
||||||
|
if (rr > 1.001) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
x: texX,
|
||||||
|
y: -texY,
|
||||||
|
z: Math.sqrt(Math.max(0, 1 - rr)),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function ellipseBodyRing(ellipse, steps) {
|
||||||
|
const out = [];
|
||||||
|
for (let i = 0; i <= steps; i++) {
|
||||||
|
const a = (i / steps) * Math.PI * 2;
|
||||||
|
const body = hubPixelToBody(
|
||||||
|
ellipse.cx + ellipse.rx * Math.cos(a),
|
||||||
|
ellipse.cy + ellipse.ry * Math.sin(a)
|
||||||
|
);
|
||||||
|
if (body) {
|
||||||
|
out.push(body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parallelStyle(bright, scale, z) {
|
||||||
|
const t = Math.max(0, Math.min(1, (z - FRONT_Z) / (0.95 - FRONT_Z)));
|
||||||
|
if (t <= 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const alpha = bright ? 0.35 + 0.55 * t : 0.15 + 0.45 * t;
|
||||||
|
const rgb = bright ? '219,231,246' : '231,236,243';
|
||||||
|
return {
|
||||||
|
color: 'rgba(' + rgb + ',' + alpha.toFixed(3) + ')',
|
||||||
|
width: Math.max(bright ? 2.5 : 1.5, scale * (bright ? 0.007 : 0.0055)) * (0.4 + 0.6 * t),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function strokeBodyRing(ctx, cx, cy, r, rotY, bodies, styleAt) {
|
||||||
|
let run = [];
|
||||||
|
|
||||||
|
function flush() {
|
||||||
|
if (run.length < 2) {
|
||||||
|
run = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let zSum = 0;
|
||||||
|
for (let i = 0; i < run.length; i++) {
|
||||||
|
zSum += run[i].z;
|
||||||
|
}
|
||||||
|
const style = styleAt(zSum / run.length);
|
||||||
|
if (!style) {
|
||||||
|
run = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(run[0].sx, run[0].sy);
|
||||||
|
for (let i = 1; i < run.length; i++) {
|
||||||
|
ctx.lineTo(run[i].sx, run[i].sy);
|
||||||
|
}
|
||||||
|
ctx.strokeStyle = style.color;
|
||||||
|
ctx.lineWidth = style.width;
|
||||||
|
ctx.lineCap = 'round';
|
||||||
|
ctx.lineJoin = 'round';
|
||||||
|
ctx.stroke();
|
||||||
|
run = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < bodies.length; i++) {
|
||||||
|
const view = bodyToView(bodies[i], rotY);
|
||||||
|
if (view.z <= FRONT_Z) {
|
||||||
|
flush();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
run.push({
|
||||||
|
sx: cx + view.x * r,
|
||||||
|
sy: cy - view.y * r,
|
||||||
|
z: view.z,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Phase 1 — E–W hub parallels (equator + pole ellipses from SVG). */
|
||||||
|
function drawEwParallels(ctx, cx, cy, r, rotY, layoutScale) {
|
||||||
|
ctx.save();
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(cx, cy, r, 0, Math.PI * 2);
|
||||||
|
ctx.clip();
|
||||||
|
|
||||||
|
HUB_EW_PARALLELS.forEach(function (ellipse) {
|
||||||
|
const ring = ellipseBodyRing(ellipse, AXIS_STEPS);
|
||||||
|
strokeBodyRing(ctx, cx, cy, r, rotY, ring, function (z) {
|
||||||
|
return parallelStyle(ellipse.bright, layoutScale, z);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
|
|
||||||
function sampleHub(layer, tex) {
|
function sampleHub(layer, tex) {
|
||||||
const hp = {
|
const hp = {
|
||||||
x: GLOBE_VIEW.cx + tex.x * GLOBE_VIEW.r,
|
x: GLOBE_VIEW.cx + tex.x * GLOBE_VIEW.r,
|
||||||
@@ -125,6 +237,13 @@ function sampleHub(layer, tex) {
|
|||||||
return sampleImageDataBilinear(layer.data, layer.w, layer.h, sx, sy);
|
return sampleImageDataBilinear(layer.data, layer.w, layer.h, sx, sy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function texLonLat(tex) {
|
||||||
|
return {
|
||||||
|
lon: Math.atan2(tex.x, tex.z),
|
||||||
|
lat: Math.asin(Math.max(-1, Math.min(1, tex.y))),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function sampleMercFlat(mercFlat, lon, lat) {
|
function sampleMercFlat(mercFlat, lon, lat) {
|
||||||
const u = ((lon + Math.PI) / (2 * Math.PI)) * (mercFlat.w - 1);
|
const u = ((lon + Math.PI) / (2 * Math.PI)) * (mercFlat.w - 1);
|
||||||
const v = (0.5 - lat / Math.PI) * (mercFlat.h - 1);
|
const v = (0.5 - lat / Math.PI) * (mercFlat.h - 1);
|
||||||
@@ -135,62 +254,17 @@ function isLandPixel(r, g, b, a) {
|
|||||||
return a > 10 && r > 100 && g < 140 && b < 140;
|
return a > 10 && r > 100 && g < 140 && b < 140;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isGridPixel(r, g, b, a) {
|
|
||||||
return a > 8 && r + g + b > 240;
|
|
||||||
}
|
|
||||||
|
|
||||||
function wrapGridRgba(lon, lat) {
|
|
||||||
const wrapped = ((lon + Math.PI) % (2 * Math.PI) + 2 * Math.PI) % (2 * Math.PI);
|
|
||||||
const cell = wrapped % GRID_MERIDIAN_SPACING;
|
|
||||||
const merDist = Math.min(cell, GRID_MERIDIAN_SPACING - cell);
|
|
||||||
const onMeridian = merDist < GRID_LINE_RAD;
|
|
||||||
let onParallel = false;
|
|
||||||
let bright = false;
|
|
||||||
for (let i = 0; i < GRID_PARALLELS.length; i++) {
|
|
||||||
const targetLat = Math.asin(Math.max(-1, Math.min(1, GRID_PARALLELS[i])));
|
|
||||||
if (Math.abs(lat - targetLat) < GRID_LINE_RAD) {
|
|
||||||
onParallel = true;
|
|
||||||
bright = i === 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!onMeridian && !onParallel) {
|
|
||||||
return [0, 0, 0, 0];
|
|
||||||
}
|
|
||||||
if (onMeridian) {
|
|
||||||
const prime = Math.abs(lon) < GRID_LINE_RAD * 1.5;
|
|
||||||
return prime ? [238, 245, 255, 230] : [238, 245, 255, 175];
|
|
||||||
}
|
|
||||||
return bright ? [219, 231, 246, 200] : [231, 236, 243, 140];
|
|
||||||
}
|
|
||||||
|
|
||||||
function sampleOceanRgba(globe, tex) {
|
function sampleOceanRgba(globe, tex) {
|
||||||
if (tex.z <= FRONT_Z) {
|
if (tex.z <= FRONT_Z) {
|
||||||
return [OCEAN_FALLBACK.r, OCEAN_FALLBACK.g, OCEAN_FALLBACK.b, 255];
|
return [OCEAN_FALLBACK.r, OCEAN_FALLBACK.g, OCEAN_FALLBACK.b, 255];
|
||||||
}
|
}
|
||||||
const s = sampleHub(globe, tex);
|
const s = sampleHub(globe, tex);
|
||||||
if (s[3] > 8 && !isGridPixel(s[0], s[1], s[2], s[3])) {
|
if (s[3] > 8) {
|
||||||
return [s[0], s[1], s[2], 255];
|
return [s[0], s[1], s[2], 255];
|
||||||
}
|
}
|
||||||
return [OCEAN_FALLBACK.r, OCEAN_FALLBACK.g, OCEAN_FALLBACK.b, 255];
|
return [OCEAN_FALLBACK.r, OCEAN_FALLBACK.g, OCEAN_FALLBACK.b, 255];
|
||||||
}
|
}
|
||||||
|
|
||||||
function sampleGridRgba(globe, gridOverlay, tex) {
|
|
||||||
if (tex.z > FRONT_Z) {
|
|
||||||
const overlay = sampleHub(gridOverlay, tex);
|
|
||||||
if (overlay[3] >= 12) {
|
|
||||||
return overlay;
|
|
||||||
}
|
|
||||||
const base = sampleHub(globe, tex);
|
|
||||||
if (isGridPixel(base[0], base[1], base[2], base[3])) {
|
|
||||||
return base;
|
|
||||||
}
|
|
||||||
return [0, 0, 0, 0];
|
|
||||||
}
|
|
||||||
const ll = texLonLat(tex);
|
|
||||||
const g = wrapGridRgba(ll.lon, ll.lat);
|
|
||||||
return g[3] > 0 ? g : [0, 0, 0, 0];
|
|
||||||
}
|
|
||||||
|
|
||||||
function sampleLandRgba(continents, mercFlat, tex) {
|
function sampleLandRgba(continents, mercFlat, tex) {
|
||||||
if (tex.z > FRONT_Z) {
|
if (tex.z > FRONT_Z) {
|
||||||
const ortho = sampleHub(continents, tex);
|
const ortho = sampleHub(continents, tex);
|
||||||
@@ -214,7 +288,9 @@ function fillDiskRegion(ctx, cx, cy, r, rotY, fn) {
|
|||||||
const y1 = Math.min(ctx.canvas.height - 1, Math.ceil(cy + r));
|
const y1 = Math.min(ctx.canvas.height - 1, Math.ceil(cy + r));
|
||||||
const w = x1 - x0 + 1;
|
const w = x1 - x0 + 1;
|
||||||
const h = y1 - y0 + 1;
|
const h = y1 - y0 + 1;
|
||||||
if (w <= 0 || h <= 0) return null;
|
if (w <= 0 || h <= 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const out = ctx.createImageData(w, h);
|
const out = ctx.createImageData(w, h);
|
||||||
const px = out.data;
|
const px = out.data;
|
||||||
@@ -247,7 +323,9 @@ function fillDiskRegion(ctx, cx, cy, r, rotY, fn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function blitLayer(ctx, cx, cy, r, layer) {
|
function blitLayer(ctx, cx, cy, r, layer) {
|
||||||
if (!layer) return;
|
if (!layer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
ctx.save();
|
ctx.save();
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(cx, cy, r, 0, Math.PI * 2);
|
ctx.arc(cx, cy, r, 0, Math.PI * 2);
|
||||||
@@ -256,44 +334,6 @@ function blitLayer(ctx, cx, cy, r, layer) {
|
|||||||
ctx.restore();
|
ctx.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawOceanLayer(ctx, cx, cy, r, rotY, globe) {
|
|
||||||
blitLayer(
|
|
||||||
ctx,
|
|
||||||
cx,
|
|
||||||
cy,
|
|
||||||
r,
|
|
||||||
fillDiskRegion(ctx, cx, cy, r, rotY, function (tex) {
|
|
||||||
return sampleOceanRgba(globe, tex);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawGridLayer(ctx, cx, cy, r, rotY, globe, gridOverlay) {
|
|
||||||
blitLayer(
|
|
||||||
ctx,
|
|
||||||
cx,
|
|
||||||
cy,
|
|
||||||
r,
|
|
||||||
fillDiskRegion(ctx, cx, cy, r, rotY, function (tex) {
|
|
||||||
const g = sampleGridRgba(globe, gridOverlay, tex);
|
|
||||||
return g[3] < 8 ? [0, 0, 0, 0] : g;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawLandLayer(ctx, cx, cy, r, rotY, continents, mercFlat) {
|
|
||||||
blitLayer(
|
|
||||||
ctx,
|
|
||||||
cx,
|
|
||||||
cy,
|
|
||||||
r,
|
|
||||||
fillDiskRegion(ctx, cx, cy, r, rotY, function (tex) {
|
|
||||||
const l = sampleLandRgba(continents, mercFlat, tex);
|
|
||||||
return l || [0, 0, 0, 0];
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawRim(ctx, globeImg, cx, cy, r, rim, layoutScale) {
|
function drawRim(ctx, globeImg, cx, cy, r, rim, layoutScale) {
|
||||||
const drawW = GLOBE_VIEW.imgW * layoutScale;
|
const drawW = GLOBE_VIEW.imgW * layoutScale;
|
||||||
const drawH = GLOBE_VIEW.imgH * layoutScale;
|
const drawH = GLOBE_VIEW.imgH * layoutScale;
|
||||||
@@ -321,19 +361,16 @@ export async function mountHubGlobe(stage, opts) {
|
|||||||
const urls = {
|
const urls = {
|
||||||
globe: hubAsset('assets/hub-logo-fragment-globe.svg', build),
|
globe: hubAsset('assets/hub-logo-fragment-globe.svg', build),
|
||||||
continents: hubAsset('assets/hub-logo-continents-mercator-globe.svg', build),
|
continents: hubAsset('assets/hub-logo-continents-mercator-globe.svg', build),
|
||||||
gridOverlay: hubAsset('assets/hub-logo-fragment-globe-grid-overlay.svg', build),
|
|
||||||
mercatorFlat: hubAsset('assets/hub-logo-continents-mercator-flat.svg', build),
|
mercatorFlat: hubAsset('assets/hub-logo-continents-mercator-flat.svg', build),
|
||||||
};
|
};
|
||||||
|
|
||||||
let globeImg;
|
let globeImg;
|
||||||
let continentsImg;
|
let continentsImg;
|
||||||
let gridOverlayImg;
|
|
||||||
let mercatorFlatImg;
|
let mercatorFlatImg;
|
||||||
try {
|
try {
|
||||||
[globeImg, continentsImg, gridOverlayImg, mercatorFlatImg] = await Promise.all([
|
[globeImg, continentsImg, mercatorFlatImg] = await Promise.all([
|
||||||
loadImage(urls.globe),
|
loadImage(urls.globe),
|
||||||
loadImage(urls.continents),
|
loadImage(urls.continents),
|
||||||
loadImage(urls.gridOverlay),
|
|
||||||
loadImage(urls.mercatorFlat),
|
loadImage(urls.mercatorFlat),
|
||||||
]);
|
]);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -344,7 +381,6 @@ export async function mountHubGlobe(stage, opts) {
|
|||||||
|
|
||||||
const globe = rasterizeImage(globeImg, GLOBE_VIEW.imgW, GLOBE_VIEW.imgH, RASTER_SCALE);
|
const globe = rasterizeImage(globeImg, GLOBE_VIEW.imgW, GLOBE_VIEW.imgH, RASTER_SCALE);
|
||||||
const continents = rasterizeImage(continentsImg, GLOBE_VIEW.imgW, GLOBE_VIEW.imgH, RASTER_SCALE);
|
const continents = rasterizeImage(continentsImg, GLOBE_VIEW.imgW, GLOBE_VIEW.imgH, RASTER_SCALE);
|
||||||
const gridOverlay = rasterizeImage(gridOverlayImg, GLOBE_VIEW.imgW, GLOBE_VIEW.imgH, RASTER_SCALE);
|
|
||||||
const mercW = (mercatorFlatImg.naturalWidth || 800) * 2;
|
const mercW = (mercatorFlatImg.naturalWidth || 800) * 2;
|
||||||
const mercH = (mercatorFlatImg.naturalHeight || 519) * 2;
|
const mercH = (mercatorFlatImg.naturalHeight || 519) * 2;
|
||||||
const mercFlat = rasterizeImage(mercatorFlatImg, mercW, mercH, 1);
|
const mercFlat = rasterizeImage(mercatorFlatImg, mercW, mercH, 1);
|
||||||
@@ -383,17 +419,35 @@ export async function mountHubGlobe(stage, opts) {
|
|||||||
const cy = (rect.cy - rect.top) * dpr;
|
const cy = (rect.cy - rect.top) * dpr;
|
||||||
const r = rect.r * dpr;
|
const r = rect.r * dpr;
|
||||||
const rim = rect.rim * dpr;
|
const rim = rect.rim * dpr;
|
||||||
|
const layoutScale = rect.scale * dpr;
|
||||||
|
|
||||||
ctx.clearRect(0, 0, px, px);
|
ctx.clearRect(0, 0, px, px);
|
||||||
drawOceanLayer(ctx, cx, cy, r, rotation, globe);
|
blitLayer(
|
||||||
drawGridLayer(ctx, cx, cy, r, rotation, globe, gridOverlay);
|
ctx,
|
||||||
drawLandLayer(ctx, cx, cy, r, rotation, continents, mercFlat);
|
cx,
|
||||||
drawRim(ctx, globeImg, cx, cy, r, rim, rect.scale * dpr);
|
cy,
|
||||||
|
r,
|
||||||
|
fillDiskRegion(ctx, cx, cy, r, rotation, function (tex) {
|
||||||
|
return sampleOceanRgba(globe, tex);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
drawEwParallels(ctx, cx, cy, r, rotation, layoutScale);
|
||||||
|
blitLayer(
|
||||||
|
ctx,
|
||||||
|
cx,
|
||||||
|
cy,
|
||||||
|
r,
|
||||||
|
fillDiskRegion(ctx, cx, cy, r, rotation, function (tex) {
|
||||||
|
const l = sampleLandRgba(continents, mercFlat, tex);
|
||||||
|
return l || [0, 0, 0, 0];
|
||||||
|
})
|
||||||
|
);
|
||||||
|
drawRim(ctx, globeImg, cx, cy, r, rim, layoutScale);
|
||||||
ctx.save();
|
ctx.save();
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(cx, cy, r, 0, Math.PI * 2);
|
ctx.arc(cx, cy, r, 0, Math.PI * 2);
|
||||||
ctx.strokeStyle = 'rgba(10,14,20,0.55)';
|
ctx.strokeStyle = 'rgba(10,14,20,0.55)';
|
||||||
ctx.lineWidth = Math.max(2, rect.scale * dpr * 0.006);
|
ctx.lineWidth = Math.max(2, layoutScale * 0.006);
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
};
|
};
|
||||||
@@ -457,6 +511,7 @@ export async function mountHubGlobe(stage, opts) {
|
|||||||
|
|
||||||
raf = requestAnimationFrame(tick);
|
raf = requestAnimationFrame(tick);
|
||||||
stage.dataset.globe3d = 'active';
|
stage.dataset.globe3d = 'active';
|
||||||
|
stage.dataset.globeAxis = 'ew-parallels';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
destroy() {
|
destroy() {
|
||||||
@@ -464,6 +519,7 @@ export async function mountHubGlobe(stage, opts) {
|
|||||||
window.removeEventListener('resize', resize);
|
window.removeEventListener('resize', resize);
|
||||||
canvas.remove();
|
canvas.remove();
|
||||||
delete stage.dataset.globe3d;
|
delete stage.dataset.globe3d;
|
||||||
|
delete stage.dataset.globeAxis;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ unset($__platformDir);
|
|||||||
var supportsLayout = !!(window.CSS && CSS.supports && CSS.supports('object-fit', 'cover'));
|
var supportsLayout = !!(window.CSS && CSS.supports && CSS.supports('object-fit', 'cover'));
|
||||||
var logoEnabled = !!(stage && supportsSvg && supportsLayout);
|
var logoEnabled = !!(stage && supportsSvg && supportsLayout);
|
||||||
|
|
||||||
var logoBuild = '20260606globe10';
|
var logoBuild = '20260606globe11';
|
||||||
|
|
||||||
function hubAsset(rel) {
|
function hubAsset(rel) {
|
||||||
var link = document.querySelector('link[href*="hub.css"]');
|
var link = document.querySelector('link[href*="hub.css"]');
|
||||||
|
|||||||
Reference in New Issue
Block a user