I'm working on a website for my Sound Design degree for which I need to visualize the music.
I managed to animate the background of my website according to the "volume" of the sound playing (variation of the opacity). It works like a charm on Chrome osx but I can't can't figure out how to make it work on android/iOS. Should I use a specific library for mobile css animation ?
Thanks a lot !!
Here is the messy my code in his entirety :
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Choir_Test</title>
<link href="http://fonts.googleapis.com/css?family=Open+Sans:400,300" rel="stylesheet" type="text/css">
<style>
body {
font-family:'Open Sans', serif; font-size:40px;
background-color:#000000;
padding : 0;
margin: 0;
width: 100%;
height: 100%;
}
Header {
position: center 40px;
height: 100px;
width: 100%;
color: white;
}
.contentWrapper {
width:1000px; margin-left: 40px; font-size:22px; font-weight:200;
}
h1 {
font-size:60px; font-weight:300;
}
.area {
height: 150px;
width: 100%;
color: white;
z-index:10;
padding : 0;
margin: 0;
}
#circularCenter {
margin: auto;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
width:74px;
height:74px;
border-radius:100%;
background:rgb(255,0,0);
}
.circle {
background:rgba(255,0,0, 1);
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
-webkit-transition:0.1s ease all;
z-index:-1;
}
.initiator {
position:absolute;
width:100%; height:100%;
background:rgba(255,255,255, 0);
-webkit-transition:0.3s ease all;
z-index:1;
cursor:pointer;
}
.experiment {
background:rgba(0,0,0, 1);
background:-webkit-linear-gradient(#000,#000);
background:-moz-linear-gradient(#000,#000);
background:-ms-linear-gradient(#000,#000);
width:100%;
height:100%;
position: center 40px;
background-image:url(Images/Choirs.png);
background-size:150px 75px;
background-attachment:fixed;
background-repeat:no-repeat;
background-position:center 40px;
z-index: 100;
height: 100%;
Width: 100%;
padding : 0;
margin: 0;
}
.header
{
height: 100px;
padding-right: auto;
padding-left:auto;
z-index: 1000;
}
.footer
{
position: absolute;
bottom: 0px;
height: 30px;
padding-left:40px;
margin-bottom: 40px;
z-index: 750;
-webkit-filter: invert(100%);
}
</style>
</head>
<body>
<div class="experiment" id="r3">
<div class="initiator"></div>
<div id="circles" class="area"></div>
<div id="circles" class="footer">
<img src="Images/Twitter.png" width="40px"></img>
<img src="Images/Facebook.png" width="40px"></img>
</div>
</div>
</div>
<audio id="r0audio" loop>
<source src="Musics/China1.mp3"></audio>
<script>
window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext;
var renderers = {
'r0': (function() {
var barsArr = [],
initialized = false,
barsEl;
var height = 0;
var init = function(config) {
var count = config.count;
var width = config.width;
var barWidth = (width/count) >> 0;
height = config.height;
barsEl = document.getElementById('bars');
for(var i = 0; i < count; i++ ){
var nunode = document.createElement('div');
nunode.classList.add('bar');
nunode.style.width = barWidth + 'px';
nunode.style.left = (barWidth * i) + 'px';
barsArr.push(nunode);
barsEl.appendChild(nunode);
}
initialized = true;
};
var max = 256;
var renderFrame = function(frequencyData) {
for(var i = 0; i < barsArr.length; i++) {
var bar = barsArr[i];
bar.style.height = ((frequencyData[i]/max)*height + 'px');
}
};
return {
init: init,
isInitialized: function() {
return initialized;
},
renderFrame: renderFrame
}
})(),
'r3': (function() {
var circles = [];
var initialized = false;
var height = 0;
var width = 0;
var init = function(config) {
var count = config.count;
width = config.width;
height = config.height;
var circleMaxWidth = (width*0.99) >> 0;
circlesEl = document.getElementById('circles');
for(var i = 0; i < count; i++ ){
var node = document.createElement('div');
node.style.width = node.style.color = (i/count*circleMaxWidth) + 'px';
node.classList.add('circle');
circles.push(node);
circlesEl.appendChild(node);
}
initialized = true;
};
var max = 256;
var renderFrame = function(frequencyData) {
for(var i = 0; i < circles.length; i++) {
var circle = circles[i];
circle.style.cssText = '-webkit-transform:scale('+1+');';
circle.style.cssText += 'opacity:'+((frequencyData[i]/max))+';';
}
};
return {
init: init,
isInitialized: function() {
return initialized;
},
renderFrame: renderFrame
}
})(),
};
window.onload = function() {
function Visualization(config) {
var audio,
audioStream,
analyser,
source,
audioCtx,
canvasCtx,
frequencyData,
running = false,
renderer = config.renderer,
width = config.width || 360,
height = config.height || 360;
var init = function() {
audio = document.getElementById('r0audio');
audioCtx = new AudioContext();
analyser = audioCtx.createAnalyser();
source = audioCtx.createMediaElementSource(audio);
source.connect(analyser);
analyser.connect(audioCtx.destination);
analyser.fftSize = 64;
frequencyData = new Uint8Array(analyser.frequencyBinCount);
renderer.init({
count: analyser.frequencyBinCount,
width: width,
height: height
});
};
this.start = function() {
audio.play();
running = true;
renderFrame();
};
this.stop = function() {
running = false;
audio.pause();
};
this.setRenderer = function(r) {
if (!r.isInitialized()) {
r.init({
count: analyser.frequencyBinCount,
width: width,
height: height
});
}
renderer = r;
};
this.isPlaying = function() {
return running;
}
var renderFrame = function() {
analyser.getByteFrequencyData(frequencyData);
renderer.renderFrame(frequencyData);
if (running) {
requestAnimationFrame(renderFrame);
}
};
init();
};
var vis = document.querySelectorAll('.initiator');
var v = null;
var lastEl;
var lastElparentId;
for(var i=0; i<vis.length; i++) {
vis[i].onclick = (function() {
return function() {
var el = this;
var id = el.parentNode.id;
if (!v) {
v = new Visualization({renderer: renderers[id] });
}
v.setRenderer(renderers[id]);
if (v.isPlaying()) {
if (lastElparentId === id) {
v.stop();
el.style.backgroundColor = 'rgba(0,0,0,0.5)';
} else {
lastEl.style.backgroundColor = 'rgba(0,0,0,0.5)';
el.style.backgroundColor = 'rgba(0,0,0,0)';
}
}else {
v.start();
el.style.backgroundColor = 'rgba(0,0,0,0)';
}
lastElparentId = id;
lastEl = el;
};
})();
}
};
</script>
</body>
</html>
Related
I've built a small balloon game , trying to learn the foundations,
anyways I've successfully rendered balloons, i can see them both on the page however the move functions doesn't work,it should do so on page load that I've set in the index.html body(the startGame func) , code looks fine,however nothing happens.
var gNextId = 100
var gBaloons = createBalloons()
var gInterval = null
function startGame() {
renderBaloons();
gInterval = setInterval(() => {
moveBalloons();
}, 500);
}
function renderBaloons() {
var strHtml = ''
for (var i = 0; i < gBaloons.length; i++) {
var balloon = gBaloons[i]
strHtml += `
${balloon.txt}
`
}
document.querySelector('.balloon-container').innerHTML = strHtml
}
function moveballoons() {
var elballoons = document.querySelectorAll('.balloon')
for (var i = 0; i > gBaloons.length; i++) {
var balloon = gBaloons[i]
var elballoon = elballoons[i]
balloon.bottom += balloon.speed
elballoon.style.bottom = balloon.bottom + 'px'
}
if (balloon.bottom >= 800) clearInterval(gInterval)
}
function createBalloons() {
var ballons = [
createBalloon('A'),
createBalloon('B'),
createBalloon('C')
];
return ballons
}
function createBalloon(txt) {
return {
id: gNextId++,
bottom: 0,
speed: 45,
txt: txt
}
}
body {
background-color: lightblue;
}
.balloon {
position: absolute;
width: 170px;
height: 200px;
border-radius: 40%;
bottom: 0;
transition: 3s;
background-color: yellow;
text-align: center;
font-weight: bold;
}
.balloon1 {
left: 200px;
background-color: rgb(3, 61, 23);
}
.balloon2 {
left: 600px;
background-color: rgb(182, 24, 50);
}
.fade {
opacity: 0;
}
In the moveballoons() function the following line:
for (var i = 0; i > gBaloons.length; i++) {
Should be
for (var i = 0; i < gBaloons.length; i++) {
Note: I've swapped > with <
I couldn't the get example running, so there could well be other reasons as to why this is not working but that is definitely an issue.
I have a yellow box in a grid. When click button 'UP' the yellow box is going one box UP. How can I stop the yellow box when it arrives at the edge? I do not want it to go out of the grid.
let moveCounter = 0;
var grid = document.getElementById("grid-box");
for (var i = 1; i <= 100; i++) {
var square = document.createElement("div");
square.className = 'square';
square.id = 'square' + i;
grid.appendChild(square);
}
var playerTwo = [];
while (playerTwo.length < 1) {
var randomIndex = parseInt(99 * Math.random());
if (playerTwo.indexOf(randomIndex) === -1) {
playerTwo.push(randomIndex);
var drawPtwo = document.getElementById('square' + randomIndex);
$(drawPtwo).addClass("p-1")
}
};
$('#button_up').on('click', function() {
moveCounter += 1;
$pOne = $('.p-1')
var id = $pOne.attr('id')
var idNumber = +id.slice(6);
var idMove = idNumber - 10
var idUpMove = 'square' + idMove;
$pOne.removeClass('p-1');
$('#' + idUpMove).addClass('p-1');
});
#grid-box {
width: 400px;
height: 400px;
margin: 0 auto;
font-size: 0;
position: relative;
}
#grid-box>div.square {
font-size: 1rem;
vertical-align: top;
display: inline-block;
width: 10%;
height: 10%;
box-sizing: border-box;
border: 1px solid #000;
}
.p-1{
background-color: yellow;
}
<div id="grid-box"></div>
<div class="move">
<button id="button_up">UP</button>
<br>
</div>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
I am new to Javascript / jQuery. Any help will be much appreciated ! Thank you
let moveCounter = 0;
var grid = document.getElementById("grid-box");
for (var i = 1; i <= 100; i++) {
var square = document.createElement("div");
square.className = 'square';
square.id = 'square' + i;
grid.appendChild(square);
}
var playerTwo = [];
while (playerTwo.length < 1) {
var randomIndex = parseInt(99 * Math.random());
if (playerTwo.indexOf(randomIndex) === -1) {
playerTwo.push(randomIndex);
var drawPtwo = document.getElementById('square' + randomIndex);
$(drawPtwo).addClass("p-1")
}
};
$('#button_up').on('click', function() {
moveCounter += 1;
$pOne = $('.p-1')
var id = $pOne.attr('id')
var idNumber = +id.slice(6);
var idMove = idNumber - 10;
if(idMove < 0){idMove +=10;}
var idUpMove = 'square' + idMove;
$pOne.removeClass('p-1');
$('#' + idUpMove).addClass('p-1');
});
#grid-box {
width: 400px;
height: 400px;
margin: 0 auto;
font-size: 0;
position: relative;
}
#grid-box>div.square {
font-size: 1rem;
vertical-align: top;
display: inline-block;
width: 10%;
height: 10%;
box-sizing: border-box;
border: 1px solid #000;
}
.p-1{
background-color: yellow;
}
<div id="grid-box"></div>
<div class="move">
<button id="button_up">UP</button>
<br>
</div>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
Here I have added the condition which restrict box to out of the grid
if(idMove < 0){idMove +=10;}
if movable position is in the minus then it again initialise it existing position.
You can add a check to stop it from moving out of the squares
var idMove = idNumber - 10
if(idMove > 0){
// do all the moving stuffs
}
$('#button_up').on('click', function() {
moveCounter += 1;
$pOne = $('.p-1')
var id = $pOne.attr('id')
var idNumber = +id.slice(6);
var idMove = idNumber - 10;
if(idMove > 0) {
var idUpMove = 'square' + idMove;
$pOne.removeClass('p-1');
$('#' + idUpMove).addClass('p-1');
}
});
You can use an if statement to check idMove > 0) If it is, then you can move your square, if it isn't then you shouldn't move your square. it will be undefined, and so you can run your code only when pOne's id is not undefined.
See example below:
let moveCounter = 0;
var grid = document.getElementById("grid-box");
for (var i = 1; i <= 100; i++) {
var square = document.createElement("div");
square.className = 'square';
square.id = 'square' + i;
grid.appendChild(square);
}
var playerTwo = [];
while (playerTwo.length < 1) {
var randomIndex = parseInt(99 * Math.random());
if (playerTwo.indexOf(randomIndex) === -1) {
playerTwo.push(randomIndex);
var drawPtwo = document.getElementById('square' + randomIndex);
$(drawPtwo).addClass("p-1")
}
};
$('#button_up').on('click', function() {
moveCounter += 1;
$pOne = $('.p-1')
var id = $pOne.attr('id')
var idNumber = +id.slice(6);
var idMove = idNumber - 10
if (idMove > 0) {
var idUpMove = 'square' + idMove;
$pOne.removeClass('p-1');
$('#' + idUpMove).addClass('p-1');
}
});
#grid-box {
width: 400px;
height: 400px;
margin: 0 auto;
font-size: 0;
position: relative;
}
#grid-box>div.square {
font-size: 1rem;
vertical-align: top;
display: inline-block;
width: 10%;
height: 10%;
box-sizing: border-box;
border: 1px solid #000;
}
.p-1 {
background-color: yellow;
}
<div id="grid-box">
</div>
<div class="move">
<button id="button_up">UP</button><br>
</div>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
I'm making a plugin for loading animation. Here is my example:
let loading = document.getElementsByClassName('loading')[0];
let width = +loading.style.width.split('px')[0], x = width / 50;
let O = {};
for (let i = 0; i <= 50; i++) {
O[i] = {
left: `0`,
width: `${i * x}px`
}
}
for (let i = 50, m = 1; i > 0; i-- , m++) {
O[m + 50] = {
left: `${m * x}px`,
width: `${(i - 1) * x}px`
}
}
let style = document.createElement('style');
let css = '';
for (let o in O) {
let c = O[o];
css += `${o}% { margin-left: ${c.left}; width: ${c.width} }`;
}
style.innerHTML = `#keyframes loading{ ${css} }`;
document.head.appendChild(style);
loading.style.animation = 'loading 2s infinite';
.container {
width: 200px;
height: 3px;
background-color: rgba(0,0,0,.12);
}
.loading {
height: 3px;
background-color: #f00;
}
<div class="container">
<div class="loading" style="width: 200px;"></div>
</div>
It's working. I want to upgrade this plugin by expanding the container width and keeping the loading width (still 200px).
let loading = document.getElementsByClassName('loading')[0];
let width = +loading.style.width.split('px')[0], x = width / 50;
let O = {};
for (let i = 0; i <= 50; i++) {
O[i] = {
left: `0`,
width: `${i * x}px`
}
}
for (let i = 50, m = 1; i > 0; i--, m++) {
O[m + 50] = {
left: `${m * x}px`,
width: `${(i - 1) * x}px`
}
}
let style = document.createElement('style');
let css = '';
for (let o in O) {
let c = O[o];
css += `${o}% { margin-left: ${c.left}; width: ${c.width} }`;
}
style.innerHTML = `#keyframes loading{ ${css} }`;
document.head.appendChild(style);
loading.style.animation = 'loading 2s infinite';
.container {
width: 300px;
height: 3px;
background-color: rgba(0,0,0,.12);
}
.loading {
height: 3px;
background-color: #f00;
}
<div class="container">
<div class="loading" style="width: 200px;"></div>
</div>
How to let it run to the end of the container?
My default example is easier because the loading width equals to the container width. So, spliting the width to multiple block (mini-widths) by width / 50 (twice).
Now, if the container width is 300, and the loading width is still 200. How to split it?
Thank you!
My idea: Split the container width to 3 parts:
50%
|----------|-----|-----|----------|
{ loading1 }{ 1 }{ 2 }{ loading2 }
The m variable is enabled and increased after getting full the loading width (1).
Inside the part 2, if m * z + loading_width < max_left (the loading2 is larger than the loading width (200 by default)), keep the width. Otherwise, decreased the width.
Also, because the second loop doesn't stop at 100%, I have added that field to the css alone:
100% { margin-left: 0; width: 0; }
let container = document.getElementsByClassName('container')[0];
let loading = document.getElementsByClassName('loading')[0];
let container_width = +container.style.width.split('px')[0];
let loading_width = +loading.style.width.split('px')[0];
let max_left = container_width - (container_width - loading_width);
let z = container_width / 50;
let O = {};
let m = 1;
for (let i = 0; i <= 50; i++) {
if (i * z <= loading_width) {
O[i] = {
left: `0`,
width: `${i * z}px`
}
} else {
O[i] = {
left: `${m++ * z}px`,
width: `${loading_width}px`
}
}
}
for (let i = 50, k = 51, n = 1; i > 0; i-- , k++ , n++) {
if (m * z + loading_width <= max_left) {
O[n + 50] = {
left: `${m++ * z}px`,
width: `${loading_width}px`
}
} else {
O[n + 50] = {
left: `${m * z}px`,
width: `${container_width - (m * z)}px`
}
if (!(container_width - m * z)) {
break;
}
m++
}
}
let style = document.createElement('style');
let css = '';
for (let o in O) {
let c = O[o];
css += `${o}% { margin-left: ${c.left}; width: ${c.width} }`;
}
style.innerHTML = `#keyframes loading{ ${css} 100% { margin-left: 0; width: 0; } }`;
document.head.appendChild(style);
loading.style.animation = 'loading 2s infinite';
.container {
height: 3px;
background-color: rgba(0,0,0,.12);
}
.loading {
height: 3px;
background-color: #f00;
}
<div class="container" style="width: 300px;">
<div class="loading" style="width: 200px;"></div>
</div>
Please I need I help on how to implement something like this responsively using bootstrap
html code for is displayed below
<div class="wrapper">
<div class="container">
<div class="special">
<div id="counter">
<div id="shading"></div>
</div>
</div>
</div>
please below is the css file for the above html code
.special
{
position: relative;
width: 840px;
height: 247px;
background-image: url('https://www.jqueryscript.net/demo/Colorful-Countdown-Timer/images/special_offer_bg.png');
background-position: -10px 74px;
background-repeat: no-repeat;
}
#counter
{
position: absolute;
top: 135px;
left: 279px;
z-index: 4000;
}
.digit-separator
{
position: relative;
float: left;
width: 17px;
height: 44px;
overflow: hidden;
background-image: url('https://www.jqueryscript.net/demo/Colorful-Countdown-Timer/images/digit_separator.png');
background-repeat: no-repeat;
background-position: 0px 0px;
}
.digit
{
background-image: url('https://www.jqueryscript.net/demo/Colorful-Countdown-Timer/images/digits.png');
}
#shading
{
background-image: url('https://www.jqueryscript.net/demo/Colorful-Countdown-Timer/images/sprites.png');
background-position: 0px -396px;
background-repeat: repeat-x;
float: left;
height: 44px;
position: absolute;
width: 291px;
z-index: 4100;
top: 0;
left: 0;
}
please this is the JavaScript code for the above html code
function C3Counter(id, opt) {
this.options = {
stepTime: 60, // not used
format: "dd:hh:mm:ss", // not used
startTime: "01:04:40:59",
digitImages: 1,
digitWidth: 30,
digitHeight: 44,
digitSlide : true,
digitSlideTime : 200,
digitImageHeight : 484,
digitAnimationHeight : 44,
timerEnd: function(){},
image: "digits.png",
updateInterval : 1000
};
var s;
if (typeof opt != "undefined") {
for (s in this.options) {
if (typeof opt[s] != "undefined") {
this.options[s] = opt[s];
}
}
}
if (String(options.startTime).indexOf(":") == -1) {
options.tempStartTime = options.startTime;
} else {
//TODO - does not convert time with : to seconds to count
var td = new Date(options.startTime);
}
this.pad2 = function(number) {
return (number < 10 ? '0' : '') + number;
}
var timer = setInterval( "this.updateCounter()", options.updateInterval);
var startTime = new Date().getTime();
var secNo = 0;
var timerSingle = new Array();
var dc = 0;
var digits = new Array();
var d = new Date();
var lastTime = d.getTime();
this.calculateTime = function() {
var tempTime = options.tempStartTime;
if (String(options.tempStartTime).indexOf(":") == -1) {
var seconds=Math.round(options.tempStartTime % 60);
options.tempStartTime=Math.floor(options.tempStartTime/60);
var minutes=Math.round(options.tempStartTime % 60);
options.tempStartTime=Math.floor(options.tempStartTime/60);
var hours=Math.round(options.tempStartTime % 24);
options.tempStartTime=Math.floor(options.tempStartTime/24);
var days=Math.round(options.tempStartTime);
options.timeStr = this.pad2(days)+this.pad2(hours)+this.pad2(minutes)+this.pad2(seconds);
}
var currTime = new Date().getTime();
var diff = currTime - startTime;
options.tempStartTime = options.startTime - Math.round(diff/1000);
}
this.calculateTime();
for (dc=0; dc<8; dc++) {
digits[dc] = { digit: this.options.timeStr.charAt(dc)};
$("#"+id).append("<div id='digit"+dc+"' style='position:relative;float:left;width:"+this.options.digitWidth+"px;height:"+this.options.digitHeight+"px;overflow:hidden;'><div class='digit' id='digit-bg"+dc+"' style='position:absolute; top:-"+digits[dc].digit*this.options.digitAnimationHeight+"px; width:"+this.options.digitWidth+"px; height:"+this.options.digitImageHeight+"px; '></div></div>");
if (dc % 2 == 1 && dc < 6) {
$("#"+id).append("<div class='digit-separator' style='float:left;'></div>");
}
}
$("#"+id).append("<div style='clear:both'></div>");
this.animateDigits = function() {
for (var dc=0; dc<8; dc++) {
digits[dc].digitNext = Number(this.options.timeStr.charAt(dc));
digits[dc].digitNext = (digits[dc].digitNext + 10)%10;
var no = dc;
if (digits[no].digit == 0) $("#digit-bg"+no).css("top", -this.options.digitImageHeight+this.options.digitHeight + "px");
if (digits[no].digit != digits[no].digitNext) {
$("#digit-bg"+no).animate( { "top" : -digits[no].digitNext*options.digitHeight+"px"}, options.digitSlideTime);
digits[no].digit = digits[no].digitNext;
}
}
var end = this.checkEnd();
}
this.checkEnd = function() {
for (var i = 0; i < digits.length; i++) {
if (digits[i].digit != 0) {
return false;
}
}
clearInterval(timer);
this.options.timerEnd();
return true;
}
this.updateCounter = function() {
d = new Date();
if ((d.getTime() - lastTime) < (options.updateInterval - 50)) {
return;
}
lastTime = d.getTime();
this.calculateTime();
this.animateDigits();
}
}
C3Counter("counter", { startTime :16100 });
Note* you need to use Bootstrap v3.3.4 or higher and jQuery v2.1.3 or higher
Note* This doesnt look like the exact example you linked to. Its not posible to achieve that with default boostrap library.
html:
<div class="wrapper">
<div class="special">
<span id="clock"></span>
</div>
</div>
js:
$('#clock').countdown('2020/10/10', function(event) {
$(this).html(event.strftime('%D days %H:%M:%S'));
});
css:
.wrapper
{
width: 100%;
height: auto;
background-color: #dc403b;
}
.special
{
width:100%;
background-image: url('https://www.jqueryscript.net/demo/Colorful-Countdown-Timer/images/special_offer_bg.png');
background-position: cover;
background-repeat: no-repeat;
text-align: center;
padding: 50px 0;
font-size: 18px;
}
I'm having a hard time trying to access the caption property within the image model. I'm creating a lightbox, where the image opens up full size on the page and has the image information underneath. In the after call back function I was able to create a function that expands the thumbnail image. However I can't access the caption or likes data.
I understand that I can do it using the template property, but that shows up when all of the images are loaded. I'm trying to show that information once the image is clicked. I keep getting an error. [gallery css test.html:35 Uncaught TypeError: Cannot read property 'custom' of undefined] when trying to retrieve the data from the custom property.
Note: In order to test the caption retrieval I changed the event listener on the thumbnails to the caption function. Normally I would attach it to the expandImage function.
Instafeed doc's
https://github.com/stevenschobert/instafeed.js
body {
margin: 0;
padding: 0;
background-color: black;
}
#container {
margin-left: auto;
margin-right: auto;
}
#galleryBox {
padding: 2%;
margin: 4%;
background-color: white;
}
#innerGallery {
margin-left: auto;
margin-right: auto;
text-align: center;
}
.thumbnail {
margin: 1%;
display: inline-block;
}
.location{
}
.caption {
}
.likes {
}
#backgroundChanger {
margin: 0;
padding: 0;
/*min-height: 150%;*/
/*min-width: 100%;*/
background-color: rgba(0,0,0,0.5);
left: 0;
right: 0;
top: 0;
bottom: 0;
position: fixed;
}
/*change lightbox to class*/
#lightBox {
left: 0;
right: 0;
top: 5%;
margin: 0 auto;
/*height: 800px;
width: 800px;*/
position: absolute;
}
#instafeed img {
object-fit: cover;
height: 20em;
width: 20em;
margin: 1%;
}
<!DOCTYPE html>
<html>
<head>
<title>Gallery</title>
<link rel="stylesheet" type="text/css" href="style2.css">
</head>
<body>
<div id="container">
<div id="galleryBox">
<div id="innerGallery"><div id="instafeed"></div></div>
</div>
</div>
</div>
</body>
<script type="text/javascript" src="js/instafeed.min.js"></script>
<script type="text/javascript">
function init() {
var feed = new Instafeed({
get: 'user',
userId: '1418648047',
resolution: 'standard_resolution',
template: '<img class="thumbnail" src="{{model.images.standard_resolution.url}}" />',
clientId: '66e8640ecc1c4145af1bb497cda6897c',
// custom: '<div class="location">{{location}}</div><div class="caption">{{caption}}</div><div class="likes">{{likes}}</div>',
custom: {
images: [],
currentImage: 0,
showImage: function () {
var result, image;
image = this.options.custom.images[this.options.custom.currentImage];
result = this._makeTemplate(this.options.template, {
model: image,
id: image.id,
link: image.link,
image: image.images[this.options.resolution].url,
caption: this._getObjectProperty(image, 'caption.text'),
likes: image.likes.count,
comments: image.comments.count,
location: this._getObjectProperty(image, 'location.name')
});
var imageInfoDiv = document.createElement("div");
imageInfoDiv.innerHTML = result;
}
},
after: function() {
var backgroundChanger = document.createElement("div");
backgroundChanger.id = "backgroundChanger";
var lightBox = document.createElement("div");
lightBox.id = "lightBox";
var expandedImg = document.createElement("img");
// var imageInfoDiv = document.createElement("div");
var thumbnails = document.getElementsByClassName("thumbnail");
var innerGallery = document.getElementById("innerGallery");
for (i = 0; i < thumbnails.length; i++) {
thumbnails[i].addEventListener("click", caption);
}
function caption(imageInfoDiv) {
console.log(feed.options.custom.showImage(imageInfoDiv));
lightBox.appendChild(feed.options.custom.showImage(imageInfoDiv));
}
function expandImage() {
expandImage = this;
expandedImg.src = this.src;
document.body.appendChild(backgroundChanger);
backgroundChanger.appendChild(lightBox);
lightBox.appendChild(expandedImg);
lightBox.style.width = expandedImg.width + "px";
expandedImg.addEventListener("click", removeImage);
backgroundChanger.addEventListener("click", removeImage);
}
//TO DO: Add captions, favorite. Next previous. Alt tag? Work on canvas
function removeImage() {
document.body.removeChild(backgroundChanger);
backgroundChanger.removeChild(lightBox);
lightBox.removeChild(expandedImg);
expandedImg.removeEventListener("click", removeImage);
backgroundChanger.removeEventListener("click", removeImage);
}
// feed.next();
}
});
feed.run();
// var hew = Instafeed.prototype.
var rgb = getAverageRGB(document.getElementById("i"));
document.body.style.backgroundColor = "rgb('+rgb.r+', '+rgb.b+', '+rgb.g+')";
function getAverageRGB(imgEl) {
var blockSize = 5, //every 5 pixels
defaultRGB = {r:0, g:0, b:0},
canvas = document.createElement,
context = canvas.getContext && canvas.getContext('2d'),
data, width, height,
i = -4,
length,
rgb = {r:0, g:0, b:0},
count = 0;
if (!context) {
return defaultRGB;
}
height = canvas.height = imgEl.naturalHeight || imgEl.offsetHeight || imgEl.height;
width = canvas.width = imgEl.naturalWidth || imgEl.offsetWidth || imgEl.width;
context.drawImage(imgEl, 0, 0);
try {
data = context.getImageData(0, 0, width, height);
} catch(e) {
console.log("x");
return defaultRGB;
}
length = data.data.length;
while ((i += blockSize * 4) < length) {
++count;
rgb.r += data.data[i];
rgb.g += data.data[i+1];
rgb.b += data.data[i+2];
}
rgb.r = ~~(rgb.r/count);
rgb.g = ~~(rgb.g/count);
rgb.b = ~~(rgb.b/count);
return rgb;
}
};
window.onload = init();
</script>
</html>
Cannot read property 'custom' of undefined means, options is not exists on object this. that's because the context of showImage is bind to object custom instead of object feed. That means, you are calling custom.options.custom.
use this.images[this.currentImage] instead if this represented to custom itself, use feed if this represented to feed object