Hide image with play button - javascript

The play button image hides when I click it, how do I also have the green image hide?
That is all I am trying to do in the code.
Hide the green image after the play image is clicked.
Currently only the play image hides, how to I have the green image hide aftr the play image is clicked?
https://jsfiddle.net/075anu3x/
css green image
.video-wrapper::after {
content: "";
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
border: 1px solid #333;
pointer-events: none;
background: url(https://i.imgur.com/ShS6nAO.png) no-repeat;
background-size: contain;
background-position: center;
}
javascript
const manageCover = (function makeManageCover() {
const events = {};
function show(el) {
el.classList.remove("hide");
}
function hide(el) {
el.classList.add("hide");
}
function fadeVideoIn(cover) {
hide(cover);
const videoWrapper = document.querySelector(".video-wrapper");
videoWrapper.classList.add("slide");
return videoWrapper;
}
function showVideo(videoWrapper) {
const thewrap = videoWrapper.parentElement.querySelector(".wrap");
show(thewrap);
}
function coverClickHandler(evt) {
const cover = evt.currentTarget;
const videoWrapper = fadeVideoIn(cover);
showVideo(videoWrapper);
cover.dispatchEvent(events.afterClickCover);
}
function init(callback) {
const cover = document.querySelector(".play");
cover.addEventListener("click", coverClickHandler);
events.afterClickCover = new Event("afterClickCover");
cover.addEventListener("afterClickCover", callback);
}
return {
init
};
}());

maybe you can try add background: unset; to .video-wrapper.slide::after class

for your issue, it is easier to make the green background with the button as the same component.
The reason why the green background doesn't get away:
It is set up as a pseudo-class under video-wrapper
In my experience, javascript can't reach a pseudo-class, even if it is possible, it will make your code super messy and hard to read and follow.
Suggestion:
Remove the green background from the video wrapper class and move it to the button.
See here
HTML
<div class="container">
<div class="video-wrapper">
<div class="ratio-keeper">
<div class="wrap hide">
<div class="video video-frame"></div>
</div>
</div>
</div>
<div class="play">
<button type="button" aria-label="Open"></button>
</div>
</div>
CSS
.play {
position: relative;
width: 100vw;
height: 100vh;
}
.play button {
-webkit-appearance: none;
appearance: none;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: auto;
display: flex;
justify-content: center;
align-items: center;
width: 90px;
height: 90px;
border-radius: 50%;
cursor: pointer;
border: 9px solid;
background: transparent;
filter: drop-shadow(3px 3px 3px #000000b3);
animation: rotate 700ms linear forwards;
border-color: red transparent red transparent;
}
.play::before {
content: "";
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
border: 1px solid #333;
pointer-events: none;
background: url(https://i.imgur.com/ShS6nAO.png) no-repeat;
background-size: contain;
background-position: center;
}
#keyframes rotate {
0% {
transform: rotate(0deg);
}
99.9% {
border-color: red transparent red transparent;
pointer-events: none;
}
100% {
transform: rotate(360deg);
border-color: blue;
}
}
.play button:hover {
box-shadow: 0 0 0 5px rgba(43, 179, 20, 0.5);
}
.play button:focus {
outline: 0;
box-shadow: 0 0 0 5px rgba(0, 255, 255, 0.5);
}
.play button::before {
content: "";
width: 0;
height: 0;
border-top: 20px solid transparent;
border-bottom: 20px solid transparent;
border-left: 27px solid;
transform: translateX(4px);
animation: triangle 700ms linear forwards;
}
#keyframes triangle {
0% {
opacity: 0;
}
99.9% {
opacity: 0;
}
100% {
border-left-color: blue;
opacity: 1;
}
}
.hide {
display: none;
}

Related

How to abort downloading an audio stream

I hope someone can help with this.
I want to stop/abort audio instead of pause, how would this be done?
I was trying to figure out how to do that.
That is all I am trying to figure out how to do.
How to abort an audio stream instead of pausing it.
How would I be able to do that?
https://jsfiddle.net/s0ae7ph9/
(function iife() {
"use strict";
function getButtonContainer(el) {
while (el.classList.contains("playButton") === false) {
el = el.parentNode;
}
return el;
}
function getPlay(button) {
return button;
}
function showPlayButton(button) {
button.classList.remove("active");
}
function isPlaying(button) {
const play = getPlay(button);
return play.classList.contains("active");
}
function pauseAllButtons() {
var buttons = document.querySelectorAll(".playButton");
buttons.forEach(function hidePause(buttons) {
if (isPlaying(buttons)) {
showPlayButton(buttons);
}
});
}
function showPauseButton(button) {
pauseAllButtons();
button.classList.add("active");
}
function getAudio() {
return document.querySelector("audio");
}
function playAudio(player, src) {
player.volume = 1.0;
if (player.getAttribute("src") !== src) {
player.setAttribute("src", src);
}
player.play();
}
function showButton(button, opts) {
if (opts.playing) {
showPlayButton(button);
} else {
showPauseButton(button);
}
}
function pauseAudio(player) {
player.pause();
}
function manageAudio(player, opts) {
if (opts.playing) {
pauseAudio(player);
} else {
playAudio(player, opts.src);
}
}
function playButton(button) {
const player = getAudio();
const playing = isPlaying(button);
showButton(button, {
playing
});
manageAudio(player, {
playing,
src: button.getAttribute("data-audio")
});
}
function playButtonClickHandler(evt) {
const button = getButtonContainer(evt.target);
playButton(button);
}
const playButtons = document.querySelectorAll(".button");
playButtons.forEach(function addHandler(el) {
el.addEventListener("click", playButtonClickHandler);
});
}());
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
.outer {
display: table;
height: 100%;
margin: 0 auto;
}
.tcell {
display: table-cell;
vertical-align: middle;
}
.wrap {
position: relative;
width: 190px;
height: 235px;
background: red;
}
.playButton {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
width: 150px;
height: 195px;
background-color: black;
box-shadow: 0 0 10px 2px rgba(0, 0, 0, 0.2), 0 0 1px 2px black, inset 0 2px 2px -2px white, inset 0 0 2px 15px #47434c, inset 0 0 2px 22px black;
border-radius: 5px;
padding: 20px;
perspective: 700px;
}
.playButton.active .button {
transform: translateZ(20px) rotateX(25deg);
box-shadow: 0 -10px 20px #ff1818;
}
.playButton.active .button .light {
animation: flicker 0.2s infinite 0.3s;
}
.playButton.active .button .shine {
opacity: 1;
}
.playButton.active .button .shadow {
opacity: 0;
}
.playButton .button {
transition: all 0.3s cubic-bezier(1, 0, 1, 1);
transform-origin: center center -20px;
transform: translateZ(20px) rotateX(-25deg);
transform-style: preserve-3d;
background-color: #9b0621;
width: 100%;
height: 100%;
position: relative;
cursor: pointer;
background: linear-gradient(#980000 0%, #6f0000 30%, #6f0000 70%, #980000 100%);
background-repeat: no-repeat;
}
.playButton .button::before {
content: "";
background: linear-gradient(rgba(255, 255, 255, 0.8) 10%, rgba(255, 255, 255, 0.3) 30%, #650000 75%, #320000) 50% 50%/97% 97%, #b10000;
background-repeat: no-repeat;
width: 100%;
height: 50px;
transform-origin: top;
transform: rotateX(-90deg);
position: absolute;
top: 0;
}
.playButton .button::after {
content: "";
background-image: linear-gradient(#650000, #320000);
width: 100%;
height: 50px;
transform-origin: top;
transform: translateY(50px) rotateX(-90deg);
position: absolute;
bottom: 0;
box-shadow: 0 50px 8px 0px black, 0 80px 20px 0px rgba(0, 0, 0, 0.5);
}
.playButton .light {
opacity: 0;
animation: light-off 1s;
position: absolute;
width: 100%;
height: 100%;
background-image: radial-gradient(#ffc97e, #ff1818 40%, transparent 70%);
}
.playButton .dots {
position: absolute;
width: 100%;
height: 100%;
background-image: radial-gradient(transparent 30%, rgba(101, 0, 0, 0.7) 70%);
background-size: 10px 10px;
}
.playButton .characters {
position: absolute;
width: 100%;
height: 100%;
background: linear-gradient(white, white) 50% 20%/5% 20%, radial-gradient(circle, transparent 50%, white 52%, white 70%, transparent 72%) 50% 80%/33% 25%;
background-repeat: no-repeat;
}
.playButton .shine {
transition: all 0.3s cubic-bezier(1, 0, 1, 1);
opacity: 0.3;
position: absolute;
width: 100%;
height: 100%;
background: linear-gradient(white, transparent 3%) 50% 50%/97% 97%, linear-gradient(rgba(255, 255, 255, 0.5), transparent 50%, transparent 80%, rgba(255, 255, 255, 0.5)) 50% 50%/97% 97%;
background-repeat: no-repeat;
}
.playButton .shadow {
transition: all 0.3s cubic-bezier(1, 0, 1, 1);
opacity: 1;
position: absolute;
width: 100%;
height: 100%;
background: linear-gradient(transparent 70%, rgba(0, 0, 0, 0.8));
background-repeat: no-repeat;
}
#keyframes flicker {
0% {
opacity: 1;
}
80% {
opacity: 0.8;
}
100% {
opacity: 1;
}
}
#keyframes light-off {
0% {
opacity: 1;
}
80% {
opacity: 0;
}
}
<audio></audio>
<div class="outer">
<div class="tcell">
<div class="wrap">
<div class="playButton" data-audio="https://stream.sunfmua.com:8443/rock">
<div class="button">
<div class="light"></div>
<div class="dots"></div>
<div class="characters"></div>
<div class="shine"></div>
<div class="shadow"></div>
</div>
</div>
</div>
</div>
</div>
It seems something like HTML5 audio start over should work. I know this works for audio files locally, but not sure about the one you have in your code. I would assume it should work the same though.
If you want to eventually stop loading the media, you can't use the native HTMLMediaElement.
You should fetch and stream the media yourself, and abort it when you please using an AbortController. Aborting a fetch.
let controller;
// Play button event
playButton.addEventListener('click', playAudio);
// Stop button event
stopButton.addEventListener('click', () => {
controller?.abort();
});
async function playAudio() {
controler = new AbortController();
const response = await fetch(mediaURL, { signal: controller.signal })
const reader = await response.body.getReader();
async function read() {
const { value, done } = await reader.read();
/* value = audioChunk;
Push the audio chunk to audio or video context
*/
}
read();
}
Check this example on streaming the response or this function on streaming an audio.
I'm not sure, but try
audio.currentTime = 0;
audio.play();

Infinite carousel with magnific zooming effect

I'm trying to achieve a responsive carousel which supports auto-play infinite loop, and the center item always take 70% of the view port with.
Right now the best I can do is something like this by taking advantage of a library called Slick:
https://codepen.io/anon/pen/pBvQBM
$('.slick')
.on('init', () => {
$('.slick-slide[data-slick-index="-2"]').addClass('lt2');
$('.slick-slide[data-slick-index="-1"]').addClass('lt1');
$('.slick-slide[data-slick-index="1"]').addClass('gt1');
$('.slick-slide[data-slick-index="2"]').addClass('gt2');
})
.slick({
centerMode: true,
centerPadding: 0,
slidesToShow: 3,
autoplay: true,
autoplaySpeed: 500,
}).on('beforeChange', (event, slick, current, next) => {
$('.slick-slide.gt2').removeClass('gt2');
$('.slick-slide.gt1').removeClass('gt1');
$('.slick-slide.lt1').removeClass('lt1');
$('.slick-slide.lt2').removeClass('lt2');
const lt2 = (current < next && current > 0) ? current - 1 : next - 2;
const lt1 = (current < next && current > 0) ? current : next - 1;
const gt1 = (current < next || next === 0) ? next + 1 : current;
const gt2 = (current < next || next === 0) ? next + 2 : current + 1;
$(`.slick-slide[data-slick-index="${lt2}"]`).addClass('lt2');
$(`.slick-slide[data-slick-index="${lt1}"]`).addClass('lt1');
$(`.slick-slide[data-slick-index="${gt1}"]`).addClass('gt1');
$(`.slick-slide[data-slick-index="${gt2}"]`).addClass('gt2');
// Clone processing when moving from 5 to 0
if (current === 5 && next === 0) {
$(`.slick-slide[data-slick-index="${current - 1}"]`).addClass('lt2');
$(`.slick-slide[data-slick-index="${current}"]`).addClass('lt1');
$(`.slick-slide[data-slick-index="${current + 2}"]`).addClass('gt1');
$(`.slick-slide[data-slick-index="${current + 3}"]`).addClass('gt2');
}
// Clone processing when moving from 0 to 5
if (current === 0 && next === 5) {
$(`.slick-slide[data-slick-index="${current - 1}"]`).addClass('gt2');
$(`.slick-slide[data-slick-index="${current}"]`).addClass('gt1');
$(`.slick-slide[data-slick-index="${current - 2}"]`).addClass('lt1');
$(`.slick-slide[data-slick-index="${current - 3}"]`).addClass('lt2');
}
console.log('beforeChange', current, ':', lt2, lt1, next, gt1, gt2);
});
*, *::before, *::after {
box-sizing: border-box;
}
body {
margin: 0;
padding: 20vh 0;
}
.slick span {
display: block;
background: #3498db;
color: #fff;
font-size: 36px;
height: 100px;
line-height: 100px;
position: relative;
text-align: center;
//border: solid 1px rgb(145, 195, 0);
transform: translate(0, 0) scale(.4);
transition: all .4s ease;
opacity: .5;
}
.slick-slide {
border: solid 1px #2dc37f;
}
.slick-slide.lt2 span {
transform: translate(10%, 0) scale(.6);
}
.slick-slide.lt1 span {
opacity: .7;
transform: translate(5%, 0) scale(.8);
}
.slick-slide.gt1 span {
opacity: .7;
transform: translate(-5%, 0) scale(.8);
}
.slick-slide.gt2 span {
transform: translate(-10%, 0) scale(.6);
}
.slick-slide.slick-center span {
z-index: 1;
transform: scale(1);
opacity: 1;
color: #e67e22;
}
.slick-prev,
.slick-next{
position: absolute;
top: 50%;
appearance: none;
margin-top: -10px;
padding: 0;
border: 0;
background: none;
cursor: pointer;
color: transparent;
outline: none;
z-index: 100;
}
.slick-prev {
width: 0;
height: 0;
border-style: solid;
border-width: 15px 15px 15px 0;
border-color: transparent #007bff transparent transparent;
left: 0;
}
.slick-next {
width: 0;
height: 0;
border-style: solid;
border-width: 15px 0 15px 15px;
border-color: transparent transparent transparent #007bff;
right: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick.js"></script>
<div class="slick">
<div><span>1</span></div>
<div><span>2</span></div>
<div><span>3</span></div>
<div><span>4</span></div>
</div>
However, this is not exactly what I want. In this demo, all three items have the same width, but I want the center item to have 70% width, something like this:
Please share some pointers on how I can make it happen. I'm not limited to this Slick library and open to any other options such as pure CSS or JQuery.
You're actually not too far off, you are just a little inconsistent with your targeting of the styles. I took off a bunch of the styles on the spans, and added a few styles on the slide divs:
https://codepen.io/anon/pen/PgwXbV
You might adjust some of the details, but I think this CSS gets it pretty close to your desired effect:
*, *::before, *::after {
box-sizing: border-box;
}
body {
margin: 0;
padding: 20vh 0;
}
.slick span {
display: block;
background: #3498db;
color: #fff;
font-size: 36px;
height: 100px;
line-height: 100px;
position: relative;
text-align: center;
/* border: solid 1px rgb(145, 195, 0); */
/* make the non-centered slides partially transparent */
opacity: .5;
}
.slick-slide {
border: solid 1px #2dc37f;
/* make the non-centered slides smaller */
transform: scale(.5);
transition:transform .4s ease;
}
.slick-slide.slick-center {
/* make the center slide full size */
transform: scale(1);}
.slick-slide.slick-center span {
z-index: 1;
transform: scale(1);
/* make the centered slides solid */
opacity: 1;
color: #e67e22;
}
.slick-prev,
.slick-next{
position: absolute;
top: 50%;
appearance: none;
margin-top: -10px;
padding: 0;
border: 0;
background: none;
cursor: pointer;
color: transparent;
outline: none;
z-index: 100;
}
.slick-prev {
width: 0;
height: 0;
border-style: solid;
border-width: 15px 15px 15px 0;
border-color: transparent #007bff transparent transparent;
left: 0;
}
.slick-next {
width: 0;
height: 0;
border-style: solid;
border-width: 15px 0 15px 15px;
border-color: transparent transparent transparent #007bff;
right: 0;
}
This part seemed unnecessary with the changes, though I see what you were going for:
.slick-slide.lt2 span {
transform: translate(10%, 0) scale(.6);
}
.slick-slide.lt1 span {
opacity: .7;
transform: translate(5%, 0) scale(.8);
}
.slick-slide.gt1 span {
opacity: .7;
transform: translate(-5%, 0) scale(.8);
}
.slick-slide.gt2 span {
transform: translate(-10%, 0) scale(.6);
}

How can I make this transition smooth instead of it jumping up

I am trying to implement a notification system in my app without the use of a library. Here is a gif of the issue: https://imgur.com/oRc11dM
And here is the jsfiddle of the gif: https://jsfiddle.net/w9yk7n54/
When you click on new notification button, already displayed notifications jump up to make room for the new notification and new notification slides in. I was wondering how I could make it so that they all smoothly go up together.
The notifications wont all be the same dimensions so I cant set static values for height/etc.
Thank you!
let btn = document.querySelector('button')
let container = document.querySelector('.notifications-container')
let notif_contents = [
"<p>1</p><p>1</p><p>1</p><p>1</p>",
"<p>test</p>",
"<div><h1>testtesttest</h1><p>yoloalsdfasdf</p></div>"
]
let current = 0
btn.onclick = () => {
let notif = document.createElement('div')
notif.classList.add('notif')
notif.innerHTML = notif_contents[current]
notif.addEventListener('animationend', () => {
notif.parentElement.removeChild(notif)
})
current++
container.append(notif)
}
* {
box-sizing: border-box;
}
.container {
height: 300px;
width: 400px;
border: 1px solid black;
position: absolute;
}
.notifications-container {
position: absolute;
top: 0;
right: 0;
height: 100%;
width: 200px;
background: rgba( 0, 0, 0, 0.2);
display: flex;
flex-flow: column nowrap;
justify-content: flex-end;
overflow: hidden;
}
.notif {
position: relative;
width: 100%;
padding: 10px;
border: 1px solid black;
animation: notifAnim 5s forwards;
transition: all .2s;
background: white;
}
button {
z-index: 100;
background: lightcoral;
color: white;
border: none;
padding: 10px;
font-size: 20px;
margin: 5px;
}
#keyframes notifAnim {
0% {
transform: translateY( 100%)
}
20% {
transform: translateY( 0)
}
80% {
transform: translateY( 0)
}
100% {
transform: translateY( 100%)
}
}
<div class="container">
<button>New Notification</button>
<div class="notifications-container"></div>
</div>
Your notif container has justify-content: flex-end. This means that whenever you add a new one, the previous ones will be pushed up with the height of the new one.
The "fix" is to give each element a negative margin-top equal to its height and integrate in your current transition getting margin-top back to 0.
Example:
let btn = document.querySelector('button'),
container = document.querySelector('.notifications-container'),
notif_contents = [
"<p>1</p><p>1</p><p>1</p><p>1</p>",
"<p>test</p>",
"<div><h1>testtesttest</h1><p>yoloalsdfasdf</p></div>",
"<code>another.test()</code>",
"<strong>another</strong> <i>test</i>"
]
btn.onclick = () => {
let notif = document.createElement('div'),
index = Math.floor(Math.random() * notif_contents.length)
notif.classList.add('notif')
notif.innerHTML = notif_contents[index]
notif.addEventListener('animationend', () => {
notif.parentElement.removeChild(notif)
})
container.append(notif)
notif.style.marginTop = '-' + notif.offsetHeight + 'px'
}
* {
box-sizing: border-box;
}
.container {
height: 300px;
width: 400px;
border: 1px solid #888;
position: absolute;
}
.notifications-container {
position: absolute;
top: 0;
right: 0;
height: 100%;
width: 200px;
background: rgba( 0, 0, 0, 0.2);
display: flex;
flex-flow: column nowrap;
justify-content: flex-end;
overflow: hidden;
}
.notif {
position: relative;
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-bottom: none;
animation: notifAnim 5s forwards;
background: white;
}
button {
z-index: 100;
background: lightcoral;
color: white;
border: none;
padding: 10px;
font-size: 20px;
margin: 5px;
}
#keyframes notifAnim {
0%,
100% {
transform: translateY( 100%)
}
20%,
80% {
transform: translateY( 0);
margin-top: 0
}
}
<div class="container">
<button>New Notification</button>
<div class="notifications-container"></div>
</div>
An idea is to insert new element with a height equal to 0 and you animate the height in addition to translate. Of course, you should use max-height since height are unknown and we cannot animate to auto:
let btn = document.querySelector('button')
let container = document.querySelector('.notifications-container')
let notif_contents = [
"<p>1</p><p>1</p><p>1</p><p>1</p>",
"<p>test</p>",
"<div><h1>testtesttest</h1><p>yoloalsdfasdf</p></div>"
]
let current = 0
btn.onclick = () => {
let notif = document.createElement('div')
notif.classList.add('notif')
notif.innerHTML = notif_contents[current]
notif.addEventListener('animationend', () => {
notif.parentElement.removeChild(notif)
})
current++
container.append(notif)
}
* {
box-sizing: border-box;
}
.container {
height: 300px;
width: 400px;
border: 1px solid black;
position: absolute;
}
.notifications-container {
position: absolute;
top: 0;
right: 0;
height: 100%;
width: 200px;
background: rgba( 0, 0, 0, 0.2);
display: flex;
flex-flow: column nowrap;
justify-content: flex-end;
overflow: hidden;
}
.notif {
position: relative;
width: 100%;
padding:0 10px;
max-height:0px;
border: 1px solid black;
animation: notifAnim 5s forwards;
transition: all .2s;
background: white;
}
button {
z-index: 100;
background: lightcoral;
color: white;
border: none;
padding: 10px;
font-size: 20px;
margin: 5px;
}
#keyframes notifAnim {
0% {
transform: translateY( 100%);
max-height:0;
padding:0 10px;
}
30% {
transform: translateY( 0);
max-height:300px;
padding:10px;
}
80% {
transform: translateY( 0);
max-height:300px;
padding:10px;
}
100% {
transform: translateY( 100%);
max-height:300px;
padding:10px;
}
}
<div class="container">
<button>New Notification</button>
<div class="notifications-container"></div>
</div>

jQuery Add Markers

I'm currently trying to make a website that displays markers with its own specific text.
When a user clicks on the marker, it displays the text.
I've copied some code online and trying to mess around with it. Unfortunately, I'm not too experience with javascript. I was wondering if anyone would be able to help.
This is what I have so far:
HTML (I don't think there's any problems here):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>MarkerWeb</title>
<link rel="stylesheet" href="style.css">
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
</head>
<body>
<div id="container">
<div id="image-wrapper" data-captions='{"coords": [{"top":250,"left":200,"text":"iMac 1"},{"top":250,"left":540,"text":"iMac 2"}]}'>
<!-- layout.jpg is just a picture of a layout/floorplan -->
<img src="layout.jpg" alt=""/>
</div>
</div>
</body>
<script type="text/javascript" src="script.js"></script>
</html>
Javascript (The part I'm having a hard time with):
var Markers = {
fn: {
addMarkers: function() {
var target = $('#image-wrapper');
var data = target.attr('data-captions');
var captions = $.parseJSON(data);
var coords = captions.coords;
for (var i = 0; i < coords.length; i++) {
var obj = coords[i];
var top = obj.top;
var left = obj.left;
var text = obj.text;
$('<div class="marker"><div class="pin"><span class="popuptext" id="myPopup">' + text + '</span></div><div class="pin-effect"></div></div>').css({
top: top,
left: left
}).appendTo(target);
}
},
//This is the part I'm having trouble with.
showBeaconInfo: function() {
$('body').on('click', '.marker', function() {
var $marker = $(this),
$caption = $('popuptext', $marker);
if ($caption.is(':hidden')) {
$caption.show();
} else {
$caption.toggle("show");
}
});
}
},
init: function() {
this.fn.addMarkers();
this.fn.showBeaconInfo();
}
};
function clickBeacon() {
var popup = document.getElementById("myPopup");
popup.classList.toggle("show");
}
$(function() {
Markers.init();
});
CSS (I don't think there's any problems here):
body {
background: #e6e6e6;
}
#image-wrapper {
width: 800px;
height: 760px;
position: relative;
margin: 2em auto;
background: #f6f6f6;
border: 2px solid #ddd;
}
#image-wrapper img {
display: block;
margin: 25px auto;
}
.map-bg {
background: url(images/map-bg.jpg) no-repeat;
background-position: 0px 0px;
background-size: auto;
width: 100%;
height: 440px; /*adjust to the height of your image*/
position: relative;
}
.marker {
width: 100px;
height: 100px;
position: absolute;
/*top: 130px; /*positions our marker*/
/*left: 200px; /*positions our marker*/
display: block;
}
.pin {
width: 20px;
height: 20px;
position: relative;
top: 38px;
left: 38px;
background: rgba(5, 124, 255, 1);
border: 2px solid #FFF;
border-radius: 50%;
z-index: 1000;
cursor: pointer;
display: inline-block;
}
.pin-effect {
width: 100px;
height: 100px;
position: absolute;
top: 0;
display: block;
background: rgba(5, 124, 255, 0.6);
border-radius: 50%;
opacity: 0;
animation: pulsate 2400ms ease-out infinite;
}
#keyframes pulsate {
0% {
transform: scale(0.1);
opacity: 0;
}
50% {
opacity: 1;
}
100% {
transform: scale(1.2);
opacity: 0;
}
}
/* The actual popup (appears on top) */
.pin .popuptext {
visibility: hidden;
width: 160px;
background-color: #555;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 8px 0;
position: absolute;
z-index: 1;
bottom: 125%;
left: 50%;
margin-left: -80px;
}
/* Popup arrow */
.pin .popuptext::after {
content: "";
position: absolute;
top: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: #555 transparent transparent transparent;
}
/* Toggle this class when clicking on the popup container (hide and show the popup) */
.pin .show {
visibility: visible;
-webkit-animation: fadeIn 1s;
animation: fadeIn 1s
}
/* Add animation (fade in the popup) */
#-webkit-keyframes fadeIn {
from {opacity: 0;}
to {opacity: 1;}
}
#keyframes fadeIn {
from {opacity: 0;}
to {opacity:1 ;}
}
You need to update your showBeaconInfo function in 2 ways:
1) Fix the selector for $caption to grab the class popuptext by adding a period
2) Using the jquery function toggleClass to add or remove the class "show" on the popuptext, the css is setup to either use visibility: hidden or visibility: visible
showBeaconInfo: function() {
$('body').on('click', '.marker', function() {
var $marker = $(this);
var $caption = $('.popuptext', $marker); //needs period to indicate class
$caption.toggleClass('show'); //adding the class "show" will display the text
});
}
For Example:
var Markers = {
fn: {
addMarkers: function() {
var target = $('#image-wrapper');
var data = target.attr('data-captions');
var captions = $.parseJSON(data);
var coords = captions.coords;
for (var i = 0; i < coords.length; i++) {
var obj = coords[i];
var top = obj.top;
var left = obj.left;
var text = obj.text;
$('<div class="marker"><div class="pin"><span class="popuptext" id="myPopup">' + text + '</span></div><div class="pin-effect"></div></div>').css({
top: top,
left: left
}).appendTo(target);
}
},
//This is the part I'm having trouble with.
showBeaconInfo: function() {
$('body').on('click', '.marker', function() {
var $marker = $(this);
var $caption = $('.popuptext', $marker); //needs period to indicate class
$caption.toggleClass('show'); //adding the class "show" will display the text
});
}
},
init: function() {
this.fn.addMarkers();
this.fn.showBeaconInfo();
}
};
function clickBeacon() {
var popup = document.getElementById("myPopup");
popup.classList.toggle("show");
}
$(function() {
Markers.init();
});
body {
background: #e6e6e6;
}
#image-wrapper {
width: 800px;
height: 760px;
position: relative;
margin: 2em auto;
background: #f6f6f6;
border: 2px solid #ddd;
}
#image-wrapper img {
display: block;
margin: 25px auto;
}
.map-bg {
background: url(images/map-bg.jpg) no-repeat;
background-position: 0px 0px;
background-size: auto;
width: 100%;
height: 440px;
/*adjust to the height of your image*/
position: relative;
}
.marker {
width: 100px;
height: 100px;
position: absolute;
/*top: 130px; /*positions our marker*/
/*left: 200px; /*positions our marker*/
display: block;
}
.pin {
width: 20px;
height: 20px;
position: relative;
top: 38px;
left: 38px;
background: rgba(5, 124, 255, 1);
border: 2px solid #FFF;
border-radius: 50%;
z-index: 1000;
cursor: pointer;
display: inline-block;
}
.pin-effect {
width: 100px;
height: 100px;
position: absolute;
top: 0;
display: block;
background: rgba(5, 124, 255, 0.6);
border-radius: 50%;
opacity: 0;
animation: pulsate 2400ms ease-out infinite;
}
#keyframes pulsate {
0% {
transform: scale(0.1);
opacity: 0;
}
50% {
opacity: 1;
}
100% {
transform: scale(1.2);
opacity: 0;
}
}
/* The actual popup (appears on top) */
.pin .popuptext {
visibility: hidden;
width: 160px;
background-color: #555;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 8px 0;
position: absolute;
z-index: 1;
bottom: 125%;
left: 50%;
margin-left: -80px;
}
/* Popup arrow */
.pin .popuptext::after {
content: "";
position: absolute;
top: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: #555 transparent transparent transparent;
}
/* Toggle this class when clicking on the popup container (hide and show the popup) */
.pin .show {
visibility: visible;
-webkit-animation: fadeIn 1s;
animation: fadeIn 1s
}
/* Add animation (fade in the popup) */
#-webkit-keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<div id="image-wrapper" data-captions='{"coords": [{"top":250,"left":200,"text":"iMac 1"},{"top":250,"left":540,"text":"iMac 2"}]}'>
<!-- layout.jpg is just a picture of a layout/floorplan -->
<img src="layout.jpg" alt="" />
</div>
</div>

