How do I preload flash video and images? - javascript

I am working on a webapp that progresses through 'pages' via ajax. The content for each page is in an xml file, the app ajax's that xml file and builds the page from that, then spits it out to the browser.
Some of these pages have video or large images which im trying to preload on the previous page. Below is the code I am using to check if the media is preloaded, but when I land on the page, it seems to be loading it again... any ideas?
The video player is always present in the dom, when its not being used i hide it off screen.
I assumed using the new Image() and giving it a source caches that image too right?
var l_image = new Image();
//other stuff happens here
switch(l_next.type) {
case 'st_animation':
if(l_next.video != undefined && l_next.video != '') {
l_videoSrc = String(l_next.video);
_videoPlayer.loadVideo(l_videoSrc);
delete l_next;
}
//give 2secs for the video to load atleast the first frame
setTimeout(p_callback, 2000);
break;
default:
if(l_next.image != undefined && l_next.image != '') {
l_imageSrc = 'files/'+ l_next.image;
delete l_next;
l_image.src = l_imageSrc;
//replace the image or append it
if(this.data.type == 'st_animation') {
_$image.html('<img src="'+ l_imageSrc +'" alt="" />');
}
else {
_$image.prepend('<img src="'+ l_imageSrc +'" alt="" />');
}
//trigger callback when loaded
if(l_image.complete) {
setTimeout(p_callback, 500);
}
else {
l_image.onload = function() {
setTimeout(p_callback, 500);
}
}
}
and the callback function:
/*
* Goes to the page with the specified id
*/
goTo : function(p_pageID) {
//empty content & show loader
_$content.empty();
_currentPage = null; //empty the page data
//_$loader.fadeIn(500);
//get the page we're going to's data
var l_data = this.getData(p_pageID);
//instantiate this pages PageType sub-class
eval('_currentPage = new '+ l_data.type +'(l_data)');
l_data = null;
},
/**
* Loads the xml of the page's id you pass it
*/
getData : function(p_pageID) {
var l_cacheBuster = '?cacheBuster='+ _structure.course.settings.cache_buster,
l_xmlPath = './data/'+ p_pageID +'.xml'+ l_cacheBuster,
l_data = new Object();
//ajax request
$.ajax({
type: 'GET',
url: l_xmlPath,
dataType: 'xml',
async: false,
success: function(p_data) {
//convert the xml structure to json
l_data = $.xml2json(p_data);
//check for parsing error
if(l_data.text != undefined) {
var l_dataString = String(l_data);
if(l_dataString.indexOf('XML Parsing Error') > -1) {
trace(l_dataString);
}
}
},
error: function(p_response, p_status, p_error) {
trace('Could not load "'+ l_xmlPath +"\"\r\n"+ p_status +': '+ p_error.name);
}
});
return l_data;
}
Thanks in advance...

Image preloading is a solved problem, so no need to reinvent-the-wheel. Since Flash controls the video, preloading the swf would have to be done with ActionScript.
References
Flash object tag attributes
Preloading and Responsive Images

Related

Darkroomjs Image Cropping Post to PHP

Does anybody know how to post the cropped image to PHP using darkroomjs?
Link here: https://github.com/MattKetmo/darkroomjs
I want to upload the cropped image to the server. Also, how do I set the location of the cropped image to appear in a different HTML element.
For example, if when I hit the crop button in darkroomjs it updates the cropper canvas with the new image. How do I make it also move the cropped image to another HTML element on the page?
Thanks in advance.
I have a working version of this - it took me an hour or so to figure out and steal some other peoples suggestions mixed it all together and aletered a few bits here and there and here it is...
I parse the filename into JavaScript from my html from a hidden input type that was popuated by php ($('#profile_pic_filename').val();)
if($('.image-container.target').length){
$('#member_portrait').change(function(){
$('#member_photo_hidden_file').val("");
});
var pic_name = $('#profile_pic_filename').val();
var dkrm = new Darkroom('#target', {
// Size options
minWidth: 100,
minHeight: 100,
maxWidth: 600,
maxHeight: 500,
ratio: 4/3,
backgroundColor: '#000',
// Plugins options
plugins: {
//save: false,
crop: {
quickCropKey: 67, //key "c"
//minHeight: 50,
//minWidth: 50,
//ratio: 4/3
},
save: {
callback: function() {
this.darkroom.selfDestroy(); // Cleanup
var newImage = dkrm.canvas.toDataURL();
$.ajax({
type : "POST",
dataType : "html",
url : base_url+'ajax/updateProfilePic',
data : {
'newImage' : newImage,
'imageName' : pic_name
}
})
.done(function(response){
response = $.parseJSON(response);
var status = response.status;
var data = response.data;
if(status === "success"){
location.reload();
}else{
alert(data);
}
});
}
}
},
// Post initialize script
initialize: function() {
var cropPlugin = this.plugins['crop'];
// cropPlugin.selectZone(170, 25, 300, 300);
cropPlugin.requireFocus();
}
});
}
in my ajax file i take the image and decode the base 64 version of the image and then parse that into a function with the filname that then overwrites the original file and hey presto the image has been replaced on the server.
$newImage = '';
$imageName = '';
if(isset($_POST['newImage'])){
$newImage = $_POST['newImage'];
}
if(isset($_POST['imageName'])){
$imageName = $_POST['imageName'];
}
function saveProfilePic($filename,$filecontent){
if (strlen($filename)>0){
$folderPath = '/home/xxxxxxxxxxxxx/public_html/images/uploads/_mem_photo/';
if (!file_exists($folderPath)) {
mkdir($folderPath);
}
$file = #fopen($folderPath.$filename,"w");
if($file != false){
fwrite($file,$filecontent);
fclose($file);
return 1;
}
return -2;
}
return -1;
}
$data = explode(',',$newImage);
$final = base64_decode($data[1]);
$fileSavingResult = saveProfilePic($imageName, $final);
if($fileSavingResult == 1){
$return = array("status"=>"success", "data"=>"File was saved!");
}
else if($fileSavingResult == -2){
$return = array("status"=>"fail", "data"=>"An error occured during saving file!");
}
else if($fileSavingResult == -1){
$return = array("status"=>"fail", "data"=>"Wrong file name!");
}
echo json_encode($return);
I've just placed xxxxx into file path as I don't want to give up any server info.
If all is successfull you get a page reload and the newly transformed image loads on the page but if there is an error it will alert you.
Theoretically, in order to post the image to PHP you want to get the src contents of the <img> element which is stored in Base64 in the case of this plugin.
Once you grab that value using JQuery, you can send it to the server asynchronously using AJAX or by posting your form the regular way by putting the src contents into a hidden field somewhere. From that point you can use tools such as PHP's GD and Image functions or Intervention / Image to create an image file on the server from that Base64 data.
In your case, sending it asynchronously by just grabbing the <img src="base64img"> would probably be easiest.
$('#theForm').submit(function(event){
// preventDefault stops the regular synchronous submit from happening -- we don't want that. we want an async AJAX request
event.preventDefault();
var formData = $('#yourImgElement').attr('src');
var returnMessage = '';
$.post(site+'post/to/location', formData, function(response){
if(response.status){
returnMessage = 'Save Successful.';
} else {
returnMessage = 'Save Failed:\n\n';
for (i = 0; i < response.errors.length; i++) {
returnMessage += '- ' + response.errors[i] + '\n';
}
}
alert(returnMessage);
},'json');
return false; // return false to cancel form action
});
It's my understanding that cropping the image and saving it should reflect the changes within the Base64, but I personally and someone else is actually having problems with that.
In order to do the other stuff you want to do, you should be able to do it fairly easily with JQuery (look up restructuring the DOM). Just hook into the events:
// Post initialization method
initialize: function() {
// Active crop selection
this.plugins['crop'].requireFocus();
// Add custom listener
this.addEventListener('core:transformation', function() {
// THIS IS WHERE YOU WOULD THEN PERFORM DOM MANIPULATIONS USING JQUERY
});
}
You should be careful with moving the image after it's been edited, however. It could throw JavaScript errors if the plugin is expecting certain elements to be in certain locations.
UPDATED WITH SOLUTION:
======================
The src of the image will never change. In order to get the Base64 code of the edited image, you actually need to ask the canvas for it. Here is how you can do it:
// Plugins options
plugins: {
crop: {
//minHeight: 300,
//minWidth: 400,
//ratio: 4/3
},
save: {
callback: function() {
this.darkroom.selfDestroy(); // Turn off the bar and cleanup
var newImage = dkrm.canvas.toDataURL();
varThatStoresYourImageData = newImage;
}
}
}

How to get remote image using jQuery asynchronously?

I want to show a remote image on my page. I use Bootstrap 2.3.2 Carousel. All the information comes from another web site's RSS feed. I get data into a div like the following:
...
<div id="newsItem-<?php echo $i;?>" class="item" data-src="<?php echo $feed[$i]->image; ?>" data-alt="<?php echo $feed[$i]->title; ?>">
</div>
...
The images takes too long to load. Page is loaded about 15 seconds. So I have decided to load images after the page loading finished.
There could be various dimensions of the pictures to be displayed.
I want to show the largest existing one.
For each news item, all the images may have different but similar dimensions such as 1024x768, 620x350, 528x350, 527x350.
I have written a jQuery script to achieve this but something is wrong.
jQuery(function () {
jQuery("div[id^='newsItem-']").each(function () {
var r = jQuery(this).attr("data-src");
var r620 = r.replace(".jpg", "-620x350.jpg");
var r527 = r.replace(".jpg", "-527x350.jpg");
var r1024 = r.replace(".jpg", "-1024x678.jpg");
var r528 = r.replace(".jpg", "-528x350.jpg");
var altImg = jQuery(this).attr("data-alt");
if (pictureExists(r1024)){
r = r1024;
}
else if (pictureExists(r620)){
r = r620;
}
else if (pictureExists(r528)){
r = r528;
}
else if (pictureExists(r527)){
r = r527;
}
jQuery(this).prepend("<img src='" + r + "' alt='" + altImg + "' />");
jQuery(this).removeAttr("data-alt");
jQuery(this).removeAttr("data-src");
});
});
function pictureExists(url) {
var img = new Image();
img.src = url;
if (img.height !== 0) {
return false;
} else {
return true;
}
}
I want to display the largest existing picture in the carousel.
You cannot know the height/width of the image until its loaded. So its an async process.
In pictureExists function try to do it in this way:
/ Create new image
var img = new Image();
// Create var for image source
var imageSrc = "http://example.com/blah.jpg";
// define what happens once the image is loaded.
img.onload = function() {
// Stuff to do after image load ( jQuery and all that )
// Within here you can make use of src=imageSrc,
// knowing that it's been loaded.
};
// Attach the source last.
// The onload function will now trigger once it's loaded.
img.src = imageSrc;
If you want to use the above way then you will have to implement promise structure to tackle the async nature of the image load to fetch the height/width
Or you can use this small plugin.
https://github.com/desandro/imagesloaded

AJAX - Losing the Javascript data

I have been struggling ajaxing my website, which happens to be a WordPress.
What I am trying to do, is to only refresh the content of my blog. What I mean is that my header, footer # sidebar shouldn't be refreshed when I navigate through my website.
It sounded easy to me when I first started, but I was wrong. I've been looking around to find a way to get around problems and found this but it did not help... So, here is my terrible issue :
There are Javascript scripts that are involved in my "refreshed content" and the innerHTML does not keep the JS. Only Html is transposed... As a result, my plugins aren't working anymore.
So, I have been looking for a way to keep the JS content.
I hope I have been clear in desribing my problems and pray for you guys to be able to help me :)
Here is my website : www.construction.urbaineparis.com
If you need more details, I will be very willing to give you the code you need to help.
Here is a part of the source that I believe contains the issue.
//start changing the page content.
jQuery('#' + AAPL_content).fadeOut("slow", function() {
//See the below - NEVER TRUST jQuery to sort ALL your problems - this breaks Ie7 + 8 :o
//jQuery('#' + AAPL_content).html(AAPL_loading_code);
//Nothing like good old pure JavaScript...
document.getElementById(AAPL_content).innerHTML = AAPL_loading_code;
jQuery('#' + AAPL_content).fadeIn("slow", function() {
jQuery.ajax({
type: "GET",
url: url,
data: getData,
cache: false,
dataType: "html",
success: function(data) {
AAPL_isLoad = false;
//get title attribute
datax = data.split('<title>');
titlesx = data.split('</title>');
if (datax.length == 2 || titlesx.length == 2) {
data = data.split('<title>')[1];
titles = data.split('</title>')[0];
//set the title?
//after several months, I think this is the solution to fix & issues
jQuery(document).attr('title', (jQuery("<div/>").html(titles).text()));
} else {
if (AAPL_warnings == true) {
alert("WARNING: \nYou seem to have more than one <title> tag on the page, this is going to cause some major problems so page title changing is disabled.");
}
}
//Google analytics?
if (AAPL_track_analytics == true) {
if(typeof _gaq != "undefined") {
if (typeof getData == "undefined") {
getData = "";
} else {
getData = "?" + getData;
}
_gaq.push(['_trackPageview', path + getData]);
} else {
if (AAPL_warnings == true) {
alert("WARNING: \nAnalytics does not seem to be initialized! Could not track this page for google.");
}
}
}
///////////////////////////////////////////
// WE HAVE AN ADMIN PAGE NOW - GO THERE //
///////////////////////////////////////////
try {
AAPL_data_code(data);
} catch(err) {
if (AAPL_warnings == true) {
txt="ERROR: \nThere was an error with data_code.\n";
txt+="Error description: " + err.message;
alert(txt);
}
}
//get content
data = data.split('id="' + AAPL_content + '"')[1];
data = data.substring(data.indexOf('>') + 1);
var depth = 1;
var output = '';
while(depth > 0) {
temp = data.split('</div>')[0];
//count occurrences
i = 0;
pos = temp.indexOf("<div");
while (pos != -1) {
i++;
pos = temp.indexOf("<div", pos + 1);
}
//end count
depth=depth+i-1;
output=output+data.split('</div>')[0] + '</div>';
data = data.substring(data.indexOf('</div>') + 6);
}
//put the resulting html back into the page!
//See the below - NEVER TRUST jQuery to sort ALL your problems - this breaks Ie7 + 8 :o
//jQuery('#' + AAPL_content).html(output);
//Nothing like good old pure JavaScript...
document.getElementById(AAPL_content).innerHTML = output;
Change
document.getElementById(AAPL_content).innerHTML = AAPL_loading_code;
to
$("#"+AAPL_content).html(AAPL_loading_code);
jQuery takes care of executing scripts that are in the HTML, which .innerHTML does not do.
I doubt this really breaks in IE 7, as your comment says, unless you're using jQuery 2.x (they've dropped support for old IE versions).

Loading A text along with a picture using AJAX

I have made a photo gallery in my website using the following:
/*Begin Photo Gallery Code*/
var images = ['g1.jpg', 'g2.jpg', 'g3.jpg', 'g4.jpg'];
function loadImage(src) {
$('#pic').fadeOut('slow', function() {
$(this).html('<img src="' + src + '" />').fadeIn('slow');
});
}
function goNext() {
var next = $('#gallery>img.current').next();
if(next.length == 0)
next = $('#gallery>img:first');
$('#gallery>img').removeClass('current');
next.addClass('current');
loadImage(next.attr('src'));
}
$(function() {
for(var i = 0; i < images.length; i++) {
$('#gallery').append('<img src="images/gallery/' + images[i] + '" />');
}
$('#gallery>img').click(function() {
$('#gallery>img').removeClass('current');
loadImage($(this).attr('src'));
$(this).addClass('current');
});
loadImage('images/gallery/' + images[0]);
$('#gallery>img:first').addClass('current');
setInterval(goNext, 4000);
});
It loads one picture at a time from a set of four pictures. Also I have four html files, each of them being relevant to one of the pictures. I want to use JavaScript/JQuery/AJAX to load the relevant html file's content along with the shown picture. Does anyone have an idea how I can do this?
Should I put the ajax files (4 html files) into a JavaScript array or something?
var ajaxPages=['ajax1.html','ajax2.html','ajax3.html','ajax4.html'];
Thanks in advance.
Unless the HTML files supposed to change somehow during their displaying, should either output them via your server-side code in hidden divs with the request (would be the correct way of doing it) or use AJAX to save them in a variable or create hidden divs.
First you need two arrays like this:
var ajaxPages=['ajax1.html','ajax2.html','ajax3.html','ajax4.html'];//File Names
var divPages=['div1','div2','div3','div4'];//Div ids in order
For the AJAX part you should use something like:
var getHtml = function(filename,divid){
$.post('html/'+filename, function(data) {
//The first argument is your file location
//Second one is the callback, data is the string retrieved
$('#'+divid).html(data);
});
}
$.each(ajaxPages,function(index,value){
getHtml(value,divPages[index]);
});
That should do it... Do tell me if you require further explanation.
EDIT:
var ajaxPages=['ajax1.html','ajax2.html','ajax3.html','ajax4.html'];
var divId="yourdivid";
var textArray=new Array();
var currentImg=0;
var getHtml = function(filename){
$.post('html/'+filename, function(data) {
textArray.push(data);//Save data inside the array textArray
});
}
$.each(ajaxPages,function(index,value){
getHtml(value,divPages[index]);
});
Then your goNext() method:
function goNext() {
var next = $('#gallery>img.current').next();
if(next.length == 0){
next = $('#gallery>img:first');
currentImg=0;
}else{
currentImg++;
}
$('#gallery>img').removeClass('current');
next.addClass('current');
loadImage(next.attr('src'));
$('#'+divId).html(textArray[currentImg]);//Adds text to div based on current picture
}
That should be working fine!

javascript preloader/progress/percentage

I'm having trouble finding any good information on how to make a javascript(or jquery) progress bar WITH text that tells you the percentage.
I don't want a plug in, I just want to know how it works so that I can adapt it to what I need. How do you preload images and get a variable for the number of images that are preloaded. Also, how do you change html/css and-or call a function, based on the number of images that are loaded already?
<img> elements have an onload event that fires once the image has fully loaded. Therefore, in js you can keep track of the number of images that have loaded vs the number remaining using this event.
Images also have corresponding onerror and onabort events that fire when the image fails to load or the download have been aborted (by the user pressing the 'x' button). You also need to keep track of them along with the onload event to keep track of image loading properly.
Additional answer:
A simple example in pure js:
var img_to_load = [ '/img/1.jpg', '/img/2.jpg' ];
var loaded_images = 0;
for (var i=0; i<img_to_load.length; i++) {
var img = document.createElement('img');
img.src = img_to_load[i];
img.style.display = 'hidden'; // don't display preloaded images
img.onload = function () {
loaded_images ++;
if (loaded_images == img_to_load.length) {
alert('done loading images');
}
else {
alert((100*loaded_images/img_to_load.length) + '% loaded');
}
}
document.body.appendChild(img);
}
The example above doesn't handle onerror or onabort for clarity but real world code should take care of them as well.
What about using something below:
$('#btnUpload').click(function() {
var bar = document.getElementById('progBar'),
fallback = document.getElementById('downloadProgress'),
loaded = 0;
var load = function() {
loaded += 1;
bar.value = loaded;
/* The below will be visible if the progress tag is not supported */
$(fallback).empty().append("HTML5 progress tag not supported: ");
$('#progUpdate').empty().append(loaded + "% loaded");
if (loaded == 100) {
clearInterval(beginLoad);
$('#progUpdate').empty().append("Upload Complete");
console.log('Load was performed.');
}
};
var beginLoad = setInterval(function() {
load();
}, 50);
});
JSFIDDLE
You might also want to try HTML5 progress element:
<section>
<p>Progress: <progress id="p" max=100><span>0</span>%</progress></p>
<script>
var progressBar = document.getElementById('p');
function updateProgress(newValue) {
progressBar.value = newValue;
progressBar.getElementsByTagName('span')[0].textContent = newValue;
} </script>
</section>
http://www.html5tutorial.info/html5-progress.php

Categories