So I am experiencing a weird bug that I do not know how to fix. When I click a button on my website called "Enlarge" it starts an overlay and inside there is a canvas that loads a protein structure. But when I click the close button and try to enlarge it again it loads up nothing and I can't seem to figure out why.
Example HTML
<!-- Expanded Canvas-->
<div id= "myNav" class ="overlay">
X
<div class = "overlay-content">
<div class = "fixed">
</div>
<div id = "viewer2">
<canvas id = "expandedCanvas"></canvas>
</div>
</div>
</div>
</div>
<a id = "expandImage" style = "cursor:pointer">[Enlarge]</a>
<script>
function closeNav() {
document.getElementById("myNav").style.width = "0%";
document.getElementById("sequence-label").style.display = "none";
document.getElementById("picked-atom-name").style.display = "none";
document.getElementById("proteinAlbum").style.display = "none";
}
</script>
The JS
function expandImage() {
expandImageButton = true;
//Start off as default for both the buttons not showing
show("antibodyOn", false);
show("antibodyOff", false);
//Reset the width
document.getElementById("myNav").style.width = "100%";
viewer.requestRedraw();
viewer = pv.Viewer(document.getElementById('viewer2'), {
antialias : true, fog : true,
outline : true, quality : 'high', style : 'phong',
selectionColor : 'white', transparency : 'screendoor',
background : '#111215', animateTime: 500, doubleClick : null,
});
//Fit to the nav bar
viewer.fitParent();
this.value = "";
this.blur();
// Same principle as the loadFromPdb
var XHR = new XMLHttpRequest();
XHR.open("GET", urlPdb, true);
XHR.send();
XHR.onreadystatechange = function () {
if (XHR.readyState === 4) {
if (XHR.status === 200 || XHR.status === 0) {
staticProteinLabel = XHR.responseText.slice(0, XHR.responseText.indexOf("\n")).substr(62, 4).trim();
var canvasStaticLabel = document.getElementById('static-label');
canvasStaticLabel.textContent = staticProteinLabel;
typeOfProtein = XHR.responseText.slice(0, XHR.responseText.indexOf("\n")).substr(10, 26).trim();
var result = XHR.responseText;
var allLines = result.split("\n");
var lineTwo = String(allLines[1]);
alert(lineTwo);
var antibodyText = "ANTIBODY";
if (typeOfProtein === "COMPLEX (ANTIBODY-ANTIGEN)") {
isAntibody = true;
anitbodyOn();
}
else if (lineTwo.indexOf(antibodyText) ) {
isAntibody = true;
antibodyOn();
}
}
}
}
io.fetchPdb(urlPdb, function(s) {
structure = s;
mol.assignHelixSheet(structure);
cartoon();
viewer.autoZoom();
});
}
So I was wondering if it was just the problem with the changing of the width and it can't load up the viewer again and how to go about fixing it?
So I was able to figure it out. The data inside of the canvas needs to be destroyed, so I wrote a little function to erase the data and clear the canvas so it can reload again.
Related
I'm working on a search bar. First, the user will only be able to see the search icon. When the user clicks on the search icon then that search icon gets replaced with a div that contains a new search bar. I want that when the user click on the search icon the new div with a transition of 1 second in such a way that it looks like the new div was the expanded version of the search icon.
<img src="https://populusww.com.au/wp-content/uploads/2023/01/search.png" id="Search-Collapse" style="cursor: pointer;" onclick="toggle_div_fun();">
<br/><br/>
<script>
function toggle_div_fun() {
debugger;
document.getElementById("Search-Collapse").style.transition = "all 2s";
debugger;
var divelement = document.getElementById("Search-Collapse");
var searchelement =document.getElementById("Search-Expand");
var menusection =document.getElementById("menu-section");
var searchsection =document.getElementById("search-section");
if(divelement.style.display == 'none'){
divelement.style.display = 'block';
searchelement.style.display = 'none';
menusection.style.width = '65%';
searchsection.style.width = '15%';
searchsection.style.marginTop = '30px';
}
else{
divelement.style.display = 'none';
searchelement.style.display = 'block';
menusection.style.width = '65%';
searchsection.style.width = '15%';
searchsection.style.marginTop = '50px';
}
}
</script>
Display did not work with transition, you can use divelement.style.opacity = 0; to hide your div with effect
and do not forget set opacity for initiate set divelement.style.opacity = 1;
something like this:
<img src="https://populusww.com.au/wp-content/uploads/2023/01/search.png" id="Search-Collapse" style="cursor: pointer;" onclick="toggle_div_fun();">
<br/><br/>
<script>
document.onload = () => {
document.getElementById("Search-Expand").style.transition = "all 2s";
document.getElementById("Search-Collapse").style.transition = "all 2s";
document.getElementById("Search-Collapse").style.opacity = 1;
document.getElementById("Search-Expand").style.opacity = 1;
}
function toggle_div_fun() {
var divelement = document.getElementById("Search-Collapse");
var searchelement =document.getElementById("Search-Expand");
var menusection =document.getElementById("menu-section");
var searchsection =document.getElementById("search-section");
if(divelement.style.display == 'none'){
divelement.style.display = 'block';
searchelement.style.display = 'none';
menusection.style.width = '65%';
searchsection.style.width = '15%';
searchsection.style.marginTop = '30px';
}
else{
divelement.style.display = 'none';
searchelement.style.display = 'block';
menusection.style.width = '65%';
searchsection.style.width = '15%';
searchsection.style.marginTop = '50px';
}
}
</script>
You can do that using CSS opacity in JavaScript simple event listener;
Check this detailed code below if you don't understand any things let me know and I'll try to explain it to you :D
HTML:
<img src="https://populusww.com.au/wp-content/uploads/2023/01/search.png" id="Search-Collapse" style="cursor: pointer;">
<br>
<input type="text" id="Search-Input" placeholder="search query" />
CSS:
body {
background: red;
}
img {
width: 50px;
}
JS:
var searchIcon = document.querySelector('img');
var inputSearch = document.getElementById('Search-Input');
inputSearch.style.opacity = 0;
inputSearch.style.transition = "opacity 1s"
searchIcon.addEventListener('click', function(){
if(inputSearch.style.opacity == 0 || inputSearch.style.opacity == ''){
inputSearch.style.opacity = 1;
}
else {
inputSearch.style.opacity = 0;
}
});
and here is a working example on JSFIDDLE
I am building a web app that has a fixed positioned Sidenav bar on Desktop always visible but on Mobile the Sidenav is hidden and the user clicks the Hamburguer button to Show it as modal and of course Close it later (Using Javascript for that).
The Problem
Lets imagine an iPad, that Vertically display mobile view but Horizontally displays the desktop view. If the user is Vertically and he toggles the Sidenav Visible and then Hidden, but if later he changes the orientation to Horizontal the Sidenav will be hidden, and the expected behaviour is that on desktop the Sidenav is always visible (I think this is because CSS Styles are loaded on page render, and when I change the styles with JS to toggle visibility it remains that way even when the DOM resized).
Question
The solution that occurred to me is having 2 identical Sidenavs and 1 show only on desktop and 1 only on mobile, and that way the styles of 1 dont affect the other, but that means a duplicated code.
If I want a more elegant solution without duplicating a whole block of code, I wonder if there is a way to reset all CSS values when it detects a Media Query Breakpoint, or what could be another solution?
I hope I explained well, and thank you for you help.
Edit: Solution I found thanks tacoshy's comment
When the Resize Event detects the Breakpoint it forces to trigger the Hide/Show function for the Sidenav
const showDrawer = () => {
var drawer = document.querySelector('.drawer');
var drawerBack = document.querySelector('.drawer-back');
drawerBack.style.opacity = "1";
drawer.style.left = "0";
drawerBack.style.visibility = "visible"
}
const hideDrawer = () => {
var drawer = document.querySelector('.drawer');
var drawerBack = document.querySelector('.drawer-back');
drawerBack.style.opacity = "0";
drawer.style.left = "-16rem";
setTimeout(
() => {drawerBack.style.visibility = "hidden"}
, 500);
}
window.addEventListener("resize", resizeFunction);
const resizeFunction = () => {
var w = window.outerWidth;
var drawer = document.querySelector('.drawer');
var drawerBack = document.querySelector('.drawer-back');
if (w > 1216) {
drawerBack.style.opacity = "1";
drawer.style.left = "0";
drawerBack.style.visibility = "visible";
} else {
drawerBack.style.opacity = "0";
drawer.style.left = "-16rem";
setTimeout(
() => {drawerBack.style.visibility = "hidden"}
, 500);
}
}
Solution I found thanks tacoshy's comment
When the Resize Event detects the Breakpoint it forces to trigger the Hide/Show function for the Sidenav
const showDrawer = () => {
var drawer = document.querySelector('.drawer');
var drawerBack = document.querySelector('.drawer-back');
drawerBack.style.opacity = "1";
drawer.style.left = "0";
drawerBack.style.visibility = "visible"
}
const hideDrawer = () => {
var drawer = document.querySelector('.drawer');
var drawerBack = document.querySelector('.drawer-back');
drawerBack.style.opacity = "0";
drawer.style.left = "-16rem";
setTimeout(
() => {drawerBack.style.visibility = "hidden"}
, 500);
}
window.addEventListener("resize", resizeFunction);
const resizeFunction = () => {
var w = window.outerWidth;
var drawer = document.querySelector('.drawer');
var drawerBack = document.querySelector('.drawer-back');
if (w > 1216) {
drawerBack.style.opacity = "1";
drawer.style.left = "0";
drawerBack.style.visibility = "visible";
} else {
drawerBack.style.opacity = "0";
drawer.style.left = "-16rem";
setTimeout(
() => {drawerBack.style.visibility = "hidden"}
, 500);
}
}
I have a responsive modal image gallery through bootstrap and I'm a beginner at coding. My images were successfully sliding forward and backwards until I tried adding captions.
I've added hover captions to every image using this in my javascript:
$(".popup").wrap('<div class="alt-wrap"/>')
$('.modal-body>caption').remove();
$(".popup").each(function() {
$(this).after('<p class="alt">' + $(this).attr('alt') + '</p>');
})
Now, whenever I click my modal image, the hover caption works fine but once I click next/prev, the old images still remain.
How do I remove the old images/captions when I click next/prev through my modals?
The rest of my js looks like this:
var imagesList = $("div#imagesList");
var imagesListLength = imagesList.children().length;
var showImageGallery = function(imageNumber){
$('.modal-body>img').remove();
$('#imageModal').modal('show');
var image = imagesList.children()[imageNumber];
$(image).clone().appendTo('.modal-body');
$("#currentImageNumber").text(imageNumber);
}
var nextImage = function(){
$('.modal-body>img').remove();
var nextNum = parseInt($("#currentImageNumber").text());
if(nextNum == imagesListLength-1){ nextNum = -1;}
$("#currentImageNumber").text(nextNum+1);
var image = imagesList.children()[nextNum+1];
$(image).clone().appendTo('.modal-body');
}
var previousImage = function(){
$('.modal-body>img').remove();
var previousNum = parseInt($("#currentImageNumber").text());
if(previousNum == 0){ previousNum = imagesListLength;}
$("#currentImageNumber").text(previousNum-1);
var image = imagesList.children()[previousNum-1];
$(image).clone().appendTo('.modal-body');
}
$(window).keydown(function(event) {
if (event.key === 'ArrowLeft') {
previousImage();
}
if (event.key === 'ArrowRight') {
nextImage();
}
if (event.key === 'Escape') {
$('#close-modal').trigger('click')
}
})
I just had to add:
$('.modal-body>.alt-wrap').remove();
under
var showImageGallery = function(imageNumber){
and
$('.modal-body>.alt-wrap').remove();
to my .popup, nextImage, and previousImage functions
I'm trying to connect previous and fwd buttons to a gallery and I want the previous button to be hidden on first image of the gallery but javascript doesn't seem to be working at all.
Javascript
var imageGallery = new Array();
imageGallery[0] = '1.png';
imageGallery[1] = '2.png';
imageGallery[2] = '3.png';
imageGallery[3] = '4.png';
imageGallery[4] = '5.png';
var imgCount = 0;
function next() {
imgCount++ ;
document.getElementById("gallery").src = imageGallery[imgCount] ;
}
function previous() {
imgCount--;
document.getElementById("gallery").src = imageGallery[imgCount] ;
}
if(document.getElementById("gallery").getAttribute("src") == "1.png")
{
document.getElementById("previous").style.visibility = 'hidden';
}
else
{
document.getElementById("previous").style.visibility = 'visible';
}
HTML
<div id="img">
<img id="gallery" src="1.png" style="height:420px; width:744px" >
<div id="imgNav">
<a id="previous" href onclick="previous(); return false;">previous</a>
<span style="color:#666; font-size:0.9em"> | </Span>
<a id="next" href onclick="next(); return false;">next</a>
</div>
</div>
Actually the logic is if 'src' attribute of id 'gallery' is '1.png' then 'visibility' of element with id 'previous' is 'hidden' else not but doesn't seem to be working. Can anyone help figuring it out.
You're probably trying to check on an image that's not totally loaded yet. Did you remember to place your code to run just when the page is fully loaded (in case it's placed in the page headers - you didn't mention whether it is or not)?
UPDATED
var imageGallery = new Array();
imageGallery[0] = '1.png';
imageGallery[1] = '2.png';
imageGallery[2] = '3.png';
imageGallery[3] = '4.png';
imageGallery[4] = '5.png';
var imgCount = 0;
function checkNav() {
var previousLnk = document.getElementById("previous");
var nextLnk = document.getElementById("next");
previousLnk.style.visibility = imgCount == 0 ? 'hidden' : 'visible';
nextLnk.style.visibility = imgCount >= (imageGallery.length - 1) ? 'hidden' : 'visible';
}
function setImg() {
var gallery = document.getElementById("gallery");
gallery.src = imageGallery[imgCount];
}
function next() {
imgCount++;
setImg();
checkNav();
}
function previous() {
imgCount--;
setImg();
checkNav();
}
window.onload = function () {
checkNav();
}
Demo: http://jsfiddle.net/N7V9E/
i have added a light box function to my web page. everything works. so when i click on an image it goes bigger...
my problem is that there is no close button. how do i get it to close without having to click back.
Here is my code for the light box
window.onload = setupLightbox;
var lightboxOverlay;
var lightboxImage;
function setupLightbox() {
for (i in document.links) {
if(document.links[i].rel == "lightbox"){
document.links[i].onclick = showLightbox;
}
}
}
function showLightbox() {
lightboxOverlay = document.createElement("div");
lightboxImage = document.createElement("img");
lightboxOverlay.style.position = "fixed";
lightboxOverlay.style.top = lightboxOverlay.style.left ="0";
lightboxOverlay.style.width = lightboxOverlay.style.height ="100%";
lightboxOverlay.style.background = "#000";
lightboxOverlay.style.opacity = "0.5";
lightboxOverlay.style.filter = "alpha(opacity = 50)";
document.body.appendChild(lightboxOve…
lightboxImage.onload = showImage;
lightboxOverlay.onclick = closeLightbox;
lightboxImage.src = this.href;
return false;
}
function showImage(){
lightboxImage.style.position = "fixed";
lightboxImage.style.top = lightboxImage.style.left = "50%";
lightboxImage.style.marginLeft = -lightboxImage.width/2 + "px";
lightboxImage.style.marginTop = -lightboxImage.width/2 + "px";
lightboxImage.style.border = "10px solid #fff";
document.body.appendChild(lightboxIma…
}
function closeLightbox(){
lightboxImage.style.opacity = lightboxOverlay.style.opacity = "0";
setTimeout( function() {
lightboxImage.parentNode.removeChild…
lightboxOverlay.parentNode.removeChi…
}, 1);
}
Check the Lightbox should have a css file with it and an image folder too. Specify the css file in the header section so that it can find the image.