Mod Menu - Chaos Mode, Bouncing DVD, Custom Banner & Renaming.
// ==UserScript==
// @name Google Classroom Mod Menu
// @namespace http://tampermonkey.net/
// @version 3.0
// @description Mod Menu - Chaos Mode, Bouncing DVD, Custom Banner & Renaming.
// @author MuhammadUthman
// @match https://classroom.google.com/*
// @grant GM_addStyle
// @license MIT
// ==/UserScript==
(function() {
'use strict';
const state = {
menuVisible: true,
bannerType: null,
bannerSrc: '',
bannerScale: 1.0,
bWidth: '100%',
bHeight: '100%',
bTop: '0px',
bLeft: '0px',
bannerMuted: true,
spoofName: '',
dvdEnabled: false,
dvdMedia: '',
dvdMediaType: 'image',
dvdMultiplier: 1,
dvdSpeed: 3,
dvdScale: 1.0,
dvdMuted: true,
dvdInstances:[],
fontDistortEnabled: false,
fontDistortSpeed: 150,
fontList: 'Comic Sans MS, Impact, Papyrus, Courier New, Times New Roman, Chiller, Brush Script MT, Jokerman, Arial Black, Wingdings',
chaosEnabled: false
};
let isMediaDragging = false;
let isMediaResizing = false;
let isScrubbing = false;
let fontDistortTimer = null;
let chaosTimer = null;
// Helper: Formats seconds into MM:SS
function formatTime(seconds) {
if (isNaN(seconds)) return "0:00";
const m = Math.floor(seconds / 60);
const s = Math.floor(seconds % 60).toString().padStart(2, '0');
return `${m}:${s}`;
}
GM_addStyle(`
/* Base Mod Menu Styles */
#gc-mod-menu {
position: fixed; top: 20px; right: 20px; width: 320px;
background: #1e1e2e; color: #f8f8f2; border-radius: 12px;
box-shadow: 0 15px 35px rgba(0,0,0,0.6); z-index: 999999;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
border: 1px solid #44475a; overflow: hidden; transition: opacity 0.3s;
}
#gc-mod-header {
background: #282a36; padding: 12px 15px; cursor: move; font-weight: bold;
display: flex; justify-content: space-between; align-items: center;
border-bottom: 2px solid #bd93f9; user-select: none;
}
#gc-mod-body {
padding: 15px; max-height: 500px; overflow-y: auto;
}
#gc-mod-body::-webkit-scrollbar { width: 8px; }
#gc-mod-body::-webkit-scrollbar-thumb { background: #6272a4; border-radius: 4px; }
.mod-section-title {
font-size: 14px; color: #8be9fd; text-transform: uppercase;
margin: 15px 0 10px 0; border-bottom: 1px solid #44475a; padding-bottom: 3px;
}
.mod-section-title:first-child { margin-top: 0; }
.mod-btn {
background: #44475a; color: #f8f8f2; border: none; border-radius: 6px;
padding: 8px 12px; margin: 4px 0; width: 100%; cursor: pointer;
transition: all 0.2s; text-align: left; font-size: 13px;
}
.mod-btn:hover { background: #6272a4; }
.mod-btn.active { background: #50fa7b; color: #282a36; font-weight: bold; }
.mod-input {
width: 100%; background: #282a36; color: #f8f8f2;
border: 1px solid #6272a4; border-radius: 6px; padding: 8px;
margin-bottom: 8px; font-size: 13px; outline: none; box-sizing: border-box;
}
/* Custom Slider Styling */
input[type="range"].mod-slider {
-webkit-appearance: none; width: 100%; background: transparent; margin: 10px 0 15px 0;
}
input[type="range"].mod-slider::-webkit-slider-thumb {
-webkit-appearance: none; height: 16px; width: 16px; border-radius: 50%;
background: #50fa7b; cursor: pointer; margin-top: -6px;
}
input[type="range"].mod-slider::-webkit-slider-runnable-track {
width: 100%; height: 4px; cursor: pointer; background: #6272a4; border-radius: 2px;
}
#gc-mod-toggle {
position: fixed; top: 20px; right: 20px; width: 45px; height: 45px;
border-radius: 50%; background: #bd93f9; color: #282a36; border: none;
box-shadow: 0 5px 15px rgba(0,0,0,0.4); z-index: 999998; cursor: pointer;
font-size: 24px; display: none; align-items: center; justify-content: center;
}
/* Banner Resizer Handles */
.mod-handle {
position: absolute; width: 18px; height: 18px; background: #50fa7b;
border: 2px solid #282a36; border-radius: 50%; z-index: 10; opacity: 0;
transition: opacity 0.2s, transform 0.2s;
}
.gc-mod-wrapper:hover .mod-handle { opacity: 0.7; }
.mod-handle:hover { opacity: 1 !important; transform: scale(1.3); }
.mod-handle-nw { top: -9px; left: -9px; cursor: nw-resize; }
.mod-handle-ne { top: -9px; right: -9px; cursor: ne-resize; }
.mod-handle-sw { bottom: -9px; left: -9px; cursor: sw-resize; }
.mod-handle-se { bottom: -9px; right: -9px; cursor: se-resize; }
`);
function doFontGlitch() {
let styleTag = document.getElementById('gc-mod-font-distort');
if (!styleTag) {
styleTag = document.createElement('style');
styleTag.id = 'gc-mod-font-distort';
document.head.appendChild(styleTag);
}
const fonts = state.fontList.split(',').map(f => f.trim()).filter(f => f);
if (fonts.length > 0) {
const randomFont = fonts[Math.floor(Math.random() * fonts.length)];
const randomSpacing = (Math.random() * 4 - 2).toFixed(1) + 'px'; // -2px to 2px
styleTag.textContent = `
*:not([id^="gc-mod-"]):not([id^="gc-dvd-"]):not([id^="gc-mod-"] *):not([id^="gc-dvd-"] *) {
font-family: "${randomFont}" !important;
letter-spacing: ${randomSpacing} !important;
}
`;
}
}
function startFontDistortion() {
stopFontDistortion();
state.fontDistortEnabled = true;
fontDistortTimer = setInterval(doFontGlitch, state.fontDistortSpeed);
}
function stopFontDistortion() {
state.fontDistortEnabled = false;
if (fontDistortTimer) {
clearInterval(fontDistortTimer);
fontDistortTimer = null;
}
const styleTag = document.getElementById('gc-mod-font-distort');
if (styleTag) styleTag.textContent = '';
}
function startChaos() {
state.chaosEnabled = true;
chaosTimer = setInterval(() => {
const els = document.querySelectorAll('div, span, a, p, img, button, li');
els.forEach(el => {
if(el.closest('[id^="gc-mod-"]') || el.closest('[id^="gc-dvd-"]') || el.tagName === 'BODY' || el.tagName === 'HTML' || el.tagName === 'MAIN') return;
if(Math.random() > 0.7) {
const x = (Math.random() - 0.5) * 200; // -100px to 100px
const y = (Math.random() - 0.5) * 200;
const rot = (Math.random() - 0.5) * 60; // -30deg to 30deg
el.style.transform = `translate(${x}px, ${y}px) rotate(${rot}deg)`;
el.style.transition = "transform 0.3s cubic-bezier(0.68, -0.55, 0.27, 1.55)";
}
});
}, 200);
}
function stopChaos() {
state.chaosEnabled = false;
clearInterval(chaosTimer);
const els = document.querySelectorAll('div, span, a, p, img, button, li');
els.forEach(el => {
if(el.closest('[id^="gc-mod-"]') || el.closest('[id^="gc-dvd-"]')) return;
el.style.transform = '';
el.style.transition = '';
});
}
function spawnDVD(startX, startY, dx = null, dy = null) {
const container = document.getElementById('gc-dvd-container');
if (!container) return;
let el;
if (state.dvdMediaType === 'video') {
el = document.createElement('video');
el.src = state.dvdMedia;
el.autoplay = true;
el.loop = true;
el.muted = state.dvdMuted;
el.volume = 1.0;
el.playsInline = true;
} else {
el = document.createElement('img');
el.src = state.dvdMedia;
}
el.style.position = 'absolute';
el.style.transformOrigin = 'top left';
el.style.width = '150px';
el.style.pointerEvents = 'none';
container.appendChild(el);
if (dx === null || dy === null) {
let angle = Math.random() * Math.PI * 2;
dx = Math.cos(angle);
dy = Math.sin(angle);
}
state.dvdInstances.push({
x: startX || window.innerWidth / 2,
y: startY || window.innerHeight / 2,
dx,
dy,
element: el
});
}
function clearDVDs() {
state.dvdInstances.forEach(d => d.element.remove());
state.dvdInstances =[];
}
function animateDVD() {
if (state.dvdEnabled) {
const screenW = window.innerWidth;
const screenH = window.innerHeight;
let pendingSpawns =[];
for (let i = 0; i < state.dvdInstances.length; i++) {
let dvd = state.dvdInstances[i];
let el = dvd.element;
dvd.x += dvd.dx * state.dvdSpeed;
dvd.y += dvd.dy * state.dvdSpeed;
el.style.transform = `scale(${state.dvdScale})`;
let rect = el.getBoundingClientRect();
let width = rect.width;
let height = rect.height;
let bounced = false;
if (dvd.x <= 0) { dvd.x = 0; dvd.dx *= -1; bounced = true; }
else if (dvd.x + width >= screenW) { dvd.x = screenW - width; dvd.dx *= -1; bounced = true; }
if (dvd.y <= 0) { dvd.y = 0; dvd.dy *= -1; bounced = true; }
else if (dvd.y + height >= screenH) { dvd.y = screenH - height; dvd.dy *= -1; bounced = true; }
if (bounced && state.dvdMultiplier > 1 && state.dvdInstances.length + pendingSpawns.length < 150) {
for (let m = 0; m < state.dvdMultiplier - 1; m++) {
let angle = Math.random() * Math.PI * 2;
pendingSpawns.push({ x: dvd.x, y: dvd.y, dx: Math.cos(angle), dy: Math.sin(angle) });
}
}
el.style.left = dvd.x + 'px';
el.style.top = dvd.y + 'px';
}
pendingSpawns.forEach(s => {
spawnDVD(s.x, s.y, s.dx, s.dy);
});
}
requestAnimationFrame(animateDVD);
}
requestAnimationFrame(animateDVD);
function buildMenu() {
if (document.getElementById('gc-mod-menu')) return;
const menu = document.createElement('div');
menu.id = 'gc-mod-menu';
menu.style.display = state.menuVisible ? 'block' : 'none';
const toggleBtn = document.createElement('button');
toggleBtn.id = 'gc-mod-toggle';
toggleBtn.innerText = '⚙️';
toggleBtn.style.display = state.menuVisible ? 'none' : 'flex';
document.body.appendChild(toggleBtn);
const header = document.createElement('div');
header.id = 'gc-mod-header';
const title = document.createElement('span');
title.innerText = 'Google Classroom Mod Menu';
header.appendChild(title);
const ctrlGroup = document.createElement('div');
const minBtn = document.createElement('button');
minBtn.innerText = '➖';
minBtn.style.cssText = 'background:none; border:none; cursor:pointer; font-size:16px; margin-right:5px; color:#f1fa8c;';
ctrlGroup.appendChild(minBtn);
const closeBtn = document.createElement('button');
closeBtn.innerText = '✖';
closeBtn.style.cssText = 'background:none; border:none; cursor:pointer; font-size:16px; color:#ff5555;';
ctrlGroup.appendChild(closeBtn);
header.appendChild(ctrlGroup);
menu.appendChild(header);
const body = document.createElement('div');
body.id = 'gc-mod-body';
function createTitle(text) {
const el = document.createElement('div');
el.className = 'mod-section-title';
el.innerText = text;
body.appendChild(el);
}
function createInput(id, placeholder, val) {
const el = document.createElement('input');
el.type = 'text'; el.id = id; el.className = 'mod-input'; el.placeholder = placeholder;
if (val) el.value = val;
body.appendChild(el);
return el;
}
function createButton(text, onClick, extraStyle = '') {
const el = document.createElement('button');
el.className = 'mod-btn'; el.innerText = text;
if(extraStyle) el.style.cssText = extraStyle;
el.onclick = onClick;
body.appendChild(el);
return el;
}
createTitle('🖼️ Custom Banner');
const inpBanner = createInput('inp-banner', 'Image/Video URL (mp4, gif, jpg)');
createButton('▶ Set URL as Banner', () => {
if(inpBanner.value) {
state.bannerSrc = inpBanner.value;
state.bannerType = inpBanner.value.match(/\.(mp4|webm|ogg)$/i) ? 'video' : 'image';
}
});
const fileInput = document.createElement('input');
fileInput.type = 'file'; fileInput.accept = 'video/*, image/*'; fileInput.style.display = 'none';
fileInput.onchange = (e) => {
const file = e.target.files[0];
if(file) {
state.bannerSrc = URL.createObjectURL(file);
state.bannerType = file.type.startsWith('video') ? 'video' : 'image';
}
e.target.value = '';
};
body.appendChild(fileInput);
createButton('📁 Upload Local File', () => fileInput.click());
// Banner Audio Controls
const btnBannerMute = createButton(
state.bannerMuted ? '🔇 Unmute Banner Audio' : '🔊 Mute Banner Audio',
() => {
state.bannerMuted = !state.bannerMuted;
btnBannerMute.innerText =
state.bannerMuted
? '🔇 Unmute Banner Audio'
: '🔊 Mute Banner Audio';
btnBannerMute.classList.toggle('active', !state.bannerMuted);
document.querySelectorAll('.gc-mod-media').forEach(media => {
if (media.tagName === 'VIDEO') {
media.muted = state.bannerMuted;
// Needed because browsers block autoplay audio
media.play().catch(() => {});
}
});
}
);
if (!state.bannerMuted) {
btnBannerMute.classList.add('active');
}
state.bannerVolume = state.bannerVolume || 1.0;
const bannerVolumeLabel = document.createElement('label');
bannerVolumeLabel.innerText = `Banner Volume: ${Math.round(state.bannerVolume * 100)}%`;
bannerVolumeLabel.style.cssText =
'font-size:12px;color:#8be9fd;margin-bottom:5px;display:block;';
body.appendChild(bannerVolumeLabel);
const inpBannerVolume = document.createElement('input');
inpBannerVolume.type = 'range';
inpBannerVolume.className = 'mod-slider';
inpBannerVolume.min = '0';
inpBannerVolume.max = '1';
inpBannerVolume.step = '0.01';
inpBannerVolume.value = state.bannerVolume;
inpBannerVolume.oninput = (e) => {
state.bannerVolume = parseFloat(e.target.value);
bannerVolumeLabel.innerText =
`Banner Volume: ${Math.round(state.bannerVolume * 100)}%`;
document.querySelectorAll('.gc-mod-media').forEach(media => {
if (media.tagName === 'VIDEO') {
media.volume = state.bannerVolume;
}
});
};
body.appendChild(inpBannerVolume);
createTitle('🔍 Master Zoom & Layout');
const scaleLabel = document.createElement('label');
scaleLabel.id = 'lbl-scale';
scaleLabel.innerText = `Uniform Scale: ${state.bannerScale}x`;
scaleLabel.style.cssText = 'font-size: 12px; color: #8be9fd; margin-bottom: 5px; display: block;';
body.appendChild(scaleLabel);
const inpScale = document.createElement('input');
inpScale.type = 'range'; inpScale.id = 'inp-scale'; inpScale.className = 'mod-slider';
inpScale.min = '0.1'; inpScale.max = '4.0'; inpScale.step = '0.05'; inpScale.value = state.bannerScale;
inpScale.oninput = (e) => {
state.bannerScale = e.target.value;
scaleLabel.innerText = `Uniform Scale: ${state.bannerScale}x`;
};
body.appendChild(inpScale);
createButton('🔄 Reset Banner Layout', () => {
state.bWidth = '100%'; state.bHeight = '100%';
state.bTop = '0px'; state.bLeft = '0px';
state.bannerScale = 1.0;
inpScale.value = 1.0;
scaleLabel.innerText = `Uniform Scale: 1x`;
}, 'background: #ffb86c; color: #282a36; font-weight: bold;');
createTitle('🔠 Font Distorter');
const inpFonts = createInput('inp-fonts', 'Comma separated fonts...', state.fontList);
inpFonts.onchange = (e) => { state.fontList = e.target.value; };
const btnFontToggle = createButton(
state.fontDistortEnabled ? '⏸ Stop Distortion' : '▶ Start Distortion',
() => {
if (!state.fontDistortEnabled) {
startFontDistortion();
btnFontToggle.innerText = '⏸ Stop Distortion';
btnFontToggle.classList.add('active');
} else {
stopFontDistortion();
btnFontToggle.innerText = '▶ Start Distortion';
btnFontToggle.classList.remove('active');
}
}
);
if (state.fontDistortEnabled) btnFontToggle.classList.add('active');
const fontSpeedLabel = document.createElement('label');
fontSpeedLabel.innerText = `Speed: ${state.fontDistortSpeed}ms`;
fontSpeedLabel.style.cssText = 'font-size: 12px; color: #8be9fd; margin-bottom: 5px; display: block;';
body.appendChild(fontSpeedLabel);
const inpFontSpeed = document.createElement('input');
inpFontSpeed.type = 'range'; inpFontSpeed.className = 'mod-slider';
inpFontSpeed.min = '10'; inpFontSpeed.max = '1000'; inpFontSpeed.step = '10'; inpFontSpeed.value = state.fontDistortSpeed;
inpFontSpeed.oninput = (e) => {
state.fontDistortSpeed = parseInt(e.target.value);
fontSpeedLabel.innerText = `Speed: ${state.fontDistortSpeed}ms`;
if (state.fontDistortEnabled) startFontDistortion();
};
body.appendChild(inpFontSpeed);
createTitle('🤯 Chaos Mode');
const btnChaos = createButton(
state.chaosEnabled ? '⏸ Stop Chaos' : '🌪️ Enable Chaos Mode',
() => {
if (!state.chaosEnabled) {
startChaos();
btnChaos.innerText = '⏸ Stop Chaos';
btnChaos.classList.add('active');
} else {
stopChaos();
btnChaos.innerText = '🌪️ Enable Chaos Mode';
btnChaos.classList.remove('active');
}
}
);
if (state.chaosEnabled) btnChaos.classList.add('active');
createTitle('📀 Bouncing Multiplier');
const inpDvd = createInput('inp-dvd', 'Image/GIF/Video URL...', state.dvdMedia);
inpDvd.onchange = () => {
if (!inpDvd.value) return;
state.dvdMedia = inpDvd.value;
state.dvdMediaType = inpDvd.value.match(/\.(mp4|webm|ogg)$/i) ? 'video' : 'image';
clearDVDs();
if (state.dvdEnabled) spawnDVD();
};
const dvdFileInput = document.createElement('input');
dvdFileInput.type = 'file'; dvdFileInput.accept = 'image/*,video/*'; dvdFileInput.style.display = 'none';
dvdFileInput.onchange = (e) => {
const file = e.target.files[0];
if (!file) return;
state.dvdMedia = URL.createObjectURL(file);
state.dvdMediaType = file.type.startsWith('video') ? 'video' : 'image';
clearDVDs();
if (state.dvdEnabled) spawnDVD();
e.target.value = '';
};
body.appendChild(dvdFileInput);
const btnDvdMute = createButton(
state.dvdMuted ? '🔇 Unmute Bouncer Audio' : '🔊 Mute Bouncer Audio',
() => {
state.dvdMuted = !state.dvdMuted;
btnDvdMute.innerText = state.dvdMuted ? '🔇 Unmute Bouncer Audio' : '🔊 Mute Bouncer Audio';
btnDvdMute.classList.toggle('active', !state.dvdMuted);
state.dvdInstances.forEach(dvd => {
if (dvd.element.tagName === 'VIDEO') {
dvd.element.muted = state.dvdMuted;
dvd.element.play().catch(() => {});
}
});
}
);
if (!state.dvdMuted) btnDvdMute.classList.add('active');
const btnDvdUploadRow = document.createElement('div');
btnDvdUploadRow.style.cssText = 'display:flex; gap:5px;';
const btnDvdUpload = createButton('📁 Local Media', () => dvdFileInput.click());
btnDvdUploadRow.appendChild(btnDvdUpload);
btnDvdUploadRow.appendChild(btnDvdMute);
body.appendChild(btnDvdUploadRow);
const multiLabel = document.createElement('label');
multiLabel.innerText = `Bounce Multiplier: ${state.dvdMultiplier}x`;
multiLabel.style.cssText = 'font-size:12px;color:#8be9fd;margin-bottom:5px;display:block;';
body.appendChild(multiLabel);
const inpMulti = document.createElement('input');
inpMulti.type = 'range'; inpMulti.className = 'mod-slider';
inpMulti.min = '1'; inpMulti.max = '10'; inpMulti.step = '1'; inpMulti.value = state.dvdMultiplier;
inpMulti.oninput = (e) => {
state.dvdMultiplier = parseInt(e.target.value);
multiLabel.innerText = `Bounce Multiplier: ${state.dvdMultiplier}x`;
};
body.appendChild(inpMulti);
const btnDvdToggle = createButton('▶ Start Bouncing', () => {
state.dvdEnabled = !state.dvdEnabled;
btnDvdToggle.innerText = state.dvdEnabled ? '⏸ Pause Bouncing' : '▶ Start Bouncing';
btnDvdToggle.classList.toggle('active', state.dvdEnabled);
if (state.dvdEnabled && state.dvdInstances.length === 0) {
spawnDVD();
}
});
const speedLabel = document.createElement('label');
speedLabel.innerText = `Speed: ${state.dvdSpeed}`;
speedLabel.style.cssText = 'font-size: 12px; color: #8be9fd; margin-bottom: 5px; display: block;';
body.appendChild(speedLabel);
const inpSpeed = document.createElement('input');
inpSpeed.type = 'range'; inpSpeed.className = 'mod-slider';
inpSpeed.min = '1'; inpSpeed.max = '20'; inpSpeed.step = '1'; inpSpeed.value = state.dvdSpeed;
inpSpeed.oninput = (e) => {
state.dvdSpeed = parseFloat(e.target.value);
speedLabel.innerText = `Speed: ${state.dvdSpeed}`;
};
body.appendChild(inpSpeed);
const dvdScaleLabel = document.createElement('label');
dvdScaleLabel.innerText = `Image Scale: ${state.dvdScale}x`;
dvdScaleLabel.style.cssText = 'font-size: 12px; color: #8be9fd; margin-bottom: 5px; display: block;';
body.appendChild(dvdScaleLabel);
const inpDvdScale = document.createElement('input');
inpDvdScale.type = 'range'; inpDvdScale.className = 'mod-slider';
inpDvdScale.min = '0.1'; inpDvdScale.max = '3.0'; inpDvdScale.step = '0.1'; inpDvdScale.value = state.dvdScale;
inpDvdScale.oninput = (e) => {
state.dvdScale = parseFloat(e.target.value);
dvdScaleLabel.innerText = `Image Scale: ${state.dvdScale}x`;
};
body.appendChild(inpDvdScale);
createButton('🗑️ Clear All Images', () => {
clearDVDs();
if (state.dvdEnabled) spawnDVD(window.innerWidth / 2, window.innerHeight / 2);
});
createTitle('✏️ Class Settings');
const inpClassname = createInput('inp-classname', 'New Class Name...');
createButton('Apply New Class Name', () => { state.spoofName = inpClassname.value; });
createButton('RESET ENTIRE MOD', () => location.reload(), 'background:#ff5555; color:#fff; text-align:center; margin-top: 15px;');
menu.appendChild(body);
document.body.appendChild(menu);
let isDraggingMenu = false, offsetX, offsetY;
header.addEventListener('mousedown', (e) => {
isDraggingMenu = true;
offsetX = e.clientX - menu.getBoundingClientRect().left;
offsetY = e.clientY - menu.getBoundingClientRect().top;
});
document.addEventListener('mousemove', (e) => {
if (!isDraggingMenu) return;
menu.style.left = (e.clientX - offsetX) + 'px';
menu.style.top = (e.clientY - offsetY) + 'px';
menu.style.right = 'auto';
});
document.addEventListener('mouseup', () => isDraggingMenu = false);
minBtn.onclick = () => {
state.menuVisible = false;
menu.style.display = 'none';
toggleBtn.style.display = 'flex';
};
closeBtn.onclick = () => {
state.menuVisible = false;
menu.style.display = 'none';
};
toggleBtn.onclick = () => {
state.menuVisible = true;
menu.style.display = 'block';
toggleBtn.style.display = 'none';
};
let iconDragging = false, iconX, iconY;
toggleBtn.addEventListener('mousedown', (e) => {
iconDragging = true;
iconX = e.clientX - toggleBtn.getBoundingClientRect().left;
iconY = e.clientY - toggleBtn.getBoundingClientRect().top;
});
document.addEventListener('mousemove', (e) => {
if(!iconDragging) return;
toggleBtn.style.left = (e.clientX - iconX) + 'px';
toggleBtn.style.top = (e.clientY - iconY) + 'px';
toggleBtn.style.right = 'auto';
});
document.addEventListener('mouseup', () => iconDragging = false);
}
function makeResizableAndDraggable(wrapper) {
let currentHandle = null;
let startX, startY, startW, startH, startL, startT;
const handles =['nw', 'ne', 'sw', 'se'];
handles.forEach(pos => {
const h = document.createElement('div');
h.className = `mod-handle mod-handle-${pos}`;
h.onmousedown = (e) => {
e.stopPropagation(); e.preventDefault();
isMediaResizing = true;
currentHandle = pos;
startX = e.clientX; startY = e.clientY;
startW = wrapper.offsetWidth; startH = wrapper.offsetHeight;
startL = wrapper.offsetLeft; startT = wrapper.offsetTop;
};
wrapper.appendChild(h);
});
wrapper.style.cursor = 'move';
wrapper.onmousedown = (e) => {
if(e.target.classList.contains('mod-handle')) return;
e.preventDefault();
isMediaDragging = true;
startX = e.clientX; startY = e.clientY;
startL = wrapper.offsetLeft; startT = wrapper.offsetTop;
};
document.addEventListener('mousemove', (e) => {
if (isMediaResizing) {
const scale = parseFloat(state.bannerScale) || 1;
const dx = (e.clientX - startX) / scale;
const dy = (e.clientY - startY) / scale;
let newW = startW, newH = startH, newL = startL, newT = startT;
if (currentHandle.includes('e')) newW = startW + dx;
if (currentHandle.includes('w')) { newW = startW - dx; newL = startL + dx; }
if (currentHandle.includes('s')) newH = startH + dy;
if (currentHandle.includes('n')) { newH = startH - dy; newT = startT + dy; }
state.bWidth = newW + 'px'; state.bHeight = newH + 'px';
state.bLeft = newL + 'px'; state.bTop = newT + 'px';
wrapper.style.width = state.bWidth; wrapper.style.height = state.bHeight;
wrapper.style.left = state.bLeft; wrapper.style.top = state.bTop;
} else if (isMediaDragging) {
const dx = (e.clientX - startX);
const dy = (e.clientY - startY);
state.bLeft = (startL + dx) + 'px';
state.bTop = (startT + dy) + 'px';
wrapper.style.left = state.bLeft;
wrapper.style.top = state.bTop;
}
});
document.addEventListener('mouseup', () => {
isMediaResizing = false;
isMediaDragging = false;
currentHandle = null;
});
}
setInterval(() => {
buildMenu();
if (!document.getElementById('gc-dvd-container')) {
const dvdCont = document.createElement('div');
dvdCont.id = 'gc-dvd-container';
dvdCont.style.cssText = 'position:fixed; top:0; left:0; width:100%; height:100%; pointer-events:none; z-index:999995; overflow:hidden;';
document.body.appendChild(dvdCont);
state.dvdInstances.forEach(d => dvdCont.appendChild(d.element));
}
if (state.bannerSrc) {
const banners = document.querySelectorAll('.qyN25');
banners.forEach(banner => {
const origImg = banner.querySelector('.PFLqgc');
if (origImg) origImg.style.display = 'none';
const textContainer = banner.querySelector('.T4tcpe');
if(textContainer) {
textContainer.style.zIndex = '3';
textContainer.style.pointerEvents = 'none';
}
let wrapper = banner.querySelector('.gc-mod-wrapper');
if (wrapper) {
const media = wrapper.querySelector('.gc-mod-media');
if (media) {
const isCurrentlyVideo = media.tagName === 'VIDEO';
const wantsVideo = state.bannerType === 'video';
if (isCurrentlyVideo !== wantsVideo) {
wrapper.remove();
wrapper = null;
}
}
}
if (!wrapper) {
wrapper = document.createElement('div');
wrapper.className = 'gc-mod-wrapper';
wrapper.style.cssText = 'position:absolute; z-index:0; transform-origin:center;';
let customElem;
if (state.bannerType === 'video') {
customElem = document.createElement('video');
customElem.autoplay = true;
customElem.loop = true;
customElem.playsInline = true;
customElem.muted = state.bannerMuted;
customElem.volume = state.bannerVolume || 1.0;
customElem.play().catch(() => {});
} else {
customElem = document.createElement('img');
}
customElem.className = 'gc-mod-media';
customElem.style.cssText = 'width:100%; height:100%; object-fit:fill; pointer-events:none; border-radius:inherit; display:block;';
wrapper.appendChild(customElem);
banner.insertBefore(wrapper, banner.firstChild);
const overlay = document.createElement('div');
overlay.style.cssText = 'position:absolute; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.3); z-index:2; border-radius:inherit; pointer-events:none;';
banner.insertBefore(overlay, textContainer);
banner.style.backgroundColor = '#1e1e2e';
makeResizableAndDraggable(wrapper);
}
const media = wrapper.querySelector('.gc-mod-media');
if (media.src !== state.bannerSrc) media.src = state.bannerSrc;
if (!isMediaDragging && !isMediaResizing) {
wrapper.style.width = state.bWidth;
wrapper.style.height = state.bHeight;
wrapper.style.top = state.bTop;
wrapper.style.left = state.bLeft;
wrapper.style.transform = `scale(${state.bannerScale})`;
}
});
}
if (state.spoofName) {
const titles = document.querySelectorAll('.tNGpbb, .YVvGBb');
titles.forEach(title => {
if (title.tagName === 'H1' || title.classList.contains('XL4gNd')) {
title.innerText = state.spoofName;
}
});
}
}, 500);
})();