background image shaky on div resize - javascript

I want to use HTML to create an "opening" effect of one on top of another one.
After some research i figured out a way (see JSFiddle).
I now have the problem that the background image moves a little bit when the circle is resizing.
Can anyone help me figure out how to get the background image to stand still.
The image in the circle needs to keep same zoom level when opening.
The circle needs to be centered and the bottom half needs to be out of the window.
Circle css is this:
.circle {
width: 0px;
height: 0px;
z-index: 10;
position: absolute;
border-radius: 50%;
overflow: hidden;
margin: 0 auto;
left: 50%;
-moz-transform: translate(-50%, 50%);
-webkit-transform: translate(-50%, 50%);
bottom: 0;
-moz-transition: all 1.5s;
-webkit-transition: all 1.5s;
}
JSFiddle: http://jsfiddle.net/GmvUQ/2/
Update,
Let me explain a little more. i notice that my question is not clear enough.
I have a few screenshot for the effect i want to create:
1st frame:
2nd frame
The entire effect is already working but when the transition is in progress (The circle with the image is getting bigger or smaller) the image inside the circle moves a little bit.
This is probably because of the calculations that need to be done by Javascript / CSS positioning.
I would like some help how to let this image stand entirely still during resize transition.
Thanks!

DEMO: http://jsfiddle.net/GmvUQ/5/
Updated HTML
<div>
<div class="buttons">
<button onclick="changeboleto(0)">Click here</button>
<button onclick="changeboleto(500)">Click here</button>
<button onclick="changeboleto(1000)">Click here</button>
</div>
<div class="circle girl">
</div>
<div class="circle lamborghini">
</div>
</div>
Note that I've removed the nested </div> elements within each .circle. Instead I've added an extra class for each, which sets the background-image (and some positioning for them, if necessary).
Updated CSS
.circle {
width: 250px;
height: 250px;
z-index: 10;
position: absolute;
border-radius: 50%;
overflow: hidden;
margin: 0 auto;
background-repeat: no-repeat;
background-size: cover;
background-origin: content-box;
background-position: center center;
}
.lamborghini {
background-image: url(http://www.hdwallpapers.in/walls/2013_wheelsandmore_lamborghini_aventador-wide.jpg);
}
.girl {
background-image: url(http://www.hdwallpapers.in/walls/colorful_background_girl-normal5.4.jpg);
top: 50%;
}
.buttons {
position: relative;
z-index: 5;
}
I've moved most of the CSS in to the .circle class as it is common to both image sets. Pay special attention to the values for the background-* attributes.
Updated JQuery
function changeboleto(pix) {
circleHeight = pix;
circleWidth = pix;
$('.circle').animate({
'width' : circleWidth,
'height': circleHeight
}, 1500, 'linear');
//css('width', circleWidth).css('height', circleHeight);
changeCircleBackgroundToWindow();
}
function changeCircleBackgroundToWindow() {
windowWidth = $(window).width();
windowHeight = $(window).height();
$(".circle > div").animate({
'width' : windowWidth,
'height': windowHeight
}, 1500, 'linear');
$(".circle > div").animate({
'width' : windowWidth,
'height': windowHeight
}, 1500, 'linear');
//$(".circle-background").css("width", windowWidth).css("height", windowHeight);
//$(".circle-background2").css("width", windowWidth).css("height", windowHeight);
}
Rather than mix JQuery and CSS transitions I've lumped all the animation together in the JQuery.
I've used the animate() function and specified the easing method. The default easing is swing but I've used linear as this progresses the animation at a constant pace.
Edit
The solution above includes CSS that allows the image to scale with the animation. However you are requesting that the image stays at the same "zoom level" throughout.
To achieve this simply remove a line from the CSS, namely this one:
.circle {
...
background-size: cover;
...
}

I know this is 5 years too late, but I found this thread via a search engine and thought I'd provide my own thoughts.
This effect can also be achieved with clip-path, which is a bit more forgiving than jquery's animate (which can still result in image shakiness if you're animating certain/enough properties).
clip-path has the additional benefit of not needing javascript at all if you're doing, say, hovers rather than button clicks. It also results in a simpler HTML file.
I've made an updated version of the original question's jsfiddle, http://jsfiddle.net/GmvUQ/13/ which demonstrates doing this with clip-path. It's still using jquery to handle the button clicks, but the "magic" all happens via CSS transitions, rather than javascript animations.
JQuery:
function changeboleto(pix) {
...
$('.circle-background').css('clip-path', 'circle(' + pix/2 + 'px at 50% 100%)');
}
CSS (including original CSS from original fiddle):
.circle-background {
position: absolute;
z-index: 10;
clip-path: circle(0% at 50% 100%);
background:url(http://www.hdwallpapers.in/walls/colorful_background_girl-normal5.4.jpg);
background-size: cover;
-webkit-transition: all 1.5s;
-moz-transition: all 1.5s;
bottom: 0%;
left: 50%;
-moz-transform: translateX(-50%);
-webkit-transform: translateX(-50%);
}
What this does is simply cause the CSS to transition on the clip-path property, animating the circle expansion. Because the image itself never moves, just the boundaries between which it displays, it never shakes.

Full screen demo
JSFiddle: http://jsfiddle.net/7bP7Z/4/ (Click around to see things grow)
Okay, so now that the question has more clarification I have revisited the drawing board and have come up with a better solution.
HTML
<div class="circle">
<div class="circle-overlay"></div>
<img src="http://www.hdwallpapers.in/walls/2013_wheelsandmore_lamborghini_aventador-wide.jpg" />
</div>
<div class="circle">
<div class="circle-overlay"></div>
<img src="http://www.hdwallpapers.in/walls/colorful_background_girl-normal5.4.jpg" />
</div>
Note the changes to the structure:
A containing element
An "overlay" element
An </img>
CSS
.circle {
position: relative;
overflow: hidden;
}
.circle-overlay {
position: absolute;
left: 50%;
margin-left: -150px;
bottom: -150px;
border-radius: 50%;
width: 300px;
height: 300px;
box-shadow: 0px 0px 0px 3000px white;
}
Nice and simple CSS!
The majority of the code is used to position our .circle-overlay class. This class provides a transparent circle (using border-radius) and utilises one of my favourite new CSS features - box-shadow - to apply a solid, white "outline" of an arbitrarily large value that covers the image below it. Have a play with the colour and size (adjust the 300px value) of the box-shadow to see how this works.
JQuery
$('.circle').click(function() {
var c = $(this).children('.circle-overlay');
var w = c.width() + 100;
c.animate({
'width' : w,
'height': w,
'bottom': (w*-0.5),
'margin-left': (w*-0.5)
}, 500, 'linear');
});
Once again, keeping things nice and simple!
The above JQuery performs a very simple task. It increases the size of the circle-overlay whilst maintaining its bottom, centre positioning on every click.
This should be a very smooth animation and the image should not "judder" or "shake" as the image is not being manipulated.

Related

Background color changing it's height onload

I've been reading for couple hours from now, and probably I have problem even with asking right question.
What I would like to achieve is: changing the main page background height from 0 to 100% in let's say 10s, so after 1 second background color got 10% page height, after 2 seconds 20% of page height and so on. It should start to change after page load.
It could be jquery, css, or some external library, just want it to work.
Something like this?
body {
width: 100vw;
height: 100vh;
position: relative;
&::before {
content: "";
display: block;
position: fixed;
width: 100%;
background: red;
height: 0;
z-index: 0;
animation-fill-mode: forwards;
animation-name: expand;
animation-duration: 10s;
}
}
#keyframes expand {
from { height: 0; }
to { height: 100%; }
}
So basically, you add another layer underneath your content, which animates to the height of your page for 10s (the animation-duration)
Working JSFiddle: https://jsfiddle.net/y4kpcmjc/2/
From the official jquery docs
The .animate() method allows us to create animation effects on any numeric CSS property. The only required parameter is a plain object of CSS properties. This object is similar to the one that can be sent to the .css() method, except that the range of properties is more restrictive.
Here is the example
<img id="image" src="..." />
...
<script>
$(document).ready(function() {
$('#image').css('height', '0');
$('#image').animate({
height: "100%"
}, 10000, function() {
//Finished loading
});
})
</script>

Shared element transition using ReactJS

In Android, shared element transition allows 2 exact same elements existing in both pages to link together when transitioning pages, just like the album art in the gif shown below:
I wonder if it is possible to achieve the same kind of transition with ReactJS between classes. If so, any examples? If not, what about with jQuery?
You can do this transition almost entirely with the CSS transform property. React JS is all about manipulating the DOM, but you don't need to do that here much.
The animation:
Hides the text content of the small panel.
Scales the picture and text background to fill full screen.
Puts in the new text content.
Of those 1 and 3 are easy with React, so you only really need the transition animation.
Here is a very very basic example using no JS at all:
body {
background-color: #ccc;
}
.card {
width: 150px;
padding: 0;
margin: 0;
background-color: #fff;
position: absolute;
top: 0: left: 0;
z-index: 1;
/* Transition properties mean changes to them are animated */
transition-property: transform;
transition-timing-function: ease-in-out;
transition-duration: 500ms;
transform-origin: top left;
}
.card>img {
width: 150px;
height: 150px;
margin: 0;
padding: 0;
}
.card>.content {
width: 150px;
height: 50px;
background-color: #fff;
margin: 0;
}
/* This is only for the purposes of this demo.
* In production you'd have an underlying grid layout and JS to figure out the position */
.card:nth-of-type(2) {
left: 175px;
}
.card:nth-of-type(3) {
top: 230px;
}
.card:nth-of-type(4) {
top: 230px;
left: 175px;
}
/* On hover transform the card to full size and translate it to the top left
* Note that translate comes before scale. */
.card:nth-of-type(1):hover {
transform: scale(2.1667);
z-index: 2;
}
.card:nth-of-type(2):hover {
transform: translate(-175px, 0) scale(2.1667);
z-index: 2;
}
.card:nth-of-type(3):hover {
transform: translate(0, -230px) scale(2.1667);
z-index: 2;
}
.card:nth-of-type(4):hover {
transform: translate(-175px, -230px) scale(2.1667);
z-index: 2;
}
<div class="card">
<img src="http://via.placeholder.com/325/F50057/ffffff">
<div class="content"></div>
</div>
<div class="card">
<img src="http://via.placeholder.com/325/F44336/ffffff">
<div class="content"></div>
</div>
<div class="card">
<img src="http://via.placeholder.com/325/1DE9B6/000000">
<div class="content"></div>
</div>
<div class="card">
<img src="http://via.placeholder.com/325/FFEB3B/000000">
<div class="content"></div>
</div>
The basic trick is to use CSS transform with translate and scale - these properties can be handled by the graphics card and so keep animations smooth even on mobile.
Note that the CSS is rather clunky - I've done it like that just to show that it can be done with pure CSS. In practice you're going to want some JS to set the offset properties, hook up a click event, etc.
Another trick (which I haven't done here) is to scale the animation backwards - start with the full size control and translate/scale it down into the position it appears to start in. When the user clicks on it remove the transform - that saves the browser from having to recalculate the full sized object's DOM before starting the animation.
I am not sure if I understand the question correctly because I am unaware of Android framework. Here is my solution based upon ReactJS knowledge:
Steps:
Maintain 2 state variables: CurrentMode & NextMode. Possible values are 1 & 2.
At the click of album change the NextMode to 2. And in code compare the values of CurrentMode & NextMode. If CurrentMode < NextMode than set the size accordingly.
Similarly when CurrentMode > NextMode than set the size accordingly.
You can do this with mauerwerk: https://github.com/drcmda/mauerwerk
It's basically a grid where each cell gets a status whether it's in thumbnail or opened mode. You can use this status to switch or transition between contents, whether you want to fade them or let parts stand is up to you. There's an additional toggle function which you can use to toggle a cell open/closed.

parallax scrolling is a bit jumpy

I've a small bit of parallax on a site I'm working on, it's working almost fine but the foreground divs are a bit jumpy when I scroll down the page.
Near the top of the page I have a div called #top-banner, it has a fixed background image, sitting within this div are two more within a row, the fisrt div / column has an image of a model & the second div has just text.
Below the #top-banner div is a div with a background image of a waterline, the desired effext is to have the waterline to cover the #top-banner as the user scrolls down, to make it seem as if the model, text & background are being covered by water.
I've got it working by using jQuery to change the css bottom property to make it seem that the two columns divs are moving down the page beneath the waterline at a similar speed to the scroll when the user scrolls down the page. I've set the speeds/increments to be slightly different to create a parallax effect.
It's working pretty well but is a bit jumpy, I've also tried to use the jQuery animate function but that is even more jumpy.
HTML
<section id="top-banner">
<div class="row">
<div class="col-2 prlx-1">
<img src="model.png"/>
</div>
<div class="r-col-2 prlx-2">
<h3>Lorem Ipsum</h1>
<p>More Ipsum</p>
</div>
</section>
<section id="hp-water-line"></section>
CSS
#hp-top-banner {
background: url(bg.png);
height: 600px;
background-attachment: fixed;
background-origin: initial;
background-clip: initial;
background-size: cover;
overflow: hidden;
width: 100%;
position: relative;
}
#hp-water-line {
background: url(water-line.png) no-repeat transparent;
min-height: 92px;
margin: 0 auto;
width: 100%;
position: relative;
top: -15px;
background-size: cover;
}
JS
$(document).ready(function(){
function parallax(){
var prlx_effect_1= -((window.pageYOffset / 4) *2.25 );
$('.prlx-1').css({"position": "relative","bottom":prlx_effect_1, "transition": "0s ease-in-out"});
// jQ('.prlx-1').css({"position": "relative"});
// jQ('.prlx-1').animate({"bottom":prlx_effect_1},"fast");
var prlx_effect_2= -(window.pageYOffset / 5 );
$('.prlx-2').css({"position": "relative","bottom":prlx_effect_2, "transition": "0s ease-in-out"});
}
window.addEventListener("scroll", parallax, false);
});
Updated JS based on Prinzhorn Comment
var requestAnimationFrame = window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame;
function onScroll() {
requestAnimationFrame(parallax);
}
function parallax(){
var prlx_effect_1= +(window.pageYOffset *.7).toFixed(2); // .55 is a good speed but slow
var prlx_str_1 = "translate3d(0, "+prlx_effect_1+"px, 0)";
jQ('.prlx-1').css({
"transform":prlx_str_1,
"-ms-transform":prlx_str_1,
"-webkit-transform":prlx_str_1
});
var prlx_effect_2= +(window.pageYOffset * 1 ).toFixed(2); // .33 is a good speed but slow
var prlx_str_2 = "translate3d(0, "+prlx_effect_2+"px, 0)";
jQ('.prlx-2').css({
"transform":prlx_str_2,
"-ms-transform":prlx_str_2,
"-webkit-transform":prlx_str_2
});
requestAnimationFrame(parallax);
}
window.addEventListener("scroll", onScroll, false);
I used to build parallax sites in a similar way,by using jquery to adjust the background-position or margins, however, i read this article a few months back which really changed the way I approach them.
He suggest using CSS translateZ and perspective to move containers or imagery forward and backwards into the 3 dimensional space to create 'real' parralax. This creates more fluid animations, and also renders better on mobile devices. I also personally find this much easier to execute.
I.E.
.parallax {
perspective: 1px;
height: 100vh;
overflow-x: hidden;
overflow-y: auto;
}
.parallax__layer {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.parallax__layer--base {
transform: translateZ(0);
}
.parallax__layer--back {
transform: translateZ(-1px);
}
The only issue is, that using real 3Dimensional layers, means you have to be smart with your Z-Index to make sure your layers are not overlapping at the wrong places.
The article has an excellent demo, which you can view the side profile of the 3D space to see how the layers are distributed in the z-axis. Just click the 'debug' button in the top left corner.
http://keithclark.co.uk/articles/pure-css-parallax-websites/

Lightbox like overlay effect to display a hidden DIV on click

I'm working on web page and when I'm browsing for inspiration i cam across with this site, which uses a which uses overlay effect to display and hidden DIV on click, I like to use this type of effect on my site also.
any idea how to do will be highly appreciated.
this link will take you to the relevant web site.
The site i came across.
You could do it like that:
In the HTML-code:
<div class="overlay">
[whatever you want to display in the overlay DIV]
</div>
In the CSS-Code:
div.overlay {
width: 650px;
height: 400px;
position: fixed;
left: calc(50% - 340px);
top: calc(50% - 230px);
-moz-border-radius: 15px;
border-radius: 15px;
z-index: 999;
-webkit-transition: opacity 1.5s;
transition: opacity 1.5s;
opacity: 0;
}
All other design things (such as font-family, color etc) go in that, too.
Code-Explanation
width: 650px - The boxes width
height: 400px - The boxes height
position: fixed - it doesn't scroll
left: calc(50% - 340px) - It's located in the middle
top: calc(50% - 230px) - It's located in the middle
border-radius: 15px - Make it round-rect
z-index: 999 - It's on top every time (Make sure others have lower z-indexes).
transition: opacity 1.5s - Makes it fading in
opacity: 0 - Makes it invisible
So, for now the box is completely invisible. You can make it visible using javascript:
function open() {
document.getElementById("overlay").style.visibility = "visible";
document.getElementById("overlay").style.opacity = 1;
}
function close() {
document.getElementById("overlay").style.opacity = 1;
document.getElementById("overlay").style.visibility = "visible";
}
The Last step you'll have to do is calling the function in your HTML:
Open
and in your Box a Link to close:
Close
Another possible way, in my opinion the user-friendlier way, is to make another with the class background. That gets onClick="close". The code can look like this:
HTML
<div class="background" onClick="close()"></div>
CSS
div.dark {
position:fixed;
height: 100%;
width: 100%;
background-color: rgba(0, 0, 0, 0.5);
-webkit-transition: opacity 0.8s;
transition: opacity 0.8s;
opacity: 0;
}
Then you have to add the following in the open() function:
document.getElementById("background").style.visibility = "visible";
document.getElementById("background").style.opacity = 1;
And in the close() Function:
document.getElementById("background").style.opacity = 0;
document.getElementById("background").style.visibility = "hidden";
If you do it like that, when the visitor clicks anywhere on the page, except on the overlay, it'll fade out. The background also makes the page a bit darker while the overlay is open, so the visitor will concentrate on the overlay box. If you don't want to make the page darker, change
background-color: rgba(0, 0, 0, 0.5);
to
background-color: rgba(0, 0, 0, 0);
I wish you good luck with your web-page and I hope I was able to help you!

CSS or JavaScript to highlight certain area of image opacity

I'm looking to do something like this but with CSS or JavaScript.
I need to highlight a certain part of an image but everything I find is how to do it in Photoshop. Can I do this with CSS or maybe JavaScript?
Am I even asking the right question?
EDIT:
Well here is a great submission but I have a follow up question:
I need this for a mobile device and portrait and landscape views as well for many devices like: iOS, iPad, Android, WebOS, Etc... So the fixed position I'm not sure will work.
Any advice?
You could use background-position with absolutely positioned divs as follows:
CSS:
.container {
position:relative;
height:455px;
width:606px;
}
.container div {
position:absolute;
background-image:url(http://www.beachphotos.cn/wp-content/uploads/2010/07/indoensianbeach.jpg);
}
.container .bg-image {
opacity:0.3;
height:455px;
width:606px;
}
.container div.highlight-region {
height:50px;
width:50px;
opacity:0;
}
.container div.highlight-region:hover {
opacity:1;
}
HTML:
<div class="container">
<div class="bg-image"></div>
<div class="highlight-region" style="top:50px;left:50px;background-position: -50px -50px;"></div>
<div class="highlight-region" style="top:150px;left:150px;background-position: -150px -150px;"></div>
</div>
Please see http://jsfiddle.net/MT4T7/ for an example
Credit to beachphotos.com for using their image.
EDIT (response to OP comment): Please also see http://jsfiddle.net/zLazD/ I turned off the hover aspect. also added some borders.
CSS changes:
.container div.highlight-region {
height:50px;
width:50px;
border: 3px solid white;
}
/* removed :hover section */
You can probably fake it, here is a sample:
http://jsfiddle.net/erick/JMBFS/3/
I covered the image with an opaque element. The color of the element is the same as the background of the image. Used z-index to put it on top.
You sure can. For example, most crop plugins provide "highlighting" as the basis of their UI. So for a complete cross-browser solution, just use an existing plugin, like Jcrop.
Of course, you might want it to be fixed, in which case you can programmatically tell the plugin which section to highlight and that the user shouldn't be able to move it, and then it will act as a highlighter, not a cropper.
These are the steps you can take to highlight a part of an image:
Access the image in JavaScript, and dynamically add another identical image immediately after it. (this could be done just in HTML, but it would change the semantics of your markup)
Position the second image over the first image
Apply a css mask on the second image so that only the "highlighted" part shows up
When the user hovers over the images' container, adjust the opacity of the first image.
I can provide more technical details on this later if need be.
What about overlaying the cropped image (with 100% opacity) on top of the whole image (with 30% opacity)?
This answer is only a proof of concept
body {
margin: 0 0 0 0;
padding: 0 0 0 0;
}
.img {
position: absolute;
top: 0;
left: 0;
}
.img-base {
opacity: 0.3;
z-index: -99;
}
.img-overlay {
opacity: 1.0;
}
.cropper{
width: 150px; /* input width and height of the box here */
height: 120px;
overflow: hidden;
position: relative;
padding: 0 0 0 0;
margin: 0 0 0 0;
left: 90px; top: 170px; /* input starting location of the box here */
}
#overlay1 {
position: absolute;
left: 0px; right: 0px;
margin-left: -90px; margin-top: -170px; /* input starting location of the box here */
}
<img src="https://images.unsplash.com/photo-1583355862089-81e9e6e50f7a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=334&q=80" class="img img-base">
<div class="cropper">
<img src="https://images.unsplash.com/photo-1583355862089-81e9e6e50f7a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=334&q=80" class="img img-overlay" id="overlay1">
</div>

Categories

Resources