flex countdown algorithm - apache-flex

The algorithm must take in an Int-value of the number of seconds remaining (ex. 2005), then convert and return a "0-padded-String" of the hours, minutes, and seconds remaining (ex. 02:35:15).
I have another event handler that will invoke the above algorithm change in seconds (count down).

Here is an implementation for your conversion method:
public static function Seconds2HHMMSS(Time:Number):String
{
var hours:int =int(int(Time/60)/60);
var hoursZeroPadding:String = "";
if (hours<10)
hoursZeroPadding="0";
var minutes:int =int(Time/60)%60;
var minutesZeroPadding:String = "";
if (minutes<10)
minutesZeroPadding="0";
var seconds:int =Time%60;
var secondsZeroPadding:String = "";
if (seconds<10)
secondsZeroPadding="0";
var result:String = hoursZeroPadding + hours.toString()
+ minutesZeroPadding + minutes.toString()
+ secondsZeroPadding + seconds.toString();
return result;
}
The opposite conversion is quite simpler:
public static function HHMMSS2Seconds(Time:String):int
{
var result:int = int(Time.substr(0,2))*3600
+ int(Time.substr(2,2))*60
+ int(Time.substr(4,2));
return result;
}

Use div and mod and your knowledge of how many seconds in an hour / min / second to come up with each of the groupings. You can then do a padding of zeros with an if statement (or the ?: operator)
Edit: or just use Dunaril's code, I didn't want to just give you the code without you having tried something first, that goes against the spirit of SO for me :P

Related

createImage() vs createImg() vs loadImage() in p5. which to use to load in an array of images for use in ml5?

