Slight problem with pixels and browser with my jQuery effect - javascript

In order to highlight a certain p element, I've written some JS to make it appear above a darkened background.
In order to do this, I used jQuery to create an overlay, and then clone the information p element and absolutely positioned it over the overlay.
Because it dropped a few CSS properties (not being inherited because of the new position in the page), I used jQuery to add them.
It works almost perfectly. In my Firefox 3.5.6 on Mac OS X, when it fades away, there is a slight disrepencacy of a matter of pixels. I know it's nitpicking, but I'd love to have it disappear and the end user not know the difference.
The test is available here: https://www.ikatanspa.com/book-online/?test
Here is the jQuery function too
var highlightFormSuccess = function() {
var fadeTo = 0.6;
var $info = $('p.information');
if ($info.length) {
// make overlay
var $overlay = $('<div />')
.css({
display: 'none',
width: '100%',
height: $(document).height(),
position: 'absolute',
top: 0,
left: 0,
zIndex: 32767,
opacity: 0
})
.attr({
id: 'overlay'
})
.appendTo('body');
// pull out success block and position above overlay
var left = $info.position().left,
top = $info.position().top,
fontSize = $info.css('font-size'),
width = $info.width(),
color = $info.css('color'),
lineHeight = $info.css('line-height');
var $newInfo = $info.clone()
.css({
position: 'absolute',
top: top,
left: left,
'font-size': fontSize,
'line-height': lineHeight,
width: width,
color: color,
zIndex: 32767
})
.appendTo('body');
$overlay
.show()
.fadeTo(1000, fadeTo);
// wait then fade back out
setTimeout(function() {
$($overlay, $newInfo).fadeOut(1000, function() {
$newInfo.fadeOut(250, function() { $(this).remove(); } );
});
}, 2500);
};
};

Perhaps you can make things a bit easier. I just replicated the desired effect by setting my paragraph rules to:
p.highlight {
position:relative;
background-color:#ffffff;
z-index:10;
}
And my overlay to:
div.overlay {
position:fixed;
background-color:#000000;
z-index:5; // lower than my paragraph, higher than all else
top:0; left:0; width:100%; height:100%;
}
--
<body>
<div class="overlay"></div>
<p>I'm a paragraph.</p>
<p class="highlight">I too am a paragraph.</p>
</body>

Related

Sticky element inside a div with absolute position on scroll

