I'm using anime.js to create a couple of simple animations but I'm struggling to make it work.
The goal is to enable the user to roll a couple of dice. The dice starts in the middle of the screen and, when clicking a button, it should go down the screen until it disappears. Then it should appear again from the top of the screen (already with a new face), but this time it should come rolling.
I'm trying to do it with two, sequencial, animations. In the middle it should draw the new value.
Here is the html:
<div class="outerDice" style="position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; pointer-events: none; z-index: 15;">
<div class="dice" style="position: absolute; overflow: visible; z-index: 15; top:325px; left: 171px; width: 133px; height: 133px;">
<div style="position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; pointer-events: none; z-index: 4;">
<div id="dice1" style="position: absolute; background-image: url(images/plain_dice.png); background-size: 100% 100%; opacity: 1; background-repeat: no-repeat; display: inline; border-style: none; overflow: visible; z-index: 4; width: 133px; height: 133px;">
<img src="images/story_dice33.png " height="125" width="125">
</div>
</div>
</div>
<div style="position: absolute; top: 310px; left: 119px; width: 100%; height: 100%; z-index: 2;">
<img class="shadow" src="images/shadow.png" height="240px" width="240px" style="z-index: 4; display: inline; opacity: 0.5; position: absolute; overflow: visible;">
</div>
</div>
<button onclick="move();" style="z-index: 9999; position: absolute; top: 0; left: 0px;" >CLICK ME</button>
And here the javascript:
function move(obj){
var rollDice = anime({
targets: ['.dice', '.shadow'],
translateY: ["-500px", "0px"],
duration: 1000,
loop: false,
autoplay: false,
rotate: '1turn',
easing: 'linear'
});
var dcount = 0, scount = 0;
var drop = anime({
targets: ['.dice', '.shadow'],
translateY: ["0px", "100vh"],
easing: 'easeInBack',
duration: 2000,
loop: false,
autoplay: false,
delay: function(el, i, l) {
if(el.classList.contains("dice"))
return ++dcount*100;
if(el.classList.contains("shadow"))
return ++scount*100;
return i * 100;
},
complete: function(anim) {
roll(document);
rollDice.restart();
}
});
drop.restart();
}
The funny thing is that, the first time I click the button, it works exactly as expected.
From there on, it works EXCEPT that the dice doesn't roll when coming back in...
I don't understand why...
Finally, after a lot more search, I found the solution here: https://github.com/juliangarnier/anime/issues/380
The problem is that the first time the animation is run, it goes from 0turn to 1turn.
The second time the element is already in 1turn so it will not change anything.
The solution is to force to go from 0turn to 1turn always:
rotate: ['0turn', '1turn']
Related
I am a little new to using TweenLite. As you will see in the example, I have a div that I slide up which is all good, and I want to rotate the div itself so am using rotation 18deg however, can rotate this before the animation as appears it animated the rotation as it slides up. So I need to rotate out of view.
$(document).ready(function(){
TweenLite.to("#slide_one .background",
0.4, // set the speed
{rotation:"18deg", top:"0" // set the angel and end position
});
});
.container {
display: block;
width: 300px;
height: 250px;
border: 1px solid #000000;
overflow: hidden;
position: relative;
}
.background {
position: relative;
display: block;
width: 200%;
height: 200%;
left: -100%;
bottom: -300px;
}
.background.dark-blue {
background: #071D49;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.15.0/TweenMax.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div id="slide_one">
<div class="background dark-blue"></div>
</div>
</div>
For anyone wanting to know the solution you have to use set so does not animate
TweenLite.set(slide_one, { rotation: "18deg" });
I want to display image, expanded such as radial effect (from width 0 to 100%). I've tried using jQuery animated property, image work as I want but don't remains at fixed point.
js
<script>
jQuery(function(){
jQuery( "#vert img" ).animate({
width: "100%",
height: "100%",
opacity: 1
}, 1500 );
});
</script>
html
<div id="vert">
<img src="images/radial.png" alt="Radial" />
</div>
css
#vert{ width: 960px; height: 600px; position: absolute; top: 50%; left: 50%; margin-top: -333px; margin-left: -480px; }
#vert img{ width: 0; height: 0; opacity: 0; }
I'm trying to create a column (<div id="scroller"></div>) inside of which the user will be able to scroll infinitely upwards or downwards.
I believe the trick is to increase the height of <div id="scrollee"></div> downwards every time the user's scroll is about to reach the bottom and increase its height upwards every time the user's scroll is about the reach the top.
Alternatively (seems easier), the top of <div id="scrollee"></div> could be increased every time the user's scroll is about to reach the bottom and vice versa.
However, I can't seem to find the right combination. I tried the 2nd version (increasing the top of <div id="scrollee"></div>) and obviously only managed to make it infinitely scrollable downwards. Decreasing the top when moving upwards didn't work so I have omitted that part from the code.
Any suggestions ?
You can see it in action here : http://jsfiddle.net/1uzdj12d/5/
CSS
#scroller {
position: absolute;
top: 0px;
left: 0px;
height: 200px;
width: 100px;
overflow: hidden;
border: 1px solid black;
}
#scroller>div {
position: absolute;
top: 0px;
left: 0px;
height: 100%;
width: 100%;
overflow-x: hidden;
}
#scrollee {
position: absolute;
top: -10px;
left: 0px;
height: 200%;
width: 100%;
}
span {
position:absolute;
top:0px;
left: 300px;
}
HTML
<div id="scroller">
<div>
<div id="scrollee"></div>
</div>
</div>
<span></span>
Javascript
var timeout;
$("#scroller>div").scroll(function ()
{
clearTimeout(timeout);
$('span').text('scrolling');
timeout = setTimeout(function ()
{
$('span').text('');
}, 500);
});
$("#scroller>div").scroll(function ()
{
var currentTop = $("#scroller>div").scrollTop();
$(this).find('div').css({top : currentTop});
});
Turns out it was easier than I thought :-)
If you want to create an infinitely scrollable div (on the y-axis), all you need to do is set the height of <div id="scrollee"> to the height of <div id="scroller"> plus 20px. You also need to set its initial scrollTop to 10px (this will allow an upwards and downwards scrolling).
Now every time a scroll occurs, reset the scrollTop of <div id="scrollee"> to 10px.
You can see my solution in action here : http://jsfiddle.net/vxzw68jk/22/
If you're wondering why I'm using :
<div id="scroller">
<div>
<div id="scrollee"></div>
</div>
</div>
instead of simply :
<div id="scroller">
<div id="scrollee"></div>
</div>
It's because if you set the width of #scroller>div to 150% the scrollbar will be hidden which can be useful (at least for my project..), you can check it out here : http://jsfiddle.net/8psu5L6v/1/
CSS
#scroller {
position: absolute;
top: 0px;
left: 0px;
height: 200px;
width: 100px;
overflow: hidden;
border: 1px solid black;
}
#scroller>div {
position: absolute;
top: 0px;
left: 0px;
height: 100%;
width: 100%;
overflow-x: hidden;
}
#scrollee {
position: absolute;
top: 0px;
left: 0px;
height: 220px;
width: 100%;
}
span {
position:absolute;
top: 0px;
left: 300px;
}
HTML
<div id="scroller">
<div>
<div id="scrollee"></div>
</div>
</div>
<span></span>
Javascript
$("#scroller>div").scrollTop(10);
var timeout;
$("#scroller>div").scroll(function ()
{
$('span').text('scrolling');
$("#scroller>div").scrollTop(10);
clearTimeout(timeout);
timeout = setTimeout(function ()
{
$('span').text('');
}, 500);
});
the app I am working on right now requires the user to hover over an icon, which launches a tooltip, which the user can click a link inside of to launch a fancybox with the corresponding product. I am running into the problem of the tooltipster not launching the fancybox.
Here is the code I am currently using.
HTML:
<body class="body">
<div class="main-container">
<div class="column">
<div class="anicontainer">
<a id="p1tooltip" class="overlay" href="javascript:void(0)" >
<img src="icon.png"/>
</a>
</div>
</div>
</div>
CSS:
.main-container {
position: absolute;
overflow: hidden;
overflow-x: hidden;
overflow-y: hidden;
margin: 0;
padding: 0;
z-index: -1;
height: 1080px;
width: 1920px;
background-image: url(../bk.png);
background-size: 1920px 1080px;
background-repeat: no-repeat;
display: inline-table;
border: 1px solid #C0C0C0;
border-radius: 5px;
}
.anicontainer {
z-index: 100;
width: 1530px;
height: 1080px;
margin: 0 0 0 0;
padding 0 0 0 0;
overflow: hidden;
overflow-x: hidden;
overflow-y: hidden;
position: relative;
display: table-cell;
vertical-align: top;
}
.column {
display: table-row;
z-index: 100;
overflow: hidden;
overflow-x: hidden;
overflow-y: hidden;
margin: 0;
padding: 0;
}
#p1tooltip {
top: 440px;
left: 290px;
}
.overlay {
display: table-cell;
height: auto;
width:auto;
position:absolute;
z-index: 5;
}
First Code I tried JS:
$('#mst').tooltipster({
animation: 'fade',
delay: 100,
trigger: 'hover',
position: 'right',
fixedWidth: 30,
interactive: 'true',
contentAsHTML: 'true',
content: $('<p class="font tt">Title</p><hr><p class="tt font"><a id="p1" href="javascript:void(0)"><img src="icon.png"/></a>Product1</p>')
});
Second Code I tried JS:
$('#p1tooltip').tooltipster({
animation: 'fade',
delay: 100,
trigger: 'hover',
position: 'right',
fixedWidth: 30,
interactive: 'true',
content: $('<p class="font tt">Title:</p><hr><p class="tt font"><a class="fancybox" href="javascript:$.fancybox( {href : '
product.html '} );"><img src="icon.png"/></a>Product1</p>')
});
JSFIDDLE
Your problem is that the Fancybox link inside the tooltipster content option doesn't exist in the DOM when the Fancybox trigger initialises everything.
Solution would be to set your tooltipster content option to an element already on the page (a div inside of a hidden div should work fine), or to reinitialise Fancybox inside the tooltipster functionReady callback option.
Javascript is a functional language, you can just pass a new function back through the options.
Example:
$('#p1tooltip').tooltipster({
functionReady: function () {
$("a.fancybox").fancybox();
}
});
first thing I see : do not use $('<p>aaa</p><p>bbb</p>') but $('<div><p>aaa</p><p>bbb</p></div>'). It's important fot Tooltipster to have only one container tag for all your stuff, it makes a difference in some cases.
If that's not enough, please prepare a JSfiddle, it will be easier to debug for everyone.
Please have a look at this:
http://liveweave.com/5bhHAi
If you click the "Get Pos" link you will see the red div's position relative to the image.
Now say this image's size has changed at some point down the line. How can I get the new position for the red div based on the initial data?
HTML:
<div id="watermark"></div>
<img src="http://placekitten.com/g/320/270" class="small-img">
<div><br><br>Get Pos</div>
jQuery:
$(document).ready(function() {
var $watermark = $('#watermark');
$('.get-pos').on('click', function(e) {
e.preventDefault();
var watermark_position = {
top: $watermark.position().top - $('.small-img').position().top,
left: $watermark.position().left - $('.small-img').position().left
};
alert(watermark_position.top + 'px from the top');
alert(watermark_position.left + 'px from the left');
});
});
CSS:
#watermark { background: red; position: absolute; top: 215px; left: 265px; width: 50px; height: 50px; }
Here is a solution to what I understand you want from question/comments:
http://jsfiddle.net/tXT2d/
var imgPos = $(".image img").offset();
var wmPos_tmp = $(".watermark").offset();
var watermarkPosition = {
top: wmPos_tmp.top - imgPos.top,
left: wmPos_tmp.left - imgPos.left
}
You can accomplish your intended goal (placing the watermark at the right place even after size changes) without using javascript at all if you do just a little reworking. A working example of the following solution is here
(just change the width of the .img-container to see it function).:
.watermark {
background: red;
width: 50px;
height: 50px;
}
.img-container {
width: 295px;
height: auto;
position: relative;
}
.img-container img {
width: 100%;
}
.img-container .watermark {
position: absolute;
right: 10px;
bottom: 10px;
}
<div class="img-container">
<div class="watermark"></div>
<img src="http://placekitten.com/g/320/270" class="small-img">
</div>
Your html containing the image will look basically like this:
<div class="img-container">
<div class="watermark"></div>
<img src="http://placekitten.com/g/320/270" class="small-img">
</div>
And the css to get the placement to happen looks like this:
.watermark { background: red; width: 50px; height: 50px; }
.img-container {
width: 275px;
height: auto;
position: relative;
}
.img-container img {
width: 100%;
}
.img-container .watermark {
position: absolute;
right: 10px;
bottom: 10px;
}
Here, the image will always match the width of its container, and the watermark will always place itself ten pixels from the right and ten pixels from the bottom of the container.