smooth horizontal scroll like k2.pl - javascript

I am trying to build a website with a horizontal scroll like this website k2.pl
Desc
i have made this code so far jquery animate and scroll to
// i am getting y and x axis and moving the whole page agains it
$('.scroll').animate( { scrollLeft: '+='+newScroll }
but what i made is that my script gets page X axis of website and move againts it but what i want is that when i hover on an element on the site it should scroll to the center like on this site k2.pl
can you guys suggest me some jquery plugin or that tell me how can improve it

If you check the website and move the mouse, you'll see that the element that you hover on doesn't really go to the center, the movement of the scroll is associated to the horizontal movement of the mouse and has nothing to do with hovering over the different list elements.
The idea is simple:
Have a container that occupies the whole width of the window and that has a overflow:hidden.
Inside that container have a second container with the same width as the list of elements.
Inside that container have a list of elements (or a series of inline elements) that occupy more than the width of the window.
When the mouse moves over the container, calculate the position of the mouse within the window, and scroll the container horizontally accordingly.
A basic version of it would be like this:
$(document).ready(function() {
$(".scroll").on("mousemove", function(e) {
var ww = $(window).width(); // window width
var uw = $(".scroll ul").width(); // ul width
var mp = e.clientX; // mouse position
var ms = uw - ww; // max scroll
var sc = - ms * mp / ww; // amount to be scrolled
$(".scroll > div").stop().animate({ left: sc +"px" }, 600, "easeOutCirc");
});
});
html, body {
margin:0;
padding:0;
border:0;
}
div.scroll {
width:100%;
height:400px;
overflow:hidden;
background:#f0f0f0;
position:relative;
}
div.scroll > div {
width:1400px;
position:absolute;
top:0;
left:0;
}
div.scroll > div > ul {
width:1400px;
margin:0;
padding:0;
}
div.scroll > div > ul > li {
display:inline-block;
float:left;
width:200px;
height:400px;
opacity:0.7;
transition:all 0.5s;
}
div.scroll > div > ul > li:hover {
opacity:1;
background:#6699cc;
}
div.scroll > div > ul > li:hover > span {
color:white;
background:black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.3/jquery-ui.min.js"></script>
<div class="scroll">
<div>
<ul>
<li><span>AAA</span></li>
<li><span>BBB</span></li>
<li><span>CCC</span></li>
<li><span>DDD</span></li>
<li><span>EEE</span></li>
<li><span>FFF</span></li>
<li><span>GGG</span></li>
</ul>
</div>
</div>
(Note: the code above may not work if the width of the window is larger than 1400px)
If you check the source code for k2.pl you'll see that they are using jQuery, jQuery UI, and Ariel Flesler's scrollTo plugin. You can see the code that controls the scrolling (in a different way to what I explained above) in the script.min.js file (search for mousemove.sapp).

As promised, here's my working solution. Alvaro's is great, but it uses the jQuery animate function which is a big no-no (it's about 10x slower than CSS transitions / the GSAP JavaScript animation library, for example), so I thought you might benefit from another implementation.
I personally like GSAP, which is super easy to pick up; that's why I've used it here. The rest is in native JS so you don't need all that library bloat:
var wrapper = document.getElementById("wrapper");
var tiles = document.getElementsByClassName("tile");
var tileWidth = tiles[0].getBoundingClientRect().width;
var containingWidth = tileWidth * tiles.length;
wrapper.addEventListener("mousemove", function(e){
var pos = (e.clientX / (wrapper.getBoundingClientRect().width)) * containingWidth - (tileWidth / 1.5);
TweenLite.to(wrapper, 1, { scrollLeft: pos, ease: Circ.easeOut })
});
html, body {
height: 100%;
overflow: hidden;
white-space: nowrap;
}
#wrapper {
height: 100%;
overflow-y: hidden;
overflow-x: auto;
}
.tile {
display: inline-block;
height: 100%;
width: 400px;
transition: background 0.2s ease-in-out;
}
.tile:hover {
background: transparent !important;
}
<div id="wrapper">
<div style="background: #6d8745" class="tile"></div>
<div style="background: #aa715a" class="tile"></div>
<div style="background: #a25fe3" class="tile"></div>
<div style="background: #8e84f5" class="tile"></div>
<div style="background: #259a5c" class="tile"></div>
<div style="background: #d5b67a" class="tile"></div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.18.0/TweenMax.min.js"></script>
The principles are essentially the same as Alvaro's. What you have to understand is that the width of the viewport will be a certain percentage of the width of the div / element which contains all of the "tiles" so, taking this into consideration, you have to calculate how to make them map at a 1:1 ratio. That calculation is represented by this line of code (the subtraction at the end is an offset):
var pos = (e.clientX / (wrapper.getBoundingClientRect().width)) * containingWidth - (tileWidth / 1.5);
Hope this helps!
Original codepen

Related

Positioning of element with JS transform properties (CSS get's overwritten by JS)

I'm trying to position two images on top of eachother, and having one of them rotate on scroll while the other one is not rotating - which works, except i'm unable to position and scale my elements in my CSS. As soon as i start scrolling, the image with the JS jumps into the corner while the other one remains where it is. I believe it's because my JS overwrites my CSS properties, but is there any way of working around this? Can i position my two elements while maintaining my JS?
var elem = document.getElementById("rotatelogo");
window.addEventListener('scroll', function() {
var value = window.scrollY * 0.25;
elem.style.transform = `translatex(-50%) translatey(-50%) rotate(${value}deg)`;
});
body {
height: 200vh;
background: darkblue;
}
.guide {
width:150px;
height:150px;
margin-top:50px;
margin-bottom:-300px;
margin-left:50px;
}
<div class="guide" style="position:relative">
<img src="http://jakobnatorp.com/wp-content/uploads/2021/10/ARROW.png" style="position:fixed;"/>
<img class="portfolio" id="rotatelogo" src="http://jakobnatorp.com/wp-content/uploads/2021/10/SELECTED-WORK-BEIGE.png" style="position:fixed"/>
</div>
Remove translate from your code.
var elem = document.getElementById("rotatelogo");
window.addEventListener('scroll', function() {
var value = window.scrollY * 0.25;
elem.style.transform = `rotate(${value}deg)`;
});
body {
height: 200vh;
background: darkblue;
}
.guide {
width:150px;
height:150px;
margin-top:50px;
margin-bottom:-300px;
margin-left:50px;
}
<div class="guide" style="position:relative">
<img src="http://jakobnatorp.com/wp-content/uploads/2021/10/ARROW.png" style="position:fixed;"/>
<img class="portfolio" id="rotatelogo" src="http://jakobnatorp.com/wp-content/uploads/2021/10/SELECTED-WORK-BEIGE.png" style="position:fixed"/>
</div>
I am not sure what you want to achieve by usingtranslatex(-50%) translatey(-50%), but this is causing the images center to be positioned on the top left corner of the parent element.
If you just use elem.style.transform = `rotate(${value}deg)`; it will rotate in place.

centering a div in a container larger than 100%

i need to center a div in the viewport in a container larger then 100%.
assuming it's 160% large, i prepared this fiddle:
https://jsfiddle.net/mz0bbz14/2/
usually i would go for:
position:absolute;
top:50%;
left:50%;
transform:translate(-50%,-50%);
but this works only when its container is 100% large.
it's solved with this css
position:absolute;
top:50%;
text-align: center;
transform:translate(0,-50%);
width: 100vw;
but the vw unit doesn't work on older android browsers and i need to support it. I can't use jQuery and i don't know how to center it with pure javascript.
i tried setting .div to half the width of the container, but the text inside the div doesn't visually center.
i can't find a solution. any ideas? thanks
If I understand your problem correctly, you want the red .div centered in the left 100% of the parent container that has a width of 160% of the view port.
In that case, you need to adjust the left offset to be 50% of 100%/160%, which is 31.25%.
body,html {
height: 100%;
}
.cont-inner {
width:160%;
height: 100%;
background: hotpink;
position:relative;
}
.div {
position:absolute;
top:50%;
left: 31.25%;
transform:translate(-50%,-50%);
background:red;
padding:50px; /* smaller size for demo in snippet window */
}
<div class="cont-inner">
<div class="div">
asd
</div>
</div>
You need to change the left property.
It needs to be in the middle of the visible part of the container.
Since it's 160%, it is
(100 / 160) * 0.5 -> 31.25%
body,html {
height: 100%;
}
.cont-inner {
width:160%;
height: 100%;
background: hotpink;
position:relative;
}
.div {
position:absolute;
top:50%;
left:31.25%;
transform:translate(-50%,-50%);
background:red;
padding:100px;
}
<div class="cont-inner">
<div class="div">
asd
</div>
</div>
;
I wanted to place an answer with modified left property, but I already see them, so here's some other attempt with position:static freeing inner div from its parent
https://jsfiddle.net/mz0bbz14/9/
It just doesn't force you to stick with 160%.
If you need to support older browsers you shall use Javascript to make sure it will work since all CSS solution require hard-coding values.
var parent = document.querySelector('.cont-inner'),
child = parent.querySelector('div');
child.style.left = ((window.innerWidth / 2) - (child.offsetWidth / 2)) + 'px';
child.style.top = ((window.innerHeight / 2) - (child.offsetHeight / 2)) + 'px';
Example: https://jsfiddle.net/9syvq2r2/

resizing and centering an <img> inside a div and keeping aspect ratio

I have a div that has a fixed size of 500x500. Inside this div I have an image tag which can be dynamic. Meaning that it can have a size of a square, a rectangle (width > height), or a vertical rectangle (height > width). The issue is that I don't want this image to be squished, I wanted to keep the aspect ratio of the image. So say the image size is 1000x250, then I want it to be resized as 500x125 and then centered on this 500x500 box. If the size is 500x1000 then we wanted it to be resized as 250x500 and then centered with white spacing on the left and right.
Is there an easy way to do this using purely css or do I need javascript in order to do this? and how?
Here's the structure of what I have now:
<div class="product-large" style="position: relative; overflow: hidden;"><img src="/images/store_logos/9ae3d8f75c80d5a48bf59f975e8450c9e8b7a9d9.jpeg" alt=""><img src="/images/store_logos/9ae3d8f75c80d5a48bf59f975e8450c9e8b7a9d9.jpeg" class="zoomImg" style="position: absolute; top: -236.43249427917618px; left: -188.05491990846681px; opacity: 0; width: 1024px; height: 714px; border: none; max-width: none;"></div>
Updated for vertical centering - jQuery required.
HTML
<div class="product-large">
<img src="image1.jpg">
</div>
<div class="product-large">
<img src="image2.jpg">
</div>
CSS
.product-large {
width:500px;
height:500px;
border:1px red solid;
position:relative;
}
.product-large img {
max-width:500px;
max-height:500px;
width:auto;
height:auto;
position:absolute;
top:50%;
left:50%;
}
Javascript (jQuery)
$(".product-large img").each(function () {
//get height and width (unitless) and divide by 2
var hWide = ($(this).width()) / 2; //half the image's width
var hTall = ($(this).height()) / 2; //half the image's height, etc.
// attach negative and pixel for CSS rule
hWide = '-' + hWide + 'px';
hTall = '-' + hTall + 'px';
$(this).addClass("js-fix").css({
"margin-left": hWide,
"margin-top": hTall
});
});
New Fiddle: http://jsfiddle.net/Asvdk/2/
I think you can do:
#conatiner {
line-height:500px;
height:500px;
width:500px;
}
#img {
max-width: 100%;
max-height:100%;
display: block;
margin: 0 auto;
vertical-align: middle;
}
minimal partial example here: http://jsfiddle.net/cahs4/
I didn't do the vertical alignment but you can see what I mean
If you're consider to use jQuery, then you can have a look at the ImgCenter jQuery plugin here.

How to scroll diagonally with jQuery or Javascript

Are there projects or plugins that utilize javascript or jQuery to scroll diagonally?
e.g. when you scroll down your content, It would be pulled at the top-left corner of the browser; and when you scroll up your content would be pulled at the bottom-right of the corner.
I see some similar project/website that they animate their elements when scroll. Most of the site that use javascript has some lags with the effect though. Another i've seen is using html5 + parallax effect similar to "Nike a Better World" (http://coding.smashingmagazine.com/2011/07/12/behind-the-scenes-of-nike-better-world/)
Can you point me where can be a good starting point? Basically I want to scroll the items diagonally left-or-right. If this can be done plainly in HTML5, I would highly consider that since I feel It would have less lag or less calculation being done.
I was able to create the effect that you wanted in a fiddle:
http://jsfiddle.net/t0nyh0/8QTYt/36/
Important Tidbits
A "fixed" full-width and full-height wrapper that holds all your moving elements help you animate the div more consistently based on the scroll position (which is effectively the "keyframe" number).
scroll_max, wrapper_width, and wrapper_height helps normalize the dimensions of wrapper. I.e. the very bottom of the scroll corresponds to the bottom/right of the wrapper, and the very top of the scroll corresponds with the top/left of the wrapper.
Set your body's height to whatever number of "keyframes" that you want.
To move from top left to bottom right on going down, adjust the top and left properties. For the reverse, adjust the bottom and right properties. Of course, you will need to formulate your own calculations for more complex animations, but know that doing $window.scrollTop() will give you the "keyframe" number.
HTML
<div id="wrapper">
<div id="a">
<h1>Meats</h1>
</div>
<div id="b">
<h1>Veggies</h1>
<hr/>
<p>Veggies sunt bona vobis, proinde vos postulo esse magis daikon epazote peanut chickpea bamboo shoot rutabaga maize radish broccoli rabe lotus root kohlrabi napa cabbage courgette mustard squash mung bean.</p>
</div>
</div>​
CSS
body
{
height: 1000px; // 1000 keyframes
}
#wrapper
{
width: 100%;
height: 100%;
position: fixed;
border: 2px solid navy;
overflow:hidden;
}
#a {
position:absolute;
background-color: #daf1d7;
width: 300px;
height: 300px;
}
#b
{
position: absolute;
background-color: #d2d0ee;
width: 200px;
height: 200px;
bottom: 0px;
right: 0px;
}
​
Javscript
var $window = $(window);
var $a = $('#a');
var $b = $('#b');
var scroll_max = document.documentElement.scrollHeight - document.documentElement.clientHeight;
var wrapper_height = $('#wrapper').height();
var wrapper_width = $('#wrapper').width();
$window.scroll(function() {
console.log(scroll_max);
$a.css({
'top': ($window.scrollTop() / scroll_max) * wrapper_height,
'left': ($window.scrollTop() / scroll_max) * wrapper_width
});
$b.css({
'bottom': ($window.scrollTop() / scroll_max) * wrapper_height,
'right': ($window.scrollTop() / scroll_max) * wrapper_width
});
});​
Here's a potential solution for you (jsFiddle example):
jQuery:
$(window).scroll(function() {
console.log($(this).scrollTop());
$('#a').css({
'width': $(this).scrollTop(),
'height': $(this).scrollTop()
});
$('#b').css({
'width': 300-$(this).scrollTop(),
'height': 300-$(this).scrollTop()
});
});
CSS:
#a,#b {
position:fixed;
background: orange;
}
#a{
top:0;
left:0;
}
#b {
bottom:0;
right:0;
width:300px;
height:300px;
}
body {
height:2000px;
}
HTML:
<div id="a"></div>
<div id="b"></div>