I have a div with position: absolute and overflow: auto. Inside this div I have a div that should act sticky and should be fixed(top: 0, bottom: 0, overflow: auto) when I scroll.
I can fix this div, but I can't return it to original position because I can't attached the scroll event when this div is fixed.
$('.right').scroll(function() {
if ($('.scroll').offset().top <= 0) {
$('.scroll').css({
'position': 'fixed',
'top': 0,
'left': '20px',
'right': '0',
'overflow': 'auto'
})
}
})
Please check my JSFiddle for more info - JSFIDDLE
Thank you.
Here's how I would do it. This doesn't position it fixed but it has the same appearance. Once scrollTop is equal to or greater than where the top of the fixed content "should be" then we set the top absolutely to that of scrollTop, if you scroll upwards once the scrollTop reaches the point where the fixed content used to be, it will drop it again.
$(document).ready(function() {
oldOffset = $('.scroll').offset().top;
$('.right').scroll(function() {
if ($('.right').scrollTop() > oldOffset) {
$('.scroll').css({
'position': 'absolute',
'top': $('.right').scrollTop(),
'left': '20px',
'right': '0',
'overflow': 'auto'
});
}
});
});
(Demo)
Set the outside div to
position: relative;
Set the inside div to
position: absolute;
top: 15px;
right: 15px;
This will put the top right corner of the inside div at the designated location within the parent container. When setting position absolute, the image is set relative to the first parent container with position defined to anything other than default, I believe. If there is no DOM element assigned a position, the absolute element will be positioned relative to the viewport.
It is very strange task you want to accomplish :)
But anyway there is the problem:
When you set you inner div to position: fixed you positioned this div above your div.right and it is prevents scrolling event from fire.
So what you need is to set pointer-events: none to the div.scroll to allow your div.right listen scroll events without any problems.
But when you do that you will face another problem - when you set your div.scroll to position: fixed it will lose its place inside the div.right and div.right jumps to the top of the scroll automatically. To prevent that you need to create clone of the div.scroll and set his height to 0 initially, and to auto when your inner element is fixed.
Note pointer-events: none - disable all mouse events including the text selection.
There is the code:
JS
$(document).ready(function() {
var cnt = $('.right');
var scrollEl = $('.scroll');
var scrollClone = scrollEl.clone().addClass('clone');
scrollEl.before(scrollClone);
cnt.scroll(function() {
var expression = scrollClone.offset().top <= 0;
scrollEl.toggleClass('stick', expression);
scrollClone.toggleClass('stick-clone', expression);
})
})
CSS
.scroll {
background: yellow;
pointer-events: none;
overflow: hidden; /* Remove top offset from h1*/
}
.scroll.stick {
position: fixed;
left: 20px;
right: 0;
top: 0;
}
.scroll.clone {
height: 0;
overflow: hidden;
}
.scroll.clone.stick-clone {
height: auto;
}
JSFiddle
You can try the following example:
Firstly, instead of adding the css as inline styles, create a css class that you can add and remove from the .scroll element.
CSS
.fixed-top {
position:fixed;
top:0;
left:20px;
right:20px;
}
Wrap your .scroll element with another div which will be used in the javascript to keep track of the original height of your .scroll div.
HTML
<div class="scroll-wrapper">
<div class="scroll"></div>
</div>
Lastly, store the scrollTop value in a variable when the fixed position is applied for the first time. You can then use that value to determine when to remove the fixed styles from the .scroll div. Also set the height of the .scroll-wrapper element equal to the height of your .scroll element to make sure the content is scrollable.
Javascript
var startScrollTop = 0;
$('.right').scroll(function () {
var $scroll = $('.scroll');
if ($scroll.offset().top <= 0 && $('.right').scrollTop() > startScrollTop) {
if (startScrollTop === 0) {
startScrollTop = $('.right').scrollTop();
}
$('.scroll-wrapper').css("height", $('.scroll').height() + 300);
$scroll.addClass("fixed-top");
} else {
$scroll.removeClass("fixed-top");
}
})
Take a look at this fiddle.
http://jsfiddle.net/a924dcge/25/
Hope that helps!

The Google card's "Flip and Grow" effect

