jQuery animate not taking easing on transform - javascript

I have a problem while trying to make a scale animation. I have a video element as a background and have scaled it to (1,1) at beginning. I have binded the mouse move in the document to get the position and scale the video whenever the mouse moves in Y axis, it scales accordingly like zoom in and out effect. However I have been trying to implement easing option to that but it just scales without the effect. Here is my code
$(document).mousemove(function(event) {
var pos = (event.pageY / 4000);
$("#bgvid").animate({
transform: pos
},
{ step: function(now, fx) {
$(this).css('-webkit-transform', 'scale('+ (1+pos) +','+ (1+pos) +')');
},
duration: '100',
queue:false,
easing:'swing'
});
});
So what it does is whenever cursor enters the document and moves in Y axis, it starts to scale from 1 to (1+value) whenever I move the cursor down/up scaling the <video> element. But it is not taking the easing.
What I am trying to achieve is similar to this website.
http://admirhadzic.com/#/project/kamui
Workaround as suggested by #ntgCleaner
my jquery
$(document).mousemove(function(event) {
var pos = (event.pageY/50);
var wid = 120+pos;
$('#bgvid').stop().animate({
width : wid+'%',
left: -(pos/2)+'%'
}, 400,false,'swing');
});
element css
video.fullscreen {
position: absolute;
top:0;
left: 0;
right:0;
bottom: 0;
width: 120%;
z-index:1;
}

So, I've made a fiddle for you here.
What I've done is make a container for the thing you want to scale, then I've used CSS width to scale the container. I also added a transition effect on the container that's being animated so the thing will ease as you want.
html
<div class="box-container">
<div class="box"></div>
</div>
js
$(document).on('mousemove', function(e){
var mouseY = e.pageY;
$('.box-container').css({"width":mouseY+"px"});
})
css
.box-container {
width:200px;
position:relative;
transition:all 400ms ease-out; /* NOTE THIS LINE HERE FOR EASING */
}
.box-container:after {
content:"";
display:block;
padding-top:100%;
}
.box {
position:absolute;
}

Related

My multilayer canvas scrolls too slowly using the scrollbar

I have a multilayered canvas. The images inside can be big so they overflow the dimensions of the , and I have to scroll (and I want that it works so). I draw different images in each layer but I want their relative position fixed, so I have to scroll all the canvas together: when I scroll the first one I want they all to scroll.
The problem is that it scrolls very slowly. When I click on the arrows down/up it scrolls only some pixel. When I keep the mouse down on an arrow it scroll few pixels/second. When I click on the scrollbar, outside the bar, it make a jump of only 50-100 pixels. But if I drag the bar it move normally (fast).
My html:
<div style='display:inline-block; width:100%; position:relative; top: 0px; left: 0px;'>
<div id='canvas1' class='canvas canvas_map' style='overflow:scroll; background-color: lightgrey; z-index: 1; position:absolute; left:133px; top:0px;'></div>
<div id='canvas2' class='canvas canvas_map' style='overflow:scroll; z-index: 2; position:absolute; left:133px; top:0px;'></div>
[...]
<div id='canvas12' class='canvas canvas_map' style='overflow:scroll; z-index: 12; position:absolute; left:133px; top:0px;'></div>
<div id='canvas13' draggable='true' class='canvas canvas_map' style='overflow:scroll; cursor: crosshair; z-index: 13; position:absolute; left:133px; top:0px;'></div>
</div>
My javascript:
var canvas_list=document.getElementsByClassName('canvas_map');
document.getElementById('canvas13').addEventListener(
'scroll', function() {
var scroll_x = document.getElementById('canvas13').scrollLeft;
var scroll_y = document.getElementById('canvas13').scrollTop;
for (var i=0; i<canvas_list.length; i++) {
canvas_list[i].scrollLeft=scroll_x;
canvas_list[i].scrollTop=scroll_y;
};
});
PS: I'm using Raphael library for drawing the images:
var paper_map1 = Raphael(canvas1, '100%', '100%');
[...]
PS2: most canvas are empty, the other have 1-2 light images, so it shouldn't be a memory problem.

Shrinking an image to the coordinates of a mouse click position? (jQuery)

I'm pretty new to this, but I've been fiddling around trying to get an image to shrink to nothing on a central point, which works fairly well using a combination of the below code and relative positioning in the CSS.
$(function() {
$('#imageID').on('click', function() {
$(this).animate({
width: 0,
height: 0,
top: '185px',
left: '-2px'
}, 200);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
What I'd like to be able to do, however, is to change this so that the image shrinks centred on the point where the click was made. I've had a go at trying out absolute positioning and trying to set the top / left to the values of pageX and pageY (and also with the extra step of assigning them to variables) but no dice.
Does anyone have any idea of how / if this can be done? Thanks.
First of all welcome to Stack Overflow!
How about using CSS animations for this?
Use transform instead of width and height in animations for a better performance.
CODE SNIPPET:
$(function() {
$('#imageID').on('click', function() {
$(this).addClass("shrink");
});
});
.shrink {
animation: shrink 300ms linear forwards;
}
#keyframes shrink {
to {
transform: scale(0);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img id="imageID" src="http://fillmurray.com/300/300">
Here's more info on CSS transform and animation properties.
$(function() {
$('#imageID').on('click', function() {
$(this).animate({
width: 0,
height: 0,
top: '185px',
left: '-2px'
}, 200);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

How to stop a CSS animation when it meets the screen edge?

I created this demo:
http://cristiantraina.altervista.org/boxfall/
When you click, it creates a red falling box.
The problem is that using only css there are no ways to detect the size of the screen, in fact in my demo I specify that the box has to fall for 1000px, regardless of the actual height of the screen.
This is the code of the keyframe:
#include keyframes("fall"){
to{
top: 1000px;
}
}
I can't use bottom:0px; because I wouldn't know from where to start the fall, and I didn't solve my main problem.
This is the FallBox.js script:
function FallBox(x, side, parent){
this.x = x;
this.parent = parent || $("body");
this.side = side || Math.random()*200;
this.createBox();
this.fall();
}
FallBox.prototype.createBox = function(){
box = document.createElement('div');
$box = $(box); // I hate brackets
$box.addClass("box");
$box.css({
width: this.side+"px",
height: this.side+"px",
left: this.x+"px",
top: "-"+(this.side+5)+"px"
});
this.box = $box;
}
FallBox.prototype.fall = function(){
this.parent.append(this.box);
this.box.addClass("fall");
}
I know that I could use overflow:hidden; in the parent div, but I don't think that this is the ideal solution. First because a user can have got a screen with a superior height, then because I want to the box stops when it meets the edge, as the border was ground and it shouldn't pass through.
Another solution that I found on the web, it's to use the CSSOM API, but not even mozilla developers are sure of the compatibilty of these.
So, how can I stop an animation when it meets the screen edge, since javascript fails to inject properties?
Thank you.
If you're looking for a css-only solution, you could use the css calc feature (http://caniuse.com/#feat=calc) in combination with vh (http://caniuse.com/#search=vh).
document.querySelector(".box").addEventListener("click", function() {
this.classList.toggle("is-dropped");
})
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.box {
position: absolute;
top: 0;
left: 200px;
width: 100px;
height: 100px;
background: red;
transition: top 2s;
}
.box.is-dropped {
top: calc(100vh - 100px);
}
<div class="box"></div>
You coul use the translatey() CSS transform function to shift each div up by 100% of its own height. That way you would just need 2 rules to change the value of the top position without having to worry about height in each case.
(function(d,M){
var div=d.createElement("div"),
wait=0,size;
d.body.addEventListener("click",function(){
if(!wait){
wait=1;
div=div.cloneNode(1);
div.classList.remove("go");// necessary so that newly created divs don't just get added to the bottom of the page
size=M.max(M.floor(M.random()*200),50);
div.style.height=div.style.width=size+"px";
div.style.left=M.max(M.floor(M.random()*this.offsetWidth)-size,0)+"px";
this.appendChild(div);
setTimeout(function(){
div.classList.add("go");// adding this class starts the animation.
wait=0;
},5);
}
},0);
})(document,Math);
*{box-sizing:border-box;margin:0;padding:0;}
html,body{height:100%}
div{
background:#000;
border:1px solid #fff;
transition:top 2s linear;
position:absolute;
top:0;
transform:translatey(-100%);
}
div.go{
top:100%;
}
ORIGINAL SOLUTION
As the height of the box is being set dynamically in your JavaScript, your CSS isn't going to know the height of each box but that doesn't stop you using the CSS calc() function to set the top position you want to animate each to, much like you currently do to set its starting top position. Here's a quick, rough example, with an alternative solution in the comments that doesn't use calc(), if you'd prefer.
var div=document.createElement("div"),
wait=0,size;
document.body.addEventListener("click",function(){
if(!wait){
wait=1;
div=div.cloneNode(0);
size=Math.max(Math.floor(Math.random()*200),50);
div.style.height=div.style.width=size+"px";
div.style.left=Math.max(Math.floor(Math.random()*this.offsetWidth)-size,0)+"px";
div.style.top="-"+size+"px";
this.appendChild(div);
setTimeout(function(){
div.style.top="calc(100% - "+size+"px)"; /* This is the important bit */
// div.style.top=document.body.offsetHeight-size+"px"; /* Alternative solution, without using calc() */
wait=0;
},5);
}
},0);
*{box-sizing:border-box;margin:0;padding:0;}
html,body{height:100%}
div{
background:#000;
border:1px solid #fff;
transition:top 2s linear; /* Using a transition instead of an animation */
position:absolute;
}

Can you fix a div and make it change opacity, size and position as you scroll with CSS3

I'm not even sure how to search this question. But effectively I'm trying to figure out how this website is achieving this fixed opacity/size changing effect on their table: http://sqlzoo.net/wiki/SELECT_within_SELECT_Tutorial . If you scroll down you'll see the effect on the table. When you hover over it it pops out having the data more visible.
The only thing I can think of is using a fixed div that when scrolled past a certain point triggers a jquery UI event that shrinks while decreasing opacity and then an on hover event that reverses this effect.
Achieving this animation in the way I described above seems inefficient and I'm not sure if more (or all) can be done with CSS3. So basically can you achieve the effect shown on the page provided completely or almost completely in CSS3.
Also i looked at the source of the page and couldn't fish it out of the css and scripts they include.
Here's a fiddle of what I have so far. Haven't started on scrolling yet:
HTML
<div id="stuff">Blahblah</div>
CSS
div {
width:250px;
height:250px;
border:2px solid #a1a1a1;
}
JavaScript
$( "#stuff" ).click(function() {
$( "#stuff" ).animate({
width: "20%",
height:"20px",
opacity: 0.4
}, 1500 );
});
http://jsfiddle.net/thed0ctor/1kx5jg1e/
You could do this easily with a combination of CSS3 transform and a bit of Javascript / jQuery:
Demo Fiddle: http://jsfiddle.net/abhitalks/hcwyth8n/2/
Relevant CSS:
#hanger {
width: 200px; height: 200px;
background-color: #00f;
position: fixed; /* Position fixed important */
top: 10px; right: 10px;
opacity: 1;
transition: 0.5s all; /* Animate transitions */
}
#hanger.dim { /* Style to make it appear dimmed */
transform: scale(.75); /* Make it smaller */
opacity: 0.5; /* Make it dimmer */
}
#hanger.dim:hover { /* To change back on hover only when it is dimmed */
transform: scale(1); /* Back to original size */
opacity: 1; /* Back to original opacity */
}
Relevant jQuery Code:
$(window).on("scroll", function() { /* When window scrolls, */
if ($(window).scrollTop() > 50) { /* Check if it scrolls more than 50 pixels */
$("#hanger").addClass("dim"); /* Apply class dim */
} else {
$("#hanger").removeClass("dim"); /* Otherwise remove class dim */
}
});
Hope that helps.
.
Pseudo code only:
window.scroll(function(){
if (window.scrolltop > selectedElement.offset().top){
selectedElement.animate({
transform: scale(.75),
opacity: .5
position: fixed
});
}else{
selectElement.animate({
transform: scale(.75),
opacity: 1
position: static
});
}
});
The links provided in the he pseudo code should point you in the right direction.

Footer slides up with .slideUp but then slides down

I've got the jQuery .slideUp and .slideDown function below, and when reaching the #showfootershop div at the bottom of the browser window, the #footershop div slides up and then immediately slidesdown.
How can I get the #footershop to remain "up" and visible when #showfootershop is at the bottom of the browser window and not slide down until the user scrolls the browser window up?
Fiddle: http://jsfiddle.net/8PUa9/1/
jQuery:
$(window).scroll(function(){
/* when reaching the element with id "showfootershop" we want to
show the slidebox. */
var distanceTop = $('#showfootershop').offset().top - $(window).height();
if ($(window).scrollTop() > distanceTop)
$("#footershop").slideUp();
else
$("#footershop").slideDown();
});
html in footer:
<div id="showfootershop"></div>
<div id="footershop">
<h1>Shop Links</h1>
</div>
</body>
</html>
CSS:
#footershop {
height:35px;
width:100%;
display: none;
z-index: 2;
}
Use two functions for slidingUp and slidingDown, and toggle them once you have shown the slider and hidden it alternatively.
$(function() {
var slideUp = function() {
if ($(window).scrollTop() + $(window).height() >= $(document).height()) {
console.log('At bottom!!');
//toggle the handlers
$("#footershop").slideDown(function() {
$(window).off('scroll', slideUp).on('scroll', slideDown);
});
}
};
var slideDown = function() {
if ($(window).scrollTop() + $(window).height() < $(document).height()) {
//toggle the handlers
$("#footershop").slideUp(function() {
$(window).off('scroll', slideDown).on('scroll', slideUp);
});
}
};
$(window).on('scroll', slideUp);
});​
EDIT: I think the main problem you have is #footershop increases document.height when it shows and reduces when hidden, which is correct. This causes additional scroll events which creates the undesired behaviour.
Check this fiddle: I fixed this partially.
http://jsfiddle.net/BuddhiP/8PUa9/8/
Check this JSBin version for fixed version: http://jsbin.com/axobow/2
Main thing I did was #footershop is now absolutely positioned, so it doesn't cause the document size to change when shown or hidden, which is important in this case as if document.height() changed it affects you calculation.
Although fiddle works as expected, div is not positioned right on bottom. I hope you can fix that.
Hope this helps.
NOTE: You need to test the fiddle with full-height window, otherwise you will not see the footer sliding up since it shows somewhere in the middle of text.
I'm not sure what's wrong with the other answers that you haven't accepted, but here's mine:
JSFiddle
JS:
$(window).scroll(function() {
var distanceTop = $('#showfootershop').offset().top - $(window).height();
if ($(window).scrollTop() >= distanceTop - 20) {
$("#footershop").animate({
'height': '35px'
}, 'fast');
}
else {
$("#footershop").animate({
'height': '0px'
}, 'fast');
}
});​
CSS:
#footershop {
height:0px;
width:100%;
z-index: 2;
background:#00ffff;
position: absolute;
bottom:0;
left:0;
overflow:hidden;
}
body {
position:relative;
}
​
An alternative to all of this jQuery slideUp/slideDown is to use CSS to handle it.
We detect when the user has reached your #showfootershop element and then add or remove a class from the footer:
$(window).scroll(function()
{
var distanceTop = $('#showfootershop').offset().top - $(window).height();
if($(document).scrollTop() >= distanceTop)
$('#footershop').addClass("show");
else
$('#footershop').removeClass("show");
}
Then we use CSS to display the footer or hide it depending on the presence of that class:
#footershop
{
position: fixed;
height: 0px;
z-index:999;
bottom: 0;
overflow:none;
-moz-transition:all 0.5s ease-in-out;
-o-transition:all 0.5s ease-in-out;
transition:all 0.5s ease-in-out;
-webkit-transition:all 0.5s ease-in-out;
}
#footershop.show
{
height:35px;
-moz-transition:all 0.5s ease-in-out;
-o-transition:all 0.5s ease-in-out;
transition:all 0.5s ease-in-out;
-webkit-transition:all 0.5s ease-in-out;
}
As you can see above when the .show class is on the footer we change the height of the footer element to display it. CSS transitions are then used to animate this change.
The nice thing about this method is it's very lightweight and efficient (especially if you've got a lot of jQuery animations working at the same time), and you can easily animate various different changes like the opacity, text and background colours, etc. without needing to touch your JS at all.
jsFiddle
Here's your jsFiddle modified
http://jsfiddle.net/DigitalBiscuits/8PUa9/29/
slideUp() will also hide the element and offset of a hidden element is [0,0] so the instant footer is hidden distanceTop is negative. You could animate height to zero and get same visual result and since you aren't hiding the footer it will still have same top offset
I would recommend just putting a little buffer inbetween your scroll up and scroll down code.
I have made a slight tweak to your code to put in a buffer of 100px:
Javascript
$(window).scroll(function() {
var distanceTop = $('#showfootershop').offset().top - $(window).height();
if ($(window).scrollTop() >= distanceTop) {
$("#footershop").slideDown();
}
else if ($(window).scrollTop() < (distanceTop - 100)) {
$("#footershop").slideUp();
}
});
Demo
Trying to scroll to an element is way too messy, just use the bottom of the page.
$(window).scroll(function() {
if ($(window).scrollTop() + $(window).height() == $(document).height()) {
$("#footershop").slideDown();
}
else {
$("#footershop").slideUp();
}
});​
jsfiddle

Categories