I'm working on an interactive website assignment, and I'm using video's for some parts. I managed to change the background-video src when a particular element is clicked, but the transition is very abrupt. I want it to be smooth and fade out.
I tried adding transition: all .3s ease-in-out; to the video css class, but that didn't work.
My current code:
JS
const handleClickItem = e => {
const $video = document.querySelector('.omgeving_vid');
const activeItem = e.currentTarget;
console.log(activeItem);
updateGroup(activeItem); //for changing opacity of elements, not relevant
console.log(activeItem.dataset.omgeving);
if (activeItem.dataset.omgeving === 'sneeuw') {
$video.setAttribute('src', './assets/longread/new_snowstorm.mp4');
} else if (activeItem.dataset.omgeving === 'regen') {
$video.setAttribute('src', './assets/longread/new_rainfall.mp4');
}
};
HTML
<video class="omgeving_vid" src="./assets/longread/new_snowstorm.mp4" autoplay loop muted></video>
<div class="omgeving-options">
<div data-omgeving="assen" class="omgeving--option assen">
<img src="./assets/longread/ash_icon.png" alt="ash">
<p class="omgeving-options--title">Assen</p>
</div>
<div data-omgeving="sneeuw" class="omgeving--option sneeuw">
<img src="./assets/longread/snow_icon.png" alt="snow">
<p class="omgeving-options--title">Sneeuw</p>
</div>
<div data-omgeving="regen" class="omgeving--option regen">
<img src="./assets/longread/rain_icon.png" alt="rain">
<p class="omgeving-options--title">Regen</p>
</div>
</div>
Related
In my API class today we learned how to show the camera with the tag. We also learned how to add effects with JavaScript. But, I'm stuck on how to reverse these effects. How would I make the clear button clear the current effect?
<body>
<h1>Magic Camera</h1>
<div class="tools">
<button id="sepia">Sepia</button>
<button id="">Clear</button>
</div>
<div class="scene">
<img src="billboard.jpg">
<div class="video-container">
<video id="myCamera" autoplay></video>
</div>
</div>
<script>
var myDevices = navigator.mediaDevices;
var permissions = {
audio: false,
video: true
};
myDevices.getUserMedia(permissions).then(showCam);
function showCam(stream){
$("#myCamera")[0].srcObject = stream;
}
function addEffect(event){
var effect = event.currentTarget;
var filter = `${effect.id}(1)`;
$("#myCamera").css("filter", filter);
}
$("button").click(addEffect);
</script>
</body>```
$('#myCamera').css('filter', '');
I am trying to work on a webpage in which when I click on the image tag I should be able to show the hidden video. I used handlebars. I also want to close this video when some user clicks on some other photo.
<script type = "text/x-handlebars-template" id = "template">
<div class = "row row-eq-height">
{{#each images}}
<div class = " col-xs-12 col-md-3">
<div class = "thumbnail">
<img src = "{{src}}" style = "width : 50%;height :25%;"
onClick = document.getElementById("video").style.display = "block";/>
<iframe style = "display:none;" id = "video" src = "{{video}}"/>
<h3>{{Song}}</h3>
</div>
</div>
{{/each}}
</div>
</script>
This is not working the videos are hidden but they fail to display back when I press on a photo.
Please do feel free to ask questions incase you need more clarity what my query is.
Any help is greatly appreciated. Thanks in advance.
To achieve a better performance, I suggest you just create everything but iframe. When someone click video thumbnail, create iframe in the fly and append to parent. If you do so, you won't have to hide videos and trying to display them.
<div class="video-container" data-video="{{video}}">
<div class="video-overlay" onclick="fetchVideo()">
<img src = "{{src}}" class="video-thumbnail"/>
<h3>{{Song}}</h3>
</div>
<div class="video-player"></div>
</div>
.video-player {
// this is iframe container
}
.video-overlay {
// syles
transition: opacity 0.3s ease-out;
}
.video-thumbnail {
width : 50%;
height: 25%;
object-fit: cover;
}
.hidden {
opacity: 0;
}
function fetchVideo() {
let parent = event.target.parentElement;
let video = parent.dataset.video;
let iframe = `<iframe width="560" height="315" src="${video}" frameborder="0" allowfullscreen allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"></iframe>`;
let player = event.target.nextElementSibling;
player.insertAdjacentHTML('beforeend', iframe);
event.target.classList.add("hidden");
}
I have a code like this in my html:
<div ng-mouseover="show_up()" ng-mouseleave="dont_show_up()" class="contain">
<img src="image/first_image.jpg">
<div class="overlay" ng-style="overlay">
show songs
</div>
</div>
<div ng-mouseover="show_up()" ng-mouseleave="dont_show_up()" class="contain">
<img src="image/second_image.jpg">
<div class="overlay" ng-style="overlay">
show songs
</div>
</div>
and this is my js code :
$scope.show_up = function () {
$scope.overlay={
"height":"100%"
};
};
$scope.dont_show_up = function () {
$scope.overlay={
"height":"0"
};
}
this is what I need to happen: whenever I hover on my first image it should add the style "height:100%"
to my first image, not both of them!
and when I hover on my second image it should add the style "height:100%"
to my second image, not both of them!
how can I fix this problem?
One solution would be passing some value to show_up() and dont_show_up() function, which identifies an image, say 1, 2 and then, inside function, change overlay variable to array and update appropriate item. ng-style="overlay" must be also changed to ng-style="overlays[0]"
--Edit
<div ng-mouseover="show_up(0)" ng-mouseleave="dont_show_up(0)" class="contain">
<img src="image/first_image.jpg">
<div class="overlay" ng-style="overlays[0]">
show songs
</div>
</div>
<div ng-mouseover="show_up(1)" ng-mouseleave="dont_show_up(1)" class="contain">
<img src="image/second_image.jpg">
<div class="overlay" ng-style="overlays[1]">
show songs
</div>
</div>
$scope.show_up = function (index) {
$scope.overlays[index] = {
"height":"100%"
};
};
$scope.dont_show_up = function (index) {
$scope.overlays[index] = {
"height":"0"
};
}
Well that becomes difficult to maintain when number of images increase
Second solution.
You can store all images as an array of objects and apply ng-repeat directive to loop through them.
<div ng-repeat="image in images" ng-mouseover="show_up(image.id)" ng-mouseleave="dont_show_up(image.id)" class="contain">
<img ng-src="image.src">
<div class="overlay" ng-style="image.overlay">
show songs
</div>
</div>
$scope.show_up = function (id) {
$scope.images.find(image => image.id === id).overlay = {
"height":"100%"
};
};
$scope.dont_show_up = function (id) {
$scope.images.find(image => image.id === id).overlay = {
"height":"0"
};
}
Not sure what you are trying to achieve since you state you want the image to change from 0 - 100% on the mouseover - but the ng-style is applied to the overlay. I assume you are trying to overlay the text over the image?
Anyway you don't need angular or even javascript for this - just CSS and apply a :hover on the parent level and style on the child element and you can achieve the desired outcome without the cost of the js.
.overlay {
height: 0;
overflow: hidden
}
.contain:hover .overlay {
height: 100%;
}
<div class="contain">
<img src="https://i.pinimg.com/originals/3e/6b/cd/3e6bcdc46881f5355163f9783c44a985.jpg" height="150">
<div class="overlay">
show songs
</div>
</div>
<div class="contain">
<img src="https://images-na.ssl-images-amazon.com/images/I/61W2FTW9ePL._AC_SL1500_.jpg" height="150">
<div class="overlay">
show songs
</div>
</div>
I am trying to make an image change when I click on a piece of text on a website that I am building.
At this moment I have created a class called device with one of them being device active as shown below:
<div class="col-md-3">
<div class="device active">
<img src="app/assets/images/mockup.png" alt="">
</div>
<div class="device">
<img src="app/assets/images/mockup.png" alt="">
</div>
<div class="device">
<img src="app/assets/images/mockup.png" alt="">
</div>
</div>
And then what i am currently trying to do is remove the class of active when I click on some text with the i.d of #search2. This is my whole jquery script so far:
$("#search2").click(function() {
var currentImage = $('.device.active');
var nextImage = currentImage.next();
currentImage.removeClass('active');
});
However this does not seem to remove the class of active and the image is still displayed? any ideas?
Your selection is done right and it is working for me (the active class is removed from that item). The problem must be somewhere else in your code.
Here is an alternative:
var activeDeviceIndex = 0;
$("#search2").click(function() {
var devicesContainer = $('.device');
$(devicesContainer[activeDeviceIndex]).removeClass('active');
activeDeviceIndex === devicesContainer.length - 1 ? activeDeviceIndex = 0 : activeDeviceIndex++;
$(devicesContainer[activeDeviceIndex]).addClass('active');
});
.device {
display: none;
}
.device.active {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-md-3">
<div class="device active">
<p>Device 1</p>
</div>
<div class="device">
<p>Device 2</p>
</div>
<div class="device">
<p>Device 3</p>
</div>
</div>
<button id="search2">click</button>
Check on the following, the id on the button to click should be search2 and not #search2, may be just typo stuffs.
after that update your code as follows
/**
*#description - gets the next image to slide, if the last image is the current image, it will loop the sliding
*#param {Element} current - the currently active image
*#param {Boolean} islooped - boolean value indicating if a looping just started
*/
var nextImage = function(current, islooped) {
var next = islooped? current : current.nextSibling;
while(next && next.nodeName.toLowerCase() !== 'div') {
next = next.nextSibling;
}
next = next? next : nextImage(current.parentNode.firstChild, true);
return next;
};
$('#search2').bind('click', function(event) {
var current = $('.device.active').removeClass('active').get(0);
var next = nextImage(current, false);
$(next).addClass('active');
});
I'm relatively new to JavaScript, but I'm trying to find a more efficient method for calling a rollover function without using inline events within the HTML. Below is the method I'm currently using:
HTML
<div id="work_square">
<img onmouseover="rolloverIn('rollover_1');" onmouseout="rolloverOut('rollover_1');" src="images/frugal_image.png" width="100%"/>
<div onmouseover="rolloverIn('rollover_1');" onmouseout="rolloverOut('rollover_1');" id="rollover_1" class="rollovers">
<div id="rollover_text">
<h2>ROLLOVER 1 TITLE</h2>
<p>This is rollover 1.</p>
</div>
</div>
</div>
<div id="work_square">
<img onmouseover="rolloverIn('rollover_2');" onmouseout="rolloverOut('rollover_2');" src="images/exhibiton_image.jpg" width="100%"/>
<div onmouseover="rolloverIn('rollover_2');" onmouseout="rolloverOut('rollover_2');" id="rollover_2" class="rollovers">
<div id="rollover_text">
<h2>ROLLOVER 2 TITLE</h2>
<p>This is rollover 2.</p>
</div>
</div>
</div>
JS
<script>
function rolloverIn(el){
var elem = document.getElementById(el);
elem.style.opacity = 1;
elem.style.transform = "scale(1)";
}
function rolloverOut(el){
var elem = document.getElementById(el);
elem.style.opacity = 0;
elem.style.transform = "scale(0)";
}
Basically I'm calling a function to apply a CSS transform and opacity alteration for a rollover placed over each work_square when either the image or rollover is moused over, and then to remove the alterations on mouse out.
This method works, but it's my understanding that inline coding is bad practice. Could someone point me in the right direction towards a more efficient method?
Thanks.
Sorry to ruin your dream of using JS but
this is all doable in pure CSS:
.work_square{ position:relative; }
.work_square > img{ width:100%; }
.work_square .rollovers{
position:absolute;
top:0;
opacity:0;
transform: scale(0);
transition: 0.6s;
}
.work_square:hover .rollovers{
transform: scale(1);
opacity:1;
}
<div class="work_square">
<img src="//placehold.it/800x300/cf5" />
<div class="rollovers">
<div class="rollover_text">
<h2>ROLLOVER 1 TITLE</h2>
<p>This is rollover 1.</p>
</div>
</div>
</div>
<div class="work_square">
<img src="//placehold.it/800x300/f5f" />
<div class="rollovers">
<div class="rollover_text">
<h2>ROLLOVER 2 TITLE</h2>
<p>This is rollover 2.</p>
</div>
</div>
</div>
Note that I've removed all unnecessary ID (hey, you cannot use duplicate ID's in a valid HTML document).
Use your container class .work_square and use the CSS :hover on it to add that listener, than simply add the desired class of the children element to target:
.work_square:hover .rollovers{
First of all, do not ever use the same ID for multiple elements, IDs are unique. What you want here are classes, so your HTML code should be changed to something like this:
<div class="work_square">
<img class="rollover" src="images/frugal_image.png" width="100%"/>
<div class="rollover">
<div class="rollover_text">
<h2>ROLLOVER 1 TITLE</h2>
<p>This is rollover 1.</p>
</div>
</div>
</div>
<div class="work_square">
<img class="rollover" src="images/exhibiton_image.jpg" width="100%"/>
<div class="rollover">
<div class="rollover_text">
<h2>ROLLOVER 2 TITLE</h2>
<p>This is rollover 2.</p>
</div>
</div>
</div>
Now, if you want to use pure JavaScript, without inline code, you can easily use the rollover class to select all the elements and bind the mouseover and mouseout events to your functions. Here is the correct code:
function rolloverIn(e){
this.style.opacity = 1;
this.style.transform = "scale(1)";
}
function rolloverOut(e){
this.style.opacity = 0;
this.style.transform = "scale(0)";
}
var elements = document.getElementsByClassName('rollover');
for (var i=0; i < elements.length; i++) {
elements[i].addEventListener('mouseover', rolloverIn);
elements[i].addEventListener('mouseout', rolloverOut);
}