I have been doing some research on how to create a flip and grow effect like Google card does (click on any card):
http://www.google.com/landing/now/#cards/restaurant-reservations
All resources I found is about flipping a card with front and back of same size but this is not what I'm looking for.
Any feedback will be hugely appreciated.
Both of the answers posted here are good generic css flippers but they don't address the core of the question which is "how does Google do it?". The problem is that google minifies and therefore obfuscates their code which makes it tough to tell exactly whats going on but using a DOM inspector you can get a pretty basic idea. This is the abstract:
Build a "clone" div that contains a front and a back child div but is hidden by default. Set it's css transition property to ~.5seconds so that any move it makes will be animated.
When a user clicks on a card in the grid, set the clone so it's the same position/dimensions as the clicked card, copy the contents of the clicked card into the front child element and set it as visible
Hide the original clicked card with visibility:hidden
At this point you now have a clone of the originally clicked card in the exact same place but no one can tell
Set css for top, left, height, width of the clone div to precalculated dimensions centering in the screen while also setting transform:rotateY() of the front/back children
At this point it appears as if the div is lifting up, flipping around, and moving/resizing to the center of the screen. An empty spot is left behind because the original card is still there, but visibility:hidden allows it to take up space without showing its contents
A click handler is set up so that when the user clicks outside of the clone card, the top,left,height,width,transform:rotateY() css is reset back to the original values which make it fly back in place.
Then the clone is hidden again and the original card is made visible
Demo: http://jsfiddle.net/jwhazel/AaU6v/11/
(Developed in Chrome, may need some vendor prefixes for other browsers)
HTML
<div class="cards">Generic Tile Card</div>
<div id="cardClone">
<div id="cloneFront">cardclone front</div>
<div id="cloneBack">cardclone back</div>
</div>
CSS
body {
position: relative;
font-family:Helvetica, Arial, Sans-serif;
text-align:center;
}
.cards {
margin:30px;
width:200px;
height:200px;
background-color:#59A3FF;
cursor:pointer;
display:inline-block;
overflow:hidden;
}
img {
display:block;
width:80%;
height:auto;
margin:0 auto
}
#cardClone {
position:fixed;
display:none;
margin:30px;
width:200px;
height:200px;
-webkit-transition:.6s;
transition:.6s;
-webkit-transform-style::preserve-3d;
transform-style:preserve-3d;
z-index:99;
perspective: 1000px;
-webkit-perspective: 1000px;
}
#cloneFront, #cloneBack {
backface-visibility: hidden;
width:100%;
height:100%;
position:absolute;
-webkit-transition:.6s;
transition:.6s;
overflow:hidden;
}
#cloneFront {
z-index:100;
background-color:#59A3FF;
transform: translatez(0);
}
#cloneBack {
transform:rotateY(-180deg);
z-index:101;
background-color:#aaa;
}
Javascript
//Cache the clone since we have to select it a couple of times
$clone = $('#cardClone');
//Set a global for the card we just clicked so we can track it
$lastelement = "";
//Set up an object for last clicked element so we know where to return to on collapse
lastelement = {
'top': 0,
'left': 0,
'width': 0,
'height': 0
};
//Set a flag to determine the current flip state of our clone
cloneflipped = false;
//Bind a handler to the clone so we can detect when the transition is done
$('#cardClone').on("transitionend", function (e) {
if (e.target === e.currentTarget) {
if (e.originalEvent.propertyName == 'top') {
//Toggle the clone state
cloneflipped = !cloneflipped;
//Detect if our clone has returned to the original position and then hide it
if (!cloneflipped) {
$($lastelement).css('opacity', 1);
$($clone).hide();
} else {
//Need to dynamically alter contents of the clone rear AFTER it animates? Do it here
//$('#cloneBack').html('hi');
}
}
}
});
$(".cards").click(function () {
if (!cloneflipped) {
//Cache clicked card
$lastelement = $(this);
//Store position of this element for the return trip
//[hack: subtract 30 due to the margin of .cards in this demo]
var offset = $lastelement.offset();
lastelement.top = offset.top - 30 - $(document).scrollTop();
lastelement.left = offset.left - 30;
lastelement.width = $lastelement.width();
lastelement.height = $lastelement.height();
//BONUS: lets check to see if the clicked card is further to the left or the right of the screen
//This way we can make the animation rotate inwards toward the center, google doesn't do this
var rotatefront = "rotateY(180deg)";
var rotateback = "rotateY(0deg)";
if ((lastelement.left + lastelement.width / 2) > $(window).width() / 2) {
rotatefront = "rotateY(-180deg)";
rotateback = "rotateY(-360deg)";
}
//Copy contents of the clicked card into the clones front card
$clone.find('#cloneFront').html($lastelement.html());
//Show the clone on top of the clicked card and hide the clicked card
//[hack: using opacity for hiding here, visibility:hidden has a weird lag in win chrome]
$clone.css({
'display': 'block',
'top': lastelement.top,
'left': lastelement.left
});
$lastelement.css('opacity', 0);
//Need to dynamically alter contents of the clone rear BEFORE it animates? Do it here
//$('#cloneBack').html('hi');
//Flip the card while centering it in the screen
//[hack: we have to wait for the clone to finish drawing before calling the transform so we put it in a 100 millisecond settimeout callback]
setTimeout(function () {
$clone.css({
'top': '40px',
'left': '40px',
'height': '400px',
'width': $(document).width() - 140 + 'px'
});
$clone.find('#cloneFront').css({
'transform': rotatefront
});
$clone.find('#cloneBack').css({
'transform': rotateback
});
}, 100);
} else {
$('body').click();
}
});
//If user clicks outside of the flipped card, return to default state
$('body').click(function (e) {
if (cloneflipped) {
if (e.target === e.currentTarget) {
//Reverse the animation
$clone.css({
'top': lastelement.top + 'px',
'left': lastelement.left + 'px',
'height': lastelement.height + 'px',
'width': lastelement.width + 'px'
});
$clone.find('#cloneFront').css({
'transform': 'rotateY(0deg)'
});
$clone.find('#cloneBack').css({
'transform': 'rotateY(-180deg)'
});
}
}
});
your code is here ! clickFLIPgrove
You can scale size of a div by css property called
transform:scale(2,2);
it will double the size of your element
refer this link for all css effects: cssAnimation
I have created flip effect on hover:
hoverFLIP
html
<div class="cards"></div>
css
body{
position: relative;
}
.cards{
margin:30px;
perspective: 500;
-webkit-perspective: 500;
-moz-perspective: 500;
-ms-perspective: 500;
-o-perspective: 500;
width:200px;
height:200px;
background-color:#59A3FF;
transform-style:preserve-3d;
-webkit-transform-style:preserve-3d;
-moz-transform-style:preserve-3d;
-o-transform-style:preserve-3d;
position:absolute;
cursor:pointer;
/* Animate the transitions */
-webkit-transition:0.8s; text-align:center;
-moz-transition:0.8s; text-align:center;
-ms-transition:0.8s; text-align:center;
-o-transition:0.8s; text-align:center;
transition:0.8s; text-align:center;
}
.flip{
transform:rotateY(180deg) scale(1.2,1.2);
-webkit-transform:rotateY(180deg) scale(1.2,1.2);
-moz-transform:rotateY(180deg);
-o-transform:rotateY(180deg);
-ms-transform:rotateY(180deg);
background-color:#FF5959;
}
javascript(add Jquery 2.1.0)
$(".cards").click(function(){
$(this).toggleClass("flip");
});
Try this jsFiddle
Base on this, make a 3d transform and left offset in transition,
-webkit-transform-style:preserve-3d;
-webkit-transform:rotateY(0deg);
-webkit-transition:-webkit-transform 0.25s , left 0.25s;
Use the css3 transform and transition.
Hope this can work for you.: )
maybe you like this one. check out my code using keyframes.
https://jsfiddle.net/jariesdev/y7Lz3mm0/
html:
<div id="logo">
<a>
<img src="http://fallbacks.carbonads.com/nosvn/fallbacks/2053cd7a29af8f37381467e04521a14e.png">
</a>
</div>
css:
#logo {
-moz-transform: perspective(1000px);
-moz-transform-style: preserve-3d;
}
#logo a {
display: inline-block;
}
#logo:hover a {
animation-name: rotateThis;
animation-duration: 1s;
animation-iteration-count: 1;
animation-timing-function:ease-in-out;
}
#keyframes rotateThis {
0% { transform:scale(0) rotateY(180deg) translateX(-100%);}
/*60% { transform:scale(.5) rotateY(90deg) translateX(-50%); }*/
100% { transform:scale(1) rotateY(360deg) translateX(0);}
}

