How to move an image depending on mouse location using JS? - javascript

I would like an image to move to the left if the mouse is to the left of the screen and to the right if the mouse to the right of the screen, using javascript, here is the code I have so far:
var dirx = 0;
var spdx = 35;
var imgLeftInt;
var imgTopInt;
var imgHeight;
var imgWidth;
var divWidth;
var divHeight;
var t;
var tempX;
var tempY;
So I'm pretty sure I'm not missing any variables...
function animBall(on) {
imgLeftInt = parseInt(document.images['logo'].style.left);
imgTopInt = parseInt(document.images['logo'].style.top);
imgHeight = parseInt(document.images['logo'].height);
imgWidth = parseInt(document.images['logo'].width);
divWidth = parseInt(document.images['container'].width);
if (tempX > 779){
dirx = 1;
}
else if(tempX < 767){
dirx = 2;
}
else {
spdx = 0;
}
So if tempX, which should be the x coordinate of the mouse location, is bigger than 779, which is the halfway point of the div tag, the image should go right. If it's less than that, it should go left, and otherwise, the speed should be zero, as in it should stay still.
if(dirx == 1){
goRight();
} else if(dirx == 2) {
goLeft();
}
}
function getMouseXY(e) {
tempX = e.clientX;
tempY = e.clientY;
}
I found hundreds of different ways to get the mouse location, but this was off W3C so I assume it works.
function goRight() {
document.images['logo'].style.left = imgLeftInt+spdx +"px";
if (imgLeftInt > (divWidth-imgWidth)){
dirx = 2;
spdx= 20;
}
}
function goLeft() {
document.images['logo'].style.left = (imgLeftInt-spdx) +"px";
if (imgLeftInt < 5){
dirx = 1;
spdx= 20;
}
}
</script>
So that's my whole script.
<div id="container" onmousemove="getMouseXY(event);" width="1546" height="423">
Start Animation Stop Animation <br />
<img src="http://qabila.tv/images/logo_old.png" style="position:absolute;left:10px;top:20px;" id="logo" />
</div>
I left the dependency on the mouse location to the very end so the animation script works fine (or at least worked, unless I broke something trying to get it to read the mouse location).
Any ideas what I'm doing wrong??
If it's any help, I've hosted the code here.

I went to your link and tried debugging your code. I get an error on line 21 because your document has no "container" image ("container" is a div).
At the start of your question, you said you wanted to know mouse position relative to center of "screen". For that, you'd probably want to use window.innerWidth instead of the width attribute that you set on your div.

Well that needed a whole load of work, anyway, I have done some of it for you and you can now see things partially working, but you will need to play with it on jsfiddle. Perhaps you can now open some specific questions regarding getting this to work.
<div id="container" width="1546" height="423"> <a id="start" href="#">Start Animation</a> <a id="stop" href="#">Stop Animation</a>
<br />
<img src="http://qabila.tv/images/logo_old.png" style="position:absolute;left:10px;top:20px;" id="logo" />
</div>
/*jslint sub: true, maxerr: 50, indent: 4, browser: true */
/*global */
(function () {
"use strict";
var start = document.getElementById("start"),
stop = document.getElementById("stop"),
container = document.getElementById("container"),
logo = document.getElementById("logo"),
dirx = 0,
spdx = 35,
imgLeftInt,
imgTopInt,
imgHeight,
imgWidth,
divWidth,
divHeight,
t,
tempX,
tempY;
function getMouseXY(e) {
tempX = e.clientX;
tempY = e.clientY;
}
function goRight() {
logo.style.left = imgLeftInt + spdx + "px";
if (imgLeftInt > (divWidth - imgWidth)) {
dirx = 2;
spdx = 20;
}
}
function goLeft() {
logo.style.left = (imgLeftInt - spdx) + "px";
if (imgLeftInt < 5) {
dirx = 1;
spdx = 20;
}
}
// attribute on unused
function animBall(on) {
imgLeftInt = parseInt(logo.style.left, 10);
imgTopInt = parseInt(logo.style.top, 10);
imgHeight = parseInt(logo.height, 10);
imgWidth = parseInt(logo.width, 10);
divWidth = parseInt(container.width, 10);
if (tempX > 779) {
dirx = 1;
} else if (tempX < 767) {
dirx = 2;
} else {
spdx = 0;
}
if (dirx === 1) {
goRight();
} else if (dirx === 2) {
goLeft();
}
}
function startAnim() {
t = setInterval(animBall, 80);
}
start.addEventListener("click", startAnim, false);
function stopAnim() {
clearInterval(t);
}
stop.addEventListener("click", stopAnim, false);
container.addEventListener("mousemove", getMouseXY, false);
}());

