I want to program a effect like digital signage in the webpage but I am not sure how to do it, please kindly offer some help in here.
I have several div in the page which is the place holder of region.
For each region, there are multiple media inside.
For a defined duration the current media will play other will be hidden (or destroy) and the subsequence media will come out in the same position.
Most importantly, when the last element is reach, i will replay the whole sequence again. so the webpage keep rolling.
I have made a JSFiddle for this case, please kindly help on this and i have spend a day on that on my poor coding.....
https://jsfiddle.net/vx8Lp9xd/11/
HTML
<body>
<div class='timecontrol region1 position' >
<video duration='30' width="320" height="240" controls class='position'>
<source src="movie.mp4" type="video/mp4">
</video>
<video duration='0' width="320" height="240" controls class='position'>
<source src="movie.mp4" type="video/mp4">
</video>
</div>
<div class='timecontrol region2 position'>
<img class='position' duration='10' src='1.gif'></img>
<img class='position' duration='20' src='2.gif'></img>
</div>
<div class='readyState'></div>
</body>
Javascript
function checkContainer () {
if($('#readyState').is(':visible')){ //if the container is visible on the page
$('.timecontrol').each(function() {
var elements = new Array();
elements = $(this).children().toArray();
for (element in elements){
$(element).not(element).remove();
$(element).show();
$(element).delay(parseInt($(element).attr('duration'))*1000).hide(0);
}
});
}
}
$( document ).ready(function() {
checkContainer();
});
CSS
.position{
position:absolute;
}
.region1{
position:absolute;
top:0px;
left:0px;
height:320px;
width:240px;
}
.region2{
position:absolute;
top:px;
left:320px;
height:320px;
width:100px;
border:1px;
}
A recursive function (a function that calls itself) is probably better suited to your needs here than .each() or a for loop. Here is how I would do it with recursion:
jsFiddle
function checkContainer() {
if ($('#readyState').is(':visible')) { //if the container is visible on the page
$('.timecontrol').each(function () {
change($(this).children());
});
}
}
function change(elements, index) {
index = !index || index > elements.length - 1 ? 0 : index; // if index is higher than the index of the last element or not set at all, default to 0
var element = $(elements[index]);
var timeframe = parseInt(element.attr('duration')) * 1000;
element.siblings().hide();
element.show();
if (element[0].tagName.match(/video/i)) element[0].play();
setTimeout(function () {
element.hide(0);
if (element[0].tagName.match(/video/i)) element[0].pause();
change(elements, index+1); // recursively call this same functoin passing in the elements and the index of the next one up
}, timeframe);
}
$(document).ready(function () {
checkContainer();
});
.position {
position:absolute;
}
.region1 {
position:absolute;
top:0px;
left:0px;
height:320px;
width:240px;
}
.region2 {
position:absolute;
top:px;
left:320px;
height:320px;
width:100px;
border:1px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='timecontrol region1 position'>
<video duration='6' width="320" height="240" controls class='position'>
<source src="http://stream.flowplayer.org/functional.mp4" type="video/mp4">
</video>
<video duration='6' width="320" height="240" controls class='position'>
<source src="http://stream.flowplayer.org/bauhaus.mp4" type="video/mp4">
</video>
</div>
<div class='timecontrol region2 position'>
<img class='position' duration='10' src='https://placeimg.com/350/150/any'></img>
<img class='position' duration='20' src='https://placeimg.com/350/150/animals'></img>
</div>
<div id='readyState'></div>
Related
I use the isInViewport script to play the video on scroll, but it doesn't look very good because it happens multiple times. Please tell how to limit the triggering of animation or video playback to literally once. Tried to add with one() and true/false but the code didn't work (I still green in jquery).
<div class="block"><span>Video below</span></div>
<div class="block video-block">
<video class="video" loop="loop" width="640" controls="controls" muted>
<source src="http://denis-creative.com/wp-content/uploads/2018/01/video.mp4" type="video/mp4" />
<source src="http://denis-creative.com/wp-content/uploads/2018/01/video.ogv" type="video/ogv" />
<source src="http://denis-creative.com/wp-content/uploads/2018/01/video.webm" type="video/webm" />
</video>
</div>
<div class="block"><span>Video above</span></div>
.block{
height: 100vh;
font-size: 60px;
text-align: center;
display: flex;
}
.block > *{
margin: auto;
display: inline-block;
max-width: 100%;
}
// Plugin isInViewport
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(require("jquery"),require("window")):"function"==typeof define&&define.amd?define("isInViewport",["jquery","window"],n):n(e.$,e.window)}(this,function(e,n){"use strict";function t(n){var t=this;if(1===arguments.length&&"function"==typeof n&&(n=[n]),!(n instanceof Array))throw new SyntaxError("isInViewport: Argument(s) passed to .do/.run should be a function or an array of functions");return n.forEach(function(n){"function"!=typeof n?(console.warn("isInViewport: Argument(s) passed to .do/.run should be a function or an array of functions"),console.warn("isInViewport: Ignoring non-function values in array and moving on")):[].slice.call(t).forEach(function(t){return n.call(e(t))})}),this}function o(n){var t=e("<div></div>").css({width:"100%"});n.append(t);var o=n.width()-t.width();return t.remove(),o}function r(t,i){var a=t.getBoundingClientRect(),u=a.top,c=a.bottom,f=a.left,l=a.right,d=e.extend({tolerance:0,viewport:n},i),s=!1,p=d.viewport.jquery?d.viewport:e(d.viewport);p.length||(console.warn("isInViewport: The viewport selector you have provided matches no element on page."),console.warn("isInViewport: Defaulting to viewport as window"),p=e(n));var w=p.height(),h=p.width(),v=p[0].toString();if(p[0]!==n&&"[object Window]"!==v&&"[object DOMWindow]"!==v){var g=p[0].getBoundingClientRect();u-=g.top,c-=g.top,f-=g.left,l-=g.left,r.scrollBarWidth=r.scrollBarWidth||o(p),h-=r.scrollBarWidth}return d.tolerance=~~Math.round(parseFloat(d.tolerance)),d.tolerance<0&&(d.tolerance=w+d.tolerance),l<=0||f>=h?s:s=d.tolerance?u<=d.tolerance&&c>=d.tolerance:c>0&&u<=w}function i(n){if(n){var t=n.split(",");return 1===t.length&&isNaN(t[0])&&(t[1]=t[0],t[0]=void 0),{tolerance:t[0]?t[0].trim():void 0,viewport:t[1]?e(t[1].trim()):void 0}}return{}}e="default"in e?e.default:e,n="default"in n?n.default:n,/**
* #author Mudit Ameta
* #license https://github.com/zeusdeux/isInViewport/blob/master/license.md MIT
*/
e.extend(e.expr[":"],{"in-viewport":e.expr.createPseudo?e.expr.createPseudo(function(e){return function(n){return r(n,i(e))}}):function(e,n,t){return r(e,i(t[3]))}}),e.fn.isInViewport=function(e){return this.filter(function(n,t){return r(t,e)})},e.fn.run=t});
//# isInViewport
// Play Video
$(function() {
var $video = $('.video');
var $window = $(window);
$window.scroll(function() {
if ($video.is(":in-viewport")) {
$video[0].play();
} else {
$video[0].pause();
}
});
});
You could add a var to check if the video is still playing (for example is_playing) and check it with an inner if:
$(function() {
var $video = $('.video');
var $window = $(window);
var is_playing = false;
$window.scroll(function() {
if ($video.is(":in-viewport")) {
if (!is_playing) {
is_playing = true;
$video[0].play();
}
} else {
$video[0].pause();
}
});
});
how could I make this happen? For example.....
Once I have clicked 'button play' the changes to 'button pause'
and once I have clicked 'button pause' the changes to 'button play'.
I want to custom audio tags,but I don't know how to make it.
I don't know how to use Javascript to switch image.
I trying to find a way,but I don't understand it. T-T
Below is what I using in html template:
<button><img src="{% static "img/play.png" %}"></button>
<button><img src="{% static "img/pause.png" %}"></button>
<audio controls>
<source src="{{ song.song_file.url }}" type="audio/mp3">
</audio>
Thanks a lot
var track = document.getElementById('track');
var controlBtn = document.getElementById('play-pause');
function playPause() {
if (track.paused) {
track.play();
//controlBtn.textContent = "Pause";
controlBtn.className = "pause";
} else {
track.pause();
//controlBtn.textContent = "Play";
controlBtn.className = "play";
}
}
controlBtn.addEventListener("click", playPause);
track.addEventListener("ended", function() {
controlBtn.className = "play";
});
#player-container #play-pause {
cursor: pointer;
text-indent: -999999px;
height:40px;
width: 40px;
background: #eb01a5;
background-image: url('http://basichow.com/asserts/images/play.png');
background-repeat:no-repeat;
background-position:center;
background-size:20px;
}
.play {
background-image: url('http://basichow.com/asserts/images/play.png');
}
.pause {
background-image: url('http://basichow.com/asserts/images/pause.png')!important;
}
<audio id="track">
<source src="http://basichow.com/asserts/interlude.mp3" type="audio/mpeg" />
</audio>
<div id="player-container">
<div id="play-pause" class="play">Play</div>
</div>
What I want is whenever I mouseover on an element for it to set the style of video to display: none; and then the img to display: block;
Here's my code:
Javascript
document.addEventListener("DOMContentLoaded", function() {
document.getElementById("container").addEventListener("mouseenter", function(event) {
alternate(event);
});
document.getElementById("container").addEventListener("mouseout", function(event) {
alternate(event);
});
function alternate(e) {
var target = e.target || e.srcElement;
if (target) {
if (target.nodeName == "IMG") {
target.querySelector(".video").style.display = "block";
target.querySelector(".img").style.display = "none";
} else if (target.nodeName == "VIDEO") {
target.querySelector(".video").style.display = "none";
target.querySelector(".img").style.display = "block";
}
}
}
});
HTML
<div id="container">
<li>
<div>
<video class="video" src="./test.mp4" type="video/mp4" muted autoplay></video>
<img class="img" src="./test.jpg"></img>
</div>
</li>
<li>
<div>
<video class="video" src="./test.mp4" type="video/mp4" muted autoplay></video>
<img class="img" src="./test.jpg"></img>
</div>
</li>
</div>
Essentially what I am trying to achieve is whenever I mouseout from the video, put the image back and then back from. video: hidden, image:shown to video:shown, image:hidden.
I did manage to get something working by using the target.previousSibling technique but it didn't work 100%,
Hopefully I formatted this question right, thank you for reading. Any help is really appreciated.
You could achieve this with pure CSS. A very simple approach would be:
.hover-toggle {
position: relative;
}
.hover-toggle .video {
/* Use absolute positioning to place video along-side image */
position: absolute;
top: 0;
left: 0;
/* Set video to be transparent by default */
opacity: 0;
}
/* When hovering the transparent video, cause it to become opaque */
.hover-toggle .video:hover {
opacity: 1;
}
<div class="hover-toggle">
<video class="video" src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4" muted autoplay></video>
<img class="img" src="https://via.placeholder.com/320x176" />
</div>
<div class="hover-toggle">
<video class="video" src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4" muted autoplay></video>
<img class="img" src="https://via.placeholder.com/320x176" />
</div>
mouseenter and mouseleave are the proper events to use.
If you use <li> then you must use <ol> or <ul> as the parent.
Register the events to each <li>
const items = document.querySelectorAll('li');
for (let item of items) {
item.addEventListener('mouseenter', alternate);
item.addEventListener('mouseleave', alternate);
}
Define the event handler using e.target and .matches('li') to insure that the events only apply to <li>. Then use e.type to insure that only mouseenter and mouseleave` events apply.
const tgt = e.target;
const evt = e.type;
if (tgt.matches('li')) {
if (evt === 'mouseenter') {
...
else if (evt === 'mouseleave') {
...
}
The reason why target.previousSibling worked some of the time is because display: none removes elements from the flow thereby not being recognized as a sibling. Try assigning a class that has visibility and z-index properties and alternate that class between events.
tgt.children[0].classList.add('on');
tgt.children[1].classList.remove('on');
// and vice versa
BTW <img> tags are void elements (no end tag </img>)
const items = document.querySelectorAll('li');
for (let item of items) {
item.addEventListener('mouseenter', alternate);
item.addEventListener('mouseleave', alternate);
}
function alternate(e) {
const tgt = e.target;
const evt = e.type;
if (tgt.matches('li')) {
if (evt === 'mouseenter') {
tgt.children[0].classList.add('on');
tgt.children[1].classList.remove('on');
} else if (evt === 'mouseleave') {
tgt.children[1].classList.add('on');
tgt.children[0].classList.remove('on');
} else {
return false;
}
}
return false;
}
li {
position: relative;
height: 135px;
}
li * {
visibility: hidden;
position: absolute;
z-index: -1;
top: 0;
left: 0;
}
.on {
visibility: visible;
z-index: 1;
}
<ul>
<li>
<video src='https://storage04.dropshots.com/photos6000/photos/1381926/20170326/005610.mp4' muted autoplay loop width='240' height='135'></video>
<img class='on' src='https://branditprintit.com/wp-content/uploads/2017/04/logo-degin-logo-design-design-art-free.png' width='240' height='135'>
</li>
<li>
<video src='https://storage04.dropshots.com/photos6000/photos/1381926/20170326/005609.mp4' muted autoplay loop width='240' height='135'></video>
<img class='on' src='https://branditprintit.com/wp-content/uploads/2017/04/logo-degin-logo-design-design-art-free.png' width='240' height='135'>
</li>
</ul>
I have several kinds of videos, like this
<video id='abd' height="200" width="200" ></video>
<embed id='bcd' height="200" width="200" ></embed>
<object id='cde' height="200" width="200" ></object>
I have calculated target position like this
<script>
var vid=document.getElementById('abd');
var width = vid.offsetWidth;
var height = vid.height;
var x = width/2+ 'px';
var y = height - 12+'px';
var div = '<div>Heloo</div>';
</script>
Now i want to put a div at position (x,y).
How can i do this. div is stored in var div, Is there any way to do this perfectly,
Your help will be greatful
Thanks
You can do this using pure CSS - no JS required!
The HTML
<div id="video-container">
<iframe width="420" height="315" src="//www.youtube.com/embed/dQw4w9WgXcQ" frameborder="0" allowfullscreen> </iframe>
<div class="video-overlay">
Overay Content
</div>
</div>
The CSS
#video-container {
position:relative;
width:420px;
}
.video-overlay {
position:absolute;
top:50px;
right:50px;
background:#000;
color:#FFF;
}
See it in action
http://jsfiddle.net/y28Zs/
try this
http://jsfiddle.net/miquelcamps/BJN8x/3/
html
<video id="embed" width="200" height="200" controls>
<source src="http://vjs.zencdn.net/v/oceans.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
javascript
var vid = document.getElementById('embed');
var width = vid.width;
var height = vid.height;
var x = vid.offsetLeft;
var y = vid.offsetTop;
var div = '<div class="overlay" style="height:'+height+'px;width:'+width+'px;left:'+x+'px;top:'+y+'px;">Hello</div>';
document.body.innerHTML += div;
css
.overlay{
position:absolute;
background:red;
z-index:99;
}
Please check is it what you want :
<div id="adds">
<video id='abd' height="200" width="200" style="border:2px solid" ></video>
</div>
Javascript ----
vid=document.getElementById('abd');
addDiv =document.getElementById('adds');
var width = vid.offsetWidth;
var height = vid.height;
var x = width/2+ 'px';
var y = height - 12+'px';
var newDiv = document.createElement("div");
newDiv.innerText = "Hello....";
newDiv.style.left = "102px";
newDiv.style.top = "108px";
newDiv.style.position = "absolute";
addDiv.appendChild(newDiv);
Live demo : (http://jsfiddle.net/7EhtL/)
I am creatinga page specifically for an ipad.
I have 12 audio players on a page. They are all working fine but if you click a second player the first one continues to play. I've seen this question asked before but none of the answers are specific to my code.
<script>
function EvalSound(soundobj) {
var thissound=document.getElementById(soundobj);
if (thissound.paused)
thissound.play();
else
thissound.pause();
thissound.currentTime = 0;
}
</script>
The players themselves:
<a href="card3_ipad.php?card=funny" onClick="EvalSound('song1'); return true;"
target="player"><IMG SRC="images/funnytab.gif" BORDER=0 WIDTH=128 HEIGHT=29>
</A>
<audio id="song1" style="display: none; width: 0px; height: 0px;"
src="mp3examples/funnyauto.mp3" controls preload="auto" autobuffer>
then another player is:
<a href="card3_ipad.php?card=country" onClick="EvalSound('song2'); return true;"
target="player"><IMG SRC="images/countrytab.gif" BORDER=0 WIDTH=128 HEIGHT=29>
</A>
<audio id="song2" style="display: none; width: 0px; height: 0px;"
src="mp3examples/countryauto.mp3" controls preload="auto" autobuffer>
Any help would be massively appreciated!
Cheers
Tom
use another variable which hold current active player
<script>
var currentPlayer;
function EvalSound(soundobj) {
var thissound=document.getElementById(soundobj);
if(currentPlayer && currentPlayer != thissound) {
currentPlayer.pause();
}
if (thissound.paused)
thissound.play();
else
thissound.pause();
thissound.currentTime = 0;
currentPlayer = thissound;
}
</script>