I need to make an animated gif 'fly over a page and follow a path. I'm thinking of using jQuery but would I be right in thinking the only way to do it is manually calculating the percentage of width/height where the shape layer should be placed, then using absolute positioning is the only way to do this? I know there are some amazing jQuery plugins available for this type of thing.
Absolute positioning is likely to be the best way to do it, yes. (I wouldn't put my hand on heart as saying it's the only way, I'm sure you could play other games to do something similar, but you probably don't want to.)
You don't have to do it as a percentage unless that's intrinsic to your problem. The following will happily make an element absolutely-positioned and then move it 5 pixels right and down every 10th of a second for up to 'count' iterations:
function moveDemo(element, count) {
element.style.position = "absolute";
moveit();
function moveit() {
element.style.left = ((parseInt(element.style.left) || 0) + 5) + "px";
element.style.top = ((parseInt(element.style.top) || 0) + 5) + "px";
if (count-- > 0) {
setTimeout(moveit, 100);
}
}
}
That's just raw JavaScript, but frameworks like jQuery, Prototype, Closure, YUI, etc. help you with a lot of things and are worth looking into. For instance, if you use the above, unless you make the element absolutely-positioned in advance and also specify the left and top styles on the element itself (via an inline style attribute), it'll jump to 0,0 at the outset and then start moving from there. Frameworks can help you with the fairly complex task of figuring out where an inline element is before making it absolutely-positioned.
Here's a complete example that doesn't rely on a framework (but probably should, at least for determining the starting position of 'myElement'):
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Move It Demo Page</title>
<style type='text/css'>
body {
font-family: sans-serif;
}
#myElement {
border: 1px solid black;
}
</style>
<script type='text/javascript'>
function startMoving() {
moveDemo(document.getElementById('myElement'), 10);
}
function moveDemo(element, count) {
element.style.position = "absolute";
moveit();
function moveit() {
element.style.left = ((parseInt(element.style.left) || 0) + 5) + "px";
element.style.top = ((parseInt(element.style.top) || 0) + 5) + "px";
if (count-- > 0) {
setTimeout(moveit, 100);
}
}
}
</script>
</head>
<body><div>
<input type='button' value='Start' onClick="startMoving();">
<div id='myElement'>I'm on the move</div>
</div></body>
</html>
jQuery seems to be the way to go, basic and more of a hack than a solution, but if you definitely need something with JS.
<style type="text/css">
#butterfly
{
display:block;
background: #f00;
width: 100px;
height: 100px;
left: 0;
top: 0;
position: fixed;
background: url(butterfly.gif) no-repeat;
}
</style>
<script type='text/javascript'>
function moveButterfly() {
//moveDemo(document.getElementById('butterfly'), 10);
var butterfly = $('#butterfly');
var positions = [
{ props: { left: '25%', top: '20%' }, time: 1000 },
{ props: { left: '40%', top: '18%' }, time: 610 },
{ props: { left: '58%', top: '38%'}, time: 400 },
{ props: { left: '81%', top: '52%' }, time: 520 },
{ props: { left: '150%', top: '67%'}, time: 440 },
];
jQuery.each(positions, function(i, e) {
butterfly.animate(e.props, e.time);
});
}
$().ready(function() {
moveButterfly();
});
</script>
Related
I've already asked this question but it did not solve my problem (JavaScript / CSS - How can I start an animation, creating new Divs from cursor position?).
I've found a solution but it doesn't seem to work properly on Mozilla and Opera. Also, when I click multiple times, the div starts flashing, which is not what I want. I need to have more than one div at the same time, so to have multiple animations simultaneously. Here's an example from an existing game: http://www.cram.com/flashcards/games/stellar-speller/gre-hit-parade-group-1-320949 Please don't use jQuery, just normal Javascript. Thank you!
<!DOCTYPE html>
<html>
<head>
<style>
#table{
height:300px;
width:900px;
background:red;
}
#ball {
width: 25px;
height: 25px;
position: absolute;
background-color: white;
border-radius:50px;
display:none;
z-index:11;
}
</style>
<script> function animation(){ var elem =
document.getElementById("ball");
document.getElementById("ball").style.display ='block';
document.getElementById("ball").disabled = true;
var x = event.clientX;
var y = event.clientY;
var id = setInterval(frame, 2);
function frame() {
if (x == 900) {
clearInterval(id);
}
else {
x++;
elem.style.top = y + 'px';
elem.style.left = x + 'px';
}
}
}
</script>
</head>
<body>
<div id="table" onclick="animation()">
<div id="ball"></div>
</body>
</html>
few issues in your code. First you have to clone or create a new ball each time you click (be aware that cloning an element won't copy attached events). Don't mix HTML and Javascript and use addEventListener, which let you have event as argument
document.getElementById('table').addEventListener("click",animation);
function animation(event){
var ball = document.getElementById("ball");
//clone element or create another one (you should set a class in you css)
var elem = ball.cloneNode(true);
document.getElementById("table").appendChild(elem);
elem.style.display ='block';
// document.getElementById("ball").disabled = true;
var x = event.clientX;
var y = event.clientY;
var id = setInterval(frame, 2);
function frame() {
if (x == 900) {
clearInterval(id);
}
else
{
x++;
elem.style.top = y + 'px';
elem.style.left = x + 'px';
}
}
}
#table{
height:300px;
width:900px;
background:red;
}
#ball {
width: 25px;
height: 25px;
position: absolute;
background-color: white;
border-radius:50px;
display:none;
z-index:11;
}
<div id="table">
<div id="ball"></div>
</div>
You're reusing the same #ball element for every animation, it can't be in two places at once. To create a new element each time, use document.createElement. Then you'll have to place that element somewhere with appendChild, and remove it with removeChild when the animation's finished.
And some smaller things:
If you will have more than one ball in the document, use a class instead of an ID - IDs are only supposed to be used once.
Your <div>s aren't closed with </div> in the HTML, which is probably Firefox's problem. Do people still use Opera?
You should use requestAnimationFrame here instead of setInterval.
And you should try to use addEventListener instead of onclick.
Good luck!
I'm new to jQuery and i'm still in the process of learning HTML and CSS. I wanted to have a responsive image on the homepage of my website that scaled itself with the user's browser window. I found this at github: https://github.com/gutierrezalex/photo-resize.git
but i think i might be using it wrong, since i can't get it to work for me.
Here's my html:
<head>
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js">
</script>
<reference path="jquery-1.5.1.min.js" />
<script src="jquery-photo-resize.js"></script>
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
$("img").photoResize()
});
</script>
</head>
and here's the jquery-photo-resize.js file:
function photoResize($) {
"use strict";
$.fn.photoResize = function (options) {
var element = $(this),
defaults = {
bottomSpacing: 10
};
function updatePhotoHeight() {
var o = options,
photoHeight = $(window).height();
$(element).attr('height', photoHeight - o.bottomSpacing);
}
$(element).load(function () {
updatePhotoHeight();
$(window).bind('resize', function () {
updatePhotoHeight();
});
});
options = $.extend(defaults, options);
};
}
Like i said, i'm a novice, so please let me know what i'm doing wrong, and how i can achieve my desired effect.
You don't need jquery for this. Just set a class name and then in your style sheet use a width. If you only set a width it'll auto size the height to maintain the aspect ratio. Same goes for setting the height only. If you set both your aspect ratio may be off. The width can be a percentage of the current element. You could also use vw (view port width). Also calc is super helpful.
{ width:75%}
Update:
.cropper {
width: 75px;
height: 75px;
overflow: hidden;
position: relative;
}
.cropped {
width: 100px;
position: absolute;
left: -12.5px;
top: -12.5px;
}
<div class="cropper">
<img class="cropped" src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/SIPI_Jelly_Beans_4.1.07.tiff/lossy-page1-256px-SIPI_Jelly_Beans_4.1.07.tiff.jpg"/>
</div>
Here is code :
CSS :
.featured { overflow:hidden;
border:2px solid #000;
position:relative;}
.featured img { width:100%; position:relative;}
#pos_1 { width:200px; height:190px; }
#pos_2 { width:150px; height:250px; }
#pos_3 { width:350px; height:150px; }
HTML :
<div id="topGallery">
<article class="featured" id="pos_1">
<img src="abc.jpd" class="attachment-post-thumbnail wp-post-image" alt="piano" />
</article>
</div>
Javascript :
jQuery(document).ready(function($) {
///HOME PAGE - image resizing
function imageLoaded() {
var w = $(this).width();
var h = $(this).height();
var parentW = $(this).parent().width();
var parentH = $(this).parent().height();
//console.log(w + '-' + h + '-' + parentW + '-' + parentH);
//if (w >= parentW){ //always true because of CSS
if (h > parentH){
$(this).css('top', -(h-parentH)/2);
} else if (h < parentH){
$(this).css('height', parentH).css('width', 'auto');
$(this).css('left', -($(this).width()-parentW)/2);
}
//}
}
$('#topGallery img').each(function() {
if( this.complete ) {
imageLoaded.call( this );
} else {
$(this).one('load', imageLoaded);
}
});
});
I'm trying to move a rectangle in a canvas element, and haven't had any luck. This is my code so far. I want to do it in PURE JavaScript, not jQuery or any other library.
My JavaScript:
window.onload = beginningMovement; // load beginning movement
function beginningMovement() {
var elem = document.getElementById("rectangle");
var pos = 0;
var id = setInterval(frame, 8);
function frame() {
if (pos == 203) {
clearInterval(id);
//Color funcs
setTimeout(black, 0);
setTimeout(lightgray, 500);
setTimeout(black, 1000);
setTimeout(lightgray, 1500);
setTimeout(black, 2000);
setTimeout(lightgray, 2500);
function black() {
var color = document.getElementById('container').style.backgroundColor = "black";
}
function lightgray() {
var color = document.getElementById('container').style.backgroundColor = "lightgray";
}
//End of color funcs
} else {
pos++;
elem.style.top = pos + 'px';
elem.style.middle = pos + 'px';
}
}
}
//Arrow switching
var X = 40;
var Y = 20;
function switchKey(event) {
Key = event.keyCode;
myCanvas.fillstyle = "white";
myCanvas.filRect(X, Y, 50, 50);
}
switch(key) {
case 37: X -=5;
break;
case 37: Y -=5;
break;
case 37: X +=5;
break;
case 37: Y +=5;
}
myCanvas.fillstyle = "blue";
myCanvas.filRect(X, Y, 50, 50);
HTML:
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
#container {
width: 450px;
height: 400px;
border: 5px solid black;
background: lightgray;
}
#rectangle {
height: 50px;
width: 150px;
background: cyan;
margin-left: 150px;
margin-top: 160px;
position: absolute;
}
</style>
</head>
<body onkeyup="switchKey(event)">
<div id="container">
<div id="rectangle">
</div>
</div>
</body>
</html>
I've been at this for hours and haven't had any luck. I would appreciate it if someone could help me, and get this done soon.
There were a lot of issues with you code and I eventually thought it would be easier to remake a simple version for you to look at. If you really want to stick with your version, please check any browser console for errors and you'll see the issues I'm seeing. Some functions aren't yet available onload, there is no key variable, yet there is a Key variable. There were other issues, too, regarding variable and function scope.
Here's a new version for you to look at: http://codepen.io/antibland/pen/ONwEBE
It's not my finest work, but it's a step in the right direction for you. Instead of setInterval, you should be using requestAnimationFrame to do the redraw. It's much more performant (more on that here if you're interested).
In my demo, a real <canvas> element is used. The smaller rectangle is added to it. I figured you intended to use the real canvas since you included a myCanvas variable in your code. If not, apologies. Either way, you'll probably want to add bounds checking in there, to keep the small rectangle from moving beyond the walls.
Good luck!
The webpage I'm trying to create has a bidirectional sliding animation on it. However the animation is only partially working. To be more precise, the animation slides up, but it only slides down partway. Here's my JavaScript:
function showLayer() {
var hiddenLayer = document.getElementById("mainmenu");
var layerPosition = parseInt(hiddenLayer.style.top);
if (layerPosition > 315) {
hiddenLayer.style.top = (layerPosition - 5) + "px";
setTimeout("showLayer()", 20);
}
}
function hideLayer() {
var hiddenLayer = document.getElementById("mainmenu");
var layerPosition = parseInt(hiddenLayer.style.top);
if (layerPosition <= 315) {
hiddenLayer.style.top = (layerPosition + 5) + "px";
setTimeout("hideLayer()", 20);
}
}
Notice on the fourth line of the hideLayer function, I have the condition set to <= 315, this is due to the fact that setting it equal to 315 causes the element to move only a few pixels in either direction after clicking the trigger element. Here's the HTML elements I have dedicated to the animation:
<div id="mainbutton" onclick="showLayer('mainmenu'); hideLayer('mainmenu')"></div>
<div id="mainmenu" style="position: absolute; top: 690px; left: 9px;"
onclick="showLayer('mainmenu')"> </div>
And here are the styles for them:
div#mainmenu { width: 600px; height: 350px; border-style: solid; background-color:
rgb(0, 0, 0) ; border-width: 3px; border-top-right-radius: 7px; border-top-left-
radius: 7px; }
div#mainbutton { position: absolute; top: 674px; left: 12px; width: 28px; height:
28px; border-style: solid; border-color: rgb(255, 255, 255); border-width: 1px; border-
radius: 4px; }
And the fiddle : http://jsfiddle.net/JAtLA/
I had to put some of the styles inline with the HTML because the animation wouldn't work any other way. At first I thought the problem had solely lain in the if conditional of the hideLayer function. But after tweaking it I'm not so sure now.
I don't know if it's what you want but here is my answer :
There is a problem of logic in your code. You wrote
if(layerPosition<=315){
hiddenLayer.style.top = (layerPosition + 5) + "px";}
It means that if the top is 315 or less, the top will increase until it arrives to 316. But in the first function, you say it to stop at 315. So the function hideLayer will just get it moving from 1 pixel.
The solution is to tell him <400 instead of <=315 (or something higher than 400).
Here is a modified fiddle : http://jsfiddle.net/7egr7/2/
It looks like "hideLayer" will stop if (layerPosition <= 315). Is that really what you want? It happens after 1 iteration.
Note that the y axis goes down the screen (i.e. zero is at the top).
Clicking the button will call showLayer, and then hideLayer.
If the menu is open (i.e. layerPosition > 315), showLayer will not do anything (i guess that is what you intend), and hideLayer will make the menu go up by 5 (from 315 to 320).
On the next iteration of hideLayer (layerPosition <= 315) will be false, so it will not do anything.
Try this:
var open = false;
function showLayer() {
if (open)
return;
var hiddenLayer = document.getElementById("mainmenu");
var layerPosition = parseInt(hiddenLayer.style.top);
if (layerPosition > 315) {
hiddenLayer.style.top = (layerPosition - 5) + "px";
setTimeout("showLayer()", 20);
}
else {
open = true;
}
}
function hideLayer() {
if (!open)
return;
var hiddenLayer = document.getElementById("mainmenu");
var layerPosition = parseInt(hiddenLayer.style.top);
if (layerPosition <= 685) {
hiddenLayer.style.top = (layerPosition + 5) + "px";
setTimeout("hideLayer()", 20);
}
else {
open = false;
}
}
In the html, I would like to check if the thing is open or closed before doing anything.
<div id="mainbutton" onclick="if (!open) { showLayer('mainmenu'); } else { hideLayer('mainmenu'); }">
but layerPosition <= 685 is the only change that really matters.
I have been trying to make this work since the beginning of this week but couldn't figure it out. I have two elements in my HTML file. They are on the same vertical lane, element1 is moving 60ems to the left horizontally with each button click. I have to compare the positions of these two elements and detect whether element1 has passed the element2 with an if/else statement. When it passes I want to move the element1 to its initial position and start over. But if statement never shoots, it always jumps to else statement.
I have tried comparing following properties:
$('#elemet1').position();
$('#elemet1').position().left;
$('#elemet1').offset();
$('#elemet1').offsetLeft;
$('#elemet1').css("position");
$('#elemet1').css("left");
$('#elemet1').css("margin");
$('#elemet1').left;
I tried to compare the positions like below:
$(function () {
$("button").click(function () {
var position1 = $('#element1').css("left");
var position2 = $('#element2').css("left");
if (position1 <= position2) {
$("#element1").animate({left:'+=240em'}, 600);
}
else {
$("#element1").animate({left:'-=60em'}, 600);
}
});
});
If you can give me an answer or direct me to another post I will appreciate it. Thank you in advance.
EDIT: The style I use is below:
.element2 {
position: relative;
width: 60em;
height: 40em;
bottom: 8em;
background: rgba(242, 210, 139, 0.6);
border-radius: 1.2em;
z-index: 1;
overflow: hidden;
#element1 {
position: absolute;
margin-left: 180em;
width: 60em;
height: 40em;
z-index: 1;
}
And I should have mentioned this at the beginning: element1 is inside element2:
<div class="element2">
<img id="element1" src="image/bg1.png" />
</div>
This will give you the current position of an element:
$('#element').position().left;
If you need position relative to the document (instead of relative to a parent element) you can use:
$('#element').offset().left;
You should just be able to compare the return values of these for the different elements directly. Here's some sample code that works for me, note there is no need to parse since they always return pixel values.
var pos = Math.max($(w).scrollTop(), 38),
top = $(ballon).position().top,
dist = Math.abs(pos-top),
time = dist > 1000 ? 2000 : dist / 0.15;
if (pos + $(w).height() >= pHeight) {
pos = pHeight - bHeight - gHeight;
$(ballon).animate({'top': pos}, time, 'easeInOutSine');
}
else if (dist > 150 || pos < 100) {
$(ballon).animate({'top': pos}, time, 'easeInOutBack');
}