Why don't you usee the html5 canvas and gee.js
Here's the js fiddle result (it may take a while to load, but that's fault of jsfiddle, the script will load much faster once on your website): http://jsfiddle.net/wLCeE/7/embedded/result/
and here's the much simpler code to make it work:
var g = new GEE({
width: 500,
height: 423,
container: document.getElementById('canvas')
});
var img = new Image(); // Create new img element
img.onload = function () {
demo(g)
};
img.src = 'http://qabila.tv/images/logo_old.png'; // Set source path
function demo(g) {
var style = "left"
g.draw = function () {
if (g.mouseX > g.width / 2 && style == "left") styleRight()
else if (g.mouseX < g.width / 2 && style == "right") styleLeft()
}
function styleLeft() {
style = "left"
g.ctx.clearRect(0, 0, g.width, g.height)
g.ctx.drawImage(img, 0, 0)
}
function styleRight() {
style = "right"
g.ctx.clearRect(0, 0, g.width, g.height)
g.ctx.drawImage(img, g.width - img.width, 0)
}
}

Related

Random movement of circles created by the script

I have a function that craeates divs with a circle.
Now they are all created and appear at the beginning of the page and go further in order.
Next, I need each circle to appear in a random place. I did this.
Now I need all of them to move randomly across the entire page, I have difficulties with this.
Here is an example of how everything works for one element that is already on the page.
https://jsfiddle.net/quej8wko/
But when I add this code, all my created circles don't move.
I get an error:
"message": "Uncaught TypeError: Cannot set properties of null (setting 'willChange')",
This is probably due to the fact that initially there are no circles on the page. How can I connect the code so that all created circles move?
//creating circles
var widthHeight = 40; // <-- circle width
var margin = 20; // <-- margin - is it necessary ?
var delta = widthHeight + margin;
function createDiv(id, color) {
let div = document.createElement('div');
var currentTop = 0;
var documentHeight = document.documentElement.clientHeight;
var documentWidth = document.documentElement.clientWidth;
div.setAttribute('class', id);
if (color === undefined) {
let colors = ['#35def2', '#35f242', '#b2f235', '#f2ad35', '#f24735', '#3554f2', '#8535f2', '#eb35f2', '#f2359b', '#f23547'];
div.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)];
}
else {
div.style.backgroundColor = color;
}
div.classList.add("circle");
div.classList.add("animation");
// Get the random positions minus the delta
currentTop = Math.floor(Math.random() * documentHeight) - delta;
currentLeft = Math.floor(Math.random() * documentWidth) - delta;
// Keep the positions between -20px and the current positions
var limitedTop = Math.max(margin * -1, currentTop);
var limitedLeft = Math.max(margin * -1, currentLeft);
div.style.top = limitedTop + "px";
div.style.left = limitedLeft + "px";
document.body.appendChild(div);
}
let i = 0;
const oneSecond = 1000;
setInterval(() => {
i += 1;
createDiv(`circle${i}`)
}, oneSecond);
//move circles
function RandomObjectMover(obj, container) {
this.$object = obj;
this.$container = container;
this.container_is_window = container === window;
this.pixels_per_second = 250;
this.current_position = { x: 0, y: 0 };
this.is_running = false;
}
// Set the speed of movement in Pixels per Second.
RandomObjectMover.prototype.setSpeed = function(pxPerSec) {
this.pixels_per_second = pxPerSec;
}
RandomObjectMover.prototype._getContainerDimensions = function() {
if (this.$container === window) {
return { 'height' : this.$container.innerHeight, 'width' : this.$container.innerWidth };
} else {
return { 'height' : this.$container.clientHeight, 'width' : this.$container.clientWidth };
}
}
RandomObjectMover.prototype._generateNewPosition = function() {
// Get container dimensions minus div size
var containerSize = this._getContainerDimensions();
var availableHeight = containerSize.height - this.$object.clientHeight;
var availableWidth = containerSize.width - this.$object.clientHeight;
// Pick a random place in the space
var y = Math.floor(Math.random() * availableHeight);
var x = Math.floor(Math.random() * availableWidth);
return { x: x, y: y };
}
RandomObjectMover.prototype._calcDelta = function(a, b) {
var dx = a.x - b.x;
var dy = a.y - b.y;
var dist = Math.sqrt( dx*dx + dy*dy );
return dist;
}
RandomObjectMover.prototype._moveOnce = function() {
// Pick a new spot on the page
var next = this._generateNewPosition();
// How far do we have to move?
var delta = this._calcDelta(this.current_position, next);
// Speed of this transition, rounded to 2DP
var speed = Math.round((delta / this.pixels_per_second) * 100) / 100;
//console.log(this.current_position, next, delta, speed);
this.$object.style.transition='transform '+speed+'s linear';
this.$object.style.transform='translate3d('+next.x+'px, '+next.y+'px, 0)';
// Save this new position ready for the next call.
this.current_position = next;
};
RandomObjectMover.prototype.start = function() {
if (this.is_running) {
return;
}
// Make sure our object has the right css set
this.$object.willChange = 'transform';
this.$object.pointerEvents = 'auto';
this.boundEvent = this._moveOnce.bind(this)
// Bind callback to keep things moving
this.$object.addEventListener('transitionend', this.boundEvent);
// Start it moving
this._moveOnce();
this.is_running = true;
}
RandomObjectMover.prototype.stop = function() {
if (!this.is_running) {
return;
}
this.$object.removeEventListener('transitionend', this.boundEvent);
this.is_running = false;
}
// Init it
var x = new RandomObjectMover(document.querySelector(".circle"), window);
// Start it off
x.start();
.circle {
clip-path: circle(50%);
height: 40px;
width: 40px;
margin: 20px;
position: absolute;
}
I have modified the snippet which works as you expected.
There was a mistake where you were initializing and creating the object instance only once and none of the div elements that you created inside the setInterval function never got Instantiated.
I think you are just starting out with JavaScript with this sample project.
Below are few suggestions:
Learn to debug the code. You should be using dev tools by making use of debugger statement where it takes you to the source code to analyze the variable scope and stack during the runtime. console.log also helps in few situations.
I could see a lot of confusing naming convention (You have named the create div parameter as id but creating a div class using that id)
Try using ES6 features (class syntax is really good when writing OOP in JS although it's just a syntactic sugar for prototype)
//creating circles
var widthHeight = 40; // <-- circle width
var margin = 20; // <-- margin - is it necessary ?
var delta = widthHeight + margin;
function createAndInitializeDivObject(id, color) {
let div = document.createElement('div');
var currentTop = 0;
var documentHeight = document.documentElement.clientHeight;
var documentWidth = document.documentElement.clientWidth;
div.setAttribute('class', id);
if (color === undefined) {
let colors = ['#35def2', '#35f242', '#b2f235', '#f2ad35', '#f24735', '#3554f2', '#8535f2', '#eb35f2', '#f2359b', '#f23547'];
div.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)];
}
else {
div.style.backgroundColor = color;
}
div.classList.add("circle");
div.classList.add("animation");
// Get the random positions minus the delta
currentTop = Math.floor(Math.random() * documentHeight) - delta;
currentLeft = Math.floor(Math.random() * documentWidth) - delta;
// Keep the positions between -20px and the current positions
var limitedTop = Math.max(margin * -1, currentTop);
var limitedLeft = Math.max(margin * -1, currentLeft);
div.style.top = limitedTop + "px";
div.style.left = limitedLeft + "px";
document.body.appendChild(div);
var x = new RandomObjectMover(document.querySelector(`.${id}`), window);
x.start();
}
let i = 0;
const oneSecond = 1000;
setInterval(() => {
i += 1;
createAndInitializeDivObject(`circle${i}`)
}, oneSecond);
//move circles
function RandomObjectMover(obj, container) {
this.$object = obj;
this.$container = container;
this.container_is_window = container === window;
this.pixels_per_second = 250;
this.current_position = { x: 0, y: 0 };
this.is_running = false;
}
// Set the speed of movement in Pixels per Second.
RandomObjectMover.prototype.setSpeed = function(pxPerSec) {
this.pixels_per_second = pxPerSec;
}
RandomObjectMover.prototype._getContainerDimensions = function() {
if (this.$container === window) {
return { 'height' : this.$container.innerHeight, 'width' : this.$container.innerWidth };
} else {
return { 'height' : this.$container.clientHeight, 'width' : this.$container.clientWidth };
}
}
RandomObjectMover.prototype._generateNewPosition = function() {
// Get container dimensions minus div size
var containerSize = this._getContainerDimensions();
var availableHeight = containerSize.height - this.$object.clientHeight;
var availableWidth = containerSize.width - this.$object.clientHeight;
// Pick a random place in the space
var y = Math.floor(Math.random() * availableHeight);
var x = Math.floor(Math.random() * availableWidth);
return { x: x, y: y };
}
RandomObjectMover.prototype._calcDelta = function(a, b) {
var dx = a.x - b.x;
var dy = a.y - b.y;
var dist = Math.sqrt( dx*dx + dy*dy );
return dist;
}
RandomObjectMover.prototype._moveOnce = function() {
// Pick a new spot on the page
var next = this._generateNewPosition();
// How far do we have to move?
var delta = this._calcDelta(this.current_position, next);
// Speed of this transition, rounded to 2DP
var speed = Math.round((delta / this.pixels_per_second) * 100) / 100;
//console.log(this.current_position, next, delta, speed);
this.$object.style.transition='transform '+speed+'s linear';
this.$object.style.transform='translate3d('+next.x+'px, '+next.y+'px, 0)';
// Save this new position ready for the next call.
this.current_position = next;
};
RandomObjectMover.prototype.start = function() {
if (this.is_running) {
return;
}
// Make sure our object has the right css set
this.$object.willChange = 'transform';
this.$object.pointerEvents = 'auto';
this.boundEvent = this._moveOnce.bind(this)
// Bind callback to keep things moving
this.$object.addEventListener('transitionend', this.boundEvent);
// Start it moving
this._moveOnce();
this.is_running = true;
}
RandomObjectMover.prototype.stop = function() {
if (!this.is_running) {
return;
}
this.$object.removeEventListener('transitionend', this.boundEvent);
this.is_running = false;
}
// Init it
var x = new RandomObjectMover(document.querySelector(".circle"), window);
// Start it off
x.start();
.circle {
width: 35px;
height: 35px;
border-radius: 35px;
background-color: #ffffff;
border: 3px solid purple;
position: absolute;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="circle"></div>
<script src="app.js"></script>
</body>
</html>

canvas not responding to touch when inside a div on ios safari

I'm trying to get a nice knob/dial that can be rotated to send a value back to the server via websockets.
The basic premise works well, I got the code from the web.
I am trying to modify the code so that I get a prettier knob. I've been successful by placing the canvas inside a couple of divs which display static images, while the canvas rotates a translucent image in response to mouse/touch events.
The additions that I made to the code work well on the desktop (I'm running Firefox 45.0.2) but do not work at all on an iPad (Safari, iOS 9.3.5) and only partially on an iPhone (iOS 10.2.1)
On the iPhone, the knob rotates in the opposite direction to that expected, and often only horizontal movement will start the knob rotating.
I'm not using (nor do I want to use) any libraries such as jquery.
The code below will work as is. However, removing the comment marks in the body section will cause the problems I indicated.
(Oh and to forestall any comments, the black background and odd text colour is just there to so that you can see the translucent element without the static backgrounds)
I'm not at all experienced with jscript and can only just manage to follow what the code is doing at the moment. (one of the reasons I don't want to use additional libraries)
I suspect that the problem lies with how the touch event coordinates are interpreted, but I can't test them in any way.
Any help or suggestions would be appreciated.
HTML Code:
<!DOCTYPE html>
<html>
<head>
<title>Stepper example</title>
<meta name="viewport" content="width=device-width, initial-scale=0.7">
<style>
body {
text-align: center; background-color: black;
color: red
}
.container{
position: relative;
background: url(step_background.png);
width: 480px;
height: 480px;
margin: auto;
z-index:1;
}
.knob{
position: relative;
top: 59px;
background: url(knob_bg.png);
width: 362px;
height:362px;
margin:auto;
z-index:2;
}
#stepper{
position: relative;
}
</style>
<script>
var MIN_TOUCH_RADIUS = 20;
var MAX_TOUCH_RADIUS = 200;
var CANVAS_WIDTH = 362, CANVAS_HEIGHT = 362;
var PIVOT_X = 181, PIVOT_Y = 181;
var plate_angle = 0;
var plate_img = new Image();
var click_state = 0;
var last_angle_pos = 0;
var mouse_xyra = {x:0, y:0, r:0.0, a:0.0};
var ws;
plate_img.src = "knob_fg.png";
function init() {
var stepper = document.getElementById("stepper");
var ctx = stepper.getContext("2d");
stepper.width = CANVAS_WIDTH;
stepper.height = CANVAS_HEIGHT;
stepper.addEventListener("touchstart", mouse_down);
stepper.addEventListener("touchend", mouse_up);
stepper.addEventListener("touchmove", mouse_move);
stepper.addEventListener("mousedown", mouse_down);
stepper.addEventListener("mouseup", mouse_up);
stepper.addEventListener("mousemove", mouse_move);
ctx.translate(PIVOT_X, PIVOT_Y);
rotate_plate(plate_angle);
}
function connect_onclick() {
if(ws == null) {
ws = new WebSocket('ws://'+ window.location.hostname + ':81/', ['arduino']);
document.getElementById("ws_state").innerHTML = "CONNECTING";
ws.onopen = ws_onopen;
ws.onclose = ws_onclose;
ws.onmessage = ws_onmessage;
ws.onerror = function(){ alert("websocket error " + this.url) };
}
else
ws.close();
}
function ws_onopen() {
document.getElementById("ws_state").innerHTML = "<font color='blue'>CONNECTED</font>";
document.getElementById("bt_connect").innerHTML = "Disconnect";
rotate_plate(plate_angle);
}
function ws_onclose() {
document.getElementById("ws_state").innerHTML = "<font color='gray'>CLOSED</font>";
document.getElementById("bt_connect").innerHTML = "Connect";
ws.onopen = null;
ws.onclose = null;
ws.onmessage = null;
ws = null;
rotate_plate(plate_angle);
}
function ws_onmessage(e_msg) {
e_msg = e_msg || window.event; // MessageEvent
plate_angle = Number(e_msg.data);
rotate_plate(plate_angle);
//alert("msg : " + e_msg.data);
}
function rotate_plate(angle) {
var stepper = document.getElementById("stepper");
var ctx = stepper.getContext("2d");
ctx.clearRect(-PIVOT_X, -PIVOT_Y, CANVAS_WIDTH, CANVAS_HEIGHT);
ctx.rotate(-angle / 180 * Math.PI);
ctx.drawImage(plate_img, -PIVOT_X, -PIVOT_Y);
ctx.rotate(angle / 180 * Math.PI);
/*
Currently, the angle displayed and sent as a message appears to be set such that movement in a clockwise direction
reports a negative number. Needs to be looked at, probably by changing "angle.toFixed" to "-angle.toFixed"
*/
if(ws && (ws.readyState == 1))
ws.send(plate_angle.toFixed(4) + "\r\n");
ws_angle = document.getElementById("ws_angle");
ws_angle.innerHTML = angle.toFixed(1);
}
function check_update_xyra(event, mouse_xyra) {
var x, y, r, a;
var min_r, max_r, width;
if(event.touches) {
var touches = event.touches;
x = (touches[0].pageX - touches[0].target.offsetLeft) - PIVOT_X;
y = PIVOT_Y - (touches[0].pageY - touches[0].target.offsetTop);
}
else {
x = event.offsetX - PIVOT_X;
y = PIVOT_Y - event.offsetY;
}
/* cartesian to polar coordinate conversion */
r = Math.sqrt(x * x + y * y);
a = Math.atan2(y, x);
mouse_xyra.x = x;
mouse_xyra.y = y;
mouse_xyra.r = r;
mouse_xyra.a = a;
if((r >= MIN_TOUCH_RADIUS) && (r <= MAX_TOUCH_RADIUS))
return true;
else
return false;
}
function mouse_down(event) {
if(event.target == stepper)
event.preventDefault();
if(event.touches && (event.touches.length > 1))
click_state = event.touches.length;
if(click_state > 1)
return;
if(check_update_xyra(event, mouse_xyra)) {
click_state = 1;
last_angle_pos = mouse_xyra.a / Math.PI * 180.0;
}
}
function mouse_up() {
click_state = 0;
}
function mouse_move(event) {
var angle_pos, angle_offset;
if(event.touches && (event.touches.length > 1))
click_state = event.touches.length;
if(!click_state || (click_state > 1))
return;
if(!check_update_xyra(event, mouse_xyra)) {
click_state = 0;
return;
}
event.preventDefault();
angle_pos = mouse_xyra.a / Math.PI * 180.0;
if(angle_pos < 0.0)
angle_pos = angle_pos + 360.0;
angle_offset = angle_pos - last_angle_pos;
last_angle_pos = angle_pos;
if(angle_offset > 180.0)
angle_offset = -360.0 + angle_offset;
else
if(angle_offset < -180.0)
angle_offset = 360 + angle_offset;
plate_angle += angle_offset;
rotate_plate(plate_angle);
}
window.onload = init;
</script>
</head>
<body>
<h2>
Smart Expansion / Stepper Motor<br><br>
Angle <font id="ws_angle" color="blue">0</font><br><br>
<!--
<div class="container">
<div class="knob">
-->
<canvas id="stepper"></canvas>
<!--
</div>
</div>
-->
<br><br>
WebSocket <font id="ws_state" color="gray">CLOSED</font>
</h2>
<p><button id="bt_connect" type="button" onclick="connect_onclick();">Connect</button></p>
</body>
</html>
I might need to add an additional comment to give the link to the backgound image
knob_bg.png
knob_fg.png
So, after managing to find out how to debug html on an ios device via firefox on windows, I have managed to find out what was causing my code to fail.
The problem was in the function check_update_xyra(event, mouse_xyra)
Specifically the lines :
x = (touches[0].pageX - touches[0].target.offsetLeft) - PIVOT_X;
y = PIVOT_Y - (touches[0].pageY - touches[0].target.offsetTop);
The target.offsetxxx was returning a value of 0. This made the radian value (r) to be out of bounds which caused the function to return false, or in the case of the iPhone caused the touch event to behave strangely.
The reason for for the offsets coming back as 0 was because I did not factor in the fact that they provided the offset from the targets parent only, not the document as a whole.
I managed to fix this by adding some code to add the offsets for all parent elements then used that sum to calculate new x and y coordinates.
My code change follows.
However, if anyone has a more elegant method of calculating the offsets, I would appreciate it.
Cheers...
function check_update_xyra(event, mouse_xyra) {
var x, y, r, a;
var tgtoffleft = 0;
var tgtofftop = 0;
var min_r, max_r, width;
if(event.touches) {
var touches = event.touches;
// Bit of code to calculate the actual Left and Top offsets by adding offsets
// of each parent back through the hierarchy
var tgt = event.touches[0].target;
while (tgt) {
tgtoffleft = tgtoffleft + tgt.offsetLeft;
tgtofftop = tgtofftop + tgt.offsetTop;
tgt = tgt.offsetParent;
}
// x = (touches[0].pageX - touches[0].target.offsetLeft) - PIVOT_X;
// y = PIVOT_Y - (touches[0].pageY - touches[0].target.offsetTop);
x = (touches[0].pageX - tgtoffleft) - PIVOT_X;
y = PIVOT_Y - (touches[0].pageY - tgtofftop);
}
else {
x = event.offsetX - PIVOT_X;
y = PIVOT_Y - event.offsetY;
}
/* cartesian to polar coordinate conversion */
r = Math.sqrt(x * x + y * y);
a = Math.atan2(y, x);
mouse_xyra.x = x;
mouse_xyra.y = y;
mouse_xyra.r = r;
mouse_xyra.a = a;
if((r >= MIN_TOUCH_RADIUS) && (r <= MAX_TOUCH_RADIUS))
return true;
else
return false;
}

