Changing the background-Image using Jquery causing a flickering kind of effect - javascript

Following is the portion of the script which I am using to create a slider by changing the background image for every imageobject I have for a cycle of time.
#Sliderimg - height is 500px,
$("#Sliderimg").css({
"background-image": "url(../Images/" +SliderImageObj.image + ")",
"display": "block",
"z-index": "50px"
});
What could have gone wrong with this as I'm getting the flickering effect every time I change the image, My problem is not with the new image about to load, its flickering(flashing on to the bottom of the screen) for the old image which is about to be replaced.

You see a flicker because every time you change the background image, your browser has to download it before it can show the background. If the images aren't too big (more than say, 5kb) you can try caching them in the browser by applying them to elements where they won't show up.
Also, 50px isn't a valid z-index, that property requires integers only.

Maybe delete "px" from your z-index atribute? It take decimal values.

the browser is forced to redraw the entire background.
how this is done is by setting background to white and then redrawing the new background.
use jquery.animate() to battle this.

I had the same issue the other day. Oddly enough, it seemed to be OK in FF, but would flicker in IE, Chrome, and sometimes Safari. The solution is to use a css sprite sheet. You create an image that has both backgrounds next to each other. You only show a portion of the background sheet. you toggle it by adjusting the margin on the background. You can handle the margin adjustments using addClass and removeClass. Below is code, see here for a fiddle: http://jsfiddle.net/fMhMY/
CSS
.navButton span{
width:32px;
height:32px;
display:block;
}
a.leftButton span, a#leftButton span{
background-image:url(Prev.png);
background-position:-64px 0px;
}
/*nav button sprites */
/*sprite order is pushed, hover, natural */
a.leftButton.navOver span, a.rightButton.navOver span{
background-position:-32px 0px;
}
a.leftButton.navPressed span, a.rightButton.navPressed span{
background-position:0px 0px;
}
HTML
<div style='display:inline-block'>
<a href="javascript:void(0);" class="leftButton navButton" id='lefty'>
<span></span>
</a>
</div>
jQuery
$('.leftButton').mousedown(function() {
$('.leftButton').addClass('navPressed');
console.log('mousedown');
});
$('.leftButton').mouseup(function() {
$('.leftButton').removeClass('navPressed');
console.log('mouseup');
});
$('.leftButton').hover(function() {
$('.leftButton').addClass('navOver');
console.log('hover');
});
$('.leftButton').mouseout(function() {
$('.leftButton').removeClass('navPressed').removeClass('navOver');
console.log('mouseout');
});

Related

Image background color bleeding on circular image