Got double "onmouseover" Javascript

first can you look on those two image so you understand.
When not hover: http://s15.postimg.org/sn6rk45rf/not_Hover.png
When hover: http://s16.postimg.org/yk6beg1ad/on_Hover.png
Right now when I have my mouse over a image, both image get buttons.
But I just want each image have theve own buttons on mouse over and the other image hide the buttons.
I don't really know how to fix it, and I'm very beginner with Javascript.
Here is my HTML/CSS/Javascript codes.
var buttonNew = document.getElementsByClassName('buttonNewest');
var buttonRan = document.getElementsByClassName('buttonRandom');
function imageOver() {
for(var i = 0; i < buttonNew.length; i++) {
buttonNew[i].style.display = "block";
buttonNew[i].style.animation = "moveButtonsRight 2s";
}
for(var i = 0; i < buttonRan.length; i++) {
buttonRan[i].style.display = "block";
buttonRan[i].style.animation = "moveButtonsLeft 2s";
}
}
function imageLeave() {
for(var i = 0; i < buttonNew.length; i++) {
buttonNew[i].style.display = "none";
}
for(var i = 0; i < buttonRan.length; i++) {
buttonRan[i].style.display = "none";
}
}
.charSelect[role="Background"] {
width: 1600px;
min-height: 600px;
margin: 25px auto;
}
.charSelect[role="Background"] > h1 {
width: 300px;
margin: 0 auto;
border: dashed 2px rgba(255, 207, 0, 0.75);
text-align: center;
text-transform: uppercase;
font-size: 2.6em;
text-shadow: 2px 2px 3px rgb(0, 0, 0);
}
.charSelect[role="Characters"] {
position: relative;
display: inline-block;
width: 250px;
height: auto;
background: rgba(42, 42, 42, 0.7);
border: dashed 2px rgba(255, 207, 0, 0.4);
color: rgba(255, 207, 0, 1);
opacity: 0.6;
-webkit-transition: opacity 1s;
margin-left: 250px;
}
.charSelect[role="Characters"]:hover {
opacity: 1;
transform: scale(1.05);
}
.charSelect[role="Names"] {
width: 100%;
font-size: 1.8em;
}
.charSelect[role="Names"] > p {
margin: 0 !important;
text-align: center;
text-transform: uppercase;
text-shadow: 1px 1px 2px rgb(0, 0, 0);
}
/* Buttons */
.charSelect[role="LatestVid"], .charSelect[role="RandomVid"] {
width: 170px;
height: 45px;
background: -webkit-linear-gradient(top, rgb(255, 207, 0), rgba(255, 207, 0, 0));
text-align: center;
line-height: 45px;
color: black;
-webkit-transition: background 1s;
transition: background 1s;
box-shadow: 0px 0px 3px;
}
.charSelect[role="LatestVid"] {
display: none;
position: absolute;
top:50%;
right: 70%;
}
.charSelect[role="RandomVid"] {
display: none;
position: absolute;
top:50%;
left: 70%;
}
.charSelect[role="RandomVid"]:hover , .charSelect[role="LatestVid"]:hover {
background: rgb(255, 207, 0);
}
/* Animation */
#-webkit-keyframes moveButtonsLeft {
0% {
left: 50%;
}
100% {
left: 70%;
}
}
#-webkit-keyframes moveButtonsRight {
0% {
right: 50%;
}
100% {
right: 70%;
}
}
<!-- Character one -->
<div onmouseover="imageOver()" onmouseleave="imageLeave()" class="charSelect" role="Characters">
<img src="chars/Dekker.gif" width="250"/>
<div class="charSelect buttonNewest" role="LatestVid">Newest Videos</div>
<div class="charSelect buttonRandom" role="RandomVid">Random Videos</div>
<div class="charSelect" role="Names"><p>Dekker</p></div>
</div>
<!-- Character two -->
<div onmouseover="imageOver()" onmouseleave="imageLeave()" class="charSelect" role="Characters">
<img src="chars/Dekker.gif" width="250"/>
<div class="charSelect buttonNewest" role="LatestVid">Newest Videos</div>
<div class="charSelect buttonRandom" role="RandomVid">Random Videos</div>
<div class="charSelect" role="Names"><p>Dekker</p></div>
</div>
You're calling an imageOver() that loops all your elements.
Instead of using JS (at all) I'd go with pure CSS:
*{font: 14px/1 sans-serif;}
.charSelect{
position: relative;
display: inline-block;
vertical-align: top;
}
.charButtons{
position: absolute;
bottom: 40px;
width: 100%;
text-align:center;
opacity: 0;
visibility: hidden;
transition: 0.4s;
-webkit-transition: 0.4s;
}
.charButtons a{
display: block;
margin-top: 1px;
text-align: center;
color: #fff;
background: #444;
padding: 10px;
opacity: 0.9;
transition: 0.3s;
-webkit-transition: 0.3s;
}
.charButtons a:hover{ opacity:1; }
.charSelect:hover .charButtons{
visibility: visible;
opacity: 1;
}
<div class="charSelect">
<img src="http://placehold.it/180x150/4af/&text=Hero+1">
<div class="charButtons">
Newest Videos
Random Videos
</div>
<h2>HERO 1</h2>
</div>
<div class="charSelect">
<img src="http://placehold.it/180x150/fa4/&text=Hero+2">
<div class="charButtons">
Newest Videos
Random Videos
</div>
<h2>HERO 2</h2>
</div>
The problem is that you're not reffering tot the current object that you have cursor on. If you go with with cursor over and image, your function will apply those changes for all buttonNew and buttonRan that can be found on page.

Categories

Resources