Change HTML Background randomly on page refresh - javascript

I know this topic has been looked at loads of times, but I would like my home page to randomly select an image and then change the subtitle for that image. The URL for my site is: http://www.connorloughlin.com
At the bottom of the page is a little subtitle, would be great if it changed for the relevant background. If it's too complex I won't bother but thought it'd look good! Preferably i'd have 5 images each with their own subtitle.
Let me know if you want me to clarify anything and thanks in advance!

Since you're using jQuery, I've made a version using that: http://jsbin.com/OQugAMI/4/edit
1) create an Array containing the list of images & subtitles
var backgrounds = [
{ image: 'http://www.connorloughlin.com/images/background.jpg',
subtitle: 'Looking out at Carcassonne, France - August 2013'
},
{ image: 'http://upload.wikimedia.org/wikipedia/commons/1/13/1632x1224_sertaoe_2_rio_grande_do_norte_landscape_panorama_brasil.jpg',
subtitle: 'Version 2'
},
{ image: 'http://upload.wikimedia.org/wikipedia/commons/7/71/1632x1224_sertaoe_rio_grande_do_norte_landscape_panorama_brasil.jpg',
subtitle: 'Version 3'
}
];
2) select a random image from that array
/**
* Returns a random integer between min and max
* Using Math.round() will give you a non-uniform distribution!
* http://stackoverflow.com/questions/1527803/generating-random-numbers-in-javascript-in-a-specific-range
*/
function getRandomInt (min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
$(document).ready(function(){
var bgNumber = getRandomInt(0, backgrounds.length-1);
}
3) update the H4 & body CSS to reflect the choice
$('body').css('background-image', 'url('+backgrounds[bgNumber].image+')');
$('h4').html(backgrounds[bgNumber].subtitle);
This will pick a new image & subtitle on each page load

The following is in JQuery:
Just name each of your images bg1 or bg2
// On Page Load
backgroundSelect();
function backgroundSelect(){
var sub1 = "this is my subtitle"
var numImgs = 5; // The Number of images you have total.
var select = Math.round(Math.random() * numImgs) + 1; // add one so not zero based.
$('body').css('background-image', 'bg' + select);
$('subtitle_element').replaceWith(sub1);
}
This is not the cleanest and most semantic way to write your code. But hopefully it will get you started in the right direction.

The simplest way, in plain JavaScript:
var images = [
{
subtitle : 'Subtitle text for image one...',
src : 'http://placekitten.com/1000/1000'
},
{
subtitle : 'Subtitle text for image two...',
src : 'http://lorempixel.com/1000/1000/people/'
},
{
subtitle : 'Subtitle text for image three...',
src : 'http://lorempixel.com/1000/1000/nightlife/'
},
{
subtitle : 'Subtitle text for image four...',
src : 'http://lorempixel.com/1000/1000/nature/'
}
];
function setBackground (images) {
// generates a random integer between 0 and the length of the supplied array:
var n = Math.floor(Math.random() * images.length),
// works out whether to use the 'textContent' or 'innerText' property:
textProperty = 'textContent' in document ? 'textContent' : 'innerText';
// sets the background-image of the 'body' element:
document.body.style.backgroundImage = 'url(' + images[n].src + ')';
// sets the text of the relevant subtitle element:
document.getElementById('subtitleElementID')[textProperty] = images[n].subtitle;
}
setBackground(images);
JS Fiddle demo.
Or, if you'd rather change the background every n milliseconds, you could add the following:
window.setInterval(function(){
setBackground(images)
}, 5000);
JS Fiddle demo.
Which, obviously, will change the image (and subtitle) every 5000 milliseconds.

Related

Add text to header with .text method

Can someone tell me how to get text to repeat like header does in jspdf. if I add text like this (jspdf.text(x,y,'test') it's only going on first page!
note: I already have a header on this doc but that's done in the html with the <header> tag. I want to append to that sort of. I have to add the text this way as a work around for alignment issues jspdf has.
var pdf = new jsPDF('p', 'pt', 'letter');
pdf.rect(430, 20, 125, 50);
pdf.text('Order', 430, 35);
pdf.autoTableHtmlToJson
source = $('#content')[0]; //table Id
I ended up cracking the entire jspdf.debug.js code and adding tons of if statements to it in order to solve my issues with how it renders tables. a few examples below:
--the cell height was huge for the headers
if (printHeaders) {
//changed by me on 4/5/16 to calculate lineheight manually
var lineHeight = 20;//this.calculateLineHeight(headerNames, columnWidths, headerPrompts.length?headerPrompts:headerNames);
I had a problem that once I was adding tables to my header, the doc was repeating the last header from the header for my MAIN DATA table that had 100 records or more (so it repeated multiple pages and pages 2+ had wrong header)
// Store the table header config
//changed by me
this.setTableHeaderRow(tableHeaderConfigs);
if (tableHeaderConfigsMain != undefined) {
if (tableHeaderConfigsMain.length > 0) {
this.setTableHeaderRowMain(tableHeaderConfigsMain);
}
}
--I added this to the for loop that constructs the header row (my main table had 5 columns)
if (headerNames.length == 5) {
tableHeaderConfigsMain.push([x, y, columnWidths[header], lineHeight, String(headerPrompts.length ? headerPrompts[i] : header)]);
}
--added this to the print header row function
if (this.tableHeaderRowMain != undefined && new_page) {
if (this.tableHeaderRowMain.length > 0) {
this.tableHeaderRow = this.tableHeaderRowMain;
}
}
--in the tabletojson function i changed this to manually set up my tables
if(table.id=='rightAlignTable'){
headers[i] = {
name : cell.textContent.toLowerCase().replace(/\s+/g, ''),
prompt: 'Date', //cell.textContent.replace(/\r?\n/g, ''),
width : 100 //(cell.clientWidth / table_with) * renderer.pdf.internal.pageSize.width
};
headers[1] = {
name : cell.textContent.toLowerCase().replace(/\s+/g, ''),
prompt: 'PO #',//cell.textContent.replace(/\r?\n/g, ''),
width : 100 //(cell.clientWidth / table_with) * renderer.pdf.internal.pageSize.width
};
}
--i also manually changed tables here in the ****TABLE RENDERING**** section:
if (cn.id === "rightAlignTable") {
x = 425;
y = 25;
}

My script for page loading bar, returns differently everytime of F5

I got a free source progress bar, and I wrote a script for it.
the script is here,
var nanobar = new Nanobar( options );
var loaded = 0;
var number_of_media = $("body img").length;
doProgress();
// function for the progress bar
function doProgress() {
$("img").load(function() {
loaded++;
var newWidthPercentage = (loaded / number_of_media) * 100;
nanobar.go(newWidthPercentage);
document.getElementById("showing").innerHTML = newWidthPercentage;
})
};
});
This. I think,
Loaded <-- (which gets + 1 every time an image finished loaded)
divided by
Number of total body images,,
and then multiplied by 100
So that this can make the percentage number of loading process.
Then I put that percentage number into the box of,
A Loading bar's destination point. (which is : nanobar.go( here ))
But the bar moves werid,
everytime I click the menu, it returns different.
so I made a box to display the percentage number ( in the red box you can see in the picture )
I don't understand how this kind of random numbers are coming out every time.
Please advice.
Consider....
6/7 = 0.8571428571;
0.8571428571 * 100 = 85.71428571;
So if you want to 'tidy' these long decimals, then you need to truncate the float. http://www.w3schools.com/jsref/jsref_tofixed.asp
var num = 0.8571428571 * 100;
var n = num.toFixed(2);
Then n == 85.71
I hope this helps.

Word wrapping in JointJS

I am working on JointJS. I have various elements with text in it. However the element's width increases with increase in text. I want to dynamically set the size of element such that there is a maximum height and width that the box can attain and expands accordingly by text wrapping. If the text os unable to fit in the maximum height and width element, then the fontsize may be reduced dynamically.
I hav tried using style="word-wrap: break-word;" in my div id. However there is no effect.
<div id="myholder" style="word-wrap: break-word;"> </div>
My holder is defined in the JS file as follows:
var paper = new joint.dia.Paper({
el: $('#myholder'),
width: 1200,
height: 700,
model: graph
});
What strategy may I follow?
It is also possible (if you don't want to bother with extra shapes) to use the
joint.util.breakText()
utility. It works like this:
var wraptext = joint.util.breakText('My text here', {
width: holderElement.size.width,
height: optionalHeight
});
After that you can add wraptext to your holderElement as into attrs when creating it. Like this:
var holder = joint.shapes.basic.Rect({
//position, size blablabla
attrs: {
text: {
text: wraptext,
//text styling
}
}
});
I have to say it's a bit strange that your holder is an entire paper, but you can probably use it the same way, just put the attrs when you define it.
To get word wrap working you can use joint.shapes.basic.TextBlock.
Now, to work with TextBlock you are going to set a top level map entry for "content" (instead of including "text" inside of "attrs" => "text" map entry)
graph.addCell (
new joint.shapes.basic.TextBlock({
position: { x:100, y:100 },
size: { width: 100, height: 100 },
attrs: { rect: { fill: 'green' }},
content: "<p style='color:white;'>asdf asdf asdf asdf this needs to word wrap</p>"
})
);
As you can see, the "content" entry can be raw html and will be rendered as such.
For this to work your browser needs to have SVG ForeignObject support, which most browsers these days have. To first check that this is the case you can run this in your console:
document.implementation.hasFeature("w3.org/TR/SVG11/feature#Extensibility","1.1")
I made a javascript function to wrap words based on the Line size and Max size of the shape you want the sentence wrap in.
If the sentence is very long then the function trim it and put 3 duts instead of the rest of the sentence.
Every Line size of the sentence the function put a '\n' (newline ASCII).
var sentenceWrapped = function (sentence, lineSize, maxSize) {
var descriptionTrim = "";
if (sentence.length + 3 > maxSize) {
descriptionTrim = sentence.substring(0, maxSize - 3);
descriptionTrim = descriptionTrim + '...';
}
else {
descriptionTrim = sentence
}
var splitSentence = descriptionTrim.match(new RegExp('.{1,' + lineSize + '}', 'g'));
var sentenceWrapped = "";
for (i = 0; i < splitSentence.length; i++)
{
sentenceWrapped = sentenceWrapped + splitSentence[i] + '\n';
}
return sentenceWrapped;
}
LineSize = the max size of characters for every line you want inside
your shape
MaxSize = the max size of characters you want inside your
shape
sentence = description you want to put in your shape
If you are interested in creating custom element you can create like this
joint.shapes.devs.Model = joint.shapes.basic.TextBlock.extend( {
markup: ['>',
joint.env.test('svgforeignobject') ? '' : '',
''].join(''),
defaults: joint.util.deepSupplement({
content: 'A content of the Activity'
}});

Heavy image(very large image) loading effect

I have a problem want to share with you.
So here it is. Imagine I have a very large image and it take a heavy loading when I open my page. Is it possible if I want to have the effect like cut the image to many smaller pieces and merge them one by one while the image is loading(just javascript, jquery, css and html code).
html:
<div>
<div style="float:left; width: 200px; height: 200px;">
<img id="imgHeavy" src="http://i.stack.imgur.com/kLQe4.png" width="200"/>
</div>
<div id="frameMerge" style="float:left; width: 200px; height:200px; background: #ddd;">
</div>
</div>
So now I want to set the background of my element(#frameMerge) is every single pieces of the image(#imgHeavy) that have been cut when the page is opened.
Please take a look at 2 pictures!
My img:
My div element:
Any idea would be appreciated!
You can use the functionality of multiple background images provided by css3, but it won't be faster in the end as the data being loaded with multiple pictures is even bigger (header-information of every single file) than with just one. The only difference would be, that you see parts of the image before the rest is loaded. But you can have the same effect if your image is a jpg. So you can use a progressive jpg that will show parts of your image while the rest is still loading.
You can do it with CSS3 and jquery.
Here is an example for you :
jsfiddle.net/elclanrs/4nsJE/
;(function( $, window ) {
var _defaults = {
x : 2, // number of tiles in x axis
y : 2, // number of tiles in y axis
random : true, // animate tiles in random order
speed : 2000 // time to clear all times
};
/**
* range Get an array of numbers within a range
* #param min {number} Lowest number in array
* #param max {number} Highest number in array
* #param rand {bool} Shuffle array
* #return {array}
*/
function range( min, max, rand ) {
var arr = ( new Array( ++max - min ) )
.join('.').split('.')
.map(function( v,i ){ return min + i })
return rand
? arr.map(function( v ) { return [ Math.random(), v ] })
.sort().map(function( v ) { return v[ 1 ] })
: arr
}
// Prevent css3 transitions on load
$('body').addClass('css3-preload')
$( window ).load(function(){ $('body').removeClass('css3-preload') })
$.fn.sliced = function( options ) {
var o = $.extend( {}, _defaults, options );
return this.each(function() {
var $container = $(this);
/*---------------------------------
* Make the tiles:
---------------------------------*/
var width = $container.width(),
height = $container.height(),
$img = $container.find('img'),
n_tiles = o.x * o.y,
tiles = [], $tiles;
for ( var i = 0; i < n_tiles; i++ ) {
tiles.push('<div class="tile"/>');
}
$tiles = $( tiles.join('') );
// Hide original image and insert tiles in DOM
$img.hide().after( $tiles );
// Set background
$tiles.css({
width: width / o.x,
height: height / o.y,
backgroundImage: 'url('+ $img.attr('src') +')'
});
// Adjust position
$tiles.each(function() {
var pos = $(this).position();
$(this).css( 'backgroundPosition', -pos.left +'px '+ -pos.top +'px' );
});
/*---------------------------------
* Animate the tiles:
---------------------------------*/
var tilesArr = range( 0, n_tiles, o.random ),
tileSpeed = o.speed / n_tiles; // time to clear a single tile
// Public method
$container.on( 'animate', function() {
tilesArr.forEach(function( tile, i ) {
setTimeout(function(){
$tiles.eq( tile ).toggleClass( 'tile-animated' );
}, i * tileSpeed );
});
});
});
};
}( jQuery, window ));
$('.sliced').sliced({ x: 6, y: 4, speed: 1000 });
$('button').click(function() {
$('.sliced').trigger('animate');
});
Of course you can just put an onload event on every segment (must be on <img> though) that makes it fade in. However, actually splitting the image into segments cannot be done on client side. You will need to either manually split the image beforehand or rely on server side scripting (e.g. php) to do this.
Also, do note that doing this will create quite a lot of overhead depending on the amount of segments you use, since every segment will need to make a new request to the server including downloading the file headers for every image.

Random image load

so I already have a image randomiser, but i am now looking to extend this so that IF image 1 was loaded last, load image 2 and so on.
$(document).ready(function () {
var images = ['imageTest.jpg', 'imageTest2.jpg', 'imageTest3.jpg', 'imageTest4.jpg'];
$('.mainHero-fluid').css({
'background-image': 'url(/assets/images/' + images[Math.floor(Math.random() * images.length)] + ')',
});
});
how can I do this?
I guess somthing like that should do it. You can gain the current Image from the source attribute of the imageā€¦
//copy the whole list
var newImages = [].concat(images), newImage;
//remove the current image
newImages.splice(images.indexOf(<currentImage>),1);
//get a random entry
newImage = newImages[Math.round(Math.random() * (newImages.length - 1))];
Good luck!

Categories

Resources