RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1068158
Accepted
voytenkodev
voytenkodev
Asked:2020-01-10 20:54:11 +0000 UTC2020-01-10 20:54:11 +0000 UTC 2020-01-10 20:54:11 +0000 UTC

在两个对象(图像)之间创建一条线 HTML、JavaScript

  • 772

我有一个 HTML 文件

<div> 
<img src="1.jpg" id="img1"> 
<img src="2.jpg" id="img2"> 
</div>

如何使用 JavaScript 在网站上找到图像的 x,y 坐标并在它们之间画一条线?

javascript
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Михаил Камахин
    2020-01-12T17:51:20Z2020-01-12T17:51:20Z

    你想要这样的东西吗?)我是怎么得出这个结论的 -链接到我的问题的答案如何从两点画一条线
    你问了你的问题,我决定这样做,这并不容易,我记得三角法: D
    如果您想保持神经正常-在画布上进行,那里的一切都容易得多。只需选择两个点,然后在它们之间画一条线。

    让我解释一下我的代码:

    该函数elemPosition返回元素在页面上的位置值,即使页面滚动,该函数也会返回元素相对于文档左边缘和上边缘的位置文档

    function elemPosition(elem) {
        let pos = {
            top: window.pageYOffset + elem.getBoundingClientRect().top,
            left: window.pageXOffset + elem.getBoundingClientRect().left,
            right: window.pageXOffset + elem.getBoundingClientRect().right,
            bottom: window.pageYOffset + elem.getBoundingClientRect().bottom
        };
        return pos;
    }
    

    该函数通过和通过centerElem返回元素的中心xу

    function centerElem(elem) {
        let width = elem.offsetWidth;
        let height = elem.offsetHeight;
        let centerX = width/2 + elemPosition(elem).left;
        let centerY = height/2 + elemPosition(elem).top;
        let pos = {
            y: centerY,
            x: centerX
        };
        return pos;
    }
    

    该函数createPath创建一个线元素并为其设置动画

    function createPath(from, fromIndex, to, toIndex) {
    
        let child = whatElems(from, fromIndex, to, toIndex);
        let childFrom = child.from;
        let childTo = child.to;
        render(childFrom, childTo);
    
    }
    

    该函数whatElems从父级返回要为动画选择的元素

    function whatElems(from, fromIndex, to, toIndex) {
        let child = {
            from : from.children[fromIndex],
            to : to.children[toIndex]
        }
        return child;
    }
    

    该函数使用类createDiv创建,将其添加到末尾并返回这个,以便在调用此函数后可以立即操作元素div.harmonybodydiv

    function createDiv() {
        let div = document.createElement('div');
        div.classList.add('harmony');
        document.body.append(div);
        return div;
    }
    

    该函数createPathandPush使用 createPath 创建一个元素并进行动画处理,并将该元素添加到数组paths中,以便随后可以操作每个元素

    function createPathAndPush(from, fromIndex, to, toIndex) {
        createPath(from, fromIndex, to, toIndex);
        paths.push([from, fromIndex, to, toIndex]);
    }
    

    事件监听器(图片加载)通过循环load触发元素,循环后它将我们在页面上创建的所有元素输入到一个全局变量中, 该函数渲染元素并计算它旋转的点、高度、角度。如果函数有第三个参数等于,那么它创建一个元素并对其进行动画处理,如果传递了第三个参数,则函数简单 地调整它的大小,改变它的旋转角度、长度和起点的位置- 写,我会回答 PS:当你点击页面动画重新启动createPathAndPushharmonies

    renderrenderundefined


    let items = document.querySelectorAll('.item');
    
    let reqAnimFrame = (function() {
        return requestAnimationFrame       ||
               mozRequestAnimationFrame    ||
               webkitRequestAnimationFrame ||
               oRequestAnimationFrame      ||
               msRequestAnimationFrame     ||
        function(callback) {
            setTimeout(callback, 1000 / 60);
        }
    })();
    
    function animate({timing, draw, duration, active}) {
    
      let start = performance.now();
    
      reqAnimFrame(function animate(time) {
        // timeFraction изменяется от 0 до 1
        let timeFraction = (time - start) / duration;
        if (timeFraction > 1) timeFraction = 1;
    
        // вычисление текущего состояния анимации
        let progress = timing(timeFraction);
    
        draw(progress); // отрисовать её
    
        if (timeFraction < 1) {
          requestAnimationFrame(animate);
        }
    
      });
    }
    
    function elemPosition(elem) {
    	let pos = {
    	    top: window.pageYOffset + elem.getBoundingClientRect().top,
    	    left: window.pageXOffset + elem.getBoundingClientRect().left,
    	    right: window.pageXOffset + elem.getBoundingClientRect().right,
    	    bottom: window.pageYOffset + elem.getBoundingClientRect().bottom
    	};
    	return pos;
    }
    
    function centerElem(elem) {
    	let width = elem.offsetWidth;
    	let height = elem.offsetHeight;
    	let centerX = width/2 + elemPosition(elem).left;
    	let centerY = height/2 + elemPosition(elem).top;
    	let pos = {
    		y: centerY,
    		x: centerX
    	};
    	return pos;
    }
    
    function whatElems(from, fromIndex, to, toIndex) {
    	let child = {
    		from : from.children[fromIndex],
    		to : to.children[toIndex]
    	}
    	return child;
    }
    
    function createDiv() {
    	let div = document.createElement('div');
    	div.classList.add('harmony');
    	document.body.append(div);
    	return div;
    }
    
    function render(childF, childT, elemResize, j) {
    
    	let div = elemResize;
    
    	if (elemResize == undefined) {
    		div = createDiv();
    	}
    
    
    	let height = window.getComputedStyle(div, null).height; // исходная высота прямой
    	height = Number(height.slice(0, height.length-2)); // исходная высота прямой
    	let d, tang, arctg, angle, scale, final, start;
    
    	function logic() {
    
    		final = {
    			x: centerElem(childT).x,
    			y: elemPosition(childT).top
    		}; // координаты конечной точки
    
    		start = {
    			x: centerElem(childF).x,
    			y: elemPosition(childF).bottom
    		}; // координаты начальной точки
    
    		d = Math.sqrt( Math.pow((final.x - start.x), 2) + Math.pow((final.y - start.y), 2) ); // длина прямой после анимации
    		tang = (final.y-start.y) / (final.x-start.x)// Тангенс
    		arctg = Math.atan(tang); // Арктангенс
    		angle = arctg * 180 / Math.PI; // угол в градусах
    		scale = d/height; // насколько масштабировать прямую по высоте
    
    		if (tang < 0) {
    			angle = 90 + angle;
    		} else if (tang > 0) {
    			angle = -(90-angle);
    		}
    
    	}
    
    	logic();
    
    	if (elemResize !== undefined) {
    
    		if (progressGlobal[j+1] == 1) {
    			reqAnimFrame(startResize);
    		}
    
    		function startResize() {
    			div.style.transform = `translate(${start.x}px, ${start.y}px) rotate(${angle}deg) scale(1, ${scale}) translateZ(0)`;
    		}
    	} else {
    		animate({
    			duration: 5000,
    			timing(timeFraction) {
    				return timeFraction;
    			},
    			draw(progress) {
    				logic();
    				div.style.transform = `translate(${start.x}px, ${start.y}px) rotate(${angle}deg) scale(1, ${progress*scale}) translateZ(0)`;
    				progressGlobal[j] = progress;
    			}
    		});
    
    	}
    
    }
    
    function createPath(from, fromIndex, to, toIndex, j) {
    
    	let child = whatElems(from, fromIndex, to, toIndex);
    	let childFrom = child.from;
    	let childTo = child.to;
    	render(childFrom, childTo, undefined, j);
    
    }
    
    let progressGlobal = [];
    let harmonies;
    let paths = [];
    
    function startHell() {
    
    	function createPathAndPush(from, fromIndex, to, toIndex, j) {
    		createPath(from, fromIndex, to, toIndex, j);
    		paths.push([from, fromIndex, to, toIndex, j]);
    		j++;
    		return j;
    	}
    
    	let j = 0;
    
    	for (let i = 3; i <= 5; i++) {
    		j = createPathAndPush(items[i-3], 0, items[i], 1, j);
    		j = createPathAndPush(items[i-3], 0, items[i], 0, j);
    	}
    
    	for (let i = 6; i <= 8; i++) {
    		j = createPathAndPush(items[i-3], 0, items[i], 0, j);
    		j = createPathAndPush(items[i-3], 0, items[i], 1, j);
    		j = createPathAndPush(items[i-3], 1, items[i], 1, j);
    		j = createPathAndPush(items[i-3], 1, items[i], 2, j);
    	}
    
    	harmonies = document.querySelectorAll('.harmony');
    
    	for (let i = 0; i < harmonies.length; i++) {
    		progressGlobal[i] = 0;
    	}
    
    }
    
    window.addEventListener('load', () => {
    	startHell();
    });
    
    window.addEventListener('resize', () => {
    	for (let i = 0; i < harmonies.length; i++) {
    		let child = whatElems(paths[i][0], paths[i][1], paths[i][2], paths[i][3]);
    		let childFrom = child.from;
    		let childTo = child.to;
    		render(childFrom, childTo, harmonies[i], i-1);
    	}
    });
    
    window.addEventListener('click', () => {
    
    	for (let i = 0; i < harmonies.length; i++) {
    		harmonies[i].remove();
    	}
    
    	startHell();
    
    });
    @import url('https://fonts.googleapis.com/css?family=Open+Sans&display=swap');
    
    *, *:before, *:after {
    	-webkit-box-sizing: border-box;
    	-moz-box-sizing: border-box;
    	box-sizing: border-box;
    }
    
    body {
    	margin: 0;
    	color: black;
    	font-size: 16px;
    	font-family: 'Open Sans', sans-serif;
    }
    
    img {
    	display: block;
    	max-width: 100%;
    	height: auto;
    }
    
    .wrapper {
    	max-width: 1400px;
    	margin: 0 auto;
    }
    
    .line:not(:first-child) {
    	margin-top: 50px;
    }
    
    .item {
    	display: -webkit-flex;
    	display: -moz-flex;
    	display: -ms-flex;
    	display: -o-flex;
    	display: flex;
    	flex: 1;
    }
    
    .item:not(:last-child) {
    	margin-right: 2%;
    }
    
    .item__img {
    	z-index: 2;
    }
    
    .item__img:not(:first-child) {
    	margin-left: 5px;
    }
    
    .line {
    	display: -webkit-flex;
    	display: -moz-flex;
    	display: -ms-flex;
    	display: -o-flex;
    	display: flex;
    	transition: opacity .3s ease-in-out;
    }
    
    .harmony {
    	z-index: 3;
    	position: absolute;
    	width: 2.5px;
    	background-color: red;
     	height: 80px;
     	left: 0;
     	top: 0;
    	transform: translateZ(0);
    	transform-origin: 50% 0%;
    }
    <!DOCTYPE html>
    <html lang="ru">
    <head>
    	<meta charset="UTF-8">
    	<meta name="viewport" content="width=device-width, initial-scale=1">
    	<title>Document</title>
    	<link rel="stylesheet" href="style.css">
    </head>
    <body>
    	
    <div class="wrapper">
    
    	<div class="line line__one">
    
    		<div class="item">
    			<div class="item__img">
    				<img src="https://picsum.photos/500/250">
    			</div>
    		</div>
    
    		<div class="item">
    			<div class="item__img">
    				<img src="https://picsum.photos/500/250">
    			</div>
    		</div>
    
    		<div class="item">
    			<div class="item__img">
    				<img src="https://picsum.photos/500/250">
    			</div>
    		</div>
    
    	</div> <!-- .line__one -->
    
    	<div class="line line__two">
    
    		<div class="item">
    			<div class="item__img">
    				<img src="https://picsum.photos/300/150">
    			</div>
    			<div class="item__img">
    				<img src="https://picsum.photos/300/150">
    			</div>
    		</div>
    
    		<div class="item">
    			<div class="item__img">
    				<img src="https://picsum.photos/300/150">
    			</div>
    			<div class="item__img">
    				<img src="https://picsum.photos/300/150">
    			</div>
    		</div>
    
    		<div class="item">
    			<div class="item__img">
    				<img src="https://picsum.photos/300/150">
    			</div>
    			<div class="item__img">
    				<img src="https://picsum.photos/300/150">
    			</div>
    		</div>
    
    	</div> <!-- .line__two -->
    
    	<div class="line line__three">
    
    		<div class="item">
    			<div class="item__img">
    				<img src="https://picsum.photos/200/100">
    			</div>
    			<div class="item__img">
    				<img src="https://picsum.photos/200/100">
    			</div>
    			<div class="item__img">
    				<img src="https://picsum.photos/200/100">
    			</div>
    		</div>
    
    		<div class="item">
    			<div class="item__img">
    				<img src="https://picsum.photos/200/100">
    			</div>
    			<div class="item__img">
    				<img src="https://picsum.photos/200/100">
    			</div>
    			<div class="item__img">
    				<img src="https://picsum.photos/200/100">
    			</div>
    		</div>
    
    		<div class="item">
    			<div class="item__img">
    				<img src="https://picsum.photos/200/100">
    			</div>
    			<div class="item__img">
    				<img src="https://picsum.photos/200/100">
    			</div>
    			<div class="item__img">
    				<img src="https://picsum.photos/200/100">
    			</div>
    		</div>
    
    	</div> <!-- .line__three -->
    
    
    </div> <!-- .wrapper -->
    
    <script src="script.js"></script>
    
    </body>
    </html>

    • 2

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何从列表中打印最大元素(str 类型)的长度?

    • 2 个回答
  • Marko Smith

    如何在 PyQT5 中清除 QFrame 的内容

    • 1 个回答
  • Marko Smith

    如何将具有特定字符的字符串拆分为两个不同的列表?

    • 2 个回答
  • Marko Smith

    导航栏活动元素

    • 1 个回答
  • Marko Smith

    是否可以将文本放入数组中?[关闭]

    • 1 个回答
  • Marko Smith

    如何一次用多个分隔符拆分字符串?

    • 1 个回答
  • Marko Smith

    如何通过 ClassPath 创建 InputStream?

    • 2 个回答
  • Marko Smith

    在一个查询中连接多个表

    • 1 个回答
  • Marko Smith

    对列表列表中的所有值求和

    • 3 个回答
  • Marko Smith

    如何对齐 string.Format 中的列?

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5