I have a circular image (a profile picture). This image may or may not be translucent so I've given it a background color to ensure that it's always visible. The problem I'm having is that the background color is visible even on images that are completely opaque (see figures).
After messing around with borders and padding I found a workaround. I found that adding an invisible border, and then removing it will fix the problem. To deal with images being dynamically added and removed, I do this on a timer (this was easier than injecting some code in all places where images are added to the page). This is what I've done and it seems to work but I don't like it.
setInterval(() => {
for (const img of document.getElementsByTagName("img")) {
if (img.style.border.length) {
img.style.border = "";
} else {
img.style.border = "0 solid transparent";
}
}
}, 500);
The <img> has the width and height attributes set to 32. It also has a border-radius of 16px and of course, a background-color.
Surely there must be a better way to deal with this than the setInterval above. Changing the border seems to be causing the element to be rendered again (and correctly). Perhaps there's a way to do this more directly?
Since this is a weird rendering issue, I should mention that I'm using Chrome 87.
I found another workaround that's a little bit more efficient. Whenever an image is added to the page, I attached an onload listener that updates the border.
img.onload = () => {
setTimeout(() => img.style.border = "0 solid transparent", 100);
};
This still feels like an ugly hack. Also, the edge around the image appears briefly before disappearing when the page loads. I'm looking for a better way.
I tried this out in Safari and updating the border doesn't help. It seems like I'll need to think outside the box.
Figure 1 - disgusting
Figure 2 - desired
Oh neat, what an interesting issue! Unfortunately I've looked and looked and looked and can't seem to see why this is happening. Triggering a reflow of any kind seems to fix it though, so whether you use the border or not should work.
However I think I've found another solution that would work without requiring a reflow, and that's using a radial-gradient background-image instead of a solid background color.
I set up an example pen here: https://codepen.io/xhynk/pen/ZEprxqq (it was easy to increment the ?4 to uncache the image and get it to "act weird" again.
Using this CSS for the background on the image, it seems to prevent the image from being close enough to "bleed" through the edge:
img {
background-image: radial-gradient(#000 70%, transparent calc(70% + 1px));
}
You could potentially drop the 70% down to 69% if you're still seeing it. I just tried to get it as close to the edge of the container as possible, and the +1px calc smooths it out instead of being jagged.
You can see in the following image, the first avatar has the radial-gradient applied and there's no bleed, and the second has the solid background: black instead which does.
I tried to replicate what you just told. And it seems to work just fine.
From what I understood, I am thinking of one possible error that is to replace fixed width of the image and set it to 100% and not care about the height of the image in the img tag.
Set the height and width of the image in your surrounding div and give that a background color.
<!DOCTYPE html>
<html>
<head>
<style>
img {
background-color: blue;
border-radius: 50%;
width: 100%;
}
#image-container {
width: 128px;
height: 128px;
background: lightseagreen;
}
</style>
</head>
<body>
<div id="image-container">
<img src="img_avatar.png"/>
</div>
</body>
</html>
Just copy paste it into https://www.w3schools.com/html/tryit.asp?filename=tryhtml_basic to see

Make div non-transparent to cover original div

I have a div "whitebox" which is basically a div that should cover my original "stimuli" div. It goes smooth and appears nicely, yet it does not cover the original div but seems to be transparent so that I can still see my original div though it. But I want it to be covered completely.
Apparently 'opacity' does not fix it.
<div id="stimuli"> Just press B and get started... </div>
$("#whitebox").fadeIn("fast").delay(500).fadeOut("fast");
CSS:
#whitebox{
background: #fc3a54;
opacity: 1;
position:absolute;
height: 80%;
width: 70%;
}
Is there a simple trick to fix the transparency issue with my code above, or any other hints?
try using an image with #fc3a54 colour instead of using the background function, you can then use z-index to insure your whitebox is in front
Are you positive #whitebox is covering #stimuli? Also, jQuery fadeIn and fadeOut will toggle the display property so if you start with an element that has display:none and run fadeIn on it it will show it. You can use fadeToggle (https://api.jquery.com/fadeToggle/) as well.

How do I fix the image size when changing to another image?

I am learning how to do a slideshow with CSS, HTML and Javascript, everything seems to be fine but when I click on next or prev the current image gets bigger and it stays on the screen for a few seconds. I am using images with different sizes, but I added a width on CSS -> img{width:100%;}. It could be something related with the margins as well but that doesn't seem to be the problem.
Here is some code that might help you understand the problem:
figure
{
position:absolute;
opacity:0;
transition:1s opacity;
margin:0;
border-left:solid 2px black;
border-right:solid 2px black;
}
figure.show
{
opacity:1;
position:relative;
transition:1s opacity;
margin-right:15%;
margin-left:15%;
}
Also there is a space between the image and the bottom div. I am doing this on c9.io and I don't have this problem there, could it be something on codepen that is causing it?
You can check the code out here: http://codepen.io/iikinz/pen/BiLeJ
Your images are getting bigger cause you are removing the show class and the show class has the margins.
Move:
margin-right:15%;
margin-left:15%;
out of figure.show and into figure.
--UPDATE--
Here it is: http://codepen.io/anon/pen/Cuikc
--UPDATE--
This works for most of your images but a couple of them are smaller than the rest so those appear to get smaller when changing slides. The ideal solution would be to just make sure they are all the same size. Plus it will keep them looking clear since they won't have to be stretched.
About the gap under the image, it's displayed inline :
img {
display: block; /* this will fix bottom gap */
width: 100%;
}
About your images size :
Just use images of the same size will fix your situation. Otherwise try forcing them with css
figure img {width:1280px;height:960px;margin-right:15%;margin-left:15%;}
About i can i do the transition and more ... well, not to sound arsh or nothing, but .. keep studying. You are quite asking too much in a single question.