How to user controlled overlap images in JS

I'm desperately searching for solution for my client. I have graphic - something like that:
And I want to be able to take the line with circle in the center and drag it to right or left. And it will be hiding and unhiding my two full images. It's basically two images on the same place, just with another z-index I think.
I think it's possible to do it with JavaScript, but I don't know of any functions or methods for this option.
Here is my solution:
The HTML is pretty simple, just two divs for the images and one for the drag:
<div class="img" id="img1"></div>
<div class="img" id="img2"></div>
<div id="drag"></div>
For the CSS, the important part is to absolute position all the divs and give a background image.
As for the Javascript, with a little help from jQuery, we listen for the mouse events, make some calculations and adjust the CSS of the second image:
$('#drag').on('mousedown', function(e){
var $self = $(this),
dragPos = $self.position().left + $self.width()/2,
imgWidth = $('#img1').width();
$(document).on('mouseup', function(e){
$(document).off('mouseup').off('mousemove');
});
$(document).on('mousemove', function(me){
var mx = me.pageX - e.pageX + dragPos
$self.css({ left: mx });
$('#img2').css({
width: imgWidth - mx,
left: mx,
backgroundPosition: -mx + 'px 0px',
});
});
});
From there, I believe it's pretty easy to customize it and give it a unique look.
Hope this helps!
JsFiddle Demo
Something like this alphamask plugin may do the trick, though I'm not sure how simple it would be for you to implement in the manner of your slider example.
Actually quite simple. The first step is to make it work manually. I'd set it up as follows:
<div class="wrap" id="wrap1">
<div class="img-wrap img1"></div>
<div class="img-wrap img2"></div>
<div>
With CSS as follows:
.wrap {
position: relative;
width: 300px;
height: 300px;
}
.img-wrap {
width: 100%;
height: 100%;
position: absolute;
top: 0px;
left: 0px;
}
.img1 {
z-index: 1;
background: url(bg1.png) no-repeat 0px 0px;
}
.img2 {
z-index: 2;
background: url(bg1.png) no-repeat 0px 0px;
}
Now some JavaScript (with jQuery) to set a position (you can call this when you move a slider over the top later):
function setPosition(percentage){
// get the width of the container
var w = $('#wrap1').width();
// work out the width of left panel
var w1 = Math.floor(w * percentage);
// and the right panel
var w2 = w - w1;
// set the width of the right panel
// move it right by the width of the left panel
// and move the background back by the width of the left panel
$('#wrap1 .img2').css({
width: w2,
left: w1,
backgroundPosition: -w1 + 'px 0px',
});
}
You now just have to decide how to do the dragging. You could even just do it on mouseOver. Easy!