How to target a single div with JS

I'm trying to create 'snow' on the background of a single div. The code is below but you can see it here: http://www.getwiththebrand.com/makeabrew_copy/
I want to put the effect on the div with the red border only (number 4).
Can anyone tell me what I'm missing?
<!-- language: lang-js -->
var width = getWidth();
var height = getHeight();
var flakeCount = 50;
var gravity = 0.7;
var windSpeed = 20;
var flakes = [];
function getWidth() {
var x = 0;
if (self.innerHeight) {
x = self.innerWidth;
}
else if (document.documentElement && document.documentElement.clientHeight) {
x = document.documentElement.clientWidth;
}
else if (document.body) {
x = document.body.clientWidth;
}
return x;
}
function getHeight() {
var y = 0;
if (self.innerHeight) {
y = self.innerHeight;
}
else if (document.documentElement && document.documentElement.clientHeight) {
y = document.documentElement.clientHeight;
}
else if (document.body) {
y = document.body.clientHeight;
}
return y;
}
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
var currentFlake = 0;
var snowglobe = document.getElementById("snowglobe");
while (currentFlake < flakeCount) {
var flake = document.createElement("div");
flake.className = 'flake';
flake.style.fontSize = getRandom(12, 24) + 'px';
flake.style.top = getRandom(0, height) + 'px';
flake.style.left = getRandom(0, width) + 'px';
flake.innerHTML = "•";
newFlake = snowglobe.appendChild(flake);
newFlake.speed = getRandom(1, 100);
flakes.push(newFlake);
currentFlake++;
}
function doAnimation() {
for (var i = 0; i < flakes.length; i++) {
newX = false;
newY = false;
// Calculate Y position
newY = parseFloat(flakes[i].style.top) + (flakes[i].speed / 100) * gravity;
if (newY > height) {
newY = 0 - parseInt(flakes[i].style.fontSize);
// If Y is at bottom, randomize X
newX = getRandom(0, width);
}
// Calculate X position if it hasn't been set randomly
if (!newX) newX = parseFloat(flakes[i].style.left) + Math.sin(newY / windSpeed);
if (newX < -20) newX = width + 20;
if (newX > width + 20) newX = -20;
// Set new position
flakes[i].style.top = newY + 'px';
flakes[i].style.left = newX + 'px';
}
}
setInterval(doAnimation, 10);
window.onresize = function(event) {
width = getWidth();
height = getHeight();
}​
<!-- language: lang-css -->
#snowglobe .flake {
position: absolute;
width: 1px;
height: 1px;
color: rgba(255,255,255,0);
text-shadow: 0 0 3px rgba(255,255,255,1);
}​
<!-- language: lang-html -->
<div class="ui-full-width">
<div class="container even" id="snowglobe">
<h3><span class="num">4</span>Add freshly boiled water to the pot</h3>
<p>Give it a stir and secure the lid. Wrap your pot in a tea-cosy if it's nippy outside!</p>
</div>
</div>
<!-- end snippet -->
<div class="ui-full-width">
<div class="container even" id="snowglobe">
<h3><span class="num">4</span>Add freshly boiled water to the pot</h3>
<p>Give it a stir and secure the lid. Wrap your pot in a tea-cosy if it's nippy outside!</p>
</div>
</div>
Your myjs.js has an extra character at the end of the file when it's loaded in my browser and it triggers a rightful
SCRIPT1014: Invalid character
myjs.js (116,2)
The script part:
window.onresize = function(event) {
width = getWidth();
height = getHeight();
}â // << here
Also, I don't know what browser you're using but try hitting F12, you'll get the console and you'll see javascript erros and other useful informations.
Edit: it's even worse, you have multiple characters at the end of your script:
window.onresize = function(event) {
width = getWidth();
height = getHeight();
}​ // ??
Did you mess around with some file encoding options?
thanks for looking. I commented out the code so that's what the extra characters were. I haven't done anything to the file encoding options.
I checked the console and there were some elements undefined. Looks like I missed a whole chunk:
var width = getWidth();
var height = getHeight();
var flakeCount = 50;
var gravity = 0.7;
var windSpeed = 20;
var flakes = [];
All good now!