Interactive HTML webpage

EDIT: Thanks for a lot of great examples on how to solve these. I cant decide between who to accept yet, but I will go though all examples and see which I like the most. Great feedback guys! =D
I normally do these kind of things in flash, but this time it has to be compatible with mac, iPads and all those units too.
So, what do I need help with?
I've got a picture, with some "hotspots" on. I want to be able to click any of those hotspots to show some information.
This should be fairly basic and easy to achieve, but since I've never done this in html before I have to ask you guys =)
So, what would be the best way to do this? It have to be compatible with any browser and device, and it doesnt need to be very advanced. If it's possible to add effects to the box (sliding out, fading in, or anything like that) then thats a nice bonus, but not something I need.
Any help would be great!
BREAKDOWN:
I have a background image with some "hotspots" (numbers 1 and 2 in my example). The users should be able to either hover the mouse over any of these or click it to get more information, as seen in picture #2
This is that happens when you hover/click any of these hotspots.
Text and image is displayed inside a nice little info box.
If the user clicks "more information" it will open up even further to display more information if available. Like in this img:
I don't think the Javascript approach is really necessary here. I created a little CSS-only mock-up for you on JSBin.
Basically the point is that you enclose the image in a relatively positioned div, then absolute position the hotspots inside the same div. Inside the hotspots divs you will have the more info elements, showing only on :hover of their parents.
This makes it simple, and far more accessible.
Update: cropping the image equally from both sides
If you want to keep the image centered and still not use any javascript, you could set the required image as a background-image of the container, and setting its background-position parameters to center center.
You would have to make sure that the width of this div is set to the width of your image, and the max-width to 100%, so that when the window gets resized below the image width it stays at the center.
Now, a problem that I encountered here is how to make the hotspots stay center relatively to the image. I solved it this way:
I created a wrapper div for the hotspots with these characteristics:
margin: 0 auto;
position: relative;
width: 0px;
This basically makes sure that the wrapper div finds the center of our image. Then, you would position the hotspots relatively to the top-center position of the image, instead of the top-left as a starting point.
Then you have what you are looking for.
Working demo
Here's another approach, and in my opinion far superior to using a map or excessive JS. Place <div> elements on top of the element with the background-image and have HTML and CSS do the heavy lifting for you.
See it on JSFiddle
HTML
The HTML should seem pretty each enough to understand, we create <div>s with the class hotspot and rely on certain things being present. Namely .text (to show digit), .hover-popup (to show on hover) and .click-popup (which is inside .hover-popup and is shown when clicked).
<div id="hotspot1" class="hotspot">
<div class="text">1</div>
<div class="hover-popup">
I was hovered!
<div class="click-popup">
I was clicked on!
</div>
</div>
</div>
<div id="hotspot2" class="hotspot">
<div class="text">2</div>
<div class="hover-popup">
I was hovered!
<div class="click-popup">
I was clicked on!
</div>
</div>
</div>
CSS
This is where most of the magic happens, see the comments for further explanation.
/* These two position each hotspot */
#hotspot1 {
left:15%; /* we could use px or position right or bottom also */
top:20%;
}
#hotspot2 {
left:35%;
top:25%;
}
/* General styles on the hotspot */
.hotspot {
border-radius:50%;
width:40px;
height:40px;
line-height:40px;
text-align:center;
background-color:#CCC;
position:absolute;
}
.hotspot .text {
width:40px;
height:40px;
}
/* Show the pointer on hover to signify a click event */
.hotspot .text:hover {
cursor:pointer;
}
/* hide them by default and bring them to the front */
.hover-popup,
.click-popup {
display:none;
z-index:1;
}
/* show when clicked */
.hotspot.clicked .click-popup {
display:block;
}
/* show and position when clicked */
.hotspot:hover .hover-popup {
display:block;
position:absolute;
left:100%;
top:0;
width:300px;
background-color:#BBB;
border:1px solid #000;
}
JavaScript (with jQuery)
Unfortunately you're going to have to use some JavaScript for the clicking part as CSS doesn't have a 'clicked' state (outside of hacks with checkboxes). I'm using jQuery because it's dead easy to do what I want.
$(document).ready(function () {
$('.hotspot').click(function () {
$(this).toggleClass('clicked');
});
});
Creating the arrow
Over at css-tricks you can find a tutorial for attaching an arrow to a element using the :before and/or :after pseudo-elements. You can even 'simulate' a border around them by placing the :after element on top of the :before. But yea, lots of resources on how to do this.
You should be able to use the onclick or OnMouseOver event in the map area (define the href as "").
An example using OnMouseOver is here: http://www.omegagrafix.com/mouseover/mousimap.html
Give a class for that image in html (Ex: imgclass). And in javascript(using jquery), build that hover box in html format and bind it to 'mouseover' event of that image.
For example:
function bindhtmltoimage() {
myimg = $('body').find('.imgclass');
divSlot.each(function (index) {
$(this).bind('mouseover', function () {
try {
//position the hover box on image. you can customize the y and x axis to place it left or right.
var x = $(this).offset().left;
var y = $(this).offset().top;
var position = $(window).height() - ($("#divHover").height() + y);
var widthposition = $(window).width() - ($("#divHover").width() + x);
if (position < 0 || widthposition < 0) {
if (position < 0) {
$("#divHover").css({
position: 'absolute',
left: x + 20,
top: y - $("#divHover").height() - 20
});
}
if (widthposition < 0) {
$("#divHover").css({
position: 'absolute',
left: x - $("#divHover").width(),
top: y + 20
});
}
}
//build your html string for that hover box and apply to it.
$('#divHover').html("your Html content for that box goes here");
$('#divHover').show();
//if you want the box dynamically generated. create the html content and append to the dom.
}
catch (e) {
alert(e)
}
});
});
}
it will work fine in desktop and mobile. if you face any problem in touch devices, bind the function to click event instead of 'mouseover'.
Also, for map approach, i strongly recommend SVG instead of images.

