<pre class="script-css">
/* TAG SPHERE - GROSSE SCHRIFT + AUTO-EXPLODE */
#tagSphere {
position: fixed;
top: 50%;
left: 20px;
transform: translateY(-50%);
width: 280px;
height: 280px;
z-index: 999;
cursor: move;
cursor: -webkit-grab;
cursor: -moz-grab;
opacity: 0;
visibility: hidden;
transition: opacity 0.4s ease, visibility 0.4s ease, width 0.7s cubic-bezier(0.68, -0.55, 0.265, 1.55), height 0.7s cubic-bezier(0.68, -0.55, 0.265, 1.55), top 0.7s ease, left 0.7s ease, transform 0.7s ease, z-index 0s;
background: transparent;
border: none;
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
}
#tagSphere.visible {
opacity: 1;
visibility: visible;
}
#tagSphere.exploded {
width: 90vmin;
height: 90vmin;
max-width: 900px;
max-height: 900px;
top: 50vh;
left: 50vw;
transform: translate(-50%, -50%);
z-index: 2147483647;
}
@media (orientation: landscape) and (min-width: 1024px) {
#tagSphere.exploded {
width: 80vw;
height: 70vh;
max-width: 1200px;
max-height: 750px;
}
}
#tagSphereBackdrop {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: rgba(0, 0, 0, 0.3);
z-index: 2147483646;
opacity: 0;
visibility: hidden;
transition: opacity 0.3s ease, visibility 0.3s ease;
}
#tagSphereBackdrop.visible {
opacity: 1;
visibility: visible;
}
@media (max-width: 768px) {
#tagSphere {
width: 250px;
height: 250px;
left: 50vw;
top: 50vh;
transform: translate(-50%, -50%);
}
#tagSphere.exploded {
width: 100vw !important;
height: 100vh !important;
max-width: none !important;
max-height: none !important;
top: 50vh !important;
left: 50vw !important;
transform: translate(-50%, -50%) !important;
background: rgba(255, 255, 255, 0.95);
}
#tagSphereBackdrop {
display: none;
}
}
#tagSphere.dragging {
cursor: -webkit-grabbing !important;
cursor: -moz-grabbing !important;
}
#tagSphere .close-btn {
position: absolute;
top: 20px;
right: 20px;
width: 56px;
height: 56px;
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
color: #CC0000;
border: 2px solid rgba(204, 0, 0, 0.2);
border-radius: 50%;
font-size: 32px;
font-weight: bold;
line-height: 52px;
text-align: center;
cursor: pointer;
z-index: 9999;
opacity: 0;
visibility: hidden;
transition: all 0.3s ease;
user-select: none;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
}
#tagSphere.exploded .close-btn {
opacity: 1 !important;
visibility: visible !important;
}
#tagSphere .close-btn:hover {
background: #CC0000;
color: #FFFFFF;
border-color: #CC0000;
transform: scale(1.1);
box-shadow: 0 6px 24px rgba(204, 0, 0, 0.4);
}
#tagSphere .close-btn:active {
transform: scale(0.95);
}
#tagSphere .back-btn {
position: absolute;
top: 20px;
left: 20px;
width: 56px;
height: 56px;
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
color: #0066CC;
border: 2px solid rgba(0, 102, 204, 0.2);
border-radius: 50%;
font-size: 28px;
font-weight: bold;
line-height: 52px;
text-align: center;
cursor: pointer;
z-index: 9999;
opacity: 0;
visibility: hidden;
transition: all 0.3s ease;
user-select: none;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
}
#tagSphere.mode-pages.exploded .back-btn {
opacity: 1 !important;
visibility: visible !important;
}
#tagSphere .back-btn:hover {
background: #0066CC;
color: #FFFFFF;
border-color: #0066CC;
transform: scale(1.1);
box-shadow: 0 6px 24px rgba(0, 102, 204, 0.4);
}
#tagSphere .back-btn:active {
transform: scale(0.95);
}
@media (orientation: landscape) and (min-width: 1024px) {
#tagSphere.exploded .close-btn {
top: 35px;
right: 45px;
width: 64px;
height: 64px;
font-size: 38px;
line-height: 60px;
}
#tagSphere.exploded .back-btn {
top: 35px;
left: 45px;
width: 64px;
height: 64px;
font-size: 34px;
line-height: 60px;
}
}
@media (orientation: portrait) {
#tagSphere .close-btn {
width: 72px;
height: 72px;
font-size: 40px;
line-height: 68px;
top: 25px;
right: 25px;
}
#tagSphere .back-btn {
width: 72px;
height: 72px;
font-size: 36px;
line-height: 68px;
top: 25px;
left: 25px;
}
}
@media (max-width: 768px) and (orientation: portrait) {
#tagSphere .close-btn {
width: 80px;
height: 80px;
font-size: 48px;
line-height: 76px;
top: 20px;
right: 20px;
box-shadow: 0 6px 24px rgba(0, 0, 0, 0.25);
}
#tagSphere .back-btn {
width: 80px;
height: 80px;
font-size: 42px;
line-height: 76px;
top: 20px;
left: 20px;
box-shadow: 0 6px 24px rgba(0, 0, 0, 0.25);
}
}
@media (max-width: 768px) and (orientation: landscape) {
#tagSphere .close-btn {
width: 64px;
height: 64px;
font-size: 36px;
line-height: 60px;
}
#tagSphere .back-btn {
width: 64px;
height: 64px;
font-size: 32px;
line-height: 60px;
}
}
#tagSphere .tag-item {
position: absolute;
padding: 18px 32px;
white-space: nowrap;
font-size: 20px;
font-weight: 700;
text-decoration: none;
background: #FFFFFF;
border: none;
border-radius: 25px;
cursor: pointer;
min-width: 70px;
text-align: center;
box-shadow: 0 3px 10px rgba(0,0,0,0.15);
transition: transform 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, opacity 0.3s ease;
pointer-events: auto;
z-index: 100;
user-select: none;
}
@media (max-width: 768px) {
#tagSphere .tag-item {
padding: 22px 38px;
font-size: 22px;
min-width: 95px;
}
}
#tagSphere .tag-item.atom-0 { animation: float-0 4.2s ease-in-out infinite; }
#tagSphere .tag-item.atom-1 { animation: float-1 5.1s ease-in-out infinite; }
#tagSphere .tag-item.atom-2 { animation: float-2 4.7s ease-in-out infinite; }
#tagSphere .tag-item.atom-3 { animation: float-3 5.5s ease-in-out infinite; }
#tagSphere .tag-item.atom-4 { animation: float-4 4.9s ease-in-out infinite; }
#tagSphere .tag-item.atom-5 { animation: float-5 5.3s ease-in-out infinite; }
#tagSphere .tag-item.atom-6 { animation: float-6 4.5s ease-in-out infinite; }
#tagSphere .tag-item.atom-7 { animation: float-7 5.8s ease-in-out infinite; }
@keyframes float-0 {
0%, 100% { transform: translate(0, 0) rotate(0deg); }
25% { transform: translate(3px, -4px) rotate(1deg); }
50% { transform: translate(-3px, -5px) rotate(-1deg); }
75% { transform: translate(-4px, -2px) rotate(2deg); }
}
@keyframes float-1 {
0%, 100% { transform: translate(0, 0) rotate(0deg); }
25% { transform: translate(-3px, -5px) rotate(-1deg); }
50% { transform: translate(4px, -3px) rotate(1deg); }
75% { transform: translate(3px, -6px) rotate(-2deg); }
}
@keyframes float-2 {
0%, 100% { transform: translate(0, 0) rotate(0deg); }
25% { transform: translate(4px, -3px) rotate(2deg); }
50% { transform: translate(-3px, -6px) rotate(-1deg); }
75% { transform: translate(3px, -4px) rotate(1deg); }
}
@keyframes float-3 {
0%, 100% { transform: translate(0, 0) rotate(0deg); }
25% { transform: translate(-4px, -6px) rotate(-2deg); }
50% { transform: translate(3px, -4px) rotate(1deg); }
75% { transform: translate(-3px, -5px) rotate(-1deg); }
}
@keyframes float-4 {
0%, 100% { transform: translate(0, 0) rotate(0deg); }
25% { transform: translate(3px, -5px) rotate(1deg); }
50% { transform: translate(-4px, -4px) rotate(-2deg); }
75% { transform: translate(4px, -6px) rotate(2deg); }
}
@keyframes float-5 {
0%, 100% { transform: translate(0, 0) rotate(0deg); }
25% { transform: translate(-3px, -4px) rotate(-1deg); }
50% { transform: translate(4px, -6px) rotate(2deg); }
75% { transform: translate(-4px, -3px) rotate(-2deg); }
}
@keyframes float-6 {
0%, 100% { transform: translate(0, 0) rotate(0deg); }
25% { transform: translate(4px, -6px) rotate(2deg); }
50% { transform: translate(-3px, -5px) rotate(-1deg); }
75% { transform: translate(3px, -3px) rotate(1deg); }
}
@keyframes float-7 {
0%, 100% { transform: translate(0, 0) rotate(0deg); }
25% { transform: translate(-4px, -4px) rotate(-2deg); }
50% { transform: translate(3px, -6px) rotate(1deg); }
75% { transform: translate(-3px, -5px) rotate(-1deg); }
}
#tagSphere.mode-tags .tag-item {
color: #0066CC;
}
#tagSphere.mode-tags .tag-item:hover {
color: #0044AA;
box-shadow: 0 6px 20px rgba(0,102,204,0.5);
transform: scale(1.3) !important;
z-index: 9998 !important;
}
#tagSphere.mode-pages .tag-item:hover {
box-shadow: 0 6px 20px rgba(204,0,0,0.5);
transform: scale(1.3) !important;
z-index: 9998 !important;
}
</pre> <script><![CDATA[
(function() {
// ============================================
// KONFIGURATION - HIER ALLES ANPASSEN!
// ============================================
var CONFIG = {
// SPHERE GRÖßE
baseRadius: 120, // Radius der kleinen Sphere (px)
smallContainerSize: 280, // Größe klein Desktop (px)
smallContainerMobile: 250, // Größe klein Mobile (px)
// SCHRIFTGRÖSSEN
baseFontSize: 20, // Desktop Schriftgröße (px)
baseFontSizeMobile: 22, // Mobile Schriftgröße (px)
minFontPages: 18, // Min Font für Pages Desktop (px)
maxFontPages: 38, // Max Font für Pages Desktop (px)
minFontPagesMobile: 20, // Min Font für Pages Mobile (px)
maxFontPagesMobile: 40, // Max Font für Pages Mobile (px)
// VERTEILUNG (SPHERE SHAPE)
xFactorNormal: 0.4, // Horizontal komprimiert (klein)
yFactorNormal: 1.5, // Vertikal gestreckt (klein)
xFactorLandscape: 0.9, // Horizontal Landscape groß
yFactorLandscape: 1.0, // Vertikal Landscape groß
// OPACITY & AKTIVIERUNG
inactiveOpacityFactor: 0.4, // Opacity wenn nicht aktiv (0-1)
verticalGradientStrength: 0.6, // Gradient Stärke vertikal (0-1)
// AUTO-EXPLODE AKTIVIERUNGSBEREICH
autoExplodeTrigger: 0.35, // Nur links von 35% Bildschirmbreite (0-1)
// 0.5 = Mitte, 0.35 = weiter links, 0.2 = ganz links
// SCROLL AKTIVIERUNG
scrollActivationThreshold: 1000, // Ab wieviel px Scroll wird Sphere sichtbar
// MOBILE BREAKPOINT
mobileBreakpoint: 768, // Unter diesem Wert = Mobile (px)
landscapeBreakpoint: 1024, // Ab diesem Wert = Landscape Modus (px)
// DRAG SENSITIVITY
dragSensitivity: 0.008, // Rotation Empfindlichkeit beim Drag
movementThreshold: 10 // Min Pixel-Bewegung für Drag-Erkennung
};
// ============================================
// AB HIER NICHTS MEHR ÄNDERN!
// ============================================
var c = null;
var backdrop = null;
var closeBtn = null;
var backBtn = null;
var items = [];
var angleX = 0;
var angleY = 0;
var exploded = false;
var drag = false;
var lastX = 0;
var lastY = 0;
var visible = false;
var loading = false;
var mode = 'tags';
var touchStartTime = 0;
var originalTags = [];
var isMobile = false;
var startX = 0;
var startY = 0;
var hasMoved = false;
var isActive = false;
var isLandscape = false;
var lastMouseX = 0;
function detectMobile() {
isMobile = window.innerWidth <= CONFIG.mobileBreakpoint;
}
function detectLandscape() {
isLandscape = window.innerWidth > window.innerHeight && window.innerWidth >= CONFIG.landscapeBreakpoint;
}
function getViewportSize() {
if (window.visualViewport) {
return {
width: window.visualViewport.width,
height: window.visualViewport.height
};
}
return {
width: window.innerWidth,
height: window.innerHeight
};
}
function createContainer() {
backdrop = document.createElement('div');
backdrop.id = 'tagSphereBackdrop';
c = document.createElement('div');
c.id = 'tagSphere';
c.className = 'mode-tags';
closeBtn = document.createElement('button');
closeBtn.className = 'close-btn';
closeBtn.textContent = '×';
closeBtn.title = 'Close';
backBtn = document.createElement('button');
backBtn.className = 'back-btn';
backBtn.textContent = '◄';
backBtn.title = 'Back to Tags';
c.appendChild(closeBtn);
c.appendChild(backBtn);
var body = document.body || document.getElementsByTagName('body')[0];
body.appendChild(backdrop);
body.appendChild(c);
}
function extractTags() {
var box = document.querySelector('.pageTags');
if (!box) return;
var links = box.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
var link = links[i];
var txt = (link.textContent || link.innerText || '').replace(/^\s+|\s+$/g, '');
if (txt.indexOf('bearbeiten') !== -1 || txt.indexOf('edit') !== -1) continue;
if (txt.length > 0 && link.href) {
items.push({
text: txt,
url: link.href,
isTag: true,
views: 0,
phi: 0,
theta: 0
});
}
}
originalTags = items.slice();
distributeItems();
}
function distributeItems() {
var count = items.length;
if (count === 0) return;
var goldenAngle = Math.PI * (3 - Math.sqrt(5));
for (var i = 0; i < count; i++) {
var y = 1 - (i / (count - 1)) * 2;
var theta = goldenAngle * i;
items[i].phi = theta;
items[i].theta = Math.acos(y);
}
}
function clearItems() {
var elements = c.getElementsByClassName('tag-item');
while (elements.length > 0) {
c.removeChild(elements[0]);
}
items = [];
}
function createElements() {
for (var i = 0; i < items.length; i++) {
var item = items[i];
var span = document.createElement('span');
span.className = 'tag-item atom-' + (i % 8);
var icon = item.isTag ? '