Switch div from fixed to absolute at bottom of browser

Im trying to add a footer at the bottom of this content that doesn't overlay the content but moves it up.
The only way I can see it working would be something like, when browser is at the bottom remove 'fixed' class on the left red '#work'.
js fiddle DEMO
Updated js fiddle DEMO
HTML
<div id="header-block">
Header-block, this sits here in the background
</div>
<div id="content">
<div id="work">
This content should be fixed when at the top
</div>
<div id="description">
This content should scroll -
</div>
</div><!-- end content -->
<div id="footer">
This should appear at the bottom
</div>
CSS
body {
margin: 0px;
padding: 0px;
}
#header-block {
background: green;
width: 100%;
position: fixed;
z-index: 1;
height: 300px;
top: 0;
}
#content {
margin-top: 300px;
width: 100%;
position: relative;
z-index: 2;
}
#work {
background: red;
width: 50%;
height: 100vh;
float: left;
position: absolute;
}
#description {
background: blue;
width: 50%;
height: 1200px;
float: right;
font-size: 30px;
}
#footer {
background: black;
width: 100%;
height: 100px;
position: absolute;
z-index: 3;
bottom: 0;
}
If I understand your question correct, this should do the trick (although it depends very much on JavaScript unfortunately).
// Fix work column on scroll
contentStart = $("#content").offset().top ;
contentSize = $("#content").height() ;
window.onscroll = function(){
if( window.XMLHttpRequest ) {
var position=window.pageYOffset;
// calculate the position of the footer and the actual seen window
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $("#footer").offset().top;
if ( position > 300 && !(docViewBottom >= elemTop)) {
$('#work').css({'position':'fixed', 'top':'0', 'height':'100vh'});
} else {
// if the footer is visible on the screen
if(docViewBottom >= elemTop) {
$('#work').css({ 'top': 0 - (docViewBottom - elemTop) }); // scroll the #main div relative to the footer
} else {
$('#work').css({'position':'relative', 'top': 'auto'}) ;
}
}
}
}
For further informations about the calculations, perhaps this question on stackoverflow is useful.
Edit: Andrew Haining posted his answer in between of my answer, perhaps give his link a try and maybe it's a better (more proper) solution. Unfortunately I haven't actualised this page when I was testing your code in JSFiddle and I didn't see his answer.
If you want to use my script, make sure you can test it with different resolutions. It works just fine for my resolution in JSFiddle, I didn't test any other.
I'm not 100% sure what you want, but if you remove the position: absolute and the bottom: 0 from the footer, and put a div with class='clearboth' above the footer, it seems to do what you need.
CSS
.clearboth {
clear: both;
}
This is a drawing of what I see on your fiddle;
Do you want the red and the blue to always be touching the black?
I don't see the red overlying the black
You should use jQuery to add a class containing the position:fixed value when the scroll position of the page is less than the inline position of the #work div. Once it scrolls past the position, remove the class and have the element fall back in line.
You can achieve this using the following jQuery methods.. .scrollTop() .offset().top() and $(window).height().
This tutorial will give you an understanding of what you need to do to achieve the necessary results, you will just have to change the calculation slightly using $(window).height(), $('#footer').height() and a few other changes to get what you desire.
Based on the question you asked i think this is what you mean. The red div should be fixed when it gets to the top but be absolute when it is below the top for scrolling and the black footer should be below the red while scrolling, check this code i have done for you. just add this jquery script and run it.
<script type="text/javascript" src="js/jquery.js"></script>
<script>
$(document).ready(function() {
$(window).scroll(function () {
console.log($(window).scrollTop());
if ($(window).scrollTop() >= 322) {
$('#footer').css("z-index","1");
$('#work').css(
{
"background": "red",
"width": '50%',
'height': '100vh',
'float': 'left',
'position': 'fixed',
'top': '0'
});
}
if ($(window).scrollTop() <= 322)
{
$('#work').css(
{
"background": "red",
"width": "50%",
"height": "100vh",
"float": "left",
"position": "absolute"
});
};
});
});
</script>
If not exactly a parallax, this is somewhat close to how parallax works, containers moving at different speeds, and some containers sitting fixed or scrolling when they attain a particular top/bottom offset in the viewport.
There's plugin that can do it. Skrollr
You can use Skrollr along with skrollrcss, and it'll make sure how the containers take position on screen based on scrolltop of the window and the container specifically.

