Files
classroomio/apps/classroomio-com/src/lib/Hero/ImageCompare.svelte
T
Adeyemi AdetunjiandRotimi Best 1c0d6fd49b fix: get lighthouse score to 100 (#180)
* Lighthouse Report

* quick fix

* quick adjustment

* PR Corrections

* feat: move all email to defer queue (#186)

---------

Co-authored-by: Rotimi Best <best@classroomio.com>
2024-03-01 14:22:45 +01:00

194 lines
3.8 KiB
Svelte

<script>
import { onMount } from 'svelte';
export { before, after, offset, overlay, contain, hideOnSlide };
let hideOnSlide = true,
imgOffset = null,
sliding = false,
contain = false,
overlay = true,
offset = 0.5,
before = '',
after = '',
img;
function resize(e) {
imgOffset = (e.type === 'load' ? e.target : img).getBoundingClientRect();
w = imgOffset && imgOffset.width;
h = imgOffset && imgOffset.height;
style = contain ? `width:100%;height:100%;` : `width:${w}px;height:${h}px;`;
}
function move(e) {
if (sliding && imgOffset) {
let x = (e.touches ? e.touches[0].pageX : e.pageX) - imgOffset.left;
x = x < 0 ? 0 : x > w ? w : x;
offset = x / w;
}
}
function start(e) {
sliding = true;
move(e);
}
function end() {
sliding = false;
}
onMount(() => {
resize({});
});
$: w = imgOffset && imgOffset.width;
$: h = imgOffset && imgOffset.height;
$: x = w * offset;
$: opacity = hideOnSlide && sliding ? 0 : 1;
$: style = contain ? `width:100%;height:100%;` : `width:${w}px;height:${h}px;`;
</script>
<svelte:window on:resize={resize} />
<button
class="container floating w-[85%] lg:w-[70%] h-full mx-auto rounded-md"
{style}
on:touchstart={start}
on:mousedown={start}
on:touchmove={move}
on:touchend={end}
on:mousemove={move}
on:mouseup={end}
>
<img
loading="lazy"
bind:this={img}
src={after}
alt="after"
on:mousedown|preventDefault
on:load={resize}
{style}
/>
<img
loading="lazy"
src={before}
alt="before"
on:mousedown|preventDefault
style="{style}clip:rect(0, {x}px, {h}px, 0);"
/>
{#if overlay}
<div class="overlay" style="opacity:{opacity}" />
{/if}
<div class="before-label" style="opacity:{opacity}">
<slot name="before" />
</div>
<div class="after-label" style="opacity:{opacity}">
<slot name="after" />
</div>
<div class="handle" style="left: calc({offset * 100}% - 20px)">
<div class="arrow-left" />
<div class="arrow-right" />
</div>
</button>
<style>
.container {
overflow: hidden;
position: relative;
box-sizing: content-box;
border-radius: 0.75rem;
}
.container img {
top: 0;
left: 0;
z-index: 20;
display: block;
max-width: 100%;
user-select: none;
object-fit: cover;
position: absolute;
width: fit-content;
height: fit-content;
}
.overlay {
top: 0;
opacity: 0;
z-index: 25;
width: 100%;
height: 100%;
position: absolute;
transition: opacity 0.5s;
background: rgba(0, 0, 0, 0.2);
}
.before-label,
.after-label {
top: 0;
bottom: 0;
z-index: 25;
user-select: none;
position: absolute;
}
.before-label {
left: 0;
}
.after-label {
right: 0;
}
.container:hover > .overlay {
opacity: 1;
}
.handle {
z-index: 30;
width: 40px;
height: 40px;
cursor: move;
background: none;
margin-top: -4px;
margin-left: -4px;
user-select: none;
position: absolute;
border-radius: 50px;
top: calc(50% - 20px);
border: 4px solid white;
}
.handle:before,
.handle:after {
content: '';
height: 9999px;
position: absolute;
left: calc(50% - 2px);
border: 2px solid white;
}
.handle:before {
top: 40px;
}
.handle:after {
bottom: 40px;
}
.arrow-right,
.arrow-left {
width: 0;
height: 0;
user-select: none;
position: relative;
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
}
.arrow-right {
left: 17px;
bottom: 13px;
border-left: 10px solid white;
}
.arrow-left {
left: 5px;
top: 7px;
border-right: 10px solid white;
}
img,
.overlay,
.container {
max-height: 500px;
}
</style>