formha/templates/z_comps/boton_chat.html

219 lines
5.9 KiB
HTML

<style>
.floating-btn {
position: fixed;
width: 5em;
height: 5em;
background-color: #ffffff;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
cursor: move;
user-select: none;
z-index: 1000;
transition:
background-color 0.3s,
left 0.3s ease,
right 0.3s ease,
top 0.3s ease;
}
.floating-btn:active {
cursor: grabbing;
}
/* @keyframes spin-right {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.rotating {
animation: spin-right 4s linear infinite;
} */
</style>
<div class="floating-btn border border-light shadow-lg" id="floatingBtn">
<a id="floatingBtnLink" target="_blank" href="https://chatgpt.com/g/g-6828126fba608191a2803ac89f54f504-formha-rh-para-pymes">
<img src="{{ url_for('static', filename='y_img/logos/chat_ia_formha.svg') }}"
alt="logo"
class="img-fluid rounded-circle rotating"
style="width: 100%; height: 100%;">
</a>
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
const btn = document.getElementById('floatingBtn');
const link = document.getElementById('floatingBtnLink');
let offsetX, offsetY;
let isDragging = false;
let hasMoved = false;
let touchStartTimer;
const tapThreshold = 200; // Tiempo en milisegundos para considerar un "tap"
const moveThreshold = 5; // Distancia en píxeles para considerar un "move"
const savedPosition = localStorage.getItem('floatingBtnPosition');
if (savedPosition) {
const { x, y } = JSON.parse(savedPosition);
btn.style.left = x;
btn.style.top = y;
setTimeout(() => stickToNearestSide(parseInt(x), parseInt(y)), 10);
} else {
btn.style.right = '20px';
btn.style.top = '20px';
}
// Eventos para mouse
btn.addEventListener('mousedown', startDrag);
document.addEventListener('mousemove', drag);
document.addEventListener('mouseup', stopDrag);
// Eventos para touch
btn.addEventListener('touchstart', startTouch, { passive: true });
document.addEventListener('touchmove', moveTouch, { passive: false });
document.addEventListener('touchend', endTouch);
link.addEventListener('click', function (e) {
if (hasMoved) {
e.preventDefault();
hasMoved = false;
}
});
function startDrag(e) {
isDragging = true;
hasMoved = false;
const rect = btn.getBoundingClientRect();
offsetX = e.clientX - rect.left;
offsetY = e.clientY - rect.top;
btn.style.cursor = 'grabbing';
btn.style.left = `${rect.left}px`;
btn.style.top = `${rect.top}px`;
btn.style.right = 'auto';
e.preventDefault();
}
function drag(e) {
if (!isDragging) return;
const x = e.clientX - offsetX;
const y = e.clientY - offsetY;
btn.style.left = `${x}px`;
btn.style.top = `${y}px`;
hasMoved = true;
}
function stopDrag() {
if (!isDragging) return;
isDragging = false;
btn.style.cursor = 'move';
const rect = btn.getBoundingClientRect();
const x = rect.left;
const y = rect.top;
stickToNearestSide(x, y);
savePosition(x, y);
}
function startTouch(e) {
if (e.touches.length !== 1) return;
hasMoved = false;
const touch = e.touches[0];
const startX = touch.clientX;
const startY = touch.clientY;
touchStartTimer = setTimeout(() => {
// Si el temporizador termina y no ha habido movimiento, consideramos un tap
link.click();
}, tapThreshold);
// Preparar para el movimiento
const rect = btn.getBoundingClientRect();
offsetX = startX - rect.left;
offsetY = startY - rect.top;
}
function moveTouch(e) {
if (!touchStartTimer || e.touches.length !== 1) return;
const touch = e.touches[0];
const currentX = touch.clientX;
const currentY = touch.clientY;
// Verificar si el movimiento supera el umbral
if (Math.abs(currentX - (touch.clientX - offsetX)) > moveThreshold || Math.abs(currentY - (touch.clientY - offsetY)) > moveThreshold) {
clearTimeout(touchStartTimer); // Cancelar el temporizador si hay movimiento
isDragging = true;
hasMoved = true;
btn.style.cursor = 'grabbing';
btn.style.left = `${currentX - offsetX}px`;
btn.style.top = `${currentY - offsetY}px`;
btn.style.right = 'auto';
e.preventDefault(); // Evitar el scroll durante el arrastre
}
}
function endTouch(e) {
clearTimeout(touchStartTimer);
if (isDragging) {
isDragging = false;
btn.style.cursor = 'move';
const rect = btn.getBoundingClientRect();
stickToNearestSide(rect.left, rect.top);
savePosition(rect.left, rect.top);
}
}
function stickToNearestSide(x, y) {
const windowWidth = window.innerWidth;
const btnWidth = btn.offsetWidth;
if (x < windowWidth / 2) {
btn.style.left = '10px';
btn.style.right = 'auto';
} else {
btn.style.left = 'auto';
btn.style.right = '10px';
}
const windowHeight = window.innerHeight;
const btnHeight = btn.offsetHeight;
if (y < 0) {
btn.style.top = '10px';
} else if (y + btnHeight > windowHeight) {
btn.style.top = `${windowHeight - btnHeight - 10}px`;
} else {
btn.style.top = `${y}px`;
}
}
function savePosition(x, y) {
localStorage.setItem('floatingBtnPosition', JSON.stringify({
x: btn.style.left,
y: btn.style.top
}));
}
window.addEventListener('resize', function () {
const savedPosition = localStorage.getItem('floatingBtnPosition');
if (savedPosition) {
const { x, y } = JSON.parse(savedPosition);
stickToNearestSide(parseInt(x), parseInt(y));
}
});
});
</script>