CSS animation corresponding to page scroll position - javascript

How can an animation be made to correspond with page scroll position, so that when the user scrolls past it the animation goes to position A, and when the user's page scroll position is over it, it goes to position B?
Here is a mock-up of what I would like to make:
(The pivot point of the 3 pages is represented by the blue dot below them.)
I have found various examples of animations that are triggered once by page scrolling (such as AOS or ScrollTrigger), or can be re-triggered multiple times, but I haven't found any examples where the animation progress is connected to the page scroll position.
Maybe it can be done by modifying some existing example, but if not I think I will need to come up with something custom using the CSS animation property and connect it to the page scroll position somehow.
Any ideas how this can be achieved? Thanks.

It is pretty easy if you use jquery with CSS3 to achieve it. You can rotate the page and calculate the rotate value based on the scroll position.
I have made sample example below. Please see the Snippet below:
$(document).ready(function(){
$(document).scroll(function(){
var scollHeight = $(document).height();
var maxRotate = 30;
var rotateVal = 5 + (($(document).scrollTop()* maxRotate) / scollHeight);
$("#page1").css("transform", "rotate("+(-rotateVal)+"deg)");
$("#page3").css("transform", "rotate("+(rotateVal)+"deg)");
});
});
body{
background-color: rgb(252,252,230);
}
.page-container{
position: fixed;
}
.page{
background-color:white;
border:2px solid lightgray;
width:85px;
height:120px;
position:absolute;
top:20px;
left:40px;
transform-origin:bottom center -30px;
transition-duration: 0.3s;
}
#page1{
transform: rotate(-5deg);
}
#page3{
transform: rotate(5deg);
}
.data-container{
position: absolute;
right:30px;
}
.data{
background-image: url("https://i.stack.imgur.com/HwX2l.png");
width:370px;
height:283px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main-container">
<div class="page-container">
<div class="page" id="page1"></div>
<div class="page" id="page2"></div>
<div class="page" id="page3"></div>
</div>
<div class="data-container">
<div class="data" id="data1"></div>
<div class="data" id="data2"></div>
<div class="data" id="data3"></div>
</div>
</div>
You can also test it here

Related

Click on an element to let the elements after it slide forward

I'm practicing and trying to make an instagram page.
Now the layout is all done but i have some problems with javascript.
How do i make the effect like instagram as the gif below?
I make the css display: none, when the element is clicked.
But i'm not sure how to make the elements after it slide forward.
Please refer to the gif below.
I idea was:
When an element is clicked, wrap the elements after it, and then change the wrap css position.
I used jquery wrap(), but it didn't work as i wanted.
for example, the original code is like this
<div class="box">111</div>
<div class="box">222</div>
<div class="box">333</div>
<div class="box">444</div>
<div class="box">555</div>
I used
$(".box").click(function () {
$(this).nextAll().wrap('<div class="wrap"></div>');
});
if i click 222, the result would be
<div class="box">111</div>
<div class="box">222</div>
<div class="wrap">
<div class="box">333</div>
</div>
<div class="wrap">
<div class="box">444</div>
</div>
<div class="wrap">
<div class="box">555</div>
</div>
but i want it to be like this
<div class="box">111</div>
<div class="box">222</div>
<div class="wrap">
<div class="box">333</div>
<div class="box">444</div>
<div class="box">555</div>
</div>
How do i wrap all these element together, instead of giving a wrap to each?
Or is there any better way to make this effect?
I know that a part of your question has already been answered by #charlietfl, so this here is just about the animation. This here is just one way to do it and there are a lot of others to do so.
An example code is available below.
So how does it work?
Apply a wrapper to the box to get a simple element to animate (yes you could also just animate the box with margin and without the wrapper. The wrapper is just for making an easy padding animation.)
If the .close span is clicked, the wrapper is set to the following CSS:
width: 0;
opacity: 0;
padding-left: 0;
padding-right: 0;
Because the wrapper has
transition: 0.5s;
it will slide nicely to the left. (transition applies to width, opacity and padding in this case)
And maybe think about doing something with the z-index (opacity animation is a bit ugly in the front of other elements).
I hope i could help anyone - Have a nice day!
$(".close").click(function(){
var el = $(this).closest(".box_wrapper");
el.css("width", 0);
el.css("opacity", 0);
el.css("padding-left", 0);
el.css("padding-right", 0);
setTimeout(function() {
el.remove();
}, 500);
});
.box_wrapper {
float: left;
transition: 0.5s;
width: 100px;
height: 200px;
padding: 15px;
}
.box {
background-color: lightgrey;
width: 100px;
height: 100%;
padding: 10px;
}
.close {
float: right;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="box_wrapper">
<div class="box"><span class="close">X</span>1</div>
</div>
<div class="box_wrapper">
<div class="box"><span class="close">X</span>2</div>
</div>
<div class="box_wrapper">
<div class="box"><span class="close">X</span>3</div>
</div>
<div class="box_wrapper">
<div class="box"><span class="close">X</span>4</div>
</div>
And yes, this code is not perfect. There are some things to improve like the padding on .box_wrapper & .box, the opacity animation and the js. (can be simplified by a lot)

How to have entire item in Qualtrics remain in position when scrolling?

I am presenting an image embedded in a descriptive text item, followed by several questions about that image. I would like that item to remain in place while the participant scrolls.
I've been able to get the entire image to remain in place using something like this HTML code:
<html>
<style>
.image{position: fixed; background: white;}
</style>
<div class = "image">
<img src="LOCATION OF IMAGE FILE" style="width: 395px; height: 395px;" />
</div>
</html>
But this freezes the image itself in a very awkward place (it actually does this in the editor itself, which blocks me from doing anything else). Is there a way to keep the presentation of the item exactly the same as it is normally, but just keep it in place?
Edit:
This is how it should appear, as a separate item from the questions to follow. I would then like it to remain frozen in place while the user can scroll through the questions.
This shows how it currently appears. The image is frozen in place, but not where it should appear (i.e., above and separated from the questions that follow.
You can use a spacer element to align the starting height of other elements. For example:
<div class = "image">
<img src="LOCATION OF IMAGE FILE" width="395px" height="395px"/>
</div>
<div class = "image_spacer">
This is a spacer element
</div>
<style>
.image{
position: fixed;
background: white;
z-index: 1000;
}
.image_spacer{
height: 395px;
visibility: hidden;
}
</style>
Visually speaking, I may recommend adding a width of 100% to your image div as well, so that other elements are fully covered when you scroll.
To fix at the top on scroll, do the following:
<div class = "image">
<img src="IMAGE LOCATION HERE" width="395px" height="395px"/>
</div>
<div class = "image_spacer">
This is a spacer element
</div>
<style>
.image{
background: white;
width:100%;
z-index: 1000;
text-align:center;
}
.image.fixed{
position: fixed;
top:0;
left:0;
}
.image_spacer{
height: 395px;
visibility: hidden;
display:none;
}
.image_spacer.fixed{
display:block;
}
</style>
In addition, add this to the JavaScript for the question:
Qualtrics.SurveyEngine.addOnload(function()
{
var space = $$('.image')[0].cumulativeOffset().top;
console.log(space);
window.addEventListener("scroll", function(){
if( document.body.scrollTop > space){
$$('.image')[0].addClassName('fixed');
$$('.image_spacer')[0].addClassName('fixed');
}
else{
$$('.image')[0].removeClassName('fixed');
$$('.image_spacer')[0].removeClassName('fixed');
}
});
});
Did you try using the Text/Graphic option?
As I am seeing no problem if I add an image that way, and the survey questions are in their place, check the image below for reference.

JavaScript: Need lower div (under absolute div) NOT to scroll

I have an issue with the layout of my website right now...
The layout is similar to this fiddle I made. Top layer has my project thumbnails, and the lower layer gets exposed to show project details when user clicks a thumbnail.
Problem I am having is that a user has to scroll down to click a thumbnail on the top layer. Then, when the layer fades out, the lower div has already scrolled with it - and I need the div to be scrollTop(0) instead...
Please see my fiddle to understand what I am talking about:
$('#click').on('click', function(){
$('#topPanel').fadeOut(600);
})
#click {
padding:10px 15px;
position:fixed;
z-index:100;
}
#topPanel, #bottomPanel {
width:80%;
height:auto;
margin:0 auto;
padding:100px;
text-align:center;
}
#topPanel {
background:green;
position:absolute;
z-index:10;
}
#bottomPanel {
background:yellow;
position:absolute;
z-index:0;
}
#topPanel p, #bottomPanel p {
padding: 500px 0;
text-transformation:uppercase;
}
#bottomPanel p:nth-child(odd){
background:#555;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="click">CLICK ME TO FADEOUT TOP</button>
<br>
<p>please scroll down and then click button above to see issue</p>
<div id="topPanel">
<p>top of page</p>
<p>middle of page</p>
<p>bottom of page</p>
</div>
<div id="bottomPanel">
<p>top of page</p>
<p>middle of page</p>
<p>bottom of page</p>
</div>
https://jsfiddle.net/reese329/50urkgtm/
The problem is that your panels aren't scrolling: the whole document is scrolling! The trick is to set overflow: hidden on a wrapper element (or the body), and make the panels themselves scrollable with overflow-y: scroll. Here is a working example.
Notice that I had to set the height of the panels explicitly (to 100vh, filling the viewport).
I also fixed your text-transform: uppercase rule (the style is text-transform, not text-transformation :) ).

