O HTML consiste em três sliders, cada um representando um produto com um preço específico. O valor total é
exibido em um campo de saída (<output>
).
<div id="page-wrapper">
<!-- Slider 1: Apple Vision Pro -->
<div class="slider-wrapper" id="slider_1">
<img src="https://png.pngtree.com/png-clipart/20230624/original/pngtree-apple-vision-png-image_9212583.png">
<label for="apple-range"> Vision Pro <small>$3499 ea.</small></label>
<output id="appleOutput" class="qtyOutput" for="apple-range"></output>
<input type="range" id="apple-range" name="apple_range" min="0" max="100" step="1" value="50" data-price="3499.00">
</div>
<!-- Slider 2: Meta Quest 3 -->
<div class="slider-wrapper" id="slider_2">
<img src="https://s7d1.scene7.com/is/image/dmqualcommprod/meta-quest-3-1?$QC_Responsive$&fmt=png-alpha">
<label for="meta-range">Meta Quest 3 <small>$649 ea.</small></label>
<output id="metaOutput" class="rangeOutput" for="meta-range"></output>
<input type="range" id="meta-range" name="meta_range" min="0" max="100" step="1" value="50" data-price="649.00">
</div>
<!-- Slider 3: HTC VIVE XR Elite -->
<div class="slider-wrapper" id="slider_3">
<img src="https://vr-expert.com/wp-content/uploads/2023/02/vive-xr-elite-removebg-preview.png">
<label for="html-range">HTC VIVE XR Elite<small>$1099 ea.</small></label>
<output id="htcOutput" class="rangeOutput" for="htc-range"></output>
<input type="range" id="htc-range" name="htc_range" min="0" max="100" step="1" value="50" data-price="1099.00">
</div>
<!-- Total e Botão de Compra -->
<div id="slider-totals-wrapper">
<output id="total" for="apple-range meta-range htc-range">5</output>
<button id="buy-now">Buy Now</button>
</div>
<!-- Texto de Rodapé -->
<div id="footer-text">
<strong>Published July 2024</strong>. This code example is provided for demonstration and educational purposes only...
</div>
</div>
O CSS personaliza a aparência dos sliders, dos rótulos e do layout geral.
/* Estilo dos Sliders */
input[type="range"] {
-webkit-appearance: none;
width: 100%;
height: 3px;
background: #e8e8e8;
border-radius: 25px;
box-shadow: inset 0 0 1px rgba(0,0,0,.15);
cursor: pointer;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
width: 17.5px;
height: 17.5px;
background-color: #fff;
border-radius: 50%;
outline: 3px solid #000;
}
input[type="range"]::-moz-range-thumb {
width: 17.5px;
height: 17.5px;
background-color: #fff;
border-radius: 50%;
outline: 3px solid #000;
}
/* Layout Geral */
body {
background: #f8f8f8;
padding: 5vw;
font-family: sans-serif;
}
#page-wrapper {
display: inline-block;
text-align: left;
border-radius: 12px;
background: #fff;
box-shadow: 0 5px 5px rgba(0,0,0,.1);
}
.slider-wrapper {
margin: 0 20px;
padding: 10px 30px 45px;
width: 200px;
display: inline-block;
vertical-align: top;
}
#slider-totals-wrapper {
margin: 40px 15px 0;
padding: 30px;
background: #222;
color: #fff;
border-radius: 12px;
}
#total {
font-size: 30px;
font-weight: 500;
}
#buy-now {
background: rgba(255,255,255,.0);
color: #fff;
border: 2px solid #fff;
border-radius: 25px;
padding: 0 40px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: background-color .25s, color .25s;
}
#buy-now:hover {
background: #fff;
color: #000;
}
O JavaScript atualiza o valor total sempre que um slider é ajustado.
// Atualiza o valor total
function updateTotal() {
const sliders = document.querySelectorAll('input[type="range"]');
let total = 0;
sliders.forEach(slider => {
const pricePerUnit = parseFloat(slider.dataset.price);
const quantity = parseFloat(slider.value);
total += pricePerUnit * quantity;
});
const formattedTotal = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(total);
document.getElementById('total').textContent = formattedTotal;
}
// Configura cada slider
function setupSlider(slider) {
slider.addEventListener('input', function() {
const output = slider.closest('.slider-wrapper').querySelector('output');
output.innerHTML = slider.value;
const percent = (slider.value - slider.min) / (slider.max - slider.min) * 100;
slider.style.background = `linear-gradient(to right, #000 ${percent}%, #e8e8e8 ${percent}%)`;
updateTotal();
});
slider.dispatchEvent(new Event('input'));
}
// Inicializa todos os sliders
document.querySelectorAll('input[type="range"]').forEach(setupSlider);
// Efeito de confetti ao clicar em "Buy Now"
document.getElementById('buy-now').addEventListener('click', function() {
confetti({
particleCount: 100,
spread: 100,
origin: { x: 0.5, y: 0.5 }
});
});
Sliders Personalizados:
Atualização Dinâmica do Total:
Efeito de Confetti: