How to animate translate properties with Velocity.js? - javascript

I have a simple block that is suppose to move left 200px with translateX. It will move left with position left. I can't seem to move the block with translateX or translateY. CSS values for Transform translate will work. Reason to use translate is the performance compared to position. I commented out the position left with Velocity to give you an idea what I'm trying to achieve.
var button = document.getElementById('button');
var adiv = document.getElementById('panel');
button.addEventListener('click', function(){
//Velocity(adiv, { left: '100' }, [ 500, 20 ]);
Velocity(adiv, {translateX: 200}, [ 500, 20 ]);
})
#panel {
display: block;
position: absolute;
background: #ffffbd;
width: 100px;
height: 100px;
top: 0;
left: 0;
}
button {
top: 90%;
position: relative;
display: block;
}
<script src="https://cdn.jsdelivr.net/npm/velocity-animate#2.0/velocity.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<body>
<div id="topbar"></div>
<div id="panel">
</div>
<button id="button">start</button>
</body>

In Velocity V2 there are no longer any transform shortcuts such as translateX - just use the css transform property properly and it'll work (there are issues in V1 with trying to do that unfortunately).
Velocity(adiv, {transform:"translateX(200px)"}, [ 500, 20 ]);
If there's no forcefeeding it'll animate from a value of 0.

Velocity seems to be picking up steam with version 3 of VUE coming up.
I highly suggest the Velocity 2.0 docs to be a little more updated with information such as:
In Velocity V2 there are no longer any transform shortcuts such as
translateX - just use the css transform property properly and it'll
work (there are issues in V1 with trying to do that unfortunately).
Velocity(adiv, {transform:"translateX(200px)"}, [ 500, 20 ]);
Or reach out to the VUE team as they are still using the Velocity 1.x examples.

Easy example with jQuery:
$('.box').on('click', function() {
$(this).velocity({
transform: ["translateX(100px)", "translateX(0px)"]
}, {duration: 1000});
});

Related

Recenter element following page scroll with transition

I have a little chat widget, just a small square div that’s absolutely positioned vertically center in the browser window on page load. When the user scrolls down the page I want the widget to scroll with the page, I.e. disappear but once scrolling has stopped for the chat widget to transition back into vertical center.
I’ve searched high and low but can’t seem to find anything.
The nearest is this. Element transform transition between appearing 'relative' and 'fixed' not smooth
Any help greatly appreciated. I’d rather avoid jquery if poss and just use vanilla JS.
Cheers Richard
I think it will more simple if use animejs in case you want make it smooth.
let timeout;
window.addEventListener("scroll", (ev) => {
clearTimeout(timeout);
timeout = setTimeout(() => {
anime({
targets: ".chat",
top: window.scrollY + window.innerHeight / 2,
easing: "easeOutCubic",
duration: 500
});
}, 100);
});
.chat {
position: absolute;
top: 50%;
transform: translateY(-50%);
background: red;
}
.idk {
height: 400vh;
}
<script src="https://unpkg.com/animejs#3.2.1/lib/anime.min.js"></script>
<div class="chat">
hello
</div>
<div class="idk">
</div>

How to scale down and translate right to left using CSS?

I have a background of backend developer (nodejs) and I'm starting to develop web application. So I'm really new to HTML5, CSS. You can check the small web application here.
Now I want to add some animations to the web application. The first animation is a scale down of the current state and a translation right to left of the new state and I don't know where to start. I'm using ui-router, Restangular and ngAnimate as AngularJS dependencies, LESS for CSS pre-processing.
Any idea how can I achieve these animations (scale down the current state and translate right to left the next state) ?
Thanks.
Your question is not clear enough, but from what I understand, here is an example to help you. You can add a class to your element in javascript and use CSS translate and transform :
var button = document.getElementById('button'),
box = document.getElementById('box')
button.addEventListener('click', function() {
box.classList.add("move");
});
div {
width: 100px;
height: 100px;
margin: 0 auto;
background-color: orange;
transition: all 1s;
}
button {
display: block;
width: 100px;
margin: 0 auto;
}
.move {
transform: translate(-200px, 0);
height: 50px;
width: 50px;
}
<div id="box"></div>
<button id="button">click me</button>

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.

background image shaky on div resize

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.

Categories

Resources