Javascript only displays in header, but want it to display on whole page

I am using a javascript for falling images. (1) I want the images to cover the whole page, but they are only displaying in the header area. I don't know what portion to change to make it cover the whole page. It's a wordpress site, so maybe that has something to do with it? I put the call to the script in the head section. This is the script:
var image="http://abyssinianguineapigtips.com/wp-content/uploads/2014/11/onepoop.png"; //Image path should be given here
var no = 15; // No of images should fall
var time = 0; // Configure whether image should disappear after x seconds (0=never):
var speed = 10; // Fix how fast the image should fall
var i, dwidth = 900, dheight =500;
var nht = dheight;
var toppos = 0;
if(document.all){
var ie4up = 1;
}else{
var ie4up = 0;
}
if(document.getElementById && !document.all){
var ns6up = 1;
}else{
var ns6up = 0;
}
function getScrollXY() {
var scrOfX = 10, scrOfY = 10;
if( typeof( window.pageYOffset ) == 'number' ) {
//Netscape compliant
scrOfY =window.pageYOffset;
scrOfX = window.pageXOffset;
} else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
//DOM compliant
scrOfY = document.body.scrollTop;
scrOfX = document.body.scrollLeft;
} else if( document.documentElement &&
( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
//IE6 standards compliant mode
scrOfY = document.documentElement.scrollTop;
scrOfX = document.documentElement.scrollLeft;
}
return [ scrOfX, scrOfY ];
}
var timer;
function ranrot()
{
var a = getScrollXY()
if(timer)
{
clearTimeout(timer);
}
toppos = a[1];
dheight = nht+a[1];
//alert(dheight);
timer = setTimeout('ranrot()',2000);
}
ranrot();
function iecompattest()
{
if(document.compatMode && document.compatMode!="BackCompat")
{
return document.documentElement;
}else{
return document.body;
}
}
if (ns6up) {
dwidth = window.innerWidth;
dheight = window.innerHeight;
}
else if (ie4up) {
dwidth = iecompattest().clientWidth;
dheight = iecompattest().clientHeight;
}
nht = dheight;
var cv = new Array();
var px = new Array(); //position variables
var py = new Array(); //position variables
var am = new Array(); //amplitude variables
var sx = new Array(); //step variables
var sy = new Array(); //step variables
for (i = 0; i < no; ++ i) {
cv[i] = 0;
px[i] = Math.random()*(dwidth-100); // set position variables
py[i] = Math.random()*dheight; // set position variables
am[i] = Math.random()*20; // set amplitude variables
sx[i] = 0.02 + Math.random()/10; // set step variables
sy[i] = 0.7 + Math.random(); // set step variables
document.write("<div id=\"dot"+ i +"\" style=\"POSITION: absolute; Z-INDEX: "+ i +"; VISIBILITY: visible; TOP: 15px;LEFT: 15px;\"><img src='"+image+"' border=\"0\"><\/div>");
}
function animation() { // animation function
for (i = 0; i < no; ++ i) { // iterate for every dot
py[i] += sy[i];
if (py[i] > dheight-50) {
px[i] = Math.random()*(dwidth-am[i]-100);
py[i] = toppos;
sx[i] = 0.02 + Math.random()/10;
sy[i] = 0.7 + Math.random();
}
cv[i] += sx[i];
document.getElementById("dot"+i).style.top=py[i]+"px";
document.getElementById("dot"+i).style.left=px[i] + am[i]*Math.sin(cv[i])+"px";
}
atime=setTimeout("animation()", speed);
}
function hideimage(){
if (window.atime) clearTimeout(atime)
for (i=0; i<no; i++)
document.getElementById("dot"+i).style.visibility="hidden"
}
if (ie4up||ns6up){
animation();
if (time>0)
setTimeout("hideimage()", time*1000)
}
animation();
/* Free Script provided by HIOXINDIA */
/* visit us at http://www.hscripts.com */
/* This is a copyright product of hioxindia.com */
The page is here.
My second question is the best way to stop the script from executing when someone clicks on the stop sign image. I've read 10 different answers to similar questions here on stackoverflow. So my thought is to make it happen by using:
<img src="stop.png" onclick="myEventHandler(event);" />
and I add:
function myEventHandler(e)
{
if (!e)
e = window.event;
//IE9 & Other Browsers
if (e.stopPropagation) {
e.stopPropagation();
}
//IE8 and Lower
else {
e.cancelBubble = true;
}
}'
to the js file. (I got that from here)
Is that the best way to make it stop with an onclick?
This was a Z-index problem/ Changing
document.write("<div id=\"dot"+ i +"\" style=\"POSITION: absolute; Z-INDEX: "+ i +"; VISIBILITY: visible; TOP: 15px;LEFT: 15px;\"><img src='"+image+"' border=\"0\"><\/div>");
}
to
document.write("<div class=\"img-object\" id=\"dot"+ i +"\" style=\"POSITION: absolute; Z-INDEX: "+ (i + 1000) +"; VISIBILITY: visible; TOP: 15px;LEFT: 15px;\"><img src='"+image+"' border=\"0\"><\/div>");
}
made it cover the whole page.
And to stop the animation when clicking on an image, this function works:
(html):
<img src="stopsign.png" onclick="stopAnimation();" />
and the function:
function stopAnimation() {
if (window.atime) {clearTimeout(atime);}
jQuery('.img-object').hide();
}

