diff --git a/content/news/2023-07-09-bevy-0.11/index.md b/content/news/2023-07-09-bevy-0.11/index.md
index 425e98c43e..29918817e6 100644
--- a/content/news/2023-07-09-bevy-0.11/index.md
+++ b/content/news/2023-07-09-bevy-0.11/index.md
@@ -291,7 +291,7 @@ differently, we get those awkward specular highlights. With parallax mapping,
they are gone.
Drag this image to compare
-
+
diff --git a/sass/components/_image_compare.scss b/sass/components/_image_compare.scss
index 5373319c16..482161d7ee 100644
--- a/sass/components/_image_compare.scss
+++ b/sass/components/_image_compare.scss
@@ -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"] {
@@ -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);
}
}
}
diff --git a/static/components.js b/static/components.js
index cb13ee8d51..4264fdfb1d 100644
--- a/static/components.js
+++ b/static/components.js
@@ -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:
@@ -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 + "%");
});
}
}