视差效果

编程入门 行业动态 更新时间:2024-10-10 15:21:16
本文介绍了视差效果-滚动时计算子级到父级的偏移量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在尝试创建视差效果,以便绝对定位的子元素的移动速度应比滚动时其父元素的移动速度慢.

I'm trying to create a parallax effect whereby an absolutely positioned child element should move at a rate slower than it's parent on scroll.

孩子将永远是父母的130%身高,但父母可以是任何身高:

The child will always be 130% height of the parent but the parent can be any height:

HTML:

<div class="parallax-window lg"> <div class="parallax-image image-1"></div> <div class="parallax-content">Hello World</div> </div> <div class="parallax-window"> <div class="parallax-image image-2"></div> <div class="parallax-content">Hello World</div> </div>

CSS:

.parallax-window { min-height: 300px; position: relative; overflow: hidden; } .parallax-window.lg { min-height: 600px; } .parallax-image { position: absolute; top: 0; left: 0; width: 100%; height: 130%; background-size: cover; background-repeat: no-repeat; background-position: 50% 50%; transform: translate3d(0, 0, 0); z-index: -1; } .image-1 { background-image: url(i.ytimg/vi/TbC-vUPMR7k/maxresdefault.jpg); } .image-2 { background-image: url(i.ytimg/vi/xi5-YrAEChc/maxresdefault.jpg); }

我有一个公式可以移动图像,但是我的数学显然很不正确:

I have a formula to move the image but my maths is clearly way off:

var win = $(window), win_h = win.height(), parallaxers = $('.parallax-window'); function scroll_events() { var win_top = win.scrollTop(), win_btm = win_top + win_h; parallaxers.each(function() { var cont = $(this), cont_top = cont.offset().top, cont_h = cont.height(), cont_btm = cont_top + cont_h, para = cont.find('.parallax-image'), para_h = Math.round(cont_h * 1.3); if (cont_btm > win_top && cont_top <= win_btm) { var diff = (win_h - cont_h) / (win_h - para_h), value = -Math.round((win_top * diff)); // para.css('transform', 'translate3d(0,' + value*-1 + 'px, 0)'); para.css('top', value + 'px'); } }); }

图像移动但速度不正确.

The images move but not at the correct rate.

当元素首次进入视口时,图像应与父对象的顶部对齐.然后,在滚动之后,当图像到达视口顶部时,其底部应与父对象的底部对齐.

The image should be in line with the top of the parent when the element first comes into the viewport. Then after scrolling, the bottom of the image should be in line with the bottom of the parent when it reaches the top of the viewport.

任何帮助将不胜感激!

FIDDLE( jsfiddle/8dwLwgy7/1/)

推荐答案

我知道了.

对于将来遇到任何麻烦的人-诀窍是将窗口滚动值替换为窗口滚动量的其余部分减去元素的偏移顶部,再减去元素的高度.

For anyone stumbling on this in the future - the trick was to replace the window scrolled value with the remainder of the window scrolled amount minus the element's offset top, minus the height of the element.

然后通过将容器高度和元素高度之差除以窗口和容器中的最大者来计算速度:

Then calculate the speed by dividing the difference between the container height and the element height with largest of either the window and the container:

// Wrong: // value = -Math.round((win_top * diff)); // Right: var diff = elem_h - cont_h, max = Math.max(cont_h, win_h), speed = diff / max, cont_scrolled = win_top - cont_top - cont_h, value = Math.round(cont_scrolled * speed); para.css('top', value + 'px');

完整的工作代码:

(function() { var lastTime = 0; var vendors = ['ms', 'moz', 'webkit', 'o']; for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame']; } if (!window.requestAnimationFrame) window.requestAnimationFrame = function(callback, element) { var currTime = new Date().getTime(); var timeToCall = Math.max(0, 16 - (currTime - lastTime)); var id = window.setTimeout(function() { callback(currTime + timeToCall); }, timeToCall); lastTime = currTime + timeToCall; return id; }; if (!window.cancelAnimationFrame) window.cancelAnimationFrame = function(id) { clearTimeout(id); }; }()); (function($) { var win = $(window), win_h = win.height(); parallaxers = $('.parallax-window'), parallax_objs = [], scroll_busy = false; function init_parallax() { win_h = win.height(); parallax_objs = []; parallaxers.each(function() { var cont = $(this), elem = cont.find('.parallax-image'), cont_top = cont.offset().top, cont_h = cont.height(), elem_h = Math.round(cont_h * 1.3), diff = elem_h - cont_h, max = Math.max(cont_h, win_h), speed = diff / max, parallaxer = { cont_top: cont_top, cont_h: cont_h, elem: elem, speed: speed }; parallax_objs.push(parallaxer); }); } function on_scroll() { if (!scroll_busy) { scroll_busy = true; window.requestAnimationFrame(init_scroll); } } function init_scroll() { scroll_events() scroll_busy = false; } function scroll_events() { var win_top = win.scrollTop(), win_btm = win_top + win_h; $.each(parallax_objs, function(i, para) { cont_btm = para.cont_top + para.cont_h; if( cont_btm > win_top && para.cont_top <= win_btm ) { var cont_scrolled = win_top - para.cont_top - para.cont_h, value = Math.round(cont_scrolled * para.speed); para.elem.css('top', value + 'px'); } }); } $(document).ready(function() { init_parallax(); win.resize(init_parallax); scroll_events(); win.scroll(on_scroll); }); })(jQuery);

.parallax-window { min-height: 300px; position: relative; overflow: hidden; } .parallax-window.lg { min-height: 600px; } .parallax-image { position: absolute; top: 0; left: 0; width: 100%; height: 130%; background-size: cover; background-repeat: no-repeat; background-position: 50% 50%; transform: translate3d(0, 0, 0); z-index: -1; } .image-1 { background-image: url(i.ytimg/vi/TbC-vUPMR7k/maxresdefault.jpg); } .image-2 { background-image: url(i.ytimg/vi/xi5-YrAEChc/maxresdefault.jpg); } .parallax-content { position: absolute; top: 50%; left: 0; width: 100%; text-align: center; font-family: arial, sans-serif; font-size: 60px; color: #fff; transform: translateY(-50%); }

<script src="ajax.googleapis/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <div class="parallax-window lg"> <div class="parallax-image image-1"></div> <div class="parallax-content">Hello World</div> </div> <div class="parallax-window"> <div class="parallax-image image-2"></div> <div class="parallax-content">Hello World</div> </div> <div class="parallax-window lg"> <div class="parallax-image image-1"></div> <div class="parallax-content">Hello World</div> </div> <div class="parallax-window"> <div class="parallax-image image-2"></div> <div class="parallax-content">Hello World</div> </div> <div class="parallax-window lg"> <div class="parallax-image image-1"></div> <div class="parallax-content">Hello World</div> </div>

更新的小提琴: jsfiddle/8dwLwgy7/2/

更多推荐

视差效果

本文发布于:2023-11-23 04:22:17,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1620071.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:视差   效果

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!