Sessão Antes e Depois

<!DOCTYPE html>

<html lang="pt-BR">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Controle Deslizante Antes e Depois</title>

<style>

/* Estilos básicos de reset */

* {

margin: 0;

padding: 0;

box-sizing: border-box;

}


/* Container principal - isolando do contexto externo */

.comparison-container {

position: relative;

width: 100%;

max-width: 100%; /* Preenche completamente o contêiner pai */

margin: 0 auto;

overflow: hidden;

/* Garante isolamento */

box-sizing: border-box;

contain: layout style;

}


/* Imagem "depois" (fundo) */

.after-image {

position: relative;

width: 100%;

height: auto;

display: block;

}


.after-image img {

display: block;

width: 100%;

height: auto;

}


/* Imagem "antes" (frente com divisor) */

.before-container {

position: absolute;

top: 0;

left: 0;

width: 50%; /* Começa em 50% */

height: 100%;

overflow: hidden;

}


.before-container img {

display: block;

width: 200%; /* Importante: dobro da largura para compensar o container de 50% */

height: 100%;

object-fit: cover;

object-position: left;

}


/* Divisor/Handle */

.slider-divider {

position: absolute;

top: 0;

left: 50%; /* Começa em 50% */

width: 4px;

height: 100%;

background-color: white;

cursor: ew-resize;

z-index: 10;

box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);

}


/* Botão circular no divisor */

.slider-button {

position: absolute;

top: 50%;

left: 50%;

transform: translate(-50%, -50%);

width: 40px;

height: 40px;

border-radius: 50%;

background-color: white;

box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);

z-index: 11;

cursor: ew-resize;

display: flex;

justify-content: center;

align-items: center;

}


/* Setas no botão */

.slider-button::before,

.slider-button::after {

content: '';

position: absolute;

width: 10px;

height: 2px;

background-color: #333;

}


.slider-button::before {

transform: rotate(45deg);

left: 10px;

}


.slider-button::after {

transform: rotate(-45deg);

right: 10px;

}


/* Etiquetas "antes" e "depois" */

.label {

position: absolute;

bottom: 20px;

background-color: rgba(0, 0, 0, 0.7);

color: white;

padding: 5px 10px;

border-radius: 4px;

font-family: Arial, sans-serif;

font-size: 14px;

font-weight: bold;

z-index: 9;

}


.before-label {

left: 10px;

}


.after-label {

right: 10px;

}


/* Responsivo para dispositivos móveis */

@media (max-width: 767px) {

.slider-button {

width: 30px;

height: 30px;

}


.label {

font-size: 12px;

padding: 4px 8px;

}

}

</style>

</head>

<body>

<!-- Identificador único para este componente -->

<div id="before-after-systeme" class="comparison-container">

<!-- Imagem DEPOIS (fundo completo) -->

<div class="after-image">

<img src="https://via.placeholder.com/800x500/0288d1/FFFFFF?text=DEPOIS" alt="Depois">

</div>


<!-- Imagem ANTES (parte visível controlada pelo slider) -->

<div class="before-container">

<img src="https://via.placeholder.com/800x500/d32f2f/FFFFFF?text=ANTES" alt="Antes">

</div>


<!-- Divisor deslizante -->

<div class="slider-divider">

<div class="slider-button"></div>

</div>


<!-- Etiquetas -->

<div class="label before-label">ANTES</div>

<div class="label after-label">DEPOIS</div>

</div>

<script>

document.addEventListener('DOMContentLoaded', function() {

// Função para inicializar o slider (podemos chamá-la múltiplas vezes)

function initBeforeAfterSlider(containerId) {

// Use um seletor específico ou um ID se fornecido

const container = containerId ? document.getElementById(containerId) : document.querySelector('.comparison-container');


if (!container) return; // Sai se o container não for encontrado


// Elementos DOM

const beforeContainer = container.querySelector('.before-container');

const sliderDivider = container.querySelector('.slider-divider');

const beforeImage = beforeContainer.querySelector('img');


// Função para atualizar a posição do slider

function updateSliderPosition(clientX) {

// Obtém as dimensões do container

const rect = container.getBoundingClientRect();


// Calcula a posição do mouse relativa ao container (em percentagem)

let position = (clientX - rect.left) / rect.width;


// Limita entre 0 e 1 (0% e 100%)

position = Math.max(0, Math.min(1, position));


// Converte para percentagem

const percentPosition = position * 100;


// Atualiza a posição do divisor e do container "antes"

sliderDivider.style.left = `${percentPosition}%`;

beforeContainer.style.width = `${percentPosition}%`;


// Ajusta a posição da imagem "antes" para compensar

const scale = 100 / percentPosition;


// Só ajusta se a largura for maior que zero (evita divisão por zero)

if (percentPosition > 0) {

beforeImage.style.width = `${scale * 100}%`;

beforeImage.style.objectPosition = 'left';

}

}


// Flag para verificar se está arrastando

let isDragging = false;


// ID para identificar exclusivamente este slider

const sliderId = containerId || 'slider-' + Math.random().toString(36).substring(2, 9);


// Função para iniciar o arrasto

const startDrag = function(e) {

e.preventDefault();

isDragging = sliderId; // Guarda o ID do slider atual

};


// Função para finalizar o arrasto

const endDrag = function() {

if (isDragging === sliderId) {

isDragging = false;

}

};


// Função para mover o slider durante o arrasto

const moveSlider = function(clientX) {

if (isDragging !== sliderId) return;

updateSliderPosition(clientX);

};


// Eventos de mouse

sliderDivider.addEventListener('mousedown', startDrag);


document.addEventListener('mousemove', function(e) {

moveSlider(e.clientX);

});


document.addEventListener('mouseup', endDrag);


// Eventos de toque (mobile)

sliderDivider.addEventListener('touchstart', function(e) {

startDrag(e);

});


document.addEventListener('touchmove', function(e) {

if (isDragging !== sliderId) return;

// Usa a posição do primeiro toque

moveSlider(e.touches[0].clientX);

});


document.addEventListener('touchend', endDrag);

document.addEventListener('touchcancel', endDrag);


// Clique direto no container

container.addEventListener('click', function(e) {

updateSliderPosition(e.clientX);

});


// Inicializa a posição para 50%

setTimeout(function() {

updateSliderPosition(container.getBoundingClientRect().left + container.offsetWidth / 2);

}, 200);


// Re-inicializa quando todos os recursos carregarem

window.addEventListener('load', function() {

updateSliderPosition(container.getBoundingClientRect().left + container.offsetWidth / 2);

});


// Ajusta quando a janela é redimensionada

window.addEventListener('resize', function() {

updateSliderPosition(container.getBoundingClientRect().left + container.offsetWidth / 2);

});


return {

update: function() {

updateSliderPosition(container.getBoundingClientRect().left + container.offsetWidth / 2);

}

};

}


// Inicializa todos os sliders na página

document.querySelectorAll('.comparison-container').forEach(function(container, index) {

container.id = container.id || 'comparison-' + index;

initBeforeAfterSlider(container.id);

});


// Re-inicializa após um pequeno atraso (para garantir que tudo foi renderizado)

setTimeout(function() {

document.querySelectorAll('.comparison-container').forEach(function(container) {

initBeforeAfterSlider(container.id);

});

}, 500);

});

</script>

</body>

</html>