Страницы

Поиск по вопросам

среда, 10 июля 2019 г.

Начальная точки из цента экрана JS

Суть вопроса кроется в изменении скрипта, создающего точки и анимацию заднего фона. В настоящий момент первая точка устанавливается от левого верхнего края экрана и выстраивает точки до противоположных краев. Проблема в том, что логотип в центре экрана и на его углах должно быть 4 точки. Картинка для понимания проблемы:

То есть, отправная точка должна быть из центра видимой области экрана со смещением влево вверх на половину значения "pointDistance" и уже от этой точки расходиться к краям экрана.
Буду благодарен за любую помощь.
(function() { var width, height, canvas, ctx, points, target, animateHeader = true; var pointDistance = 85; var pointRadius = 2; var raf; // Main initHeader(); initAnimation(); addListeners(); function initHeader() { width = window.innerWidth; height = Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight ); target = {}; canvas = document.getElementById('background-canvas'); canvas.width = width; canvas.height = height; ctx = canvas.getContext('2d'); // create points initPoints(); } // Event handling function addListeners() { if(!('ontouchstart' in window)) { window.addEventListener('mousemove', mouseMove); } window.addEventListener('resize', resize); } function initAnimation() { animate(); } function animate() { if(animateHeader) { drawPoints(); } requestAnimationFrame(animate); } function mouseMove(e) { var posx = posy = 0; if (e.pageX || e.pageY) { posx = e.pageX; posy = e.pageY; } else if (e.clientX || e.clientY) { posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; } target.x = posx; target.y = posy; } function resize() { width = window.innerWidth; height = Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight ); canvas.width = width; canvas.height = height; for(var i in points) { TweenLite.killTweensOf(points[i]); } initPoints(); } function initPoints(){ // create points points = []; for(var x = 0; x <= width/pointDistance; x++) { for(var y = 0; y < height/pointDistance; y++) { var px = x*pointDistance; var py = y*pointDistance; var p = {x: px, originX: px, y: py, originY: py }; points.push(p); } } // for each point find the 5 closest points for(var i = 0; i < points.length; i++) { var closest = []; var p1 = points[i]; for(var j = 0; j < points.length; j++) { var p2 = points[j] if(!(p1 == p2)) { var placed = false; for(var k = 0; k < 5; k++) { if(!placed) { if(closest[k] == undefined) { closest[k] = p2; placed = true; } } } for(var k = 0; k < 5; k++) { if(!placed) { if(getDistance(p1, p2) < getDistance(p1, closest[k])) { closest[k] = p2; placed = true; } } } } } p1.closest = closest; } // assign a circle to each point for(var i in points) { var c = new Circle(points[i], pointRadius, 'rgba(255,255,255,0.3)'); points[i].circle = c; } } function drawPoints(){ ctx.clearRect(0,0,width,height); for(var i in points) { if(target){ if(Math.abs(getDistance(target, points[i])) < 4000) { points[i].opacity = 0.3; points[i].circle.opacity = 1; } else if(Math.abs(getDistance(target, points[i])) < 20000) { points[i].opacity = 0.2; points[i].circle.opacity = 1; } else if(Math.abs(getDistance(target, points[i])) < 40000) { points[i].opacity = 0.1; points[i].circle.opacity = 0.8; } else { points[i].opacity = 0; points[i].circle.opacity = 0.7; } } points[i].circle.color = 'rgba(180,180,180,1)'; drawLines(points[i]); points[i].circle.draw(); } } function shiftPoint(p) { TweenLite.to(p, 1+1*Math.random(), {x:p.originX+Math.random()*(pointDistance/2), y: p.originY+Math.random()*(pointDistance/2), ease:Circ.easeInOut, onComplete: function() { shiftPoint(p); }}); } function drawLines(p) { if(target){ for(var i in p.closest) { ctx.beginPath(); ctx.moveTo(p.x, p.y); ctx.lineTo(p.closest[i].x, p.closest[i].y); ctx.strokeStyle = 'rgba(110,110,110,'+p.opacity+')'; ctx.stroke(); } } } function Circle(pos,rad,color) { var _this = this; // constructor (function() { _this.pos = pos || null; _this.radius = rad || null; _this.color = color || null; })(); this.draw = function() { ctx.beginPath(); ctx.arc(_this.pos.x, _this.pos.y, _this.radius, 0, 2 * Math.PI, false); ctx.fillStyle = 'rgba(50,50,50,'+_this.opacity+')'; ctx.fill(); }; } // Util function getDistance(p1, p2) { return Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2); } })(); * { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { margin: 0; padding: 0; border: 0; font: inherit; font-size: 100%; vertical-align: baseline; } audio, canvas, video { display: inline-block; } audio:not([controls]) { display: none; height: 0; } [hidden], template { display: none; } html { line-height: 1; } abbr[title] { border-bottom: 1px dotted; } b, strong { font-weight: bold; } dfn { font-style: italic; } mark { background: #ff0; color: #000; } code, kbd, pre, samp { font-size: 1em; } pre { white-space: pre-wrap; } q { quotes: "\201C" "\201D" "\2018" "\2019"; } small { font-size: 80%; } sub, sup { position: relative; vertical-align: baseline; font-size: 75%; line-height: 0; } sup { top: -0.5em; } sub { bottom: -0.25em; } img { border: 0; max-width: 100%; } svg:not(:root) { overflow: hidden; } figure { margin: 0; } fieldset { margin: 0 2px; padding: 0.35em 0.625em 0.75em; border: 1px solid #c0c0c0; } legend { padding: 0; border: 0; } button, html input[type="button"], input[type="reset"], input[type="submit"] { cursor: pointer; -webkit-appearance: button; } button[disabled], html input[disabled] { cursor: default; } input[type="checkbox"], input[type="radio"] { padding: 0; } input[type="search"] { -webkit-box-sizing: content-box; -moz-box-sizing: content-box; box-sizing: content-box; -webkit-appearance: textfield; } input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; } button::-moz-focus-inner, input::-moz-focus-inner { padding: 0; border: 0; } textarea { overflow: auto; vertical-align: top; } div { border: 0px; } ol, ul { list-style: none; } table { border-spacing: 0; } caption, th, td { text-align: left; font-weight: normal; vertical-align: middle; } q, blockquote { quotes: none; } q:before, q:after, blockquote:before, blockquote:after { content: ""; content: none; } a img { border: none; } /*------ General style ------*/ body { font-family: 'MagistralC', sans-serif; font-size: 1em; line-height: 1.2; background-color: #000; color: rgba(255,255,255,.85); overflow-x: hidden; -webkit-font-smoothing: antialiased; } hr { display: block; height: 0; border: 0; border-top: 1px solid #ededed; margin: .4em 0; padding: 0; } img { vertical-align: middle; } fieldset { border: 0; margin: 0; padding: 0; } textarea { resize: vertical; } blockquote { margin: 30px 0px 30px 15px; padding-left: 15px; position: relative; font-style: italic; font-weight: 300; border-left: 2px solid #39F; } a { color: #fff; text-decoration: underline; } a:hover { text-decoration: none; } .with-clear:after, .clr:after { display: table; clear: both; content: ''; } footer .middle, header .middle { padding: 0 30px; } .middle { margin: 0 auto; max-width: 1260px; padding: 60px 30px; background: #000; } { -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px } .img { transition:All 0.36s ease; -webkit-transition:All 0.36s ease; -moz-transition:All 0.36s ease; -o-transition:All 0.36s ease; } .img { position: absolute; width: 104%; height: 104%; left: -2%; top: -1%; background-repeat: no-repeat; background-position: center; background-size: cover; } .valign-middle { display: -ms-flexbox; display: -webkit-flex; display: flex; -ms-flex-align: center; -webkit-align-items: center; -webkit-box-align: center; align-items: center; height: 100vh; } #background-canvas { position: absolute; left: 0; top: 0; z-index: -1; } .logo-block { width: 85px; height: 85px; line-height: 85px; margin: 0 auto; text-transform: uppercase; text-align: center; color: #333; background: #ccc; } EM

Logo


Ответ

Нужно рассчитать на сколько отличается позиция центральной клетки сетки и сместить каждую клетку на необходимую величину, в этом случае центральный квадрат совпадет с логотипом.
Рассчитать смещение можно например по следующей формуле:
var logo = document.querySelector('.logo-block'); var shiftX = pointDistance + logo.offsetLeft - Math.ceil(width / pointDistance/2)*pointDistance; var shiftY = pointDistance + logo.offsetTop - Math.ceil(height / pointDistance/2)*pointDistance;
Пример:
(function() { var width, height, canvas, ctx, points, target, animateHeader = true; var pointDistance = 85; var pointRadius = 2; var raf; // Main initHeader(); initAnimation(); addListeners(); function initHeader() { width = window.innerWidth; height = Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight ); target = {}; canvas = document.getElementById('background-canvas'); canvas.width = width; canvas.height = height; ctx = canvas.getContext('2d'); // create points initPoints(); } // Event handling function addListeners() { if (!('ontouchstart' in window)) { window.addEventListener('mousemove', mouseMove); } window.addEventListener('resize', resize); } function initAnimation() { animate(); } function animate() { if (animateHeader) { drawPoints(); } requestAnimationFrame(animate); } function mouseMove(e) { var posx = posy = 0; if (e.pageX || e.pageY) { posx = e.pageX; posy = e.pageY; } else if (e.clientX || e.clientY) { posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; } target.x = posx; target.y = posy; } function resize() { width = window.innerWidth; height = Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight ); canvas.width = width; canvas.height = height; for (var i in points) { TweenLite.killTweensOf(points[i]); } initPoints(); } function initPoints() { var logo = document.querySelector('.logo-block'); var shiftX = pointDistance + logo.offsetLeft - Math.ceil(width / pointDistance/2)*pointDistance; var shiftY = pointDistance + logo.offsetTop - Math.ceil(height / pointDistance/2)*pointDistance; // create points points = []; for (var x = 0; x <= width / pointDistance; x++) { for (var y = 0; y < height / pointDistance; y++) { var px = x * pointDistance + shiftX; var py = y * pointDistance + shiftY; var p = { x: px, originX: px, y: py, originY: py }; points.push(p); } } // for each point find the 5 closest points for (var i = 0; i < points.length; i++) { var closest = []; var p1 = points[i]; for (var j = 0; j < points.length; j++) { var p2 = points[j] if (!(p1 == p2)) { var placed = false; for (var k = 0; k < 5; k++) { if (!placed) { if (closest[k] == undefined) { closest[k] = p2; placed = true; } } } for (var k = 0; k < 5; k++) { if (!placed) { if (getDistance(p1, p2) < getDistance(p1, closest[k])) { closest[k] = p2; placed = true; } } } } } p1.closest = closest; } // assign a circle to each point for (var i in points) { var c = new Circle(points[i], pointRadius, 'rgba(255,255,255,0.3)'); points[i].circle = c; } } function drawPoints() { ctx.clearRect(0, 0, width, height); for (var i in points) { if (target) { if (Math.abs(getDistance(target, points[i])) < 4000) { points[i].opacity = 0.3; points[i].circle.opacity = 1; } else if (Math.abs(getDistance(target, points[i])) < 20000) { points[i].opacity = 0.2; points[i].circle.opacity = 1; } else if (Math.abs(getDistance(target, points[i])) < 40000) { points[i].opacity = 0.1; points[i].circle.opacity = 0.8; } else { points[i].opacity = 0; points[i].circle.opacity = 0.7; } } points[i].circle.color = 'rgba(180,180,180,1)'; drawLines(points[i]); points[i].circle.draw(); } } function shiftPoint(p) { TweenLite.to(p, 1 + 1 * Math.random(), { x: p.originX + Math.random() * (pointDistance / 2), y: p.originY + Math.random() * (pointDistance / 2), ease: Circ.easeInOut, onComplete: function() { shiftPoint(p); } }); } function drawLines(p) { if (target) { for (var i in p.closest) { ctx.beginPath(); ctx.moveTo(p.x, p.y); ctx.lineTo(p.closest[i].x, p.closest[i].y); ctx.strokeStyle = 'rgba(110,110,110,' + p.opacity + ')'; ctx.stroke(); } } } function Circle(pos, rad, color) { var _this = this; // constructor (function() { _this.pos = pos || null; _this.radius = rad || null; _this.color = color || null; })(); this.draw = function() { ctx.beginPath(); ctx.arc(_this.pos.x, _this.pos.y, _this.radius, 0, 2 * Math.PI, false); ctx.fillStyle = 'rgba(50,50,50,' + _this.opacity + ')'; ctx.fill(); }; } // Util function getDistance(p1, p2) { return Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2); } })(); * { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { margin: 0; padding: 0; border: 0; font: inherit; font-size: 100%; vertical-align: baseline; } audio, canvas, video { display: inline-block; } audio:not([controls]) { display: none; height: 0; } [hidden], template { display: none; } html { line-height: 1; } abbr[title] { border-bottom: 1px dotted; } b, strong { font-weight: bold; } dfn { font-style: italic; } mark { background: #ff0; color: #000; } code, kbd, pre, samp { font-size: 1em; } pre { white-space: pre-wrap; } q { quotes: "\201C""\201D""\2018""\2019"; } small { font-size: 80%; } sub, sup { position: relative; vertical-align: baseline; font-size: 75%; line-height: 0; } sup { top: -0.5em; } sub { bottom: -0.25em; } img { border: 0; max-width: 100%; } svg:not(:root) { overflow: hidden; } figure { margin: 0; } fieldset { margin: 0 2px; padding: 0.35em 0.625em 0.75em; border: 1px solid #c0c0c0; } legend { padding: 0; border: 0; } button, html input[type="button"], input[type="reset"], input[type="submit"] { cursor: pointer; -webkit-appearance: button; } button[disabled], html input[disabled] { cursor: default; } input[type="checkbox"], input[type="radio"] { padding: 0; } input[type="search"] { -webkit-box-sizing: content-box; -moz-box-sizing: content-box; box-sizing: content-box; -webkit-appearance: textfield; } input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; } button::-moz-focus-inner, input::-moz-focus-inner { padding: 0; border: 0; } textarea { overflow: auto; vertical-align: top; } div { border: 0px; } ol, ul { list-style: none; } table { border-spacing: 0; } caption, th, td { text-align: left; font-weight: normal; vertical-align: middle; } q, blockquote { quotes: none; } q:before, q:after, blockquote:before, blockquote:after { content: ""; content: none; } a img { border: none; } /*------ General style ------*/ body { font-family: 'MagistralC', sans-serif; font-size: 1em; line-height: 1.2; background-color: #000; color: rgba(255, 255, 255, .85); overflow-x: hidden; -webkit-font-smoothing: antialiased; } hr { display: block; height: 0; border: 0; border-top: 1px solid #ededed; margin: .4em 0; padding: 0; } img { vertical-align: middle; } fieldset { border: 0; margin: 0; padding: 0; } textarea { resize: vertical; } blockquote { margin: 30px 0px 30px 15px; padding-left: 15px; position: relative; font-style: italic; font-weight: 300; border-left: 2px solid #39F; } a { color: #fff; text-decoration: underline; } a:hover { text-decoration: none; } .with-clear:after, .clr:after { display: table; clear: both; content: ''; } footer .middle, header .middle { padding: 0 30px; } .middle { margin: 0 auto; max-width: 1260px; padding: 60px 30px; background: #000; } { -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px } .img { transition: All 0.36s ease; -webkit-transition: All 0.36s ease; -moz-transition: All 0.36s ease; -o-transition: All 0.36s ease; } .img { position: absolute; width: 104%; height: 104%; left: -2%; top: -1%; background-repeat: no-repeat; background-position: center; background-size: cover; } .valign-middle { display: -ms-flexbox; display: -webkit-flex; display: flex; -ms-flex-align: center; -webkit-align-items: center; -webkit-box-align: center; align-items: center; height: 100vh; } #background-canvas { position: absolute; left: 0; top: 0; z-index: -1; } .logo-block { width: 85px; height: 85px; line-height: 85px; margin: 0 auto; text-transform: uppercase; text-align: center; color: #333; background: #ccc; }

Logo

Комментариев нет:

Отправить комментарий