Trying to play a sound via javascript and want to change it dynamically using sessionstorage
The following is a simplified version that plays sound/s in android/FF Linux/Win when u click the "sprite me button" - I've included other buttons for the example to set and retrieve session values in HTML5.
http://globability.org/webapp/asprite20111124_8.html
The wiki below has Android phone specs where it works: (Samsung Galaxy SII) in case you're interested
http://globability.org/wiki/doku.php?id=current_working_specs_p-tab / also see http://globability.org/wiki/doku.php?id=mobile_pointing_tablet to get a proper idea about what it is that I am working on.
What I need is to have the "play soundsprite" javascript that you can see below in the following section load from sessionstorage and insert values loaded from sessionstorage inserted into an array.
I am not looking for any changes is how the sound is played back - just need to make a dynamically built array work from within the particular javascript.
The code below is based on the soundsprite idea from www.phpied.com/audio-sprites/ by Stoyan Stefanov - made to reduce the http calls needed for playing sounds... Also stabilizes the sound quality, less choppy sound etc.
Antway here goes: YOU ONLY NEED TO LOOK AT PSEUDOCODE SECTION - The rest is functioning
<script>
var thing = 'the thing';
function shut() {
if (typeof thing.pause !== 'undefined') {
thing.pause();
}
}
function log(what) {
document.getElementById('log').innerHTML += what + "<br>";
}
var spriteme = function(){
var sprites = {
// id: [start, length]
'blank':[0.1, 0.5], //This the first sprite, it has to be the first defined and is
called first, it is a blank piece of sound in the combined sound file and needed as of
now.
'success':[13, 2,5],
/* I would like to be able to set the parameters i.e. sound bite to play dynamically -
here a pseudocode example using session storage in preparation for getting the sound
parameters from a database
'wordgen'[null,null];
//this array should be dynamically built from values read from the two session storage keys not sure you need the new thing in HTML5
sessionStorage.globabilitykey1;
sessionStorage.globabilitykey2;
strkey1=globabilitykey1
strkey2=globabilitykey2
var gkey1=parsefloat(strkey1)
var gkey2=parsefloat(strkey2)
'wordgen':[gkey1,gkey2]
and then the idea is to replace the array success in the script with the "generated"
array 'wordgen' to allow dynamic seting of sound to play back */
//the following are sound bites from the collection of soundsprites the site plays from
'word1': [0.5, 2,36], //one
'word2': [3.1, 3.0], //two
'word3': [7.0, 1.82], //three
'word4': [10.03, 2], //four ?
},
song = ['blank', 'success'],
//here you're setting the playback sequence (this is where I would like to replace 'success' with 'wordgen'
current = 0,
id = song[current],
start = 0,
end = sprites[id][1],
int;
thing = document.getElementById('sprite');
thing.play();
log('file: ' + thing.currentSrc);
log(id + ': start: ' + sprites[id].join(', length: '));
// change
int = setInterval(function() {
if (thing.currentTime > end) {
thing.pause();
if (current === song.length - 1) {
clearInterval(int);
return;
}
current++;
id = song[current];
start = sprites[id][0];
end = start + sprites[id][1]
thing.currentTime = start;
thing.play();
log(id + ': start: ' + sprites[id].join(', length: '));
}
}, 10);
};
</script>
Any ideas on how to dynamically create the 'wordgen' array within the javascript based on the values is sessionstorage ?
The whole code/working example can be seen here: http://globability.org/webapp/asprite20111124_8.html
I know the page is one ugly mess... but this is an alpha prototype :)
Argh... it was sooooo simple, I was this close to solving it myself, however a kind freelancer at freelancer.com who has perviously helped me getting one of my ideas to work did it again this time...
And without further ado:
'wordgen':eval("["+sessionStorage.globabilitykey1+","+sessionStorage.globabilitykey2+"]"),
That was what I needed - I had been trying to do the same but without the " eval " in front and the paranthesis around the arguments....
Oh and don't forget to set the value by clicking the button before you try or there will be no sound coming out of your speakers ;)
Here's a link to the working page if you care to try and if you want to see the code in it's "entirity": http://globability.org/webapp/asprite20111201_2.html - Thanks to those of you voting the question up!!!
Related
I've made an event in Google Tag Manager, which triggers when a specific page is loaded.
The Event label is the value of my user defined variable SearchCounter with type: Custom JavaScript.
In 'SearchCounter' I have the following JS:
function(){
var counter;
if(localStorage.getItem("count_search") === null || localStorage.getItem("count_search") === 'undefined'){
localStorage.setItem("count_search", "1");
return localStorage.getItem("count_search");
}
else{
counter = parseInt(localStorage.getItem("count_search"));
counter = counter + 1;
localStorage.setItem("count_search", counter);
return localStorage.getItem("count_search");
}
return localStorage.getItem("count_search");
}
When I don't have the item in my local storage already, it still give's me 7 instead of 1. Then I'll press F5: count_search = 17, And again f5: 27. A CTRL-F5 gives me 37.
It should be 1, 2, 3, 4, 5 etcetera.
I hope someone can help me to implement a counter-alike function in Google Tag Manager, so I can send the amount of searches to GA, when a goal has been achieved. So, When someone clicks a specific button a would like to get the value of count_search, to send it to GA within an event.
Thanks very much.
First of all this metric is given by google analytics by default so i don't see why ur trying to store it somewhere else. If you dont want the avg that google uses you can just store a custom dimension at 'Session' level with the sessionID and those in a custom report open Sessions by pageviews. Here is info about it.
On the other hand, if you insist doing it your way i think even if this works it isn't the best approach you would get a much better result storing the counter in a custom dimension at 'Session' level. (It ll overwrite the value each time for a given session and you ll end up with the last one send)
Hope it helps.
What you need to do is changing the name of the parameter saved in the localStorage. I don't know why, but count_search does not work. I tested your setup and encountered the same weird effect where the count_search item is summing up to astronomical numbers. Using a different name like thisIsMyPageViewCounter works just fine though! Probably count_search is accessed by another object in the document or window and you managed to get a value out of it by chance.
If you want to add the page view count to an event, I do not see any other way than creating both a Custom HTML Tag to set the counter and a Custom JS Variable to return the count.
This is the Custom HTML Script to be added to each page view:
<script>
(function() {
if(localStorage.getItem("thisIsMyPageViewCounter") === null || localStorage.getItem("thisIsMyPageViewCounter") === 'undefined') {
localStorage.setItem("thisIsMyPageViewCounter", 1);
} else {
var counter = 0;
counter = parseInt(localStorage.getItem("thisIsMyPageViewCounter"));
counter = counter + 1;
localStorage.setItem("thisIsMyPageViewCounter", counter);
}
})();
</script>
This is the Custom JS Variable to be added as a value to the event:
function() {
pageviewCounter = parseInt(localStorage.getItem("thisIsMyPageViewCounter"));
return pageviewCounter;
}
I hope this helps!
I am trying to achieve an effect like this on mobile (ios + android):
http://i.imgur.com/6zaTdRd.png
Where the currently selected textfield has a blue tinted icon + underlining
So my framework lacks any support for grey scaling a bitmap image of any sort so I need to swap between two images to achieve this effect.
My current implementation looks like this:
Please note this for the Titanium Alloy MVC framework but I'm guessing the basic logic should be similar.
I listen for blur/focus events to toggle current image
$.firstNameField.addEventListener('focus', function(e){
swapImages($.firstNameField.getParent());
});
$.lastNameField.addEventListener('focus', function(e){
swapImages($.lastNameField.getParent());
});
and then I swap images like so:
/**
* Swaps between the images (..._0 and ..._1) of an ImageView nested in a
TableRow
* ..._0 Greyscale image
* ..._0 Colour image
* #param e current TableViewRow
*/
function swapImages(e){
var imagePathSplit = (e.children[0].image).split('_');
var newImagePath = null;
if(imagePathSplit[1] == "0.png")
newImagePath = imagePathSplit[0] + "_1.png";
else
newImagePath = imagePathSplit[0] + "_0.png";
e.children[0].image = newImagePath;
return;
}
This doesn't look that great especially since I need a lot more fields with this functionality, I also want to implement tabbing (using Return key = NEXT) between the fields which will further balloon to increase 1 more event listener per field.
How would something like this be done ideally? I can think of one way of just creating the fields in code in array form which should help simplify matters (no more looking too far for Parent/Children, but that would still end up using quite a bit of listeners for switching right?
EDIT: Forgot to add how I have the textFields setup:
<TableView id="paypalTable">
<TableViewSection>
<TableViewRow id="firstNameView" class="tableRow">
<ImageView id="firstNameIcon" class="textFieldIcon"/>
<TextField id="firstNameField" class="textField"/>
</TableViewRow>
I tried something similar in one of my projects. Although I had an Alloy project I had to use a classic approach to get my desired behaviour.
In my controller:
var textFields = [];
var yourTextFieldsArray = [];
for (var i = 0; i < yourTextFieldsArray; i++) {
//Set the selected state to false initially. Maybe you need another command for it.
textFieldIsSelected[i] = false;
//create your new view
textFields[i] = Ti.UI.createView({
top : topValues[i],
width : Titanium.UI.FILL,
height : height,
id : i + 1,
touchEnabled : true
});
textFields[i].addEventListener('click', function(e) {
//Check the source id
if (e.source.id - 1 > -1) {
//use your function swapImages(e.source.id). Notice the slightly different parameter since you do not need the complete event.
swapImages(e.source.id);
}
}
function swapImages(id){
//Check the the path variable as you did
var imagePathSplit = (textFields[i-1].image).split('_');
var newImagePath = null;
if(imagePathSplit[1] == "0.png")
newImagePath = imagePathSplit[0] + "_1.png";
else
newImagePath = imagePathSplit[0] + "_0.png";
textFields[i-1].image = newImagePath;
}
This approach lets you use the same event listener for every property.
Please notice that my ids start at 1 and not at 0. This is because I had to implement such a behaviour for images and ImageViews do not accept id=0. My guess is that TextViews don't do it either so you should stick with it. Further notice that you need to decrement the id to get the corresponding object in the textFields Array. Otherwise you would get an out of bounds error.
You should create one more event listener for your NEXT event. Implement it in the same way as the first eventListener. Maybe the code is not perfect because I wrote it from my memory. If there are any questions left feel free to ask in the comments.
I'm new to HTML and Javascript, and to learn it I am making an incremental game (similar to CookieClicker or CivClicker).
I'm trying to save and load progress, and I can save it just fine, but when I load it, it loads all the variables correctly, but when I click on a button to increment a variable, it does some weird stuff, it's hard to explain, I'll post the code so you can look at it some more.
JSFiddle Here
function loadProgress() {
if (typeof (Storage) !== "undefined") {
progress = localStorage.progress;
speed = localStorage.speed;
quality = localStorage.quality;
isDone = localStorage.isDone;
totalMoney = localStorage.totalMoney;
speedCost = localStorage.speedCost;
gamesSold = localStorage.gamesSold;
autoclick = localStorage.autoclick;
autoclickCost = localStorage.autoclickCost;
currentBugs = localStorage.currentBugs;
refreshDisplay();
} else {
console.log("LocalStore not appliable.")
}
}
Press 'Design' until you get to 100% then click 'Sell your game'. Then just press Save Progress then Load progress and click design and sell game again, you will see the numbers increase very oddly and that isn't expected at all.
'ShowMeTheMoney' will show you the variables in the console so you can verify that the variables were stored correctly.
I have no idea why this is happening, so if someone could help that would be awesome.
Local storage aka Web Storage, stores values as strings, so you need to convert/cast to numbers when you retrieve the values, otherwise the variables will remain as strings, and you'll see concatenation instead of the value being incremented. For example 1 + 1 becomes 11 not 2.
Updated working fiddle
There are many ways of converting to a number, one way is the + method:
progress = +localStorage.progress;
speed = +localStorage.speed;
quality = +localStorage.quality;
I need to do a simple pdf with some 3D objects for an oral presentation. I made several views, each one with a camera viewpoint, an object and a display mode.
To avoid the need to manually switch between the different viewpoints with the context menu, I would like the viewpoints to switch automatically with a Timer (each viewpoint staying for a few seconds). And I would like to not have to touch the mouse at all (nor the keyboard), so I would like to have the playback started as soon as the page appears.
I found the javascript command runtime.setView(N,x) to switch to the x'th view among N, but I don't know where to put it (I don't want to define a function which will be called when I press a button, since I want everything to be automated). Also, I don't know how to pause for a few seconds.
Any help ? Thanks !
I believe you're looking for setInterval(fn, time) which will call a function periodically at a time interval that you set. I'm not familiar with the setView() method you mentioned, but here's some pseudo code that you would put in tags at the end of the document body.
function startSwitcher()
var viewNum = 0;
var maxViews = 5; // you set this to how many views there are
setInterval(function() {
++viewNum;
if (viewNum >= maxViews) {
viewNum = 0;
}
runtime.setView(N, viewNum); // you will have to figure out this line
}, 2000);
}
startSwitcher();
The 2000 is 2000 milliseconds and is the time interval between executing the function. You can put any number of milliseconds there.
The runtime.setView(N, viewNum) line is something you will have to figure out as I am not familiar with whatever library you're trying to use there. The operative part of this code is the viewNum variable which configures which view in rotation should be next.
I think the runtime.SetView(..) Methods works with the name of the view as a string instead of the viewnumber. I have this function in a Dokument-level script and it works for me:
// view is the name of the view for example "TopView"
function setView(view){
console.println("Navigating to view: "+view);
var pageIndex = this.pageNum;
var annotIndex = 0;
var c3d = this.getAnnots3D( pageIndex )[ annotIndex ].context3D;
c3d.runtime.setView(view, true);
}
Combine this with the setInterval(..) from jfriend00´s answer und you should get what you need.
Best regards
On my page I load some tracks in a music player ( http://dev.upcoming-djs.com ) on page load.
Which is working fine.
However when people go to the following URL: http://dev.upcoming-djs.com/track/1/artist/title I would like to load another track in the player on page load.
Currently the JS code for the player is:
var tracks = [];
tracks.push({'url':trackurl, 'title':trackurl});
$('.upcoming-player-container').theplayer({
links: tracks // contains an array with url's
});
Which is static.
What would be the best way (not meant to be subjective, just don't know how to rephrase it) of making it dynamic.
I was thinking of adding some hyperlinks in a (hidden) container on the page which I retrieve with JS.
Is this a good way to do it? (Since I think Google might add the text to the search results).
Or perhaps there is a better way of doing it?
Assuming that the player will play the tracks in order, here's some code that will shift the track specified by the URL /track/##/artist/title to the front of the playlist, presumably playing it first on page load:
var tracks = [],
trackMatch
trackPlay;
tracks.push({'url': trackurl,'title': trackurl});
// tracks.push etc...
// find the track number
trackMatch = window.location.href.match(/track\/(\d+)/i);
// if found store as integer
if (trackMatch) {
trackPlay = parseInt(trackMatch[1], 10);
}
// if found move selected track to front of tracks array
if (trackPlay) {
tracks = [tracks[trackPlay - 1]]
.concat(tracks.slice(0, trackPlay - 1))
.concat(tracks.slice(trackPlay));
}
$('.upcoming-player-container').theplayer({
links: tracks // contains an array with url's
});