auto-clic / index.html
Chasme's picture
Add 2 files
cac422f verified
Raw
History Blame Contribute Delete
29.5 kB
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Auto-Clic Avancé</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
:root {
--bg-dark: #1a202c;
--bg-darker: #121826;
--primary: #4f46e5;
--primary-hover: #4338ca;
--text-light: #e2e8f0;
--text-lighter: #f8fafc;
--border-dark: #2d3748;
}
body {
background-color: var(--bg-dark);
color: var(--text-light);
min-height: 100vh;
padding-bottom: 80px;
}
.btn-primary {
background-color: var(--primary);
color: white;
}
.btn-primary:hover {
background-color: var(--primary-hover);
}
.card {
background-color: var(--bg-darker);
border: 1px solid var(--border-dark);
border-radius: 0.5rem;
}
input, select {
background-color: var(--bg-darker);
border: 1px solid var(--border-dark);
color: var(--text-light);
}
input:focus, select:focus {
outline: none;
border-color: var(--primary);
}
.tooltip {
position: relative;
}
.tooltip:hover .tooltip-text {
visibility: visible;
opacity: 1;
}
.tooltip-text {
visibility: hidden;
width: 200px;
background-color: var(--bg-darker);
color: var(--text-light);
text-align: center;
border-radius: 6px;
padding: 5px;
position: absolute;
z-index: 1;
bottom: 125%;
left: 50%;
margin-left: -100px;
opacity: 0;
transition: opacity 0.3s;
border: 1px solid var(--border-dark);
font-size: 0.8rem;
}
.active-btn {
animation: pulse 1.5s infinite;
}
@keyframes pulse {
0% {
box-shadow: 0 0 0 0 rgba(79, 70, 229, 0.7);
}
70% {
box-shadow: 0 0 0 10px rgba(79, 70, 229, 0);
}
100% {
box-shadow: 0 0 0 0 rgba(79, 70, 229, 0);
}
}
.modal {
display: none;
position: fixed;
z-index: 100;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0,0,0,0.8);
}
.modal-content {
background-color: var(--bg-darker);
margin: 10% auto;
padding: 20px;
border: 1px solid var(--border-dark);
width: 90%;
max-width: 500px;
border-radius: 0.5rem;
}
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
cursor: pointer;
}
.close:hover {
color: var(--text-light);
}
</style>
</head>
<body>
<div class="container mx-auto px-4 py-6">
<!-- En-tête -->
<header class="flex justify-between items-center mb-8">
<h1 class="text-2xl font-bold text-indigo-400">
<i class="fas fa-mouse-pointer mr-2"></i>Auto-Clic Avancé
</h1>
<div class="flex space-x-2">
<button id="helpBtn" class="p-2 rounded-full bg-gray-700 hover:bg-gray-600">
<i class="fas fa-question-circle"></i>
</button>
<button id="addBtn" class="btn-primary px-4 py-2 rounded-lg flex items-center">
<i class="fas fa-plus mr-2"></i> Ajouter
</button>
</div>
</header>
<!-- Liste des boutons -->
<div id="buttonsContainer" class="space-y-4">
<!-- Les boutons seront ajoutés ici dynamiquement -->
</div>
<!-- Barre d'outils -->
<div class="fixed bottom-0 left-0 right-0 bg-gray-800 py-3 px-4 flex justify-between items-center border-t border-gray-700">
<div class="flex space-x-2">
<button id="saveProfileBtn" class="bg-gray-700 hover:bg-gray-600 px-3 py-2 rounded-lg">
<i class="fas fa-save mr-1"></i> Sauvegarder
</button>
<button id="loadProfileBtn" class="bg-gray-700 hover:bg-gray-600 px-3 py-2 rounded-lg">
<i class="fas fa-folder-open mr-1"></i> Charger
</button>
</div>
<div class="flex space-x-2">
<button id="startAllBtn" class="btn-primary px-4 py-2 rounded-lg">
<i class="fas fa-play mr-1"></i> Tout démarrer
</button>
<button id="stopAllBtn" class="bg-red-600 hover:bg-red-700 px-4 py-2 rounded-lg">
<i class="fas fa-stop mr-1"></i> Tout arrêter
</button>
</div>
</div>
</div>
<!-- Modal pour ajouter un bouton -->
<div id="addButtonModal" class="modal">
<div class="modal-content">
<span class="close">&times;</span>
<h2 class="text-xl font-bold mb-4">Ajouter un bouton d'auto-clic</h2>
<form id="buttonForm" class="space-y-4">
<div>
<label for="buttonName" class="block mb-1">Nom du bouton</label>
<input type="text" id="buttonName" class="w-full p-2 rounded" placeholder="Ex: Bouton rapide" required>
</div>
<div>
<label for="clickType" class="block mb-1">Type de clic</label>
<select id="clickType" class="w-full p-2 rounded">
<option value="simple">Clic simple</option>
<option value="double">Double clic</option>
<option value="long">Clic long (1s)</option>
</select>
</div>
<div>
<label for="clickInterval" class="block mb-1 tooltip">
Intervalle entre les clics (secondes)
<span class="tooltip-text">Temps en secondes entre chaque action de clic</span>
</label>
<input type="number" id="clickInterval" min="0.1" step="0.1" value="1" class="w-full p-2 rounded" required>
</div>
<div>
<label for="clickCount" class="block mb-1 tooltip">
Nombre de clics
<span class="tooltip-text">Mettez 0 pour un nombre infini de clics</span>
</label>
<input type="number" id="clickCount" min="0" value="50" class="w-full p-2 rounded" required>
</div>
<button type="submit" class="btn-primary w-full py-2 rounded-lg">
<i class="fas fa-check mr-1"></i> Créer le bouton
</button>
</form>
</div>
</div>
<!-- Modal pour sauvegarder/charger -->
<div id="profileModal" class="modal">
<div class="modal-content">
<span class="close">&times;</span>
<h2 class="text-xl font-bold mb-4" id="profileModalTitle">Sauvegarder le profil</h2>
<div id="profileForm" class="space-y-4">
<div>
<label for="profileName" class="block mb-1">Nom du profil</label>
<input type="text" id="profileName" class="w-full p-2 rounded" placeholder="Ex: Configuration jeu" required>
</div>
<div id="profilesList" class="max-h-60 overflow-y-auto">
<!-- Les profils seront listés ici -->
</div>
<button id="confirmProfileBtn" class="btn-primary w-full py-2 rounded-lg">
<i class="fas fa-check mr-1"></i> Confirmer
</button>
</div>
</div>
</div>
<!-- Modal d'aide -->
<div id="helpModal" class="modal">
<div class="modal-content">
<span class="close">&times;</span>
<h2 class="text-xl font-bold mb-4">Comment utiliser Auto-Clic Avancé</h2>
<div class="space-y-4">
<div>
<h3 class="font-semibold text-indigo-300">Ajouter un bouton</h3>
<p>Cliquez sur le bouton "Ajouter" pour créer un nouveau bouton d'auto-clic. Donnez-lui un nom, choisissez le type de clic, l'intervalle en secondes et le nombre de clics.</p>
</div>
<div>
<h3 class="font-semibold text-indigo-300">Types de clic</h3>
<ul class="list-disc pl-5 space-y-1">
<li><strong>Clic simple</strong>: Un clic standard</li>
<li><strong>Double clic</strong>: Deux clics rapides</li>
<li><strong>Clic long</strong>: Un clic maintenu pendant 1 seconde</li>
</ul>
</div>
<div>
<h3 class="font-semibold text-indigo-300">Intervalles</h3>
<p>L'intervalle est le temps en secondes entre chaque action de clic. Vous pouvez utiliser des valeurs décimales (ex: 0.5 pour un demi-seconde).</p>
</div>
<div>
<h3 class="font-semibold text-indigo-300">Sauvegarde/Chargement</h3>
<p>Vous pouvez sauvegarder vos configurations de boutons dans des profils pour les réutiliser plus tard.</p>
</div>
<div>
<h3 class="font-semibold text-indigo-300">Contrôles globaux</h3>
<p>Utilisez les boutons "Tout démarrer" et "Tout arrêter" pour contrôler tous les boutons simultanément.</p>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Variables globales
let buttons = [];
let activeButtons = [];
let isSavingProfile = false;
// Éléments du DOM
const buttonsContainer = document.getElementById('buttonsContainer');
const addBtn = document.getElementById('addBtn');
const addButtonModal = document.getElementById('addButtonModal');
const buttonForm = document.getElementById('buttonForm');
const profileModal = document.getElementById('profileModal');
const profileModalTitle = document.getElementById('profileModalTitle');
const profileForm = document.getElementById('profileForm');
const profilesList = document.getElementById('profilesList');
const confirmProfileBtn = document.getElementById('confirmProfileBtn');
const saveProfileBtn = document.getElementById('saveProfileBtn');
const loadProfileBtn = document.getElementById('loadProfileBtn');
const startAllBtn = document.getElementById('startAllBtn');
const stopAllBtn = document.getElementById('stopAllBtn');
const helpBtn = document.getElementById('helpBtn');
const helpModal = document.getElementById('helpModal');
// Fermeture des modals
const closeButtons = document.getElementsByClassName('close');
for (let btn of closeButtons) {
btn.addEventListener('click', function() {
document.querySelectorAll('.modal').forEach(modal => {
modal.style.display = 'none';
});
});
}
// Fermeture des modals en cliquant à l'extérieur
window.addEventListener('click', function(event) {
if (event.target.classList.contains('modal')) {
event.target.style.display = 'none';
}
});
// Gestion des événements
addBtn.addEventListener('click', function() {
addButtonModal.style.display = 'block';
});
helpBtn.addEventListener('click', function() {
helpModal.style.display = 'block';
});
saveProfileBtn.addEventListener('click', function() {
isSavingProfile = true;
profileModalTitle.textContent = 'Sauvegarder le profil';
document.getElementById('profileName').value = '';
profilesList.innerHTML = '';
profileModal.style.display = 'block';
});
loadProfileBtn.addEventListener('click', function() {
isSavingProfile = false;
profileModalTitle.textContent = 'Charger un profil';
document.getElementById('profileName').value = '';
loadProfilesList();
profileModal.style.display = 'block';
});
startAllBtn.addEventListener('click', function() {
buttons.forEach(button => {
if (!button.isActive) {
startButton(button.id);
}
});
});
stopAllBtn.addEventListener('click', function() {
buttons.forEach(button => {
if (button.isActive) {
stopButton(button.id);
}
});
});
buttonForm.addEventListener('submit', function(e) {
e.preventDefault();
createButton();
addButtonModal.style.display = 'none';
buttonForm.reset();
});
confirmProfileBtn.addEventListener('click', function(e) {
e.preventDefault();
const profileName = document.getElementById('profileName').value.trim();
if (!profileName) {
alert('Veuillez entrer un nom de profil');
return;
}
if (isSavingProfile) {
saveProfile(profileName);
} else {
loadProfile(profileName);
}
profileModal.style.display = 'none';
});
// Fonctions
function createButton() {
const buttonName = document.getElementById('buttonName').value || 'Nouveau bouton';
const clickType = document.getElementById('clickType').value;
const clickInterval = parseFloat(document.getElementById('clickInterval').value) || 1;
const clickCount = parseInt(document.getElementById('clickCount').value) || 0;
const buttonId = Date.now().toString();
const button = {
id: buttonId,
name: buttonName,
type: clickType,
interval: clickInterval,
count: clickCount,
clicksDone: 0,
isActive: false,
timer: null
};
buttons.push(button);
renderButton(button);
}
function renderButton(button) {
const buttonElement = document.createElement('div');
buttonElement.className = 'card p-4';
buttonElement.id = `button-${button.id}`;
let timeRemaining = '';
if (button.count > 0) {
timeRemaining = ` | Temps restant: ${(button.count - button.clicksDone) * button.interval}s`;
}
buttonElement.innerHTML = `
<div class="flex justify-between items-start mb-3">
<h3 class="font-semibold text-lg">${button.name}</h3>
<div class="flex space-x-2">
<button class="delete-btn p-2 text-gray-400 hover:text-red-400" data-id="${button.id}">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
<div class="grid grid-cols-2 gap-2 mb-3">
<div>
<span class="text-gray-400">Type:</span>
<span>${getClickTypeName(button.type)}</span>
</div>
<div>
<span class="text-gray-400">Intervalle:</span>
<span>${button.interval}s</span>
</div>
<div>
<span class="text-gray-400">Clics:</span>
<span>${button.count === 0 ? '∞' : button.count}</span>
</div>
<div>
<span class="text-gray-400">Effectués:</span>
<span>${button.clicksDone}</span>
</div>
</div>
<div class="flex justify-between items-center">
<div class="text-sm text-gray-400">
${button.isActive ?
`<span class="text-green-400"><i class="fas fa-circle mr-1"></i> Actif</span>${timeRemaining}` :
'<span class="text-gray-400"><i class="far fa-circle mr-1"></i> Inactif</span>'}
</div>
<div class="flex space-x-2">
<button class="stop-btn bg-gray-700 hover:bg-gray-600 px-3 py-1 rounded ${!button.isActive ? 'hidden' : ''}" data-id="${button.id}">
<i class="fas fa-stop mr-1"></i> Arrêter
</button>
<button class="start-btn btn-primary px-3 py-1 rounded ${button.isActive ? 'hidden' : ''}" data-id="${button.id}">
<i class="fas fa-play mr-1"></i> Démarrer
</button>
</div>
</div>
`;
buttonsContainer.appendChild(buttonElement);
// Ajout des événements
buttonElement.querySelector('.start-btn').addEventListener('click', function() {
startButton(button.id);
});
buttonElement.querySelector('.stop-btn').addEventListener('click', function() {
stopButton(button.id);
});
buttonElement.querySelector('.delete-btn').addEventListener('click', function() {
deleteButton(button.id);
});
}
function getClickTypeName(type) {
switch(type) {
case 'simple': return 'Clic simple';
case 'double': return 'Double clic';
case 'long': return 'Clic long';
default: return type;
}
}
function startButton(buttonId) {
const button = buttons.find(b => b.id === buttonId);
if (!button || button.isActive) return;
button.isActive = true;
button.clicksDone = 0;
// Mise à jour de l'interface
updateButtonUI(button);
// Démarrer le clic automatique
const intervalMs = button.interval * 1000;
button.timer = setInterval(function() {
if (button.count > 0 && button.clicksDone >= button.count) {
stopButton(button.id);
return;
}
// Simuler le clic
simulateClick(button.type);
button.clicksDone++;
// Mise à jour de l'interface
updateButtonUI(button);
}, intervalMs);
// Premier clic immédiat
simulateClick(button.type);
button.clicksDone++;
updateButtonUI(button);
// Ajouter aux boutons actifs
if (!activeButtons.includes(buttonId)) {
activeButtons.push(buttonId);
}
}
function stopButton(buttonId) {
const button = buttons.find(b => b.id === buttonId);
if (!button || !button.isActive) return;
button.isActive = false;
// Arrêter le timer
if (button.timer) {
clearInterval(button.timer);
button.timer = null;
}
// Mise à jour de l'interface
updateButtonUI(button);
// Retirer des boutons actifs
activeButtons = activeButtons.filter(id => id !== buttonId);
}
function deleteButton(buttonId) {
// Arrêter le bouton s'il est actif
stopButton(buttonId);
// Supprimer de la liste
buttons = buttons.filter(b => b.id !== buttonId);
// Supprimer de l'interface
const buttonElement = document.getElementById(`button-${buttonId}`);
if (buttonElement) {
buttonElement.remove();
}
}
function updateButtonUI(button) {
const buttonElement = document.getElementById(`button-${button.id}`);
if (!buttonElement) return;
let timeRemaining = '';
if (button.count > 0) {
timeRemaining = ` | Temps restant: ${(button.count - button.clicksDone) * button.interval}s`;
}
// Mise à jour de l'état
const statusElement = buttonElement.querySelector('.text-sm');
if (statusElement) {
statusElement.innerHTML = button.isActive ?
`<span class="text-green-400"><i class="fas fa-circle mr-1"></i> Actif</span>${timeRemaining}` :
'<span class="text-gray-400"><i class="far fa-circle mr-1"></i> Inactif</span>';
}
// Mise à jour des boutons
const startBtn = buttonElement.querySelector('.start-btn');
const stopBtn = buttonElement.querySelector('.stop-btn');
if (startBtn) startBtn.classList.toggle('hidden', button.isActive);
if (stopBtn) stopBtn.classList.toggle('hidden', !button.isActive);
// Mise à jour du compteur
const clicksDoneElement = buttonElement.querySelectorAll('span')[7]; // Index du span des clics effectués
if (clicksDoneElement) {
clicksDoneElement.textContent = button.clicksDone;
}
// Animation pour les boutons actifs
if (button.isActive) {
buttonElement.classList.add('active-btn');
} else {
buttonElement.classList.remove('active-btn');
}
}
function simulateClick(type) {
// Dans une vraie application, vous utiliseriez element.click() ou des événements
// Pour cette démo, nous allons simplement enregistrer dans la console
switch(type) {
case 'simple':
console.log('Clic simple simulé');
break;
case 'double':
console.log('Double clic simulé');
break;
case 'long':
console.log('Clic long (1s) simulé');
break;
}
}
function saveProfile(profileName) {
const profiles = JSON.parse(localStorage.getItem('autoClickerProfiles')) || {};
profiles[profileName] = buttons;
localStorage.setItem('autoClickerProfiles', JSON.stringify(profiles));
alert(`Profil "${profileName}" sauvegardé avec succès!`);
}
function loadProfile(profileName) {
const profiles = JSON.parse(localStorage.getItem('autoClickerProfiles')) || {};
const savedButtons = profiles[profileName];
if (!savedButtons) {
alert(`Le profil "${profileName}" n'existe pas!`);
return;
}
// Arrêter tous les boutons actuels
buttons.forEach(button => {
if (button.isActive) {
stopButton(button.id);
}
});
// Vider le conteneur
buttonsContainer.innerHTML = '';
// Charger les boutons sauvegardés
buttons = JSON.parse(JSON.stringify(savedButtons));
// Réinitialiser l'état des boutons
buttons.forEach(button => {
button.isActive = false;
button.timer = null;
button.clicksDone = 0;
renderButton(button);
});
alert(`Profil "${profileName}" chargé avec succès!`);
}
function loadProfilesList() {
const profiles = JSON.parse(localStorage.getItem('autoClickerProfiles')) || {};
profilesList.innerHTML = '';
if (Object.keys(profiles).length === 0) {
profilesList.innerHTML = '<p class="text-gray-400 text-center py-4">Aucun profil sauvegardé</p>';
return;
}
for (const [name, profileButtons] of Object.entries(profiles)) {
const profileElement = document.createElement('div');
profileElement.className = 'p-3 border-b border-gray-700 hover:bg-gray-700 cursor-pointer';
profileElement.textContent = `${name} (${profileButtons.length} bouton${profileButtons.length !== 1 ? 's' : ''})`;
profileElement.addEventListener('click', function() {
document.getElementById('profileName').value = name;
});
profilesList.appendChild(profileElement);
}
}
// Charger les boutons sauvegardés au démarrage (si existants)
const savedProfiles = JSON.parse(localStorage.getItem('autoClickerProfiles')) || {};
if (Object.keys(savedProfiles).length > 0) {
// Charger le premier profil par défaut
const firstProfile = Object.keys(savedProfiles)[0];
loadProfile(firstProfile);
}
});
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Chasme/auto-clic" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>