JavaScript Windows 8 app setInterval() issue - javascript

Basically I have this code in MS Visual studio 2012 for a windows 8 JavaScript+jQuery app.
<script>
window.setInterval(function () {
var currentx = $(".ball").css("left");
var currenty = $(".ball").css("top");
$(".ball").css("top", currentx + 1);
$(".ball").css("left", currenty + 1);
//debug
var time=1;
$("p.test").text("Has been called " +time);
var time=time+1;
}, 100);
</script>
Yes, I am using jQuery 2.0
Now I looked at the API's here http://www.w3schools.com/js/js_timing.asp
and here http://api.jquery.com/css/
My code compiles, but it just is not updating the position of the ball. It appears it is only being called once. If it helps the ball is a DIV element. Maybe windows 8 Apps don't fully support DOM manipulation, or just the Window global variable, I don't really know.
What code would I need to achieve my goal of updating this element of class ball's top and left CSS rules at set intervals?

.css("left") and .css("top") return a string (e.g. 0px) and not a number so you need to parse it with parseInt otherwise the currentx + 1 results in e.g. 0px1
And it looks like it is only called once because time is defined and set to 1 in the setIntervalcallback, you need to define and initialize it outside of the callback of setInterval.
instead of .css("left") you could also think over using .position().left.
(function() {
var time=1;
window.setInterval(function () {
var currentx = parseInt($(".ball").css("left"),10);
var currenty = parseInt($(".ball").css("top"),10);
$(".ball").css("top", currentx + 1);
$(".ball").css("left", currenty + 1);
//debug
$("p.test").text("Has been called " +time);
time=time+1;
}, 100);
})();

Related

Calculate div number with distance

I'm making a carousel like a casino roulette but i can't find the way to know which div number is when i make the animation. I'm trying to calculate by distance when i make the animation loop but i doesn't work
Here's my example
https://codepen.io/anon/pen/xXbpJr?page=1&
var giftamount = 10;
var gw = $('.gift').outerWidth(true);
var giftcenter = gw/2;
var cycle = 7;
var containercenter = $('.boxwrapper').outerWidth(true)/2;
for(var i = 0; i <=5; i++)
{
var giftduplicate = $('.giftwrapper').children().clone(true,true);
$('.giftwrapper').append(giftduplicate);
}
$('.button').click(function(){
var btn = $(this);
btn.hide();
var randomgift = Math.floor((Math.random() * 10) + 1);
var distance = giftamount * gw * cycle + containercenter + (randomgift*gw) - giftcenter;
console.log(distance);
$( ".giftwrapper" ).css({left: "0"});
$('.giftwrapper').animate({left: "-="+distance},10000,function(){
alert('You Won Gift' + randomgift);
btn.show();
});
});
i get the wrong number of div, i tried a lot of combination but it doesn't work
You can try and substitute this for the distance
var distance = giftamount * cycle * gw + (randomgift*gw) - containercenter -24;
The idea is the following: with distance=- containercenter; you would move to be left-aligned with the center of the container.
To that you add a certain number of cycles giftamount * cycle * gw and finally a random number of gift elements ((randomgift*gw)).
I could not figure out where the constant -24 comes from. I hard-coded and it needs to be better defined but I guess it might depend on some margins/approximations/jQuery/CSS/??
Now you should see that the animation always stops at the same point within the gift element (in the middle). To add a random deviation you could ad a small deviation dev (that lets you stay within the gift element) like this:
var dev = Math.random()*(giftcenter+1);
var distance = giftamount * cycle * gw + (randomgift*gw) - containercenter -24 +dev;
Updated demo: https://codepen.io/anon/pen/RLNeBX
If you want to get the prize that is underneath the pointer (the vertical red bar), you actually do not have to compute the distance. Instead, you can make use of a really handy but somewhat less known DOM API method known as elementFromPoint(x, y), where you can obtain a reference to the topmost DOM node under the x,y coordinate of the page.
In order for this to work, x and y will have to correspond to the visual center of the pointer, which can we can simply calculate by using:
var $pointer = $('.rafflebox .pointer');
var pointerX = $pointer.offset().left + $pointer.width() * 0.5;
var pointerY = $pointer.offset().top + $pointer.height() * 0.5;
In jQuery's animation callback, you simply can retrieve the element (aka the prize) underneath this coordinate:
// Hide pointer first, otherwise it will be returned as the topmost element
$pointer.hide();
// Get element from pointer's visual center
var prize = document.elementFromPoint(pointerX, pointerY);
// Show it again
$pointer.show();
Now you have the correct reference to the DOM node, it is up to you to decide what kind of metadata you want to store in the "prize" DOM node. For example, you can embed a HTML5 data- attribute in your HAML:
%img{:src => "http://placehold.it/125x125?text=Prize+#{i}", :data => {:prize => "Prize #{i}"}}
...which simply stores the text Prize (n) (where n is the prize number) in the attribute data-prize, and we can access it later using:
var prize = document.elementFromPoint(pointerX, pointerY);
console.log($(prize).data('prize'));
When we replace part of your code with what I have suggested, you get this:
// Get visual center of pointer
var $pointer = $('.rafflebox .pointer');
var pointerX = $pointer.offset().left + $pointer.width() * 0.5;
var pointerY = $pointer.offset().top + $pointer.height() * 0.5;
$( ".giftwrapper" ).css({left: "0"});
$('.giftwrapper').animate({left: "-="+distance},10000,function(){
// Hide pointer first, otherwise it will be returned as the topmost element
$pointer.hide();
// Get element from pointer's visual center
var prize = document.elementFromPoint(pointerX, pointerY);
// Show it again
$pointer.show();
alert('You Won Gift ' + $(prize).data('prize'));
btn.show();
});
Here is your updated pen with a working example: https://codepen.io/terrymun/pen/dVPdMg
Updated example
There is a very small chance that the pointer will land in between prizes. To prevent this, you will want to use padding instead of margin on the .gift element:
.gift {
// Change margin to padding
padding: 0px 4px;
}
...and perform additional checks on the returned prize node:
// Hide pointer first, otherwise it will be returned as the topmost element
$pointer.hide();
// Get element from pointer's visual center
var $prize = $(document.elementFromPoint(pointerX, pointerY));
// If prize lands on the .gift element instead
if(!$prize.is('img'))
$prize = $prize.find('img')
// Show it again
$pointer.show();
alert('You Won Gift' + $prize.data('prize'));
btn.show();
The pen here is simply a fork of the original solution, but with exaggerated horizontal padding to increase the chance of the pointer landing in between iamges: https://codepen.io/terrymun/pen/rGaJmY