How to center align pop up div using Javascript

How to align a pop up division to center of monitor/screen using javascript?
I tried using screen.width and screen.height to get center. But the division gets aligned to center of scrolling page vertically
Thanks in advance for any help and suggestions
Try this:
<div id="popup" class="popup">
This a vertically and horizontally centered popup.
</div>
<a onclick="showPopup('popup');">Show Popup</a>
<style type="text/css">
.popup {
width:200px;
height:100px;
position:absolute;
top:50%;
left:50%;
margin:-50px 0 0 -100px; /* [-(height/2)px 0 0 -(width/2)px] */
display:none;
}
</style>
<script type="text/javascript">
function showPopup(id) {
var popup = document.getElementById(id);
popup.style.display = 'block';
}
</script>
CSS explained:
The div is 200x100, you position it 50% from the top and 50% from the left, but to have it centered fully, you need to substract from that 50% values the half of the width and height, the way to do this is to use negative margins, hence margin-top should be the negative value of the height/2 and margin-left should be the negative value of the width/2.
How about just doing with CSS:
<div class="div">Some Content......</div>
.div {
margin-left: auto;
margin-right: auto;
}
try:
function msgBox(message)
{
var msgbox = document.getElementById("msgbox");
msgbox.innerHTML = message;
var x = (window.innerWidth / 2) - (msgbox.offsetWidth / 2);
var y = (window.offsetHeight / 2) - (msgbox.offsetHeight / 2);
msgbox.style.top = y;
msgbox.style.left = x;
msgbox.style.display = "block";
}
Try fixed-positioning:
#box {
position: fixed;
width: 40%;
margin: 200px 30%;
}
It's only horizontally centered. Vertical will take some playing with. I have no idea how browsers act differently with the vertical alignment.
I also had this vertical centering problem on any webpage that required scrolling.
Switching to position: fixed solved it, so:
position:fixed;
top:50%;
left:50%;
margin:-50px 0 0 -100px; /* [-(height/2)px 0 0 -(width/2)px] */
This worked in firefox, google chrome, safari (pc) and IE9.
Unfortunately, I wanted it to appear in front of an pdf file - the pop up did appear in front using Firefox, Chrome but went behind in IE9 and Safari....

Categories