Reputation: 9743
I'm trying to recreate this image in my React app:
So far this is what I have:
App.js
import React, { Component } from 'react';
import './AppStyle.scss';
class App extends Component {
constructor(props) {
super(props);
this.state = { testWidth: 0 };
}
componentDidMount() {
this.setState({ testWidth: (this.myInput.offsetWidth + this.mySpan.offsetWidth)*.3 });
}
render() {
const { testWidth } = this.state;
return (
<div className="container">
<span className="test" style={{top: "17px", left: testWidth}}>30%</span>
<div className="wrapper">
<span className="num" ref={div => {this.mySpan = div}}>5</span>
<input ref={input => {this.myInput = input}} type="range" value="30" id="rangeInput" readOnly />
<span className="num">15</span>
</div>
</div>
);
}
}
export default App;
App.scss
.container {
position: relative;
width: 100%;
}
.wrapper {
align-items: center;
display: flex;
justify-content: center;
position: relative;
}
.test {
position: absolute;
z-index: 100;
}
.num {
width: 5%;
font-size: 150%;
text-align: center;
}
input[type='range'] {
box-sizing: border-box;
border: 0px solid transparent;
padding: 0px;
margin: 0px;
width: 90%;
height: 50px;
background: -webkit-repeating-linear-gradient(90deg, #000000, #000000 1px, transparent 1px, transparent 60px) no-repeat 50% 50%;
background: repeating-linear-gradient(90deg, #000000, #000000 1px, transparent 1px, transparent 60px) no-repeat 50% 50%;
background-size: 90% 15px;
font-size: 16px;
}
input[type='range'],
input[type='range']::-webkit-slider-runnable-track,
input[type='range']::-webkit-slider-thumb {
-webkit-appearance: none;
}
input[type='range']::-webkit-slider-runnable-track {
box-sizing: border-box;
width: 200px;
height: 5px;
border-radius: 2px;
background: #000000
}
input[type='range']::-webkit-slider-thumb {
border: 2px solid #00B0FA;
height: 50px;
width: 50px;
border-radius: 50px;
background: rgba(255, 255, 255, 0.98);
-webkit-appearance: none;
margin-top: -23.05px;
}
Here is a fiddle:
https://jsfiddle.net/69z2wepo/96287/
I am unable to get my span element with class test to consistently find the center of the circle. As you can see, I use ref to get the width of the input and the first span. I was hoping my math in the componentDidMount would just work but unfortunately not. Also I realized if the user resizes the screen then the math is really off. One the one upside is that the range is disabled so don't worry about the slider moving. Also, I'm only supporting Chrome/Safari.
Upvotes: 2
Views: 422
Reputation: 819
I think the reason it's not showing up in the right spot is because your math is slightly off. You have (this.myInput.offsetWidth + this.myDiv.offsetWidth)*.3
but I think you might want (this.myInput.offsetWidth*.3 + this.myDiv.offsetWidth)
. You need to add the full myDiv width to the 30% of the myInput width.
Edit - Forgot to address the resize issue:
I am not very familiar with react, but to get it to adjust when the window is resized, you need to listen to the resize event and recalculate the position. Here is a fiddle: https://jsfiddle.net/ay1qrwok/
Upvotes: 1
Reputation: 402
I've forked your fiddle https://jsfiddle.net/Lzq561f8/1/
And got the right equation that'll fit with all values
testWidth: (this.myInput.offsetWidth * 0.3) - (50 * 0.3)
(input width * Value) - ( slider-thumb width * value )
With this equation you'll get it centered with all values
The input range slider-thumb with value 0 will have same value as left :0
But at the value 100 it'll have same css value as left : calc( 100% - it's width )
And same proportional left: calc( value - width/value )
Upvotes: 1
Reputation: 4912
In this answer, i will repeat what i have been mentioned in the comments section. i hope this will provide a little more clarity.
Add below css property
.test {
position: absolute;
z-index: 100;
top: 32%;
left: 31.5%;
}
In your babel+JSX section, remove the style attribute for the element with class="test"
<span class="test">30%</span>
Below is the change i recommend you to make
i made these modifications and verified this in your fiddle and it works when i adjust the screen size. Let me know if you still are facing issues.
Outputs i get while resizing the screen after introducing this fix
Updated
i have forked your JSfiddle into my jsfiddle account and updated the fix.
Here is my fiddle with the fix
https://jsfiddle.net/Divine/48ky8yzw/2/
Let me know if it works.
Upvotes: 1