I was doing some debugging of a site in Firefox 3.6.21 using Firebug 1.7.3. When the page first loads, the Javascript I am trying to execute doesn't load at all. I open up Firebug to see what the problem is, I hit reload, and all of a sudden it's working.
I have no idea what is going on here.
function initStations() {
//console.log("in stations")
ringContainer = $("#ringContainer");
ringWidth = ringHeight = ringContainer.innerWidth();
//console.log(ringWidth + " " + ringHeight);
originX = (ringWidth / 2) - 0;
originY = (ringHeight / 2);
radius = originY + 20;
//console.log(originX + " " + originY + " " + radius);
// get the ul containing the stations
stationList = $("#stationList");
// an array of the li elements
stationLiElems = $("#stationList li");
// how many stations
length = stationLiElems.size();
// distance between stations in degrees
spacing = (360 / length)
// 360 degrees in circle divided by the number of stations
// array of stations
stations = [];
// debug
//console.log(stationList);
stationLiElems.each(function(index, element) {
//console.log(index +" - "+ spacing);
stations[index] = {
'element' : element,
// http://stackoverflow.com/questions/925118/algorithm-for-finding-out-pixel-coordinates-on-a-circumference-of-a-circle
'x' : originX + radius * Math.sin(spacing * index * 0.0174532925 ),
'y' : originY + radius * Math.cos(spacing * index * 0.0174532925 )
}
$(element).css({'top' : stations[index].y , 'left' : stations[index].x });
});
Had this same issue, and removing console.log fixed it for me. I see you have commented it out, but check you aren't using it elsewhere.
Related
So, I've built a quick function to change hue values of a target element in JavaScript, and it works mostly fine now, but I do have some more questions that go beyond the initial post's scope. So I'll open a new question and post them here.
Here's the code:
document.getElementById('left').style.filter = "hue-rotate(" + 20 + "deg)";
document.getElementById('right').style.filter = "hue-rotate(" + 20 + "deg)";
document.querySelectorAll('div').forEach(occurence => {
occurence.addEventListener('click', (e) => {
const filter = e.target.style.filter;
var deg = parseInt(filter.replace(/[^0-9.]/g, ""));
deg += 40;
e.target.style.filter = "hue-rotate(" + deg + "deg)";
if (deg >= 360) {deg -= 360}
console.log(e.target.id + " is " + deg + "deg");
});
});
My main question (1) is that I've coded an if statement to log the current hue value within 360º (the hue-rotate works anyway with values over +360º, but I find it to be clearer this way). However, while the check works perfectly the first time around, it stops working after the function loops once through the 360º (on subsequent loops, it goes beyond 360º).
For clarification, the statement has been positioned after the degree value is already set (and animated) so as to sidestep the quick loop animation that happens when it goes from, say, 340 to 20º (instead of going there directly, it seems to loop back through the whole hue wheel).
Also, (2) the initial hue-rotate states are defined (at the top) within the script because the function does not work otherwise, although both DIVs do have defined CSS values.
That's it! Thanks in advance!
Since the degree value on the element is always set before limiting the degrees to 360, the 2nd time it loops subtracting 360 wont be enough.
style logged value
0 0
360 (-360) 0
720 (-360) 360
etc
To limit the logged value between [0, 360], use the % operator instead
document.querySelectorAll('div').forEach(occurence => {
occurence.addEventListener('click', (e) => {
const filter = e.target.style.filter;
var deg = parseInt(filter.replace(/[^0-9.]/g, ""));
deg += 40;
e.target.style.filter = "hue-rotate(" + deg + "deg)";
deg %= 360; // deg = deg % 360
console.log(e.target.id + " is " + deg + "deg");
});
});
For (2):
To get the style of the element from css, use getComputedStyle
occurence.addEventListener('click', (e) => {
const filter = getComputedStyle(e.target).filter;
...
});
e.target.style.filter = "hue-rotate(" + deg + "deg)";
above line should be below if condition if (deg >= 360) {deg -= 360}
document.getElementById('left').style.filter = "hue-rotate(" + 20 + "deg)";
document.getElementById('right').style.filter = "hue-rotate(" + 20 + "deg)";
document.querySelectorAll('div').forEach(occurence => {
occurence.addEventListener('click', (e) => {
const filter = e.target.style.filter;
console.log(filter);
let deg = parseInt(filter.replace(/[^0-9.]/g, ""));
deg += 40;
if (deg >= 360) {
deg -= 360
}
e.target.style.filter = "hue-rotate(" + deg + "deg)";
console.log(e.target.id + " is " + deg + "deg");
});
});
<div id="left">left</div>
<div id="right">right</div>
I am currently writing a tracking app that is able to get your currently facing angle and the angle to a destination and point an arrow in the direction you need to travel. (As the crow flies)
I am having trouble taking these 2 angles and making them work together so that the arrow points in the correct direction.
My knowledge of Mathematics is extremely limited so any help would be appreciated.
function deviceOrientationListener(event) {
facing = Math.round(event.alpha);
deg = bearing(lat, lng, getUrlVars()["lat"], getUrlVars()["long"]);
finaldeg = facing - deg;
c.innerHTML = '<img style="-ms-transform: rotate(' + finaldeg + 'deg);-webkit-transform: rotate(' + finaldeg + 'deg);transform: rotate(' + finaldeg + 'deg);" src="images/arrow.png" />';
}
The finaldeg is what i am having trouble with working out.
I did like this with Ionic and the plugin cordova-plugin-device-orientation
to_turn is the variable in which I record the computed angle
degreeStyle is the style applied to the arrow shown on end-user's
screen
last_lat/last_lng is the current position of the user
target_lat/target_lng is the destination
`
this.destinationBearing = this.bearing(
this.last_lat,
this.last_lng,
this.target_lat,
this.target_lng);
this.compass = this.deviceOrientation.watchHeading().subscribe(
(data: DeviceOrientationCompassHeading) => {
this.currentHeading = data.trueHeading;
if (this.destinationBearing > this.currentHeading) {
this.to_turn = this.destinationBearing - this.currentHeading;
} else {
this.to_turn = 360 - (this.currentHeading - this.destinationBearing);
}
this.degreeStyle = 'rotate(' + this.to_turn + 'deg)';
}
);
bearing(startLat, startLng, destLat, destLng){
startLat = this.toRadians(startLat);
startLng = this.toRadians(startLng);
destLat = this.toRadians(destLat);
destLng = this.toRadians(destLng);
let y = Math.sin(destLng - startLng) * Math.cos(destLat);
let x = Math.cos(startLat) * Math.sin(destLat) -
Math.sin(startLat) * Math.cos(destLat) * Math.cos(destLng - startLng);
let brng = Math.atan2(y, x);
brng = this.toDegrees(brng);
return (brng + 360) % 360;
}
toRadians(degrees) {
return degrees * Math.PI / 180;
};
toDegrees(radians) {
return radians * 180 / Math.PI;
}
I have this function set up
if (window.innerWidth && window.innerHeight) {
var winW = window.innerWidth;
}
var xM = winW/180;
var axis = 0;
$(window).bind('mousemove',function(e){
var xCoord = Math.floor(e.pageX/xM);
axis = 0.6 * Math.sin(xCoord);
var pageCoords = "( " + e.pageX + ", " + e.pageY + ", " + xCoord + " )";
$("span#showme").text(pageCoords);
});
setInterval(function() {
$("#welcome-background").fadeTo(0, 0.4 + axis);
}, 100);
(for additional reference and working visual- http://jsfiddle.net/ySjqh/2/ )
The code works in theory to divide the page evenly into segments from 0-180, then calculates which segment the mouse appears in. Then uses the Math.sin() function to derive how much opacity to apply, based on a padded starting point of 0.4 opacity (jQuery style), and should use the mouse position to determine how much of the remaining 0.6 to apply based on its distance from center, where mouse at center-page should yield full opacity.
What I don't get is why the script behaves this way, rolling through an entire sine wave when I've limited the input to the Math.sin(x) function to 1 < x < 180. If you replace xCoord with axis in the place where I build the jQuery text for #showme, you'll see that it throws negative numbers- which shouldn't be happening! ... so I don't get what the problem/behavior results from!!! Frustrating!!!
Just use:
xCoord = (xCoord * Math.PI) / 180; // Convert value to Radians
and it works..
Sample
http://jsfiddle.net/ySjqh/4/
axis = 0.6 * (1 - Math.abs(e.pageX - winW/2)/(winW/2));
Using the X distance from the center instead of sin.
I am using Javascript to drag and simulate rotating an image by using multiple frames showing the image in 360 degrees. I am relatively new to JavaScript and am having a hard time with the script in trying to insert a trigger that would cause overlaying images to fade in and out when certain frames (degrees) of the image are displayed. For example, when I drag, rotate and reveal the front side of the image, let's say a range of frame 10 to frame 45, 4 popup labels will fade in (simultaneously) and remain visible until I drag and rotate the image away from that range of frame, causing the labels to fade out. On the backside of the image I would like to have 3 popup labels appear once any frame within the acceptable range of frames are displayed, let's say, frames 95 through 135. Is this possible? Please see the code that I have been working off of below:
/*** configuration variables ***/
var
totalFrames = 72,
frameUrlTemplate =
'images/frames/Skeleton_[#frame].jpg'
;
/*** state variables ***/
var
rotation = 0,
lastFrameNo = -1,
dragStartRotation
;
/*** create the Uize.Widget.Drag instance ***/
var rotationViewer = page.addChild (
'rotationViewer',
Uize.Widget.Drag,
{
cancelFade:{duration:2000,curve:Uize.Curve.Rubber.easeOutBounce ()},
releaseTravel:function (speed) {
var
deceleration = 2000, // measured in pixels/s/s
duration = speed / deceleration
;
return {
duration:duration,
distance:Math.round (speed * duration / 2),
curve:function (_value) {return 1 - (_value = 1 - _value) * _value}
};
},
html:function (input) {
var
htmlChunks = [],
frameNodeIdPrefix = input.idPrefix + '-frame'
;
for (var frameNo = 0; ++frameNo <= totalFrames;) {
htmlChunks.push (
'<img' +
' id="' + frameNodeIdPrefix + frameNo + '"' +
' src="' + Uize.substituteInto (frameUrlTemplate,{frame:(frameNo < 10 ? '0' : '') + frameNo}) +'"' +
'/>'
);
}
return htmlChunks.join ('');
},
built:false
}
);
/*** wire up the drag widget with events for updating rotation degree ***/
function updateRotation (newRotation) {
rotation = ((newRotation % 360) + 360) % 360;
var frameNo = 1 + Math.round (rotation / 360 * (totalFrames - 1));
if (frameNo != lastFrameNo) {
rotationViewer.showNode ('frame'+ lastFrameNo,false);
rotationViewer.showNode ('frame'+ (lastFrameNo = frameNo));
}
}
rotationViewer.wire ({
'Drag Start':function () {dragStartRotation = rotation},
'Drag Update':function (e) {updateRotation (dragStartRotation - e.source.eventDeltaPos [0] / -2.5)}
});
/*** function for animating spin ***/
function spin (degrees,duration,curve) {
Uize.Fade.fade (updateRotation,rotation,rotation + degrees,duration,{quantization:1,curve:curve});
}
/*** initialization ***/
Uize.Node.wire (window,'load',function () {spin (-360,2700,Uize.Curve.easeInOutPow (4))});
/*** wire up the page widget ***/
page.wireUi ();
I'd appreciate any advice on this. Thanks!!
-Adam
there are 3d transforms in javascrip fot html elements, even a few libaries.
if its a flat image, use that.
if its 3d you wish to simulate you already get very realistc effect with just 120 pictures.
rotation = ((newRotation % 360) + 360) % 360;
var frameNo = 1 + Math.round (rotation / 360 * (totalFrames -1));
if (frameNo > 0 && frameNo< 60 )//code to show box
I'm working on an orbit simulation I have the planet orbiting, but if you look at the inner 3 planets then shift from the orbit's dashed line. On the bottom of the orbit the planet is below the line. At the top of the orbit the planet is either on or above the dashed line.
You can see a working example here.
I think this has to do with the border width not being taken into account but everything I've tried to correct the issue hasn't worked. I'm currently using outerWidth() and outerHeight() but that doesn't seem to be doing the trick.
This is the relevant bit of code:
var width = parseFloat($(this).parent().outerWidth()) / 2;
var height = parseFloat($(this).parent().outerHeight()) / 2;
var point = getPoint(width, height, angle * (Math.PI / 180));
$(this).css('left', point[0] + ($(this).parent().outerWidth() / 2) + 'px');
$(this).css('top', point[1] + ($(this).parent().outerHeight() / 2) + 'px');
The getPoint function is:
function getPoint(width, height, angle)
{
var x = parseFloat(width) * Math.cos(angle);
var y = parseFloat(height) * Math.sin(angle);
return [x, y];
}
You're right - it's the border size. I checked the CSS and it seemed fine, but the smaller planets were visibly off center.
To fix it, all I did was change these lines:
'margin-top' : '-' + ($(this).outerHeight() / 2) + 'px',
'margin-left' : '-' + ($(this).outerWidth() / 2) + 'px'
To this (added two before dividing):
'margin-top' : '-' + (($(this).outerHeight() + 2) / 2) + 'px',
'margin-left' : '-' + (($(this).outerWidth() + 2) / 2) + 'px'
You can see a working example at the updated fiddle here.
UPDATE - seems this isn't totally fixing the problem - as the planets round to the RHS of the orbit, they start to travel to the outer edge. On the up side though, you know that the fix is in those two lines... you just need to compensate for the position in the right amount, which I believe may end up being dynamic or something based on planet position.