Display title attribute of an image inside a DIV

This is the page I'm trying to do: Gallery
And what I'm trying to do is when you hover over the thumbnails, the div in front of the main image would fade in and show the title attribute for the image. Hover over the left and topmost image and the title should display on the watch.
I tried following the instructions here but for the second image the title didn't swap and it only showed the first one.
Also I'm a little bit confused where to add the fadein fadeout for the div...
Sorry for the noobish question, I'm still learning this.
Thank you.
I think the title is getting swapped out as it should, the problem is that the new value is always exactly the same as the old value, so it only looks like nothing is happening.
The problem is here:
var titleString = $("#thumb").attr("title");
$("#title").html(titleString);
When you're telling it to switch the text, you're always grabbing the new text from the exact same element: the <a> element that has an id of thumb. To fix it, change that first line to something like the following:
var titleString = $(this).find('a').attr("title");
This assumes that you'll be storing the titles you want to use on the appropriate <a> elements. I add that last part because as it turns out, none of the other anchors on that page have a title, so you'll have to go through and add them if this is the way you decide to go.
Change the following:
1.
#main_view{
background: #FFFFFF;
left: 45%;
margin-top: 128px;
padding: 0 0;
position: absolute;
}
title{
background-color: #C7C3A5;
color: #000000;
font-family: Museo,Arial,Helvetica,sans-serif;
font-size: 12px;
height: 150px;
left: 44%;
opacity: 0.8;
padding: 50px;
position: absolute;
top: 22%;
width: 100px;
z-index: 555;
}
Remove the inline style for the div with title as ID.
in the hover function of ($("ul.thumb li").hover) add the below line
after - $(this).css({'z-index' : '10'});
var titleString = $(chis).children("a").attr("title");
$("#title").html(titleString);
The following code will fix the title issue (as others pointed out) and accomplishes a fade technique. Also probably do not want to a use a percent from top value on the #title element.
$(document).ready(function(){
//Larger thumbnail preview
var $title = $('#title');
$("ul.thumb li, ul.thumb2 li").hover(
function() {
var $this = $(this);
$this.css({'z-index' : '10'});
$this.find('img').addClass("hover").stop()
.animate({
marginTop: '-50px',
marginLeft: '-50px',
top: '50%',
left: '50%',
width: '100px',
height: '100px',
padding: '0px'
}, 200);
$title.stop().animate({opacity:0.4}, 200, function(){
$title.html($this.children('a').attr('title')).animate({opacity:0.8}, 500);
});
},
function() {
$this = $(this);
$this.css({'z-index' : '0'});
$this.find('img').removeClass("hover").stop()
.animate({
marginTop: '0',
marginLeft: '0',
top: '0',
left: '0',
width: '75px',
height: '75px',
padding: '0px'
}, 400);
});
//Swap Image on Click
$("ul.thumb li a, ul.thumb2 li a").click(function() {
var mainImage = $(this).attr("href"); //Find Image Name
$("#main_view img").attr({ src: mainImage });
return false;
});
});
http://jfcoder.com/test/hoverfade.html

Categories

Resources