Slide Background with AnythingSlider

I need to slide a background when clicking the "next" arrow, and the "previous" arrow - right now the background is in the #container element - However, that doesnt work - I've tried putting the background on the ul#slider element - But that doesnt work either...
What i need is that the background will be slider as much as the liinside the slider...
Any suggestions on how to do that ?
You can see the project here: http://www.i-creative.dk/Slider/
thx
I've built something like what you're asking for, and it's a total pain.
The problem is, you're talking about having a different background image, the size of the page, for EVERY slide.
2 options are:
1: Have one BIG background image, with all the background aligned horizontally, and animate the css background-position when you change a div, to keep things matching. This ahs the advanatage that only one image needs to be downloaded, but it will be big.
Problems are: you see all the other images if you jump multiple steps at once;
it requires that you use a fixed width;
it's a pain if you want to change the background for just one slide;
Preload the background for the next slide on a div which is a sibling of container but has a higher z-index. Use jquery to slide this over the existing background, from the appropriate side.
The good thing about this method is that you can use css to make the background image always take up the full-width of the screen, or use a bigger imager and have it centred. See here: http://cksk.com for an example.
Long story short, you won't get this working with an off-the-shelf solution, you'll need to get your hands dirty.
Also, you'll need to spend a hell of a lot of time on optimisation.
Try this css...
#slider {
width: 472px; /* divided the width of the background image by 4 (# of panels) */
height: 570px;
list-style: none;
/* start background after the initial cloned panel: 472px to match panel width */
background: transparent url(../images/background.png) 472px 0 repeat-x;
}
/* This makes sure the last cloned panel background matches the first panel */
ul#slider li.clone {
background: transparent url(../images/background.png) 0 0 repeat-x !important;
}
/* Make the background visible */
div.anythingSlider .anythingWindow {
overflow: visible !important;
}
The only problem is that the width of the UL is limited, so when you get to the last panel, the background ends, but reappears once you hit the right arrow.

Categories

Resources