CSS动态地将Div移动到圆心

时间:2017-12-27 04:48:21

标签: html css css3 reactjs

我试图在我的React应用中重新创建此图片:

enter image description here

到目前为止,这就是我所拥有的:

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;
}

这是一个小提琴:

https://jsfiddle.net/69z2wepo/96287/

我无法通过类测试获取我的span元素,以便始终找到圆的中心。如您所见,我使用ref来获取输入的宽度和第一个跨度。我希望我在componentDidMount中的数学能正常工作,但遗憾的是没有。此外,我意识到如果用户调整屏幕大小,那么数学实际上是关闭的。一个好处是该范围被禁用,所以不要担心滑块移动。另外,我只支持Chrome / Safari。

3 个答案:

答案 0 :(得分:1)

在这个答案中,我将重复我在评论部分提到的内容。我希望这会提供更多的清晰度。

添加以下css属性

.test {
  position: absolute;
  z-index: 100;
  top: 32%;
  left: 31.5%;
}

在您的babel + JSX部分中,使用class =“test”删除元素的style属性

<span class="test">30%</span>

以下是我建议您进行的更改我进行了这些修改,并在您的小提琴中验证了这一点,并且在我调整屏幕尺寸时它可以正常工作。如果您仍然面临问题,请告诉我。

enter image description here

在引入此修补程序后调整屏幕大小时获得的输出 enter image description here

  

更新

我已将您的JSfiddle分叉到我的jsfiddle帐户并更新了修复程序 这是我的小提琴与修复
https://jsfiddle.net/Divine/48ky8yzw/2/
如果有效,请告诉我。

答案 1 :(得分:1)

我认为它没有出现在正确位置的原因是因为你的数学略有偏差。您有(this.myInput.offsetWidth + this.myDiv.offsetWidth)*.3,但我认为您可能需要(this.myInput.offsetWidth*.3 + this.myDiv.offsetWidth)。您需要将完整的myDiv宽度添加到myInput宽度的30%。

编辑 - 忘记解决调整大小问题:

我对反应不是很熟悉,但是为了在调整窗口大小时调整它,你需要听取调整大小事件并重新计算位置。这是一个小提琴:https://jsfiddle.net/ay1qrwok/

答案 2 :(得分:1)

我把你的小提琴分开了 https://jsfiddle.net/Lzq561f8/1/

得到了适合所有值的正确等式

testWidth: (this.myInput.offsetWidth * 0.3) - (50 * 0.3)
(input width * Value) - ( slider-thumb width * value )

使用这个等式,你将使它以所有值为中心 值为0的输入范围slider-thumb将具有与左侧相同的值:0 但是在值100时,它将具有与left : calc( 100% - it's width )相同的css值 同样比例left: calc( value - width/value )