Суть вопроса кроется в изменении скрипта, создающего точки и анимацию заднего фона. В настоящий момент первая точка устанавливается от левого верхнего края экрана и выстраивает точки до противоположных краев. Проблема в том, что логотип в центре экрана и на его углах должно быть 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;
}
Ответ
Нужно рассчитать на сколько отличается позиция центральной клетки сетки и сместить каждую клетку на необходимую величину, в этом случае центральный квадрат совпадет с логотипом.
Рассчитать смещение можно например по следующей формуле:
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;
}
Комментариев нет:
Отправить комментарий