How to correctly get mouse coordinates with JavaScript without JQuery?

I am aware of the fact that variations of that question were asked many times before. Looking through Google output I found pages with examples like that:
function point_it(event) {
pos_x = event.offsetX ? (event.offsetX) : event.pageX - document.getElementById("pointer_div").offsetLeft;
pos_y = event.offsetY ? (event.offsetY) : event.pageY - document.getElementById("pointer_div").offsetTop;
document.pointform.form_x.value = pos_x;
document.pointform.form_y.value = pos_y;
}
The code works, but when I look at
MouseEvent.offsetX it says "This is an experimental technology...".
So my question is, is it save to use the above construction or not? Is it better to learn how to use JQuery?
Please try this
function getClickPosition(e) {
var xPosition = e.clientX;
var yPosition = e.clientY;
}
Call this function on "onClick" event. You can get the coordinates.
Output the coordinates of the mouse pointer when the mouse button is clicked on an element.

JavaScript filter hueRotate does not work

I am trying to change an image's (#bgImage) hue when hovering over a button (profIcon) in JavaScript. This type of button is created with JS, and there are 9 of them.
Here is the code that creates a DOM image element, sets it's source, position, size and transition. Finally it appends it to it's container. The image appears correctly, where it should be.
I am using quickID in place of document.getElementById, and it is working without error.
var bgImage = document.createElement("img");
bgImage.id = "bgImage";
bgImage.src = "./resources/images/backgrounds/profession/selector.jpg";
bgImage.style.position = "absolute";
bgImage.style.left = "0px";
bgImage.style.top = "0px";
bgImage.style.width = "100%";
bgImage.style.height = "100%";
bgImage.style.zIndex = 1;
bgImage.style.webkitTransition = "all 0.5s ease";
quickID("centerdiv").appendChild(bgImage);
Here is the code that runs when I hover over an image:
profIcon.onmouseover = function () {
var thisNr = this.id.substr(8); //last char of the profIcon ID; number between 0 and 8
var newHue = profTomb[thisNr][3]; //this contains the value and only that.
console.log(newHue); //always returns the correct value
quickID(this.id).style.webkitFilter = "grayscale(0%)"; //this part works, too
quickID("bgImage").style.webkitFilter = "hueRotate(" + newHue + "deg)";
}
My problem: for some reason, the filter does not apply. newHue is either a positive (75), or a negative (-23) value and it's inserted correctly, as it appears in the console log. I only use webkit vendor prefix as I use Google Chrome.
I waited up to 1 minute with my mouse cursor over the image, thinking my system needs time to process the transformation, but nothing happened.
Does anyone knows what is the problem?
The correct string to use is hue-rotate, not hueRotate. The following should work:
quickID("bgImage").style.webkitFilter = "hue-rotate(" + newHue + "deg)";

