React-绝对定位元素和绘图线

时间:2019-06-28 23:36:04

标签: javascript html css reactjs

我正在开发一个React应用,其中有一部分行为应该表现如下。有一个步骤列表(可折叠和可扩展)。用户可以选择“开始循环”链接,此后将出现一些可选的圆圈,以供用户选择他们要循环回到的步骤。选择该步骤后,应绘制一条曲线以表明已建立连接。

下面是一个示意图,显示了我想要的样子:

enter image description here

当前,我能够执行步骤1和2,但是迷失于如何实现步骤3。这是一个React小提琴,向您展示了我到目前为止所拥有的。

https://jsfiddle.net/xaz7c6Le/7/

我有两个问题:

1)如果您查看startMarkerclickCircle的CSS,您会发现我试图绝对定位这些元素。但是,通过调整浏览器窗口的大小,很明显这是行不通的。如何获得这些元素,使其始终在属于它的步骤div中垂直居中重命名?

  1. 如何绘制将一步连接到另一步的线?如果我在第2步和第3步之间添加了另一个步骤,则该行应拉长以仍然连接第1步和第5步。

仅供参考,我的问题是关于行为,元素的对齐方式和线条绘制,而不是JSFiddle React代码的编写水平。 (真正的应用程序相当广泛,并且遵循React的最佳实践,但是要在JSFiddle上展示一些东西,我只是将它们放在一起)。

我的代码如下:

class LoopApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
        showCircles: false,
        selectedCircleIndex: -1,
        steps: [
        { title: "Step 1", partOfLoop: false },
        { title: "Step 2", partOfLoop: false },
        { title: "Step 3", partOfLoop: false },
        { title: "Step 4", partOfLoop: false }
      ]
    }
  }

  showCircles() {
    this.setState({ showCircles: true });
  }

  selectCircle(idx) {
    this.setState({ selectedCircleIndex: idx });
  }

  render() {
    return (
      <div>
          <h2>Block A:</h2>
          <div class="inner-block">
              {
                  this.state.steps.map((step, index) => 
                      <div class="step-entry">
                          {index + 1}. {step.title}

                          {
                              this.state.showCircles &&
                                <div
                                    className={"clickCircle " + (this.state.selectedCircleIndex === index ? "selected" : "" )}
                                    onClick={() => this.selectCircle(index)}></div>
                          }
                      </div>
                  )
              }
              <div class="step-entry">
                  5. Step 5

                  <a
                      class="start-loop"
                      onClick={() => this.showCircles()}>Start loop
                  </a>

                  {
                      this.state.showCircles && <div class="startMarker"></div>
                  }
              </div>
          </div>
      </div>
    )
  }
}

ReactDOM.render(<LoopApp />, document.querySelector("#app"))

CSS

body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

.inner-block {
    margin-top: 10px;
    border: 1px black solid;
    width: 30%;
}

.step-entry {
    padding: 20px;
    position: relative;
    border-bottom: 1px solid black;
}

.clickCircle {
    position: absolute;
    border: 1px solid blue;
    border-radius: 50%;
    height: 20px;
    width: 20px;
    left: 97%;
    top: 18px;
    background-color: white;   
}

.clickCircle:hover {
    background-color: orange;
}

.selected {
    background-color: orange;
}

.start-loop {
    float: right;
    color: orange;
}

.start-loop:hover {
    cursor: pointer;
    text-decoration: underline;
}

.startMarker {
    position: absolute;
    width: 20px;
    height: 10px;
    background-color: orange;
    top: 25px;
    left: 97%;
}

1 个答案:

答案 0 :(得分:3)

95% working solution on JSFiddle


要回答您的问题:

  1. 对于您的代码:
<div className="step-entry">
    <div className="startMarker"/>
</div>

您可以实现以下CSS:

.step-entry {
    display: flex;
    align-items: center;
}

这将使.step-entry的子元素相对于.step-entry元素垂直对齐。

不幸的是,我对水平对齐.startMarker没有答案。


  1. 连接两个圆的直线的一种可能的解决方案是在.step-entry元素后面放置一个框并将其偏移,以使其右侧部分突出显示在徽标应用程序的右侧。

    然后您可以操纵基础框的高度以匹配选定圆和最后一个圆之间的距离。

    我能够在圆圈上设置的onClick事件处理程序中计算出结果。