Skip to content

Commit

Permalink
Improve image-compare widget (#703)
Browse files Browse the repository at this point in the history
  • Loading branch information
ickk authored Jul 10, 2023
1 parent 3e6cad5 commit 51d548d
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 43 deletions.
2 changes: 1 addition & 1 deletion content/news/2023-07-09-bevy-0.11/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ differently, we get those awkward specular highlights. With parallax mapping,
they are gone.

<b style="display:block; margin-bottom: -18px">Drag this image to compare</b>
<div class="image-compare" style="aspect-ratio: 16 / 9" data-title-a="Normals Only" data-title-b="Parallax+Normals">
<div class="image-compare" style="aspect-ratio: 16 / 9; --slider-value: 39%" data-title-a="Normals Only" data-title-b="Parallax+Normals">
<img class="image-a" alt="Normal Mapping Only" src="parallax_mapping_normals.jpg">
<img class="image-b" alt="Parallax & Normal Mapping" src="parallax_mapping_depth.jpg">
</div>
Expand Down
98 changes: 69 additions & 29 deletions sass/components/_image_compare.scss
Original file line number Diff line number Diff line change
@@ -1,47 +1,65 @@
div.image-compare {
// display: flex;
// align-items: center;
// default values
--slider-min: 7%;
--slider-max: 93%;
--slider-value: 50%;
aspect-ratio: 16 / 9;
// config
--text-padding: 10px;
--gap: 3px;
--range-thumb-diametre: 16px;
background-color: $color-white; // gap color;

position: relative;
border-radius: 10px;
width: 100%;
aspect-ratio: 16 / 9; // fallback
background-color: black;
--slider-value: 50%;
outline: solid 1px $color-grey-900; // fixes border leaking background color
outline-offset: -1px;

&::before,
&::after {
// calculated
--clip-L-geo: inset(0 calc(100% - var(--slider-value) + var(--gap) / 2) 0 0);
--clip-R-geo: inset(0 0 0 calc(var(--slider-value) + var(--gap) / 2));

@mixin image-title {
position: absolute;
font-weight: bolder;
font-size: 1.8rem;
width: 100%;
width: calc(100% - var(--text-padding));
text-shadow: 0 0 2px $color-black;
}
&::before {
@include image-title;

content: attr(data-title-a);
padding-left: var(--text-padding);
clip-path: var(--clip-L-geo);
-webkit-clip-path: var(--clip-L-geo);
z-index: 1;
-webkit-clip-path: inset(0 calc(100% - var(--slider-value) + 1.5px) 0 0);
clip-path: inset(0 calc(100% - var(--slider-value) + 1.5px) 0 0);
width: 100%;
}
&::after {
@include image-title;

content: attr(data-title-b);
padding-right: var(--text-padding);
clip-path: var(--clip-R-geo);
-webkit-clip-path: var(--clip-R-geo);
text-align: end;
-webkit-clip-path: inset(0 0 0 calc(var(--slider-value) + 1.5px));
clip-path: inset(0 0 0 calc(var(--slider-value) + 1.5px));
width: 100%;
}

& img {
width: 100%;
}
& .image-a {
position: absolute;
-webkit-clip-path: inset(0 calc(100% - var(--slider-value) + 1.5px) 0 0);
clip-path: inset(0 calc(100% - var(--slider-value) + 1.5px) 0 0);
}
& .image-b {
float: right;
-webkit-clip-path: inset(0 0 0 calc(var(--slider-value) + 1.5px));
clip-path: inset(0 0 0 calc(var(--slider-value) + 1.5px));
width: inherit;

&.image-a {
position: absolute;
-webkit-clip-path: var(--clip-L-geo);
clip-path: var(--clip-L-geo);
}

&.image-b {
float: right;
-webkit-clip-path: var(--clip-R-geo);
clip-path: var(--clip-R-geo);
}
}

& input[type="range"] {
Expand All @@ -50,19 +68,41 @@ div.image-compare {
margin: 0;
width: inherit;
height: 100%;
padding-left: var(--slider-min);
padding-right: var(--slider-min);
background-color: transparent;
z-index: 2;
cursor: pointer;
-webkit-appearance: none;
appearance: none;
z-index: 2;

@mixin thumb {
transform: translateX(calc(var(--slider-value) - 50%));
width: var(--range-thumb-diametre);
height: var(--range-thumb-diametre);
border-radius: 50%;
outline: solid 3px $color-white;
outline-offset: -2.9px;
background-color: darken($color-white, 40%);

&:hover,
&:active {
background-color: darken($color-white, 20%);
}
}
&::-moz-range-thumb {
border: none;
background-color: transparent;
@include thumb;
}
&::-webkit-slider-thumb {
width: 0; // no clue why this is required, but it is
@include thumb;

-webkit-appearance: none;
appearance: none;
// better than the transform approach, but doesn't work on firefox
transform: none;
position: absolute;
left: calc(var(--slider-value) - var(--range-thumb-diametre) / 2);
margin-top: calc(0px - var(--range-thumb-diametre) / 2);
}
}
}
22 changes: 9 additions & 13 deletions static/components.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@

// clamp a number to the given range
function clamp(val, min, max) {
return Math.min(Math.max(val, min), max)
}

// inserts the input element required to activate image_compare components
//
// Usage in a document should look like:
Expand All @@ -19,22 +13,24 @@ function clamp(val, min, max) {
//
// The `image_compare` scss component should be used.
//
// Ideally the `aspect-ratio` should be set, but it will
// fallback to 16/9.
// Ideally the `aspect-ratio` should be set, but it will fallback to 16/9.
// You can provide `--slider-min`, `--slider-max`, `--slider-value` styles
// which will set the minimum, maximum, & starting value of the slider. They
// default to 7%, 93%, and 50% respectively.
function enable_image_compare() {
const image_compares = document.querySelectorAll("div.image-compare");
for (const img_cmp of image_compares) {
// insert the input only when js is running
let style = window.getComputedStyle(img_cmp);
const slider = document.createElement('input');
slider.type = "range";
slider.min = "0";
slider.max = "100";
slider.value = "50";
slider.min = style.getPropertyValue('--slider-min').replace('%', '');
slider.max = style.getPropertyValue('--slider-max').replace('%', '');
slider.value = style.getPropertyValue('--slider-value').replace('%', '');
img_cmp.appendChild(slider);
// setup callback
img_cmp.style.setProperty('--slider-value', clamp(slider.value, 7, 93) + "%");
slider.addEventListener("input", (event) => {
img_cmp.style.setProperty('--slider-value', clamp(slider.value, 7, 93) + "%");
img_cmp.style.setProperty('--slider-value', slider.value + "%");
});
}
}
Expand Down

0 comments on commit 51d548d

Please sign in to comment.