Javascript News Scroller

see the news scroller on the top of this site
http://track.dc.gov/Agency/DH0
Any idea what library/functions this site uses to implment such a smooth scroller?
They have a very nicely formatted block of code you can study. Open your favorite JS debugger when you visit the site, wait for everything to get moving, and then press "Break All" or the equivalent in your debugger. You'll see something like the following:
Dashboard.UI.EndlessLine = function() {
var me = this;
me.jq = $(me);
me.classNames = { CONTAINER: "uiEndless", VIEW: "uiEndlessView", CANVAS: "uiEndlessCanvas", TILE: "uiEndlessTile" };
var canvas = null;
var view = null;
var tiles = null;
var x = 0;
var xx = 0;
var canvasWidth = 0;
var step = 1;
var delay = 40;
me.initialize = function(container, data, handler) {
required(container, "container");
required(data, "data");
required(handler, "handler");
container.addClass(me.classNames.CONTAINER);
view = newDiv(me.classNames.VIEW);
canvas = newDiv(me.classNames.CANVAS);
view.append(canvas);
container.append(view);
x = 0;
xx = 0;
canvasWidth = 0;
tiles = me.populateTiles(data, handler);
container.click(function() {
if (me.started()) me.stop(); else me.start();
});
};
me._resize = function(size) {
};
var moveId = 0;
me.start = function() {
me.stop();
me.tick();
}
me.stop = function() {
if (moveId > 0) clearTimeout(moveId);
moveId = 0;
}
me.started = function() {
return moveId > 0;
};
me.tick = function() {
var tile = tiles.current();
var width = tile.calculatedWidth;
if (x < width - step) {
x += step;
} else {
x = 0;
tile.css("left", canvasWidth + "px");
if (tiles.advance()) {
xx = 0;
canvasWidth = 0;
do {
current = tiles.current();
width = current.calculatedWidth;
current[0].style.left = canvasWidth + "px";
canvasWidth += width;
} while (!tiles.advance());
} else {
canvasWidth += width;
}
}
canvas[0].style.left = -(xx) + "px";
xx += step;
moveId = setTimeout(me.tick, delay);
}
me.populateTiles = function(data, handler) {
var tiles = new Dashboard.Core.List();
var viewWidth = view.contentWidth();
var maxHeight = 0;
each(data, function() {
var tile = newDiv(me.classNames.TILE);
handler.call(this, tile);
tile.css({ left: canvasWidth + "px", top: 0 });
canvas.append(tile);
var width = tile.outerWidth();
var height = tile.outerHeight();
if (maxHeight < height) maxHeight = height;
tile.calculatedWidth = width;
canvasWidth += width; // getting width may only be done after the element is attached to DOM
tiles.append(tile);
view.height(height);
});
return tiles.createCycle();
}
}
I'm impressed -- everything looks professional and nicely namespaced.
Update: If you want an explanation of how it works, focus on the tick method defined above. Glossing over all the details (cause I haven't really studied it myself), it calculates a step size, moves the message element to the left by the some amount, and schedules the next tick call for 40 milliseconds in the future.
jQuery enthusiast, Remy Sharp, has his own Marquee Plugin that you can implement pretty easily. You can gather deeper details of it on his blog or by visiting the demo page.
For Mootools users, there's Mooquee.
You can also view the actual code for this example online at http://track.dc.gov/Resource/Script/ - do a search for "uiEndless" to find the target-scripting.

Categories