edit parameters of iscroll4 given at the time of initialisation

I am trying to use iscroll4 in my IOS app development with cordova 2.1.0.
<script type="application/javascript" src="iscroll.js"></script>
<script type="text/javascript">
var myScroll;
function loaded() {
setTimeout(function () {
myScroll = new iScroll('wrapper');
}, 100);
}
window.addEventListener('load', loaded, false);
</script>
If i want to edit the parameters like vScroll , vScrollBar,fixedScrollbar etc. dynamically ie. after the initialisation of iscroll(myScroll = new iScroll('wrapper');), how can i do it in javascript.
Thanks in advance.
I wouldn't try to look for an 'works in every situation'-solution.
I would:
Sum up the particular options you would want to modify.
See which of these options matter during initialitation
programmatically (manually) change these options
options that only matter at runtime (i.e. are read when an event occurs), I'd simply try to modify the myScroller.options object.
For example, you can set these options:
myScroller = new iScroll( el, { x:20, y:30, onRefresh: function(){ alert(11); } } );
Would you want to modify these 3 (or more..), considering my steps you'd do:
x, y, scrollbarClass
in the initialization we see that x & y are used (line 120):
// Set starting position
that.x = that.options.x;
that.y = that.options.y;
That means that these options influences more than just runtime stuff, during initialization it modifies that.x en that.y (even tho pretty simple so far).
3.
myScroller.x = newX;
myScroller.options.x = newX;
myScroller.y = newY;
myScroller.options.y = newY;
// Also depeneds on x & y, but only do this if you actually useTransform and care about this!
/*
* obtain required variables..
*/
var appVersion = navigator.appVersion,
vendor = (/webkit/i).test(appVersion) ? 'webkit' :
(/firefox/i).test(navigator.userAgent) ? 'Moz' :
'opera' in window ? 'O' : '',
has3d = 'WebKitCSSMatrix' in window && 'm11' in new WebKitCSSMatrix(),
trnOpen = 'translate' + (has3d ? '3d(' : '('),
trnClose = has3d ? ',0)' : ')';
// Code that actually matters, and where we use above variables
if (that.options.useTransform) that.scroller.style[vendor + 'Transform'] = trnOpen + that.newX + 'px,' + that.newY + 'px' + trnClose;
else that.scroller.style.cssText += ';position:absolute;top:' + that.newY + 'px;left:' + that.newX + 'px';
4.
myScroller.options.onRefresh = function() { alert(33); }
Maybe you can even do all these things in the options.onDestroy property ;)
Update: I also noticed the destroy function, and might come in convenient if you do want to 'totally clear' the scroller. But I didn't see code that would remove the physically created scrollbar, but I'm not sure.

Articulated animation

I am trying to figure out how to sequence the train animation so I can offset and rotate each wagon in turn around curves, for example, in Route_51 (click Test>Run[twice]) in this display. Needs Chrome or other HTML5 compliant browser.
Here is my so far 'non-complying' code (using KineticJs):
function animate(nr,path,incr,train,dirX,dirY){
var steps,offsetX,offsetY,count,a;
steps = Math.round(path[nr][2] / incr);
offsetX = path[nr][2]/steps;
offsetY = path[nr][3]/steps;
count = 0;
stage.onFrame(function(frame){
layer = train[0].getLayer();
if(count < steps){
for(a=0; a<train.length; a+=1){
incrX = train[a].getX() + offsetX * -dirX;
incrY = train[a].getY() - offsetY * -dirY;
train[a].setX(incrX);
train[a].setY(incrY);
}
layer.draw();
count += 1;
}
else{
stage.stop();
nr += 1;
if(path[nr]){
animate(nr,path,incr,train,dirX,dirY);
}
}
});
stage.start();
}
I don't seem to be able to grasp the logic (getting old).
All help appreciated. Thanks.
It seems a certain amount of time has to pass before some kind of logic emerges.
In this case it was that each loco/wagon needed its own fully incremented path for the starts and optionally finishes to be staggered. Here is a screenshot of the train in motion with the "normal" scale view inset. Room for improvement of course especially with curve coordinates.
For the animation visit http://glasier.hk and follow the KJS link.

Categories

Resources