Created
August 29, 2017 09:57
-
-
Save SilencerWeb/87339ac8eb929b16ad37450058083e7d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Here is a site][1], in it a canvas (airplane), which lags when scrolling, appear artifacts, and in different ways, depending on what you scroll - with the mouse wheel or scrollbar. If you comment out parallax or video at the beginning, nothing changes. During the scrolling of calls to the house does not happen. Lags either from behind the airplane script, or because of a clearRect. How can I optimize and get rid of artifacts? The code on the [codepen][2]. | |
P.S. Artifacts do not appear on the [codepen][2], they are only on the [site][1]! | |
JS-code: | |
var scrolled; | |
var positionsArr = []; | |
var commonHeight = 0; | |
var canvas = document.querySelector('#canvas'); | |
var canvasB = document.querySelector('#canvasback'); | |
var ctx = canvas.getContext('2d'); | |
var ctxB = canvasB.getContext('2d'); | |
var centerX, centerY, radius, pointsOffset, radiusRatio, centerXRatio, | |
firstPoint, lastPoint, jet, blocksPosition, jetPositionY, jetTop, tabletOffset, headerHeight, canvasClearWidth; | |
var wWidth, mediaMobile, mediaTablet, mediaDesktop1, mediaDesktop2, mediaDesktop3; | |
jet = new Image(); | |
jet.src = 'http://silencer.website/alkor/images/jet.png'; | |
jet.onload = function () { | |
adaptive(); | |
} | |
$(window).on('resize', function () { | |
adaptive(); | |
}); | |
function adaptive() { | |
mediaMobile = mediaTablet = mediaDesktop1 = mediaDesktop2 = mediaDesktop3 = false; | |
wWidth = $(window).width(); | |
// Параметры для дуги по умолчанию | |
tabletOffset = 0; | |
radiusRatio = .95; | |
centerXRatio = 1.25; | |
// Параметры для дуги на разных разрешениях (перезаписывают параметры по умолчанию) | |
if (wWidth < 768) { | |
mediaMobile = true; | |
} | |
if (wWidth >= 768 && wWidth < 1024) { | |
mediaTablet = true; | |
tabletOffset = 120; | |
} | |
if (wWidth >= 1024 && wWidth < 1280) { | |
mediaDesktop1 = true; | |
tabletOffset = -40; | |
radiusRatio = 1.1; | |
centerXRatio = 1.03; | |
} | |
if (wWidth >= 1280 && wWidth < 1440) { | |
mediaDesktop2 = true; | |
tabletOffset = -20; | |
} | |
if (wWidth >= 1440) { | |
mediaDesktop3 = true; | |
tabletOffset = -20; | |
} | |
if (!mediaMobile) { | |
setTimeout(function () { | |
doCanvas(); | |
}, 500); | |
} else { | |
ctx.clearRect(0, 0, canvas.width, canvas.height); | |
$(window).off('scroll', onScroll); | |
} | |
} | |
function doCanvas() { | |
$(window).on('scroll', onScroll); | |
var marginBottom = 120; | |
commonHeight = 0; | |
$('.history__item').each(function () { | |
commonHeight = commonHeight + $(this).height() + marginBottom; | |
}); | |
commonHeight = commonHeight - marginBottom; | |
canvasWidth = $('.history').width() * .3; | |
canvasHeight = $('.history__blocks').height(); | |
canvas.width = canvasWidth; | |
canvas.height = canvasHeight; | |
canvasB.width = canvas.width; | |
canvasB.height = canvas.height; | |
offsetLeft = $('.history__blocks')[0].offsetLeft; | |
$('#canvas, #canvasback').css('marginLeft', -offsetLeft); | |
radius = commonHeight * radiusRatio; | |
centerX = -commonHeight / centerXRatio + offsetLeft + tabletOffset; | |
centerY = commonHeight / 2; | |
pointsOffset = 100; | |
canvasClearWidth = centerX + radius + 110; | |
blocksPosition = $('.history__blocks')[0].offsetTop; | |
jetPositionY = $('.history')[0].offsetTop; | |
headerHeight = $('.history__title').height(); | |
jetTop = $(window).height() / 2; | |
jetOnScroll = jetTop - headerHeight - jetPositionY; | |
positionsArr = []; | |
lastIndex = $('.history__item').length - 1; | |
darkened = $('.history__item'); | |
for (var i = 0; i < $('.history__item').length; i++) { | |
var position = $('.history__item').eq(i)[0].offsetTop - blocksPosition + pointsOffset; | |
positionsArr.push(position); | |
if (i == 0) { | |
firstPoint = position; | |
} | |
if (i == $('.history__item').length - 1) { | |
lastPoint = position; | |
} | |
} | |
draw(); | |
drawBackground(); | |
setTimeout(function () { | |
if (mediaTablet) { | |
jetPositionLine(firstPoint); | |
} else { | |
jetPosition(firstPoint); | |
} | |
}, 100); | |
} | |
function drawBackground() { | |
if (mediaTablet) { | |
drawLine(); | |
} else { | |
drawArc(); | |
} | |
} | |
function draw(currentY) { | |
for (var i = 0; i < positionsArr.length; i++) { | |
addPoint(positionsArr[i], currentY, i); | |
} | |
} | |
function drawArc() { | |
var firstPointRad = Math.asin((centerY - firstPoint) / radius); | |
var lastPointRad = Math.asin((centerY - lastPoint) / radius); | |
ctxB.beginPath(); | |
ctxB.lineWidth = 3; | |
ctxB.save(); | |
ctxB.arc(centerX, centerY, radius, 1.5, lastPointRad, true); | |
ctxB.strokeStyle = '#99daf0'; | |
ctxB.setLineDash([8, 5]); | |
ctxB.lineDashOffset = 1; | |
ctxB.globalCompositeOperation = 'destination-over'; | |
ctxB.stroke(); | |
ctxB.restore(); | |
} | |
function drawLine() { | |
ctxB.beginPath(); | |
ctxB.lineWidth = 3; | |
ctxB.save(); | |
ctxB.lineTo(tabletOffset, firstPoint); | |
ctxB.lineTo(tabletOffset, lastPoint); | |
ctxB.strokeStyle = '#99daf0'; | |
ctxB.setLineDash([8, 5]); | |
ctxB.lineDashOffset = 1; | |
ctxB.globalCompositeOperation = 'destination-over'; | |
ctxB.stroke(); | |
ctxB.restore(); | |
} | |
function addPoint(y, currentY, i) { | |
if (mediaTablet) { | |
var currentX = tabletOffset; | |
} else { | |
var angle = Math.asin((centerY - y) / radius); | |
var currentX = centerX + radius * (Math.cos(angle)); | |
} | |
ctx.beginPath(); | |
ctx.arc(currentX, y, 8, 0, 2 * Math.PI, false); | |
ctx.lineWidth = 3; | |
ctx.fillStyle = '#00a3da'; | |
ctx.globalCompositeOperation = 'source-over'; | |
if (currentY + 10 >= y) { | |
ctx.strokeStyle = '#fff'; | |
darkened.eq(i).removeClass('darkened'); | |
} else { | |
ctx.strokeStyle = '#99daf0'; | |
darkened.eq(i).addClass('darkened'); | |
} | |
ctx.fill(); | |
ctx.stroke(); | |
} | |
function jetPosition(y) { | |
var angle = Math.asin((centerY - y) / radius); | |
var currentX = centerX + radius * (Math.cos(angle) - 1); | |
var firstPointRad = Math.asin((centerY - firstPoint) / radius); | |
// if (toUp) { // Самолетик вверх-вниз | |
var jetAngle = Math.acos((centerY - y) / radius); | |
// } else { | |
// var jetAngle = Math.acos((centerY - y) / radius) + Math.PI; | |
// } | |
ctx.beginPath(); | |
ctx.arc(centerX, centerY, radius, -angle, -firstPointRad, true); | |
ctx.globalCompositeOperation = 'source-over'; | |
ctx.lineWidth = 3; | |
ctx.strokeStyle = '#fff'; | |
ctx.stroke(); | |
draw(y); | |
ctx.save(); | |
ctx.translate(currentX + radius, y) | |
ctx.rotate(jetAngle - 1.6); | |
ctx.globalCompositeOperation = 'source-over'; | |
ctx.drawImage(jet, -106, -80, 212, 160); | |
ctx.restore(); | |
} | |
function jetPositionLine(y) { | |
ctx.beginPath(); | |
ctx.lineTo(tabletOffset, firstPoint); | |
ctx.lineTo(tabletOffset, y); | |
ctx.lineWidth = 3; | |
ctx.strokeStyle = '#fff'; | |
ctx.stroke(); | |
draw(y); | |
ctx.beginPath(); | |
ctx.save(); | |
ctx.globalCompositeOperation = 'source-over'; | |
ctx.drawImage(jet, tabletOffset - 106, y - 80, 212, 160); | |
ctx.restore(); | |
} | |
function onScroll() { | |
requestAnimationFrame(scrollCanvas); | |
}; | |
function scrollCanvas() { | |
var prevScroll = scrolled; | |
scrolled = window.pageYOffset; | |
toUp = prevScroll < scrolled; | |
var positionY = scrolled + jetOnScroll; | |
if (positionY >= firstPoint) { | |
if (positionY <= lastPoint) { | |
ctx.clearRect(0, 0, canvasClearWidth, canvasHeight); | |
if (mediaTablet) { | |
jetPositionLine(positionY); | |
} else { | |
jetPosition(positionY); | |
} | |
} else { | |
$('.history__item').eq(lastIndex).removeClass('darkened'); | |
} | |
} | |
if (!mediaMobile && !mediaTablet) { | |
parallaxScroll(); | |
} | |
if (prevScroll > scrolled) { | |
paraCounter--; | |
} else { | |
paraCounter++; | |
} | |
} | |
[1]: http://silencer.website/alkor/ | |
[2]: https://codepen.io/SilencerWeb/pen/ayQbZb |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment