I am trying to create a puzzle game with javascript. I am grabbing an image for the puzzle from a url and loading it into the main div. But when I load the webpage it takes a second until everything loads correctly. How can I get this to look smoother?
Thanks
My webpage with the bug at start up:
http://www.acsu.buffalo.edu/~jamesber/GameOne.html#
My code:
$(function (){
var plant = "";
$.ajax({"url":"http://beta.botanicalapp.com/api/v1/plants/?photo=true"})
.success(function(fullData){
plant = fullData[2].plant.image_default.url;
$("#puzzle div").css({'background-image':'url('+ plant +')'});
$("#helper").attr("src",plant);
var puzzle = $("#puzzle");
var pieces = $("#puzzle div");
pieces.sort(function (a, b) {
var temp = parseInt(Math.random() * 100);
var isOddOrEven = temp % 2;
var isPosOrNeg = temp > 5 ? 1 : -1;
return (isOddOrEven * isPosOrNeg);
}).appendTo(puzzle);
var timer;
var secs = 0;
var mins = 0;
var millsecs = 0;
var timeString = document.getElementById("time");
timeString.innerHTML = "00:00:00";
function update(){
if(millsecs == 100) {
secs++;
millsecs = 0;
if(secs == 60){
mins++;
secs = 0;
}
}
else {
millsecs++;
}
if((millsecs<10) && (secs<10) && (mins<10)) {
timeString.innerHTML = '0' + mins + ':0' + secs + ':0' + millsecs;
}
else if ((millsecs<10) && (secs<10)) {
timeString.innerHTML = mins + ':0' + secs + ':0' + millsecs;
}
else if ((millsecs<10) && (mins<10)) {
timeString.innerHTML = '0' + mins + ':' + secs + ':0' + millsecs;
}
else if((secs<10) && (mins<10)){
timeString.innerHTML = '0' + mins + ':0' + secs + ':' + millsecs;
}
else if (millsecs<10) {
timeString.innerHTML = mins + ':' + secs + ':0' + millsecs;
}
else if (secs<10){
timeString.innerHTML = mins + ':0' + secs + ':' + millsecs;
}
else if (mins<10) {
timeString.innerHTML = '0' + mins + ':' + secs + ':' + millsecs;
}
else {
timeString.innerHTML = mins + ':' + secs + ':' + millsecs;
}
}
function start(){
timer = setInterval(function() {update()}, 10);
}
start();
initSwap();
function initSwap() {
initDroppable($("#puzzle div"));
initDraggable($("#puzzle div"));
}
function initDraggable($elements) {
$elements.draggable({
appendTo: "body",
helper: "clone",
cursor: "move",
revert: "invalid"
});
}
$("#final").dialog({
autoOpen: false,
modal: true,
width: 900,
resizable: false,
height: 520,
position: [250,75],
dialogClass: "fixed-dialog",
draggable: false
});
function initDroppable($elements) {
$elements.droppable({
activeClass: "ui-state-default",
hoverClass: "ui-drop-hover",
accept: ":not(.ui-sortable-helper)",
over: function (event, ui) {
var $this = $(this);
},
drop: function (event, ui) {
var $this = $(this);
var linew1 = $(this).after(ui.draggable.clone());
var linew2 = $(ui.draggable).after($(this).clone());
$(ui.draggable).remove();
$(this).remove();
initSwap();
var finished = "1,2,3,4,5,6,7,8,9";
var started = '';
$("#puzzle div").each(function(){
var image = $(this).attr("id");
started += image.replace("recordArr_","")+",";
});
started = started.substr(0(started.length)-1);
if(started == finished){
clearTimeout(timer);
$("#thePlant").attr("src",plant);
$("#final").dialog("open");
}
}
});
}
});
});
Everything is happening in the success / done callback of the Ajax call.
Even if the image is cached or anything like that, you still have the overhead of:
make HTTP connection
request resource
receive response
close connection
That's why there's a lag at startup.
You should start that Ajax call and handle the response with the image separately from rendering the rest of the page.
p.s.
You should switch .success to .done, because jQuery's new(er) Deferred objects prefer it, and the old methods are deprecated:
Deprecation Notice: The jqXHR.success(), jqXHR.error(), and jqXHR.complete() callbacks are deprecated as of jQuery 1.8. To prepare your code for their eventual removal, use jqXHR.done(), jqXHR.fail(), and jqXHR.always() instead.
Related
I'm trying to make a function that plays a sound effect and replaces image on site with an image from array after a certain delay (currentTime). The delay is is supposed to get longer after every repetition until time of all repetitions (maxTime) passes 20000 miliseconds (about 20 reps).
In current layout the site freezes. I tried to move calculation of currentTime, maxTime, and tabIndicator out of Timeout, but then the delay is always 2000 miliseconds(which is time lenght of the last rep). Any advice?
function roll()
{
var maxTime=0;
var currentTime=0;
var addValue=100;
var tabIndicator=0;
while(maxTime<=20000)
{
window.setTimeout(function(){
currentTime = currentTime + addValue;
maxTime = maxTime + currentTime;
music();
document.getElementById("write").innerHTML += (currentTime + "<br>" + maxTime + "<br>" + addValue + "<br><br>");
tabIndicator++;
if(tabIndicator == 9){ tabIndicator = 0; }
},currentTime)
}
}
Try this.
function roll()
{
var maxTime=0;
var currentTime=0;
var addValue=100;
var tabIndicator=0;
var playMusic = function()
{
window.setTimeout(function(){
currentTime = currentTime + addValue;
maxTime = maxTime + currentTime;
music();
document.getElementById("write").innerHTML += (currentTime + "<br>" + maxTime + "<br>" + addValue + "<br><br>");
tabIndicator++;
if(tabIndicator == 9){ tabIndicator = 0; }
if (maxTime <= 20000)
playMusic();
},currentTime);
};
playMusic();
}
I am currently working on a webpage, what I need to achieve is, when I click on an icon, a message box prompt out , and there is a count down timer on the message box, when I return the count down timer, it only return the value when I trigger it, but I would like to do a live count down timer in the message box , how can I do it??
Here is the JavaScript
function phyTimer3() {
var minutes1 = Math.floor(timeleft2 / 60);
var seconds1 = Math.floor(timeleft2 % 60);
if (timeleft2 > 0) {
timeleft2 -= 1;
} else {
autoRefresh = 1;
localStorage.setItem("translateX", translate.translateX);
localStorage.setItem("translateY", translate.translateY);
localStorage.setItem("scale", scale);
localStorage.setItem("autoRefresh", autoRefresh);
localStorage.setItem("zoomLevel", zoomLevel);
window.location.reload();
}
if (seconds1 < 10) {
seconds1 = "0" + seconds1;
}
return ("Global Timer " + minutes1 + " : " + seconds1);
}
if (bs.monitoring_status == 1) {
if (bs.cooldown_duration == '') {
var timer1 = document.getElementById('timer2').value;
monitoringmsg = "Zone:" + bs.zone + " Site:" + bs.site + " Current Monitoring Status is On" +
"</br>" + "Do you want to turn it <strong>off</strong>?" + "</br>" + "Cooldown Timer : " + phyTimer3();
} else {
monitoringmsg = "Zone:" + bs.zone + " Site:" + bs.site + " Current Monitoring Status is On" +
"</br>" + "Do you want to turn it <strong>off</strong>?"
}
$("#manualSwitch").append($("<p/>").attr("id", "monitoringon").attr("title", "Monitoring Status").html(monitoringmsg));
$("#monitoringon").dialog({
resizable: false,
height: "auto",
width: 400,
modal: true,
buttons: {
'Yes': function() {
$("#monitoring_zone_id").val(bs.zone);
$("#monitoring_site_id").val(bs.site);
$("#actionMonitoring").val('off');
document.forms["brSwitch"].submit();
$(this).dialog('close');
},
'Cancel': function() {
$(this).dialog('close');
}
}
});
}
The function phyTimer3 is where I return the minutes and seconds , but obviously this is not working , I am new to programming , I not sure what kind of function is working , can you guys help me on this ??
I want to format the time from 24 hours to 12 hours with AM/PM and display it in popover.
This is my code:
eventMouseover: function (event, jsEvent) {
var t1 = event.start;
var t2 = event.end;
$(this).popover({
html:true,
placement: 'left',
trigger: 'hover',
content: t1 + ' - ' + t2,
container: '#calendar'
}).popover('toggle');
}
I search for the answers here but it doesnt work in popover. So i decided to ask for it.
This is the code i used.
It works on here, but not in popover.
eventRender: function(event, element) {
var t1 = event.time;
var t2 = event.time2;
var tmpArr = t1.split(':'), time12;
if(+tmpArr[0] == 12) {
time12 = tmpArr[0] + ':' + tmpArr[1] + 'P';
} else {
if(+tmpArr[0] == 00) {
time12 = '12:' + tmpArr[1] + 'A';
} else {
if(+tmpArr[0] > 12) {
time12 = (+tmpArr[0]-12) + ':' + tmpArr[1] + 'P';
} else {
time12 = (+tmpArr[0]) + ':' + tmpArr[1] + 'A';
}
}
}
var tmpArrs = t2.split(':'), time13;
if(+tmpArrs[0] == 12) {
time13 = tmpArrs[0] + ':' + tmpArrs[1] + 'P';
} else {
if(+tmpArrs[0] == 00) {
time13 = '12:' + tmpArrs[1] + 'A';
} else {
if(+tmpArrs[0] > 12) {
time13 = (+tmpArrs[0]-12) + ':' + tmpArrs[1] + 'P';
} else {
time13 = (+tmpArrs[0]) + ':' + tmpArrs[1] + 'A';
}
}
}
element.find('.fc-content').append(t1 + "-" + t2 +);
}
Assuming you have moment.js included in your webpage (as FullCalendar needs it in any case) use the following code in place of declaring var t1 and var t2
var t1 = $.fullCalendar.moment(event.start).format("h:mm A")
var t2 = $.fullCalendar.moment(event.end ).format("h:mm A")
P.S. You don't need to work out the 12 hour format manually, moment.js does this for you
I have one timer and i want it in two different places in my website. But only one is working at the time.
Here is Script + first timer below it.
<script>
var interval;
var minutes = 8;
var seconds = 41;
window.onload = function() {
countdown('countdown');
myFunction();
myFunctiontoo();
}
function countdown(element) {
interval = setInterval(function() {
var el = document.getElementById("timerx");
if(seconds == 0) {
if(minutes == 0) {
el.innerHTML = "Free trial bonus has expired!";
clearInterval(interval);
return;
} else {
minutes--;
seconds = 60;
}
}
if(minutes > 0) {
var minute_text = minutes + (minutes > 1 ? ' minutes' : ' minute');
} else {
var minute_text = '';
}
var second_text = seconds > 1 ? 'seconds' : 'second';
el.innerHTML = minute_text + ' ' + seconds + ' ' + second_text + '';
seconds--;
}, 1000);
}
</script>
<div class="countdown"><span style="color:#EA0423;">Free Trial bonus ends in </span><span id="timerx" style="font-weight:bold;">8 minutes and 42 seconds</span>.
</div>
A bit lower in my HTML code i have another timer.
<span style="color:#FFF1D6;">Free Trial bonus ends in </span><span id="timerx" style="font-weight:bold;">8 minutes and 42 seconds</span>.
The second timer unfortunately is not working.
Method getElementById other than getElementsByClassName return only one DOM element.
Method getElementsByClassName returns an array of elements so you can get them using an index
Here is working example: PLUNKER
You can us getElementsByClassName and your code would look like this:
function countdown(element) {
var start_value = "Free trial bonus has expired!"
interval = setInterval(function() {
var el1 = document.getElementsByClassName("timerx")[0];
var el2 = document.getElementsByClassName("timerx")[1];
if(seconds == 0) {
if(minutes == 0) {
el1.innerHTML = start_value;
el2.innerHTML = start_value;
clearInterval(interval);
return;
} else {
minutes--;
seconds = 60;
}
}
if(minutes > 0) {
var minute_text = minutes + (minutes > 1 ? ' minutes' : ' minute');
} else {
var minute_text = '';
}
var second_text = seconds > 1 ? 'seconds' : 'second';
el1.innerHTML = minute_text + ' ' + seconds + ' ' + second_text + '';
el2.innerHTML = minute_text + ' ' + seconds + ' ' + second_text + '';
seconds--;
}, 1000);
}
If you are calling the timer twice in the same page you need to have two IDs. The id="timerx"
<span id="timerx_"<?php echo 'DYNAMIC VARIBALE'; ?>>timer</span>
And use this new ID
I have this webpage with a puzzle game that is loading the game features before the image can be pulled from a url. How can I stall this so the image can be pulled before?
Been working on it for awhile, a detailed response please :)!
My webpage to show issue:
http://www.acsu.buffalo.edu/~jamesber/GameOne.html#
var plant = "";
$(function () {
$.ajax({"url":"http://beta.botanicalapp.com/api/v1/plants/?photo=true"})
.done(function(fullData){
plant = fullData[2].plant.image_default.url;
startGame();
});
function startGame() {
$("#puzzle div").css({'background-image':'url('+ plant +')'});
$("#helper").attr("src",plant);
var puzzle = $("#puzzle");
var pieces = $("#puzzle div");
pieces.sort(function (a, b) {
var temp = parseInt(Math.random() * 100);
var isOddOrEven = temp % 2;
var isPosOrNeg = temp > 5 ? 1 : -1;
return (isOddOrEven * isPosOrNeg);
}).appendTo(puzzle);
$("#instruct").click(function(){$("final").dialog("open");
return false;
});
var timer;
var secs = 0;
var mins = 0;
var millsecs = 0;
var timeString = document.getElementById("time");
timeString.innerHTML = "00:00:00";
function update(){
if(millsecs == 100) {
secs++;
millsecs = 0;
if(secs == 60){
mins++;
secs = 0;
}
}
else {
millsecs++;
}
if((millsecs<10) && (secs<10) && (mins<10)) {
timeString.innerHTML = '0' + mins + ':0' + secs + ':0' + millsecs;
}
else if ((millsecs<10) && (secs<10)) {
timeString.innerHTML = mins + ':0' + secs + ':0' + millsecs;
}
else if ((millsecs<10) && (mins<10)) {
timeString.innerHTML = '0' + mins + ':' + secs + ':0' + millsecs;
}
else if((secs<10) && (mins<10)){
timeString.innerHTML = '0' + mins + ':0' + secs + ':' + millsecs;
}
else if (millsecs<10) {
timeString.innerHTML = mins + ':' + secs + ':0' + millsecs;
}
else if (secs<10){
timeString.innerHTML = mins + ':0' + secs + ':' + millsecs;
}
else if (mins<10) {
timeString.innerHTML = '0' + mins + ':' + secs + ':' + millsecs;
}
else {
timeString.innerHTML = mins + ':' + secs + ':' + millsecs;
}
}
function start(){
timer = setInterval(function() {update()}, 10);
}
start();
initSwap();
function initSwap() {
initDroppable($("#puzzle div"));
initDraggable($("#puzzle div"));
}
function initDraggable($elements) {
$elements.draggable({
appendTo: "body",
helper: "clone",
cursor: "move",
revert: "invalid"
});
}
$("#final").dialog({
autoOpen: false,
modal: true,
width: 900,
resizable: false,
height: 520,
position: [250,75],
dialogClass: "fixed-dialog",
draggable: false
});
function initDroppable($elements) {
$elements.droppable({
activeClass: "ui-state-default",
hoverClass: "ui-drop-hover",
accept: ":not(.ui-sortable-helper)",
over: function (event, ui) {
var $this = $(this);
},
drop: function (event, ui) {
var $this = $(this);
var linew1 = $(this).after(ui.draggable.clone());
var linew2 = $(ui.draggable).after($(this).clone());
$(ui.draggable).remove();
$(this).remove();
initSwap();
var finished = "1,2,3,4,5,6,7,8,9";
var started = '';
$("#puzzle div").each(function(){
var image = $(this).attr("id");
started += image.replace("recordArr_","")+",";
});
started = started.substr(0,(started.length)-1);
if(started == finished){
clearTimeout(timer);
$("#thePlant").attr("src",plant);
$("#final").dialog("open");
}
}
});
}
}
});
how about running the function start game function with jquery on load
$('#imageID').on('load', function() {
startGame();
});
You could wrap startGame() function in
$( window ).load(function() {
startGame();
}
Run a function when the page is fully loaded including graphics.
https://api.jquery.com/load-event/
Check out this question:
Detect image load
Here is the answer that seems to solve your issue:
$("#myImg").load(function() {
alert('I loaded!');
}).attr('src', 'myImage.jpg');
Be sure to attach it before setting the source, or the event may have fired before you attached a handler to listen for it (e.g. loading from cache).
If that's not doable (setting the src after binding), be sure to check if it's loaded and fire it yourself, like this:
$("#myImg").load(function() {
alert('I loaded!');
}).each(function() {
if(this.complete) $(this).load();
});