Monday, 21 December 2020

React: Setting a dual color slider thumb to an image with transparent background

I made slider which is supposed to be blue on the left and gray on the right. The blue is also supposed to be thicker than the gray.

enter image description here

I have 2 problems with it.

  1. If the thumb piece has a transparent cutout, then the blue part of the slider doesn't extend all the way to the left side of what is visible on the image.
  2. I would like the edges of the slider to be round, especially the blue edge(I might not need the gray)

By round edges I mean like this enter image description here


Here is a codesandbox of the code

And the code itself

import React from "react";
import styled from "styled-components";
const image = "https://i.imgur.com/XMfYtkv.png";
const thumb = {
  width: 25,
  height: 26
};

const height = 36;
const trackHeight = 4;

// colours
const lowerBackground = `linear-gradient(to bottom, gray, gray) 100% 50% / 100% ${
  trackHeight / 2.5
}px no-repeat transparent`;
const upperBackground = `linear-gradient(to bottom, blue, blue) 100% 50% / 100% ${
  trackHeight / 2.5
}px no-repeat transparent`;

const makeLongShadow = (color, size) => {
  // Colors the slider to the right of the thumbpiece
  let i = 1;
  let shadow = `-${i}px 0 0 ${size} ${color}`;

  for (; i < 1950; i++) {
    //If i is a small number, like 720, then when the slider gets set to its minimum, the end of the slider is the color for the left side of the slider, when it should be the colour for the right side
    shadow = `${shadow}, -${i}px 0 0 ${size} ${color}`;
  }

  return shadow;
};

const StyledSlider = styled.input`
  overflow: hidden;
  appearance: none;
  height: ${height}px;
  cursor: pointer;

  marginbottom: 0;

  &:focus {
    outline: none;
  }

  &::-webkit-slider-runnable-track {
    width: 100%;
    height: ${height}px;
    background: ${lowerBackground};
  }

  &::-webkit-slider-thumb {
    position: relative;
    appearance: none;
    height: ${thumb.height}px;
    width: ${thumb.width}px;
    background: url(${image});
    background-size: cover;
    border: 0;
    top: 50%;
    transform: translateY(-50%);
    box-shadow: ${makeLongShadow("blue", "-11px")};
    transition: background-color 150ms;
  }

  &::-moz-range-progress {
    background: ${lowerBackground};
  }

  &::-moz-range-track,
  &::-moz-range-progress {
    width: 100%;
    height: ${height};
    background: ${upperBackground};
  }

  &::-moz-range-thumb {
    appearance: none;
    margin: 0;
    height: ${thumb.height}px;
    width: ${thumb.height}px;
    background: url(${image});
    border: 0;
    transition: background-color 150ms;
  }

  &::-ms-track {
    width: 100%;
    height: ${height}px;
    border: 0;
    /* color needed to hide track marks */
    color: transparent;
    background: transparent;
  }

  &::-ms-fill-lower {
    background: ${lowerBackground};
  }

  &::-ms-fill-upper {
    background: ${upperBackground};
  }

  &::-ms-thumb {
    appearance: none;
    height: ${thumb.height}px;
    width: ${thumb.height}px;
    background: url(${image});
    border-radius: 100%;
    border: 0;
    transition: background-color 150ms;
    /* IE Edge thinks it can support -webkit prefixes */
    top: 0;
    margin: 0;
    box-shadow: none;
  }
`;

//!Black line is too thick when then margin at the bottom is 11 or 10 ? I don't know what would cause this
export default (props) => <StyledSlider type="range" {...props} />;


from React: Setting a dual color slider thumb to an image with transparent background

No comments:

Post a Comment