gpt4 book ai didi

html - 如何在 Angular 中用线条连接两个 div

转载 作者:行者123 更新时间:2023-12-05 04:52:05 25 4
gpt4 key购买 nike

* 元素描述

我正在创建响应式锦标赛括号树网页。

* 问题

我的问题是我想用一条装饰线将每个支架“每个支架都是它自己的一个 div”连接到下一个支架,一般来说,我想要两个连接两个 div 和一条我可以装饰的线。

- 示例

例子1

Example1

例子2

Example2

* 我尝试了什么

我尝试使用 CanvasRenderingContext2D但我并没有太多运气,或者至少不知道如何充分利用它

* 我想要什么/期望什么

我希望能够将两个括号/div 与一条可以 flex 和移动的线连接起来,“由开发人员而非用户”进行设计。

  • p.s:这只需要在大于“xs”的屏幕上显示,因此移动设备不是问题。

* 我的代码

Stackblitz Project

- 使用的库和版本

  • Angular V:5.1
  • Flex-Layout“angular”V:2.00 beta 12
  • Angular Material V:5.01

最佳答案

<div style="position:absolute; left:0; top:0; width: 100px; height: 50px; background:red;"></div>
<div style="position:absolute; left:250px; top:150px; width: 100px; height: 50px; background: blue;"></div>

<svg style="position:absolute; left:0; top:0;" width="300" height="300">
<line x1="100" y1="50" x2="250" y2="150" stroke="black"/>
</svg>

示例:

在 app.component.html 文件中:

<div class="cont">
<div *ngFor="let item of arr_item; index as i" class="block d-flex align-items-center justify-content-between">
<div class="d-flex flex-column" #left>
<div *ngFor="let val of item.left" class="box box-left">
{{val}}
</div>
</div>
<div class="d-flex flex-column align-items-end" #right>
<div *ngFor="let val of item.right" class="box box-right">
{{val}}
</div>
</div>
</div>
<svg style="position: absolute; z-index: -1; width:100%; height:100%; top: 0; left: 0;">
<polyline *ngFor="let item of polylines"
[attr.points]="item.points"
[attr.fill]="item.fill"
[attr.stroke]="item.stroke"
[attr.stroke-width]="item.strokeWidth"
/>
</svg>
</div>

在 app.component.css 文件中:

.cont {
position: relative;
}
.box {
padding: 10px;
border: 1px solid #292929;
width: fit-content;
margin: 10px;
max-width: 200px;
}
.block {
margin: 10px;
}

在 app.component.ts 文件中:

import {
AfterViewInit,
Component,
ElementRef,
OnInit,
QueryList,
ViewChildren
} from "@angular/core";

export class Polyline {
points: string;
fill: string;
stroke: string;
strokeWidth: number;
constructor(
points?: string,
fill?: string,
stroke?: string,
strokeWidth?: number
) {
this.points = points || "";
this.fill = fill || "none";
this.stroke = stroke || "blue";
this.strokeWidth = strokeWidth || 3;
}
}

@Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent implements OnInit, AfterViewInit {
arr_item = [
{
left: ["Lorem Ipsum", "ABC"],
right: ["Hello World", "Hello"]
},
{
left: [
"Lorem Ipsum is simply dummy text of the printing and typesetting industry.",
"Lorem Ipsum is simply dummy text"
],
right: [""]
},
{
left: [
"",
"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s"
],
right: ["Rainbow"]
}
];

@ViewChildren("left", { read: ElementRef }) left: QueryList<ElementRef>;
@ViewChildren("right", { read: ElementRef }) right: QueryList<ElementRef>;

polylines: Polyline[] = [];

ngAfterViewInit() {
this.drawLines();
}

ngOnInit(): void {
window.addEventListener("resize", () => {
this.drawLines();
});
}

getPos_line(ele) {
var className = ele.getAttribute("class");
if (className.indexOf("left") !== -1) {
return {
x: Math.round(ele.offsetLeft + ele.offsetWidth),
y: Math.round(ele.offsetTop + ele.offsetHeight / 2)
};
} else {
return {
x: Math.round(ele.offsetLeft),
y: Math.round(ele.offsetTop + ele.offsetHeight / 2)
};
}
}

getMaxX_Left(arr: any) {
if (arr.length >= 1) {
var maxX = this.getPos_line(arr[0]).x;
for (var i = 0; i < arr.length; i++) {
var posLine = this.getPos_line(arr[i]);
if (posLine.x > maxX) {
maxX = posLine.x;
}
}
return maxX;
} else {
return null;
}
}

getMinX_Right(arr: any) {
if (arr.length >= 1) {
var minX = this.getPos_line(arr[0]).x;
for (var i = 0; i < arr.length; i++) {
var posLine = this.getPos_line(arr[i]);
if (posLine.x < minX) {
minX = posLine.x;
}
}
return minX;
} else {
return null;
}
}

getCenY(left, right) {
if (left.offsetHeight >= right.offsetHeight) {
return Math.round(left.offsetTop + left.offsetHeight / 2);
} else {
return Math.round(right.offsetTop + right.offsetHeight / 2);
}
}

drawLines() {
this.polylines = [];
for (var i = 0; i < this.arr_item.length; i++) {
var polylines_temp: Polyline[] = [];
var left_children = this.left.get(i).nativeElement.children;
var right_children = this.right.get(i).nativeElement.children;
var left_childrenLen = left_children.length;
var right_childrenLen = right_children.length;
var maxX_left = this.getMaxX_Left(left_children);
var minX_right = this.getMinX_Right(right_children);
var cenY = this.getCenY(
this.left.get(i).nativeElement,
this.right.get(i).nativeElement
);
var cenX = Math.round((maxX_left + minX_right) / 2);

var space = 0;
if (left_childrenLen > 1 && right_childrenLen > 1) {
space = 10;
}

for (var j = 0; j < left_childrenLen; j++) {
var posLine = this.getPos_line(left_children[j]);
polylines_temp.push(
new Polyline(`
${posLine.x},${posLine.y}
${cenX - space},${posLine.y}
${cenX - space},${cenY}
${cenX},${cenY}
`)
);
}
for (var j = 0; j < right_childrenLen; j++) {
var posLine = this.getPos_line(right_children[j]);
polylines_temp.push(
new Polyline(`
${cenX},${cenY}
${cenX + space},${cenY}
${cenX + space},${posLine.y}
${posLine.x},${posLine.y}
`)
);
}
this.polylines = this.polylines.concat(polylines_temp);
}
}
}

Link to Stackblitz

Image Result

关于html - 如何在 Angular 中用线条连接两个 div,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66600951/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com