Correct approach for duplicating html elements for zoom to full-screen

I have a page that looks like this...
<body>
<div id="detailDiv1" style="height 100px; overflow:auto">
</div>
<div id="detailDiv2" style="height 100px; overflow:auto">
</div>
<div id="detailDiv3" style="height 100px; overflow:auto">
</div>
<div id="detailDiv4" style="height 100px; overflow:auto">
</div>
</body>
Each of the detailDivs are loaded dynamically with rows of content (often lots of rows, causing a vertical scroll bar to appear inside the detailDivs). Each row inside each detailDiv contains a small image, some text, and a couple of buttons that increment counts in the DB that are then dynamically updated (ajax) on the row itself.
Since each of these detailDivs is so small, I'm trying to implement a "view as full screen" option but am struggling to come up with an elegant plan...
I know that I'm going to use a bootstrap modal to present the full-screen version of each detailDiv, and I'm guessing I need to duplicate the html from each detailDiv - something like...
$('#myFullScreenModal').html($('#detailDiv1').html());
That will load the content correctly, but of course the elements will have the exact same names (and therefore the interaction with the DB will be interfered with unless I empty the original container first, and reload it when the modal is closed).
But those options sound pretty hacky to me, and so I'm wondering whether there's a more standard way of achieving this effect without having to duplicate large chunks of html.
Thanks for any thoughts.
You could use position: fixed on the div in question then expand it out. That way you don't have to copy anything at all, you're just displaying that exact element as "fullscreen".
$('.go-fullscreen').click(function() {
var $parent = $(this).parent();
if ($parent.hasClass('fullscreen')) {
$parent.removeClass('fullscreen');
} else {
$parent.addClass('fullscreen');
}
});
html, body {
width: 100%;
height: 100%;
}
div {
height: 100px;
overflow: auto;
}
.red { background-color: #F00; }
.green { background-color: #0F0; }
.blue { background-color: #00F; }
div.fullscreen {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="red">
<p>1</p>
<p>2</p>
<p>3</p>
<p>4</p>
<p>5</p>
<p>6</p>
<p>7</p>
<p>8</p>
<button class="go-fullscreen">Fullscreen</button>
</div>
<div class="blue">
<p>10</p>
<p>20</p>
<p>30</p>
<p>40</p>
<p>50</p>
<p>60</p>
<p>70</p>
<p>80</p>
<button class="go-fullscreen">Fullscreen</button>
</div>
<div class="green">
<p>100</p>
<p>200</p>
<p>300</p>
<p>400</p>
<p>500</p>
<p>600</p>
<p>700</p>
<p>800</p>
<button class="go-fullscreen">Fullscreen</button>
</div>
You can do this which will make it enlarge to a size you can configure :)
There is a css part and a jquery part. You could do this for them all. Of course change the scale to the desired size. Maybe not a full page takeover though will do a similar job. Hope you find it useful.
CSS
.transition {
-webkit-transform: scale(1.5);
-moz-transform: scale(1.5);
-o-transform: scale(1.5);
transform: scale(1.5);
}
Jquery
$(function(){
$('.detailDiv1')
.on('mouseover', function() {
$('.detailDiv1').addClass('transition')
})
.on('mouseout', function() {
$('.detailDiv1').removeClass('transition');
});
});

Setting a transform-origin of a CSS3 pseudo 3d object

I am trying to build a "pseudo 3D" CSS3 slideshow to hold the projects for my website.
The code I have for each element is
<div class="projects">
<div class="wrapper">
<section id="widget_sp_image-8" class="widget widget_sp_image">
<h1 class="widget-title">Live Manager</h1>
<div class="widget_sp_image-description">
<p>Lorem ipsum</p>
</div>
</section>
<!-- And so on -->
</div>
</div>
Basically, all each card is set to position: absolute; and I rotate them around 360 degrees width Javascript. I want to rotate it around it itself by 45deg every time an user presses left or right, but I have difficulties setting it's transform origin. I have this as a code:
.projects .wrapper {
width: 470px;
display: block;
margin: 0 auto;
position: relative;
-webkit-transform: translateZ(-700px);
-webkit-transform-style: preserve-3d;
-webkit-transform-origin: 50%;
}
But when the left or right arrows are pressed, the slideshow start rotating awkwardly around its side, so the transform-origin doesn't do the trick.
Here is a link to the codepen project:
http://codepen.io/gbnikolov/pen/qyfzp
2 problem!
first when you translate your wrapper -720px in Z axis, so must translate your origin -720px in Z axis too!
.wrapper {
-webkit-transform-origin: 50% 50% -700px;
}
and second problem is:
wrapper.style.webkitTransform += is wrong! because in every key pressing its value will be duplicated!
currently i fix it, but it's not a good way to rotate it!
see [ THIS ]

Categories

Resources