I am trying to get an effect which is to zoom in on a logo centred on the page when the page is loaded. I am using the following HTML and JS code:
<div style="display: table-cell; vertical-align: middle; text-align: center;">
<img id="logo" src="images/logo2.png" style="zoom: 200%; transition: zoom 1s ease-in-out;"/>
</div>
JS
document.addEventListener("load", pageFullyLoaded, true);
function pageFullyLoaded()
{
var elem = document.getElementById("logo");
elem.style.zoom = "300%";
}
The result is really odd.
It display the logo in it's normal size,
then it jumps on a super zoomed in version of the logo (> 1000%),
zoom in on the logo even more (1000% to 1500% say) for the duration of the transition,
jump back to the normal logo size and position (which is correct, and this is the final positon and size I want).
So obviously this technique doesn't work:
the jump at the beginning is ugly but I only suppose this happens because 2) is incorrect anyway. As it should start by default with a zoom value of 200% (which is defined in the style of the div) and then the JS should make it zoom to 300%. So there should be no jump visible really.
I don't understand why I get this incredibly zoomed in version of the logo at the start of the animation. Basically it's almost like if the entire image was filling up the screen.
Any idea on how to do this reliably, please? Thank you.
I would do this in only CSS like so:
Set the image to scaleX and scaleY 0 (or hide it in some other way)
On $(window).load or $('document').ready add a class with keyframe animations
Do whatever you need afterwards.
Fiddle
$(window).load(function(){
$('img.zoom').addClass('element-animation');
});
You can also listen to animation end events like so https://github.com/daneden/animate.css#usage
That library (Animate.css) is also pretty handy and you might be able to find some useful effects in it.
If you're looking to scale an image, you don't need to use zoom or transform or anything. Just alter the width directly and the browser will scale the image for you:
http://jsfiddle.net/C4JZv/
HTML:
<div class="wrapper">
<img class="tiny" src="http://placehold.it/200x150" />
</div>
CSS:
.wrapper {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.wrapper img {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
transition: width 1s ease-in-out;
width: 200px;
}
.wrapper img.tiny {
width: 10px;
}
JS:
document.querySelector('.wrapper img').className = "";
EDIT: You mentioned in the comments that you wanted to see this done using transform. Again, it's just a case of having a shrunken image (using transform's scale), having a transition property and then removing the CSS class that shrinks the image:
http://jsfiddle.net/C4JZv/1/
HTML & JS: Same
CSS: Mostly the same, but with a couple of changes (plus a load of vendor prefixes):
.wrapper img {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
-webkit-transition: -webkit-transform 1s ease-out;
-moz-transition: -moz-transform 1s ease-out;
-ms-transition: -ms-transform 1s ease-out;
-o-transition: -o-transform 1s ease-out;
transition: transform 1s ease-out;
}
.wrapper img.tiny {
-moz-transform: scale(0.1);
-webkit-transform: scale(0.1);
-o-transform: scale(0.1);
-ms-transform: scale(0.1);
transform: scale(0.1);
}
Related
I am trying to mimic the CSS animations from a website here: https://stanographer.com/
I want to copy the way the site:
starts by showing a full screen black div sliding away to the right
"loads" the black background (div tags) behind text (as in "Hi, I'm Stanley Sakai"), expanding left to right and
"loads" the text over the black background div, expanding left to right.
Now you might ask, "Why not just inspect the page, look at the classes on the divs and text, then inspect the CSS sheet in the network tab?" And I've tried that. The CSS looks weird. My friend said it is pre-processed by SASS, whatever that means. Anyway, I cannot decipher the code.
I've been to a few different StackOverflow pages (here's one) & over a dozen different pages on Google. I learned about using keyframes but I haven't figured out how to recreate the effect on Stanographer.com. My friend, who owns the website, also provided this example, but I don't get how to apply it to individual divs. He said something about using the z-index but I just don't see it.
I know that to make the page start with a full black screen & then slide out, I have to trigger a class change using JavaScript. I have:
let blackStuff = document.getElementById("blackness");
window.addEventListener("load", () => {
console.log("loaded");
blackStuff.setAttribute("class", "black-box-out");
},
false
);
.black-box {
position: fixed;
float: left;
top: 0;
width: 100%;
height: 100%;
bottom: 0;
background-color: #000;
z-index: 999999;
-webkit-animation: powerslide 0.5s forwards;
-webkit-animation-delay: 2s;
animation: powerslide 0.5s forwards;
animation-delay: 2s;
}
#-webkit-keyframes powerslide {
100% {
left: 0;
}
}
#keyframes powerslide {
100% {
left: 0;
}
}
.black-box-out {
margin-left: 100%;
animation: slide 0.5s forwards;
-webkit-transition: slide 0.5s forwards;
transition: slide 0.5s forwards;
}
<div id="blackness" class="black-box"></div>
But this just makes the "blackness" div disappear instantly on page load. I want it to slide out. Clearly, I don't get how to use CSS animations.
If you are interested in seeing more of what doesn't work, read on. Otherwise, you can skip this section: it only shows my failed trials.
I've learned how to make a CSS animation expand horizontally from 0:
.wrapper {
position: relative;
overflow: hidden;
width: 500px;
height: 50px;
border: 1px solid black;
}
.slide-custom {
width: 500px;
height: 50px;
background: cyan;
position: relative;
-webkit-animation: slideIn 2s forwards;
animation: slideIn 2s forwards;
}
/* moz and webkit keyframes excluded for space */
#keyframes slideIn {
0% {
transform: scaleX(0);
}
100% {
transform: scaleX(1);
}
}
<div class="wrapper slide-custom">
<h1 class="slide-custom">
<span>MEET ROLY POLY.</span>
<!-- expands horizontally from 0 width to 100% width -->
</h1>
</div>
And I've learned to make text "slide in" from the left, though it starts at 100% width when I want it to start at 0% width:
/* CSS */
.test-slide {
animation-duration: 3s;
animation-name: testSlide;
}
#keyframes testSlide {
from {
margin-left: 0%;
width: 50%;
}
to {
margin-left: 100%;
width: 100%;
}
}
<div class="test-slide">
<h1><span>ABOUT.</span></h1>
<!-- will slide in from the left -->
</div>
There's more -- unfortunately none of it mimics the website I'm trying to copy.
Explanation
There are multiple ways to achieve what you want actually. I did not opt to animate width. The first few frames of the animation will be not as expected.
So instead, we can use clip-path. What clip-path basically does is masking. You can "crop" a div such that only a part of it is visible. We will utilise clip-path and ::before or ::after pseudo-element (either is fine) to create this animation. What we need to do:
Create the pseudo-element and position it such that it covers (is on top) the whole animatable element (position: absolute)
Set the pseudo-element's background to black
Using clip-path, mask the animatable element to display no parts of the element (this will also cause the pseudo-element to not be displayed as it is part of the element). The direction of the clipping is important. The direction here is from the right side to the left side.
Using animation and #keyframes, unmask the previously masked div. This will reveal it slowly from the left side to the right side (because initially, we masked it from the right to left; upon unmasking, the reverse direction happens)
Upon unmasking the element, the pseudo-element will be on top of the text we want to display
After a short while later, mask the pseudo-element (not the whole element) from the right direction to the left direction, again using clip-path so that the text seems revealed slowly
It works! However, I recommend reading about clip-path. Also, one really handy clip-path CSS generator I really like to use is this (if you want to clip from the right to left, you should drag the points from the right to left). I also highly recommend reading about CSS positioning (a staple in good CSS animations). You needn't be using z-index: 9999; you generally want to keep track of the z-index you use.
Solution
Here's a working solution using the described method. Try running it.
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: Helvetica;
}
body,
html {
width: 100%;
height: 100%;
}
#wrapper {
background: #555555;
width: 100%;
height: 100%;
color: white;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
#wrapper * {
margin: 5px;
}
.heading {
font-size: 3em;
padding: 10px 5px;
}
.caption {
font-size: 1em;
padding: 5px;
font-family: Courier;
}
.animatable {
position: relative;
clip-path: polygon(0 0, 0 0, 0 100%, 0% 100%);
animation: .75s cubic-bezier(1,-0.01,.12,.8) 1s 1 reveal forwards;
}
.animatable::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #20262b;
padding: inherit;
animation: .75s cubic-bezier(1,-0.01,.12,.8) 1.75s 1 hideBlack forwards;
}
#keyframes reveal {
from { clip-path: polygon(0 0, 0 0, 0 100%, 0% 100%); }
to { clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%); }
}
#keyframes hideBlack {
from { clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%); }
to { clip-path: polygon(100% 0, 100% 0, 100% 100%, 100% 100%); }
}
<div id="wrapper">
<div class="heading animatable">Hi, I am Richard!</div>
<div class="caption animatable">I am a person.</div>
</div>
Although the simple animation you wanted can be created using merely CSS, I still suggest you read about how to make animations using JavaScript and the various libraries it has in making animations. This is because once there are many animations and transitions going on, it becomes hard to keep track of animations (especially when you want animations to start after another animation ends). A good library is anime.js (do explore more options before settling on one). Furthermore, notice how the animations only appear upon scrolling down in the website you provided? That's doable only with JS (one such method is using IntersectionObserver API provided by most browsers).
Here you have some CSS3 animations, you trigger that animation when the .entrance-animation gets the .active class.
You'll need an observer to watch when the item gets into view and, when the item is visible, you add the .active class to it.
Hope it helps!
setTimeout(() =>
{
let animate = document.querySelectorAll('.entrance-animation');
animate.forEach(item => item.classList.add('active'));
}
,1000);
.entrance-animation
{
position: relative;
color: blueviolet;
white-space: nowrap;
font-size: 24px;
width: 0;
overflow: hidden;
transition: width 0.5s ease;
}
.entrance-animation::before
{
content: '';
position: absolute;
top: 0;
right: 0;
height: 100%;
width: 100%;
background-color: black;
z-index: 10;
transition: width 0.5s ease;
transition-delay: 0.5s;
}
.entrance-animation.active
{
width: 100%;
}
.entrance-animation.active::before
{
width: 0%;
}
<p class="entrance-animation">
Hello
</p>
<p class = "entrance-animation">
Here we are
</p>
You can use CSS3 transitions or maybe CSS3 animations to slide in an element.
For browser support: http://caniuse.com/
I made two quick examples just to show you how I mean.
CSS transition (on hover)
Demo One
Relevant Code
.wrapper:hover #slide {
transition: 1s;
left: 0;
}
In this case, Im just transitioning the position from left: -100px; to 0; with a 1s. duration. It's also possible to move the element using transform: translate();
CSS animation
Demo Two
#slide {
position: absolute;
left: -100px;
width: 100px;
height: 100px;
background: blue;
-webkit-animation: slide 0.5s forwards;
-webkit-animation-delay: 2s;
animation: slide 0.5s forwards;
animation-delay: 2s;
}
#-webkit-keyframes slide {
100% { left: 0; }
}
#keyframes slide {
100% { left: 0; }
}
Same principle as above (Demo One), but the animation starts automatically after 2s, and in this case I've set animation-fill-mode to forwards, which will persist the end state, keeping the div visible when the animation ends.
Like I said, two quick example to show you how it could be done.
EDIT: For details regarding CSS Animations and Transitions see:
Animations
https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_animations
Transitions
https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_transitions
Hope this helped.
This is an example of the effect I want:
http://photoswipe.com/
The same effect is used for image zooming on WhatsApp web.
I want to zoom elements (not just images) to the center, with an animation scaling element from its position to the center of the page.
The animation should be css based, JS should not be used for animation purposes.
I've tried the following code, which doesn't do the job:
<div></div>
With the css:
div {
width: 100px; height: 100px; background: blue;
transition: transform 1s
}
div:hover {
transform: scale(2);
}
And, what's the difference between animating transform: scale or width/height?
Thanks
EDIT:
Another attempt:
http://jsfiddle.net/4w06Lvms/
I have made something similar to what you want (view in full screen). You can modify it as per needs. Move pointer out of the screen to get back to original state.
Also, animating using scale is better as you might not know the exact height and width in pixels if there are multiple images and using the same scale value gives your code uniformity.
Hope it helps.
html,body{
margin:0;
}
.container{
background:yellow;
display:flex;
width:100vw;
height:100vh;
justify-content:center;
transition: 0.5s ease;
vertical-align:center;
}
.imageHover{
display:flex;
height:300px;
width:200px;
transition: 0.5s ease;
}
img{
position:absolute;
height:300px;
width:200px;
transition: 0.5s ease;
}
.container:hover > .imageHover{
height:100vh;
background-color:black;
width:100vw;
transition: 0.5s ease;
}
.container:hover > .imageHover > img{
transform:translate(240%,50%) scale(1.6);
transition: 0.5s ease;
}
<div class="container">
<div class="imageHover">
<img id="yo" src="https://picsum.photos/200/300
" alt="">
</div>
</div>
You can set the position of the image to fixed, but you will need to know the offset of x and y position of the image, after that start the animation.
In this case the offset x and y are 30px, because I've set parent div padding to 30px.
When the window is scrolled down or right. You have to recalculate the top and left values of the image. For that you'll need JS.
I've set the top and left to the offset values before I've set the position to fixed. Then the image starts moving at the right position.
On photoswipe, they are using a translate3d() function and they are using JS, too. I have no idea what they are doing.
#image {
/* top and left offset */
top: 30px;
left: 30px;
width: 200px;
height: 200px;
transition: top 2s, left 2s, transform 2s;
}
#image:hover {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
#offset {
background-color: beige;
height: 1000px;
/* given offset */
padding: 30px;
}
<div id="offset">
<img id="image" src="https://picsum.photos/200/300
" alt="">
</div>
I am trying to get a container to come down when i click on an item in my menu. The animation downwards works fine. But the moment i click a different item in my menu, it doesnt animate upwards.
Css:
.card{
width: 100%;
background: blue;
transform: translateY(-100px);
opacity: 0;
height:0;
min-height: 0;
transition-timing-function: cubic-bezier(.175,.885,.32,1.275);
transition-property: opacity,transform;
transition-duration: 1s;
}
.card-appeared{
margin-top: 0;
opacity: 1;
transform: translateY(0);
min-height: 300px;
transition-delay: 1s;
height:auto;
width: 100%;
}
Html:
<div id="aboutme" class="container card ">
About me
</div>
<div id="gallery" class="container card card-appeared">
Gallery
</div>
Basic javascript for adding and removing classes
function appear(child){
parent.classList.remove("card-appeared");
let others = document.getElementsByClassName("card-appeared");
for(var i = 0; i < others.length;i++){
others[i].classList.remove("card-appeared");
}
child.classList.add("card-appeared");
}
function dissapear(child) {
child.classList.remove("card-appeared");
parent.classList.add("card-appeared");
}
others is the list of other cards in the page and the parent is the very first container.
If you need any other code, please let me know. I cannot seem to get the upwards animation working but the animation down does work.
Thank you.
Since an explicit height is only specified when the class card-appeared is added, with the property min-height, the expected behaviour cannot be observed when this class is removed again, since the inherit state of the element in question has no explicit height defined. So it just "pops" back up.
To resolve this, consider the below:
.card {
width: 100%;
background: blue;
transform: translateY(-600px); /* adjusted */
opacity: 0;
height: 0;
min-height: 300px; /* added */
transition-timing-function: cubic-bezier(.175, .885, .32, 1.275);
transition-property: opacity, transform;
transition-duration: 1s;
}
.card-appeared {
margin-top: 0;
opacity: 1;
transform: translateY(-300px); /* adjusted */
transition-delay: 1s;
height: auto;
width: 100%;
}
Breakdown: Since static positioning is being used here, elements with y-positioning offsets will still occupy space in the DOM. In order to account for this, the values of the transform: translateY() properties must be adjusted accordingly now that the elements in question always have a minimum height defined.
For Consideration: A better solution to this may be utilizing absolute positioning; this will remove the elements in question from the natural flow of the document, meaning you will not have to account for space occupied in the DOM by these elements, so transform: translateY() property values can remain intuitive.
I am currently developing a HTML game for one of my programming classes and I want to add a "game over" screen that will display an image and information on their score before dying.
What I would like to happen is for the image to overlay the body of the page and start small in the middle of the screen and "expand" or zoom into the screen to a specific size. I'm not sure if that's clear but here is what I'm sort of looking for:
But I would like it to zoom in rather than just appear. Any links or help would be greatly appreciated because I don't even know what to search on google to get information on this!
Thanks in advance for any help!
It's really rough but you can do something like this:
JS
var $foo = $('#foo');
grow = function (size) {
if (size < 50) {
console.log(size);
$foo.css('width', size + '%');
$foo.css('height', size + '%');
size++;
setTimeout(grow, 10, size);
}
}
grow(0);
CSS
#foo {
position: fixed;
right: 0;
left: 0;
top:0;
bottom: 0;
margin-left: auto;
margin-right: auto;
margin-top:auto;
margin-bottom:auto;
width: 0%;
height: 0%;
background-color: red;
}
https://jsfiddle.net/a05s1a44/
Change the timeout length to control the speed. Adjust the CSS as needed. Scale the size variable for the dimensions of your box. Change the limit. Do whatever. Should be enough to get you going.
FIDDLE: https://jsfiddle.net/shfv0b3f/
Using transform: scale and transition:
div {
-webkit-transform: scale(0);
-moz-transform: scale(0);
-o-transform: scale(0);
transform: scale(0);
}
On game over:
div.zoom {
transform: scale(1);
}
This is what I have made for you and I hope it would help.
basically in a container which it may be the window of your game, I have added the "game over" container you want to show.
The rest of the html is just so you see some false content inside game container:
<div class="container">
<div class="stuff">and here is stuff</div>
<div class="stuff">etc, ect, ect</div>
<div class="stuff">more text</div>
<div class="stuff">and more</div>
<div class="button">Click here</div>
<div class="this-is-your-game-over"></div>
</div>
You can see there's also a class called button that I have used as to trigger the "game over" container zoom effect. In your game development you may use something else to do it.
Then, basically, you will have a "game over" container positioned as this:
.this-is-your-game-over {
position:absolute;
height:0px;
width:0px;
background-color:blue;
right:0;
left:0;
bottom:0;
top:0;
margin: auto;
}
so It is always centered and by jquery:
$(document).ready(function () {
$('.button').click(function () {
$('.this-is-your-game-over').toggleClass("this-is-your-game-over-ADDED");
});
});
When you click on button you add another class to the "game over" container that will make it grow to your desire size with a simple transition:
.this-is-your-game-over-ADDED {
height:80%;
width:50%;
-webkit-transition: all 0.5s linear;
-moz-transition: all 0.5s linear;
-ms-transition: all 0.5s linear;
-o-transition: all 0.5s linear;
transition: all 0.5s linear;
}
This is the FIDDLE to see verything in action
important: If in your html the this-is-your-game-over div is not at the end of your html you may need to add a positive z-indexto it.
This is perfect use case for CSS transitions and transforms.
Very basically:
#image {
transition: all 0.5s;
}
#image.hidden {
visibility: hidden;
opacity: 0;
transform: scale(0.5);
}
Then you just toggle the .hidden class somehow, probably by JS.
Also, don't forget to add vendor prefixes (or use Autoprefixer).
See http://codepen.io/anon/pen/waaMvM for better example.
My CSS:
a:hover {
position: relative;
}
a:hover:after {
z-index: -1;
content: url(icon.jpg);
display: block;
position: absolute;
left: 0px;
bottom: 20px;
}
This displays an icon when I hover over an anchor, from this post:
Make image appear on link hover css
I am trying to apply this:
-webkit-transition: all 0.3s ease-in;
-moz-transition: all 0.3s ease-in;
-o-transition: all 0.3s ease-in;
So that the image fades in, but I cant get it to work.
WebKit (Chrome, Safari) does not support transitions on pseudo elements. It should work in Firefox.
see this q/a
To accomplish your need you could apply the background image for the link and in hover you could apply the transition by setting the background-position. You can also use an extra span inside the a tag instead of using :before pseudo class.
You could do a background image.
a {
-webkit-transition: all 0.3s ease-in;
-moz-transition: all 0.3s ease-in;
-o-transition: all 0.3s ease-in;
}
a:hover {
position: relative;
background:url(icon.jpg);
}
The code is just an example, you would need to position the background image as well, since I dont know the dimensions of your design I can't tell you the exact position.
Webkit currently support transitions and animations
http://css-tricks.com/transitions-and-animations-on-css-generated-content/
a:hover {
position: relative;
}
a:after{
-webkit-transition: all 0.3s ease-in;
-moz-transition: all 0.3s ease-in;
-o-transition: all 0.3s ease-in;
transition: all 0.3s ease-in; /*never forget the standard*/
}
a:hover:after {
z-index: -1;
content: url(icon.jpg);
display: block;
position: absolute;
left: 0px;
bottom: 20px;
}
And the example used before:
http://jsfiddle.net/d2KrC/88/
The example using image
http://jsfiddle.net/d2KrC/92/
There are some css "tricks" that can help you, maybe using css keyframes, but the best way to perform this in a compatibility way is using jQuery (a jquery version that matches your compat needs).
As some people asked you on css, where webkit actually support this kind of transitions, and this question could grow if we start talking on standards, the best you can do at first is update all your browsers and check.
If you need or want to keep compat on older browser versions, you'll need to catch the hover event with javascript and then do whatever you want (as javascript can work directly with the DOM) and with CSS is pre-loaded and the most you can do is change the properties. i.e.
load image with display: none, then change this property with an event.
example on jquery:
$('.link').click(function(){
$('.foo').fadeIn();
});
$('.link2').click(function(){
$('.foo2').fadeToggle();
if($('.link2').text() == 'show or hide') $('.link2').text('click again');
else $('.link2').text('show or hide');
});
.foo, .foo2{display: none; width: 100px; height: auto;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>
<img class="foo" src="http://joelbonetr.com/images/root.jpg" alt="">
<a class="link" href="#">show it!</a>
</p>
<p>
<img class="foo2" src="http://joelbonetr.com/images/root.jpg" alt="">
<a class="link2" href="#">show or hide</a>
</p>