I am attempting to piece together an example from ml5 on image style transfer (https://ml5js.org/docs/style-transfer-image-example) with p5.js examples parsing a JSON of image URLs, and adding them to an array to display as images. I am hitting a dead end as I do not think I fully understand the ways that p5 stores images in an array, nor do I fully understand the difference between createImg() createImage() or loadImage() (which one to use!!)
The goal is to use Bing image API to return a list of URLS from a search (this part is working fine) and run those images through a pretrained model (this part is working fine when just used on a local image). It is the bringing the two together that I am unable to figure out. Any suggestions or advice (is this even possible??!) greatly appreciated.
I have already tried loading images into an array and iterating through the array in the draw() function. The problem happens when I need to address an image in order to actually apply the style transfer model. It seems like my array is empty when I attempt to refer to it anywhere except draw(). I am sure I am thinking about this incorrectly.
var imageData;
let imgArray = [];
var w = (window.innerWidth)/3;
var h = (window.innerHeight)/4;
var index = 0;
var xPos = 0;
var yPos = 0;
var indexMax = 3;
let style;
let resultImg;
function preload() {
loadData();
}
function loadData(){
var url = api + search + subscriptionKey;
loadJSON(url, gotData);
}
function gotData(data) {
imageData = data;
for (var i=0; i < indexMax; i++){
_url = imageData.value[i].contentUrl;
imgArray.push(loadImage(_url));
}
function displayImages(){
if (index < 3){
index++;
} else {
index = 0;
};
function setup() {
createCanvas(1200, 800).parent('canvasContainer');
var button = select('#display');
button.mousePressed(displayImages);
var transferBtn = select('#transferBtn');
transferBtn.mousePressed(transferImages);
//create style method
style = ml5.styleTransfer('/model', modelLoaded);
}
function draw() {
image(imgArray[index], xPos, yPos, w, h);
}
//ml5 stuff
function modelLoaded() {
if (style.ready){
select('#status').html('Model Loaded');
//style.transfer(gotResult);
}
}
function transferImages(){
select('#status').html('applying style transfer');
style.transfer(tempImg, function(err, result){
createImg(result.src);
});
select('#status').html('done');
}
I am attempting to (unsuccessfully) create a "tempImg" from imgArray[0] to try to figure out where this createImage needs to go, but have not gotten this to work. I have CORS enabled, so I didnt think this was the problem, but am getting the following error. Please help me understand how to think about this differently.
You should use loadImage instead of createImg.
style.transfer(tempImg, function(err, result){
p5CompatibleImage = loadImage(result.src);
});

Flex how to use callLater?

In my flex mobile application, I have a loop running for over 100 iterations. In each iteration I'm updating some properties of specific Label(s). Since the loop is time consuming, I need to update the screen and display intermediate results at each iteration. How can I break the loop and refresh the display list?
function theFunction():void{
for var i:int = 0; i < n; i++{
doBusyStuff();
label_1.text = "iteration"+" i";
}
}
In that situation, I prefer to use flash.utils.setTimeout()
import flash.utils.setTimeout;
function theFunction(limit:int, current:int = 0):void
{
if (current >= limit)
return;
doBusyStuff();
label_1.text = "iteration "+ current.toString();
setTimeout(theFunction, 0, limit, current+1);
}
However, both setTimeout() and callLater() depend on the tick or the frame rate, meaning that they won't do as fast as they can. So if you also want it to run faster, you should have it run a few loops per each call.
Another solution, similar to Chaniks' answer, uses DateTime to check how long the loop has been running on each iteration. Once it detects that it's been running for too long, it ends the loop and picks up again on the next Frame.
var i:int;
function callingFunction():void {
i = 0;
stage.addEventListener(Event.ENTER_FRAME, theFunction);
}
function theFunction(e:Event):void {
var time:DateTime = new DateTime();
var allowableTime:int = 30; //Allow 30ms per frame
while ((new DateTime().time - time.time < allowableTime) && i < n) {
doBusyStuff();
i++;
}
if (i >= n) {
stage.removeEventListener(Event.ENTER_FRAME, theFunction);
}
label_1.text = "iteration"+" i";
}
There are several methods to force redraw of components:
invalidateDisplayList();
invalidateProperties();
invalidateSize();
Just use whatever you need for your components inside a function and call it after your script using callLater(yourRedrawFunction);
EDIT: For example, in your case:
function theFunction():void{
for var i:int = 0; i < n; i++{
doBusyStuff();
label_1.text = "iteration"+" i";
}
callLater(yourRedrawFunction);
}

Meteor redraw clock every second

Template.display_time.time = function() {
var date = new Date();
var hour = date.getHours();
var minute = date.getMinutes();
var now = addZero(hour) + ":" + addZero(minute);
return now
};
At the moment im using this code to display the time.
But I've been trying to use simple javascript to update it every second, yet it wont show up on the page.
Is there a meteor friendly way to do this using the function above?
Like using setTimeout on 1 second interval..
The javascript I used to use.
function updateTime() {
var currentTime = new Date();
var hours = currentTime.getHours();
var minutes = currentTime.getMinutes();
if (hours < 10)
{
hours = "0" + hours;
}
if (minutes < 10)
{
minutes = "0" + minutes;
}
var v = hours + ":" + minutes + " ";
setTimeout("updateTime()",1000);
document.getElementById('time').innerHTML=v;
}
updateTime();
The reason that method doesn't work is because it isn't a reactive data source.
Try the following.
Template.display_time.time = function() {
return Session.get('time');
};
Meteor.setInterval(function() {
Session.set('time', getTime());
}, 1000);
See the documentation on Deps
"Meteor has a simple dependency tracking system which allows it to
automatically rerun templates and other computations whenever Session
variables, database queries, and other data sources change."

Flex 4 utc date time format problem

here are my functions they work fine when timeoffset is round number(1,2,3,4...),but when is 3.5(3:30), 4.5(4:30) it doesnt work.
Can someone help me with this :
private function init_vars():void
{
timeZoneOffset = FlexGlobals.topLevelApplication.parameters.clock_time_zone; // I load this with js
timeZoneOffset = 5,50; // just for test
}
private function tick(event:TimerEvent):void
{
var local: Date = new Date();
var utc: Date = new Date(local.getTime() + (local.getTimezoneOffset() * 60000));
var utcTime:Number=utc.getTime();
var new_offset_date:Number = utcTime + ((3600000) * timeZoneOffset);
var new_date:Date = new Date(new_offset_date);
currentTime = new Date(new_date);
showTime(currentTime); // another function just to display time
}
private function showTime(time:Date):void
{
seconds = time.getSeconds();
minutes= time.getMinutes();
hours= time.getHours();
//rotate
this.secondsPointer.rotation = (seconds * 6) - 90;
this.minutesPointer.rotation = (minutes * 6) - 90;
this.hoursPointer.rotation = (hours * 30) + (minutes * 0.5) - 90;
this.secondsPointer.visible = true;
this.minutesPointer.visible = true;
this.hoursPointer.visible = true;
}
I ran your code and it worked fine. I just traced currentTime because I didn't have your showTime function, is it possible that the bug is in that function?
I would recommend to try something like the following if you can:
date.setUTCHours(date.getUTCHours() + hoursDifference); //5
date.setUTCMinutes(date.getUTCMinutes + minutesDifference); //30
Modifying dates using the time in milliseconds, depending on how/where/when you actually use the application might create weird bugs in case of daylight savings. And you don't want to deal with a bug that might happen only twice a year in only certain countries of the world.

Playing sound files one after another in flex AIR code

I have a set of sound clips to be played one after another in a sequence with couple of time interval inbetween.
In my case, its a question - followed by the set of four options.
When I write the below code, all the audop files start together at same time. How can I had time delay inbetween, so that the second clip plays only after the first one is over, and the third one starts playing, only when the second option is over.
I am with Flex AIR AS 3. See code below. Thanks in advance.
private function playCoundClips(): void
{
//set audio clips
var questionClipSource : String = "assets/quiz_voiceovers/" + questionCode + "Q.mp3";
var optionAClipSource : String = "assets/quiz_voiceovers/" + questionCode + "a.mp3";
var optionBClipSource : String = "assets/quiz_voiceovers/" + questionCode + "b.mp3";
var optionCClipSource : String = "assets/quiz_voiceovers/" + questionCode + "c.mp3";
var optionDClipSource : String = "assets/quiz_voiceovers/" + questionCode + "d.mp3";
playThisClip(questionClipSource);
playThisClip(optionAClipSource);
playThisClip(optionBClipSource);
playThisClip(optionCClipSource);
playThisClip(optionDClipSource);
}
private function playThisClip(clipPath : String) : void
{
try
{
clipPlayingNow = true;
var soundReq:URLRequest = new URLRequest(clipPath);
var sound:Sound = new Sound();
var soundControl:SoundChannel = new SoundChannel();
sound.load(soundReq);
soundControl = sound.play(0, 0);
}
catch(err: Error)
{
Alert.show(err.getStackTrace());
}
}
Thanks
Sumit
The problem is you are spawning multiple asynchronous calls. Implement a complete call back function on Sound and then call your playThisClip function inside the callback function. (You can sleep for predefined time before calling)
Time delay, is a very bad idea (in 99% of the case).
Have a look at the SOUND_COMPLETE event (see the doc)
This event is triggered when the sound stops playing.
So, it's now very easy to play sounds in sequence.
A simple example (not tested but idea is here) :
//declare somewhere a list of sounds to play
var sounds:Array=["sound_a.mp3","sound_a.mp3"];//sounds paths
//this function will play all sounds in the sounds parameter
function playSounds(sounds:Array):void{
if(!sounds || sounds.length==0){
//no more sound to play
//you could dispatch an event here
return;
}
var sound:Sound=new Sound();
sound.load(new URLRequest(sounds.pop()));
var soundChannel:SoundChannel = sound.play();
soundChannel.addEVentListener(Event.SOUND_COMPLETE,function():void{
soundChannel.removeEventListener(Event.SOUND_COMPLETE,arguments.callee);
playSounds(sounds);
});
}
This helped me
http://livedocs.adobe.com/flex/3/html/help.html?content=Working_with_Sound_09.html
One need to write code for:
sound.addEventListener(Event.ENTER_FRAME, onEnterFrame);
soundControl.addEventListener(Event.SOUND_COMPLETE, onPlaybackComplete);
private function onEnterFrame(event:Event):void
{
var estimatedLength:int =
Math.ceil(sound.length / (sound.bytesLoaded / sound.bytesTotal));
var playbackPercent:uint =
Math.round(100 * (soundControl.position / estimatedLength));
}
private function onPlaybackComplete(event:Event):void
{
Alert.show("Hello!");
}

Resources