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>
Related
I'm trying to create a number of divs and iterate through them on click.
The iteration only works on every other click.
Strangely, I'm getting no errors.
I tried moving the divs variable declaration outside of the for loop.
for (let i = 0; i <= 5; i++) {
let div = document.body.insertAdjacentHTML('beforeend', `<div class="div">${i}</div>`)
let divs = document.getElementsByClassName('div');
divs[i].style.backgroundColor = randomColor();
divs[i].onclick = () => {
close(divs[i])
open(divs[i + 1])
}
}
function randomColor() {
let e = Math.floor(Math.random() * 16777215).toString(16);
return `#${e}`;
}
function close(t) {
t.style.transform = 'scale(0.5)'
t.style.opacity = '0'
setTimeout(function() {
t.style.display = 'none'
}, 500)
}
function open(t) {
t.style.display = 'block'
setTimeout(function() {
t.style.transform = 'scale(1)'
t.style.opacity = '1'
}, 5)
}
div {
height: 100%;
width: 100%;
position: fixed;
top: 0;
bottom: 0;
right: 0;
transition: 0.5s;
opacity: 0;
transform: scale(0.5);
}
you need to
open(divs[(i + 1) % 6]) so it loop correctly
hide all divs at initial (except one)
there still some minor issue with the initial state (need to add opacity and transform, I leave it for simplicity), I think you should use proper class instead of inline css to make it easier.
for (let i = 0; i <= 5; i++) {
let div = document.body.insertAdjacentHTML('beforeend',
`<div class="div" style="display:${i==0?'block':'none'}">${i}</div>`
)
}
let divs = document.getElementsByClassName('div');
for (let i = 0; i <= 5; i++) {
divs[i].style.backgroundColor = randomColor();
divs[i].onclick = () => {
close(divs[i])
open(divs[(i + 1) % 6])
}
}
function randomColor() {
let e = Math.floor(Math.random() * 16777215).toString(16);
return `#${e}`;
}
function close(t) {
t.style.transform = 'scale(0.5)'
t.style.opacity = '0'
setTimeout(function() {
t.style.display = 'none'
}, 500)
}
function open(t) {
t.style.display = 'block'
setTimeout(function() {
t.style.transform = 'scale(1)'
t.style.opacity = '1'
}, 5)
}
div {
height: 100%;
width: 100%;
position: fixed;
top: 0;
bottom: 0;
right: 0;
transition: 0.5s;
opacity: 0;
transform: scale(0.5);
}
I have a graph that is rendering its values as a div inside the body element with a class according to their number values. This is working fine. But next I need to sort the divs according to their number values or background color. BUT, it needs to start on the lower left corner of the page and fan out upwards to towards the right as the numbers increase. Basically just like a line graph.
I'd like to stay away from libraries if at all possible.
How would I approach this? Thank you all.
let interval = setInterval(makeDivs, 5);
function makeDivs(){
let cont = checkHeight();
if(cont){
let div = document.createElement('div');
let randNum = Math.random() * 100;
if(randNum < 20) { div.classList.add('blue') }
if(randNum >= 20 && randNum < 40) { div.classList.add('green') }
if(randNum >= 40 && randNum < 60) { div.classList.add('yellow') }
if(randNum >= 60 && randNum < 80) { div.classList.add('orange') }
if(randNum >= 80 && randNum < 101) { div.classList.add('red') }
div.textContent = randNum.toFixed(2);
document.querySelector('body').appendChild(div);
} else {
alert('done');
clearInterval(interval);
sortDivs(); // Begin sorting divs
}
}
function checkHeight(){
let w = window.innerHeight;
let b = document.querySelector('body').offsetHeight;
if(b < w) {
return true;
} else {
return false;
}
}
function sortDivs(){
document.querySelector("body div:last-child").remove();
alert('sorting now...')
}
* { box-sizing: border-box;}
body { width: 100vw; margin: 0; padding: 0; display: flex; flex-wrap: wrap; align-items: end;}
body div { width: calc(10% + 1px); text-align: center; border: 1px solid #ddd; margin: -1px 0 0 -1px; padding: 10px;}
body div.blue { background: aqua; }
body div.green { background: green; }
body div.yellow { background: yellow; }
body div.orange { background: orange; }
body div.red { background: red; }
UPDATE!!!
So I have this so far based on the feed back down below. The problem now is the sorting is only happening laterally and not on an angle (spreading right and to the top).
let interval = setInterval(makeDivs, 10);
function makeDivs(){
let cont = checkHeight();
if(cont){
let div = document.createElement('div');
let randNum = Math.random() * 100;
if(randNum < 20) { div.classList.add('blue') }
if(randNum >= 20 && randNum < 40) { div.classList.add('green') }
if(randNum >= 40 && randNum < 60) { div.classList.add('yellow') }
if(randNum >= 60 && randNum < 80) { div.classList.add('orange') }
if(randNum >= 80 && randNum < 101) { div.classList.add('red') }
div.textContent = randNum.toFixed(2);
document.querySelector('.outPut').appendChild(div);
} else {
clearInterval(interval);
document.querySelector(".outPut div:last-child").remove();
compileArrays(); // Begin sorting divs
}
}
function checkHeight(){
let w = window.innerHeight;
let b = document.querySelector('.outPut').offsetHeight;
if(b < w) {
return true;
} else {
return false;
}
}
function compileArrays(){
let divs = document.querySelectorAll('.outPut div');
let bArr = [], gArr = [], yArr = [], oArr = [], rArr = [];
divs.forEach( (d) => {
if( d.classList.contains('blue') ){ bArr.push(d) }
if( d.classList.contains('green') ){ gArr.push(d) }
if( d.classList.contains('yellow') ){ yArr.push(d) }
if( d.classList.contains('orange') ){ oArr.push(d) }
if( d.classList.contains('red') ){ rArr.push(d) }
});
let finalArr = sortArray(bArr).concat(sortArray(gArr)).concat(sortArray(yArr)).concat(sortArray(oArr)).concat(sortArray(rArr));
newDom(finalArr);
}
function sortArray(arr){
let newArr = arr;
newArr.sort( (a, b) => {
return a.innerText - b.innerText;
});
return newArr;
}
function newDom(arr){
let b = document.querySelector('.outPut');
b.innerHTML = '';
arr.reverse();
arr.forEach((a) => {
b.appendChild(a);
});
}
* { box-sizing: border-box;}
body { width: 100vw; height: 100vh; margin: 0; padding: 0; display: flex; align-items: flex-end;}
body .outPut { flex: 1; display: flex; flex-wrap: wrap; flex-direction:row-reverse; }
body .outPut div { width: calc(10% + 1px); text-align: center; border: 1px solid #ddd; margin: -1px 0 0 -1px; padding: 10px;}
body .outPut div.blue { background: aqua; }
body .outPut div.green { background: #44df15; }
body .outPut div.yellow { background: yellow; }
body .outPut div.orange { background: orange; }
body .outPut div.red { background: red; }
<div class="outPut"></div>
Supposed you already have a mechanism to organise such DIVs in a grid as shown, the following should give you what you are looking for:
var items = divList.filter((div) => div.nodeType == 1); // get rid of the whitespace text nodes
items.sort(function(a, b) {
return a.innerHTML == b.innerHTML
? 0
: (a.innerHTML > b.innerHTML ? 1 : -1);
});
Then, place them back in the DOM as needed, example:
for (i = 0; i < items.length; ++i) {
divList.appendChild(items[i]);
}
This worked with the first code example!!!
try this sortDivs function:
function sortDivs() {
document.querySelector("body div:last-child").remove();
alert('sorting now...')
let toSort = document.getElementsByTagName("div")
toSort = Array.prototype.slice.call(toSort, 0)
toSort.sort((a, b) => {
let aord = parseFloat(a.textContent);
let bord = parseFloat(b.textContent);
return bord - aord;
})
document.body.innerHTML = ""
for(var i = 0, l = toSort.length; i < l; i++) {
document.querySelector('body').appendChild(toSort[i]);
}
}
and in the css file set flex-wrap to wrap-reverse. Hope I could help :)
PS: please, implement some else if instead of doing only if
Here is a small fiddle with my sample code demonstrating a simple solution in pure JavaScript and absolute CSS positioning for what you are trying to achieve. Link
As some pointed out already, there might be a library, that already provides a better and complete solution for this - I did not research if it is so.
Code:
file.js
var container = document.getElementById("container")
var results = [1,2,3,4,5,6,7,8]
//you can pre-calculate the order of the distances
//here already orderdered array [distanec][X-axis][Y-axis]
var distances =[[0,0,0],
[1,1,0],
[1,0,1],
[1.414, 1,1],
[2,0,2],
[2,2,0],
[2.234, 2,1],
[2.234, 1,2]]
for (i = 0; i < results.length; i++){
var newDiv = document.createElement("div")
newDiv.className = "result"
newDiv.innerHTML = results[i]
newDiv.style.left = distances[i][1]*20 + "px"
newDiv.style.bottom = distances[i][2]*20 + "px"
container.appendChild(newDiv)
}
function setColor(element){
// set class based on value - you already have this part
}
style.css
#container {
border: 4px;
border-color: red;
border-style: solid;
height: 200px;
width: 200px;
position: relative;
}
.result{
border: 2px;
width: 20px;
height: 20px;
position: absolute;
border-color: blue;
border-style: solid;
text-align: center;
}
site.html
<div id="container">
</div>
Output:
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 want to have a scrolling marquee that never ends, and with that, I mean that there will never be a blank space in the marquee.
So when, for example, all text has been in the screen (viewport) and the latest words are marquee'ing, the marquee will repeat without first ending the marquee (meaning: all text has gone away into the left side [marquee: right -> left]). With repeat I mean that the text will just start over right behind where the marquee is
So when I have the marquee text " Hello poeple of the earth •", and that is here:
_ = blank
! = Char of first run of marquee
^ = char of second run of marquee
& = char of third run of marquee
________!!!!!!!!!!!!!!!!!!!!!!!!!!!!****************************^^^^^^^^^^^^^^^^^^^^^^^^^^^^&&&&&&&&
Ofcourse I need it to be smooth. Something like this answer, but without the blank spaces. The use of libraries doesn't matter.
Can anyone help me?
You can use marque plugin to achieve this
$('.marquee').marquee({
//speed in milliseconds of the marquee
duration: 5000,
//gap in pixels between the tickers
gap: 0,
//time in milliseconds before the marquee will start animating
delayBeforeStart: 0,
//'left' or 'right'
direction: 'left',
//true or false - should the marquee be duplicated to show an effect of continues flow
duplicated: false
});
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script type='text/javascript' src='//cdn.jsdelivr.net/jquery.marquee/1.3.1/jquery.marquee.min.js'></script>
<body>
<div class="marquee">stuff to say 1|</div>
<div class="marquee">stuff to say 2|</div>
<div class="marquee">stuff to say 3|</div>
<div class="marquee">stuff to say 4|</div>
<div class="marquee">stuff to say 5</div>
</body>
I think this is what you want :)))
function start() {
new mq('latest-news');
mqRotate(mqr);
}
window.onload = start;
function objWidth(obj) {
if (obj.offsetWidth) return obj.offsetWidth;
if (obj.clip) return obj.clip.width;
return 0;
}
var mqr = [];
function mq(id) {
this.mqo = document.getElementById(id);
var wid = objWidth(this.mqo.getElementsByTagName("span")[0]) + 5;
var fulwid = objWidth(this.mqo);
var txt = this.mqo.getElementsByTagName("span")[0].innerHTML;
this.mqo.innerHTML = "";
var heit = this.mqo.style.height;
this.mqo.onmouseout = function () {
mqRotate(mqr);
};
this.mqo.onmouseover = function () {
clearTimeout(mqr[0].TO);
};
this.mqo.ary = [];
var maxw = Math.ceil(fulwid / wid) + 1;
for (var i = 0; i < maxw; i++) {
this.mqo.ary[i] = document.createElement("div");
this.mqo.ary[i].innerHTML = txt;
this.mqo.ary[i].style.position = "absolute";
this.mqo.ary[i].style.left = wid * i + "px";
this.mqo.ary[i].style.width = wid + "px";
this.mqo.ary[i].style.height = heit;
this.mqo.appendChild(this.mqo.ary[i]);
}
mqr.push(this.mqo);
}
function mqRotate(mqr) {
if (!mqr) return;
for (var j = mqr.length - 1; j > -1; j--) {
maxa = mqr[j].ary.length;
for (var i = 0; i < maxa; i++) {
var x = mqr[j].ary[i].style;
x.left = parseInt(x.left, 10) - 1 + "px";
}
var y = mqr[j].ary[0].style;
if (parseInt(y.left, 10) + parseInt(y.width, 10) < 0) {
var z = mqr[j].ary.shift();
z.style.left = parseInt(z.style.left) + parseInt(z.style.width) * maxa + "px";
mqr[j].ary.push(z);
}
}
mqr[0].TO = setTimeout("mqRotate(mqr)", 20);
}
.marquee {
position: relative;
overflow: hidden;
text-align: center;
margin: 0 auto;
width: 100%;
height: 30px;
display: flex;
align-items: center;
white-space: nowrap;
}
#latest-news {
line-height: 32px;
a {
color: #555555;
font-size: 13px;
font-weight: 300;
&:hover {
color: #000000;
}
}
span {
font-size: 18px;
position: relative;
top: 4px;
color: #999999;
}
}
<div id="latest-news" class="marquee">
<span style="white-space:nowrap;">
<span> •</span>
one Lorem ipsum dolor sit amet
<span> •</span>
two In publishing and graphic design
<span> •</span>
three Lorem ipsum is a placeholder text commonly
</span>
</div>
Thank You sire.....I get it....What I need....
function start() {
new mq('latest-news');
mqRotate(mqr);
}
window.onload = start;
function objWidth(obj) {
if (obj.offsetWidth) return obj.offsetWidth;
if (obj.clip) return obj.clip.width;
return 0;
}
var mqr = [];
function mq(id) {
this.mqo = document.getElementById(id);
var wid = objWidth(this.mqo.getElementsByTagName("span")[0]) + 5;
var fulwid = objWidth(this.mqo);
var txt = this.mqo.getElementsByTagName("span")[0].innerHTML;
this.mqo.innerHTML = "";
var heit = this.mqo.style.height;
this.mqo.onmouseout = function () {
mqRotate(mqr);
};
this.mqo.onmouseover = function () {
clearTimeout(mqr[0].TO);
};
this.mqo.ary = [];
var maxw = Math.ceil(fulwid / wid) + 1;
for (var i = 0; i < maxw; i++) {
this.mqo.ary[i] = document.createElement("div");
this.mqo.ary[i].innerHTML = txt;
this.mqo.ary[i].style.position = "absolute";
this.mqo.ary[i].style.left = wid * i + "px";
this.mqo.ary[i].style.width = wid + "px";
this.mqo.ary[i].style.height = heit;
this.mqo.appendChild(this.mqo.ary[i]);
}
mqr.push(this.mqo);
}
function mqRotate(mqr) {
if (!mqr) return;
for (var j = mqr.length - 1; j > -1; j--) {
maxa = mqr[j].ary.length;
for (var i = 0; i < maxa; i++) {
var x = mqr[j].ary[i].style;
x.left = parseInt(x.left, 10) - 1 + "px";
}
var y = mqr[j].ary[0].style;
if (parseInt(y.left, 10) + parseInt(y.width, 10) < 0) {
var z = mqr[j].ary.shift();
z.style.left = parseInt(z.style.left) + parseInt(z.style.width) * maxa + "px";
mqr[j].ary.push(z);
}
}
mqr[0].TO = setTimeout("mqRotate(mqr)", 20);
}
.marquee {
position: relative;
overflow: hidden;
text-align: center;
margin: 0 auto;
width: 100%;
height: 30px;
display: flex;
align-items: center;
white-space: nowrap;
}
#latest-news {
line-height: 32px;
a {
color: #555555;
font-size: 13px;
font-weight: 300;
&:hover {
color: #000000;
}
}
span {
font-size: 18px;
position: relative;
top: 4px;
color: #999999;
}
}
<div id="latest-news" class="marquee">
<span style="white-space:nowrap;">
<span> •</span>
one Lorem ipsum dolor sit amet
<span> •</span>
two In publishing and graphic design
<span> •</span>
three Lorem ipsum is a placeholder text commonly
</span>
</div>
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>