The picture is pretty much explanatory by itself. The div "behind" contains a bunch of little square photos that I want to animate smoothly. I'm really not good with jQuery animations, could anyone help me out with this?
(Window is fixed, pictures move "inside" it, animating forever since the page load)
You could do something like this
markup:
<div id="mask">
<img id="pic" alt="my img" src="http://www.destination360.com/north-america/us/idaho/images/s/idaho-sawtooth-mountains.jpg">
</div>
css:
#mask{
overflow:hidden;
width:100px;
height:100px;
position:absolute;
border:5px solid #000000;
}
#mask img{
border:none;
position:absolute;
}
js:
$('#pic').animate({left:-200},3000).animate({top:-50},3000); /* and so on... */
fiddle:
http://www.jsfiddle.net/steweb/YHAZ9/
Edit (looping it forever) http://www.jsfiddle.net/steweb/YHAZ9/4/
I'm a fan of SIN/COS functions, so let me share with you my shot at this problem.
The idea is to have a function that runs forever, and as soon as possible so that the animation is smooth. I use a sin/cos functions to determine the new x (left) and y (top) coordenates of the div, and I have a series of parameters that allow the configuration of the speed and range of the animation.
Just paste this into an HTML file and test it in your browser.
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
</head>
<body>
<div id="stuff" style="background: red; width: 200px; height: 200px; margin: auto; position: relative;">
a b c<br />
d e f<br />
g h i<br />
j k l<br />
</div>
<script>
var start = new Date();
var x_speed = 0.001, // bigger ---> faster
y_speed = 0.01, // bigger ---> faster
x_multiplier = 300, // how far away I can go on the X axis
y_multiplier = 20, // how far away I can go on the Y axis
x_offset = 0,
y_offset = 0;
function animate() {
var now = new Date();
var elapsed_time = now - start;
var x = Math.sin((elapsed_time)*x_speed) * x_multiplier + x_offset;
var y = Math.cos((elapsed_time)*y_speed) * y_multiplier + y_offset;
$("#stuff").css({
left : x,
top : y
});
setTimeout(animate, 0);
}
setTimeout(animate, 76);
</script>
</body>
</html>
For how long? After a click?
I'm not behind my own computer right now, but try something like this:
This is for after a click:
$("#frame").click(
function(){
$("#photo").animate({"left": "-=100px"}, function(){
$("#photo").animate({"top": "-=100px"}, function(){
$("#photo").animate({"left": "=100px"});
});
});
});
And so forth, after each line you can put a new line, like i did in line 3 and 4 from the code. This way the photo behind moves in a square.
Just a suggestion, don't know if this is exactly what you want.
EDIT: Btw, you can only go left, right or up and down, what might smoothen your animation is to grow the photo and shrink it. Therefore you need for instance the "width" parameter.
Check the jQuery site here.
Related
I'll first give my code:
document.documentElement.style.backgroundImage='url(\'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20"><rect width="20" height="20" style="fill-opacity:0;stroke-width:1;stroke:rgb(0,0,255)"/></svg>\')';
var c=document.getElementById("paper").getContext("2d");
c.fillStyle="#000000";
document.documentElement.onmousemove=function(e){
if((e.buttons||e.which)===1){
var x=e.pageX,y=e.pageY;
c.fillRect(x,y,1,1);
}
};
html{width:100vw;height:100vh;overflow:hidden;background-repeat:repeat;cursor:crosshair}
body{margin:0}
#paper{position:absolute;left:0;top:0;width:100vw;height:100vh;z-index:1}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>Graph Paper</title>
</head>
<body>
<canvas id="paper"></canvas>
</body>
</html>
I'm trying to make a virtual graph paper you can draw on with the cursor. The problem is that if you run it and (using your mouse) draw something, you will notice that the place it draws isn't actually where you're at - it's farther away from you as you get farther away from (0,0).
My code is a bit simple so I have no idea on why it is doing this. For example, if you start in the middle, and move towards (0,0), you will see it starts behind you but reaches at the same time as you. And if you start in the middle and go towards the bottom right, it will get much farther than you by the time you reach.
I suspect this has something to do with either the canvas being mispositioned or e.pageX and e.pageY to be incorrect in some way.
Why is this seemingly simple code not working?
Stretching a canvas with css does not change the underlying resolution of the canvas, but simply takes the resulting image, and scales it (usually rather poorly as well).
If the canvas is e.g. stretched by a factor of two due to css, your pixel counting is accordingly off by that factor: the canvas renders it inwards as many pixels as your mouse coordinates, but the result is then stretched by css afterwards.
You could compensate for this by some calculations, but it's often better to make the canvas itself the correct size:
const canvas = document.getElementById("paper");
const ctx = canvas.getContext("2d");
document.documentElement.style.backgroundImage = 'url(\'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20"><rect width="20" height="20" style="fill-opacity:0;stroke-width:1;stroke:rgb(0,0,255)"/></svg>\')';
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
ctx.fillStyle = "#000000";
document.documentElement.onmousemove=function(e){
if ((e.buttons || e.which) === 1) {
const x = e.pageX, y = e.pageY;
ctx.fillRect(x, y, 1, 1);
}
};
html {
width: 100vw;
height: 100vh;
overflow: hidden;
background-repeat: repeat;
cursor: crosshair
}
body { margin: 0 }
#paper {
position: absolute;
left: 0;
top: 0;
z-index: 1
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>Graph Paper</title>
</head>
<body>
<canvas id="paper"></canvas>
</body>
</html>
Note, that this way, you don't get resizing for free. Should the window be resized, you'd need to change the canvas again, from code, which i have omitted here.
I'm wanting to add a scrolling news feed to a small app I have built, however all the scripts or plugins I have seen so far have been for horizontal scrolling - whereas I'm wanting to scroll vertically.
I came across a question with this fiddle, http://jsfiddle.net/rNXs9/1/, which would work well for me. I would load each news item in to a div and then have it scroll.
I tried to implement this, but the DIVs overlap and become unreadable. See my fiddle here, https://jsfiddle.net/wgyxo8gv/.
I'm not very proficient with JS or CSS and so I'm not too sure what is causing this to happen and therefore how to fix it.
Here is the JS that is scrolling the items:
window.verticalScroller = function($elem) {
var top = parseInt($elem.css("top"));
var temp = -1 * $('#verticalScroller > div').height();
if(top < temp) {
top = $('#verticalScroller').height()
$elem.css("top", top);
}
$elem.animate({ top: (parseInt(top)-60) }, 600, function () {
window.verticalScroller($(this))
});
}
$(document).ready(function() {
var i = 0;
$("#verticalScroller > div").each(function () {
$(this).css("top", i);
i += 60;
window.verticalScroller($(this));
});
});
And the CSS for each DIV:
#verticalScroller {
position: absolute;
width:400px;
height: 500px;
border: 1px solid red;
overflow: hidden;
}
#verticalScroller > div{
position:absolute;
width:380px;
padding-left:10px;
height:auto;
border: dotted white;
overflow:hidden;
}
If anyone can point out how I can just get the divs to scroll one after the other without overlapping that would be great. Or if there is a plugin out there that works vertically rather than horizontally that works then that could work too - all my searches for vertical scrolling return endless pagination scripts.
I got around this by approaching this from a slightly different angle.
Instead of using divs, I used a list with the default styling removed and created a ticker function that just slid the list items up one every 5 seconds - the effect isn't quite continuous scrolling but it slides a news item up, pauses for it to be read and then continues on:
function tick(){
$('#ticker li:first').slideUp( function ()
(this).appendTo($('#ticker')).slideDown(); });
}
$(document).ready(function() {
setInterval(function(){ tick() }, 5000);
});
Fiddle
If you are already looking in adapt your first code you can do it this way.
$(document).ready(function() {
var i = 0;
var totalHeight = 0;
$("#verticalScroller > div").each(function () {
$(this).css("top", i);
i += $(this).height();
totalHeight = totalHeight + $(this).height();
});
var loop = setInterval(function(){ verticalScroller() }, 2000);
var index = 0;
function verticalScroller() {
var $currentChild = $("#verticalScroller > div").eq(index);
var scroll = $currentChild.height();
$("#verticalScroller > div").animate({ top: "-="+scroll }, 600, function() {
var top = totalHeight - $currentChild.height();
$currentChild.css({ top : top});
});
if(index == $("#verticalScroller > div").length-1) index = 0;
else index++;
}
});
#verticalScroller {
position: absolute;
width:400px;
height: 300px;
border: 1px solid red;
overflow: hidden;
background: silver;
}
#verticalScroller > div{
position:absolute;
width:380px;
padding: 0 10px;
height:auto;
border-bottom: dotted white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="verticalScroller">
<div>
Nude cyclist Nick Lowe identified as mystery rider in leopard G-string
<br>
A nude cyclist who caused a thong and dance in Marlborough has been exposed â he's Lower Hutt naturist Nick Lowe.
</div>
<div>
Josh Hazlewood pleads guilty to dissent after appeal rejected
<br>
Australian pace bowler Josh Hazlewood has pleaded guilty to dissent after reacting angrily when Black Cap Kane Williamson survived a contentious appeal and DRS review in the second test at Hagley Oval.
</div>
<div>
Firefighters attending increasing number of non-fire related and bizarre callouts
<br>
Rescuing ducklings stuck in drains, requests to fill water tanks and helping fellow firefighters' pet cockatoos - it's all part of the job for the fire service these days.
</div>
<div>
Mike Hosking gives his two cents on parenting
<br>
Mike Hosking thinks Kiwi teenagers have an "inflated sense of entitlement."
</div>
<div>
Australia cruising towards series victory after Black Caps' fight not enough
<br>
It's free entry at Hagley Oval and sadly too familiar for New Zealand against Australia on the final day of the test cricket summer.
</div>
<div>
Big fire strikes near Melbourne
<br>
A major bushfire is burning in the Melbourne area, with emergency services telling some residents it's too late to flee.
</div>
<div>
Smalltown GP offers $400k job and a slice of the business after struggling to recruit
<br>
A smalltown rural GP in the North Island is offering $400,000 to a junior doctor after a fruitless two-year search for staff.
</div>
<div>
Auckland Zoo's baby red pandas give warm fuzzies at weigh-in
<br>
Baby red panda twins at Auckland Zoo in Western Springs have had their first weigh-in and are cuter than ever.
</div>
<div>
Max Key reads ruthless messages directed at him
<br>
Max Key read out a list of mean social media posts with a smile on his face, even though he was the butt of every joke.
</div>
</div>
Change the following jquery function:
$(document).ready(function() {
var i = 0;
$("#verticalScroller > div").each(function () {
$(this).css("top", i);
i += $(this).height(); // CHANGE THIS
window.verticalScroller($(this));
});
});
Result: jsfiddle
When you set top for each div, you do not know the distance of each one of them from the top, because they have not fixed height. To set a correct top, you have to consider the real height of each div, that is why you have to change the line to i += $(this).height();.
If you want, you can add an addictional fixed amount of pixel to add some white space between the divs: i += $(this).height() + 10;.
I have a grid generator, it uses Javascript and jQuery to generate blocks in a grid that are displayed with HTML and CSS. I am trying to set up a button that will change the :hover behavior of the blocks (specifically, change their background-color). I am unable to do this and I'm not sure why my code is not working. I will copy and paste it here and I apologize that it is very long. You can see it in action here: http://codepen.io/anon/pen
HTML
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js">
</script>
<script type="text/javascript" src="script.js"></script>
<title> Odin #2 by Max Pleaner </title>
<link rel="stylesheet" type="text/css" href='stylesheet.css'>
</head>
<body>
<p> Welcome to my Odin Project #2 page. This is me showing off my basic JS and jQuery skills. If you move your mouse through the blocks you can see frogs come out of hiding. If you press the clear button below you can select a new number of blocks to fill the same space.</p>
<button id="button"> Generate a number of blocks of your liking that will position themselves to all fit in the 960px by 960px grid. </button>
<button id="button2"> <strike> Click here to generate new blocks and make hovering on blocks produce random colors.</strike> Why isn't this button working?! It's drawing new blocks fine, but not changing the :hover style as intended. </button>
<div id="square_holder">
</div>
<img src="Q6w802v.jpg" alt="froggy" ></img>
</body>
</html>
CSS
body {
background-color: grey;
}
p {
color: aqua;
}
#square_holder {
width: 960px;
}
.block {
background-color: green;
display:inline-block;
border: 1px solid black;
width: 232px;
height: 232px;
}
.block:hover {
background-color: blue;
//background-image:url("Q6w802v.jpg");
background-size: contain;
}
JS
$(document).ready(function(){
draw_grid(4);
$('#button').click(function(){
get_input();
});
$('#button2').click(function(){
get_input();
$('.block:hover').css("background-image", "none").css("background-color", get_random_color());
});
});
var draw_grid = function (blocks) {
var totalno = Math.pow(blocks, 2);
var dimension = (960 - 1 -(blocks * 2))/blocks;
for(var i = 0; i < totalno; i++){
$("#square_holder").append("<div class='block' id=" + i + "></div>");
};
$(".block").css("height", dimension).css("width", dimension);
}
var get_input = function(){
alert('Do you want to change the number of boxes?<b></b>');
$('#square_holder').empty();
var user_entry = prompt("What number do you choose?");
alert("Watch in awe as the grid fills ..... ");
draw_grid(user_entry);
}
var get_random_color = function() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++ ) {
color += letters[Math.round(Math.random() * 15)];
}
return color;
};
You need to use background, not background-color. Taken from the MDN page for background-image:
The CSS background-image property sets one or several background images for an element. The images are drawn on successive stacking context layers, with the first specified being drawn as if it is the closest to the user. The borders of the element are then drawn on top of them, and the background-color is drawn beneath them.
This translates into a declaration of background-image at all (even as none) will sit on top of background-color. Therefore, if you set background instead of background-color, it will supercede all other property-specific declarations.
Also please view the attached image for clarification. I have a div container what I want to to find a position somewhere in that div container using jquery or javascript or both. The attached image shows everything. Please help.
Update
The reason I want to find this position is that I want to animate container towards that point and eventually disappear. Secondly I would like to find position on the opposite side too so that I could animate container from that position.
Second update
In other words how can we find the point of intersection of two lines?
Given you need to find the intersection between two lines inside a div, your markup could look like this:
<div id="container" style="position:absolute; width: 100%; height: 200px;">
<div style="width: 2px; height: 100%; left: 20%; position:absolute; background-color: red; top: 0;"></div>
<div style="height: 2px; width: 100%; left: 0; position:absolute; background-color: blue; top: 25%;"></div>
</div>
Using jQuery, you can find the coordinates for the intersection like this:
var x = $('#container div:first').position().left;
var y = $('#container div:last').position().top;
console.log(x,y);
x and y would be the coordinates in pixels relative to the container element.
http://jsfiddle.net/sAsmj/
I dont see the image, however if you are looking at getting the position, which is ideally caret position, you can use the jquery plugin http://plugins.jquery.com/project/jCaret
You can find the poiter position by using this, try it
$(document).ready(function(){
$("div#container").on("mousemove", function(e){
var self = $(this);
var dx = e.pageX;
var dy = e.pageY;
var x = dx - self.offset().left ;
var y = dy - self.offset().top ;
console.log(x);
console.log(y);
});
});
If you want the X, Y of the mouse you can read this question:
getting the X/Y coordinates of a mouse click on an image with jQuery
Here is an excerpt from the question which is based upon an img but you can change it for your container:
$(document).ready(function() {
$('img').click(function(e) {
var offset = $(this).offset();
alert(e.clientX - offset.left);
alert(e.clientY - offset.top);
});
});
I'm trying to get flotr2 graphs working in my Phonegap application. I can get their example graph(http://www.humblesoftware.com/flotr2/documentation#usage) to run on an AVD, but if I try to use it in my actual application it gives me the error Uncaught The target container must be visible at file:///android_asset/www/flotr2.min.js:27 How would I fix this?
Code relating to flotr2:
//Flotr2 style contained in head below other styles
<style type="text/css">
body {
margin: 0px;
padding: 0px;
}
#container {
width : 600px;
height: 384px;
margin: 8px auto;
}
</style>
//Accidentally changing </style> to </script> causes the graph to display
//but everything else is wrong, as can be expected
and:
//Page meant to contain graph; in body
<!-- Graphs -->
<div data-role="page" data-theme="a" id="page21">
<div data-theme="a" data-role="header">
<h3>
Graphs
</h3>
<a data-role="button" data-direction="reverse" data-transition="slide" href="#page15" data-icon="arrow-l" data-iconpos="left" class="ui-btn-left">
Back
</a>
</div>
<div data-role="content" style="padding: 15px">
<div id="container"></div>
<script type="text/javascript" src="flotr2.min.js"></script>
<script type="text/javascript">
(function () {
var
container = document.getElementById('container'),
start = (new Date).getTime(),
data, graph, offset, i;
// Draw a sine curve at time t
function animate (t) {
data = [];
offset = 2 * Math.PI * (t - start) / 10000;
// Sample the sine function
for (i = 0; i < 4 * Math.PI; i += 0.2) {
data.push([i, Math.sin(i - offset)]);
}
// Draw Graph
graph = Flotr.draw(container, [ data ], {
yaxis : {
max : 2,
min : -2
}
});
// Animate
setTimeout(function () {
animate((new Date).getTime());
}, 50);
}
animate(start);
})();
</script>
</div>
</div>
By reading the source of flotr2 you can see that in that case el.clientWidth is not defined for some reason. flotr2 seems to rely on that property. Without seeing any other code it's hard to say why this happens.
EDIT:
Since you are using PhoneGap, you could try rigging up your code to use deviceready and see if that helps. It might be possible that clientWidth is missing since it hasn't been set up yet (the CSS hasn't loaded etc.). Anyway, worth a go.