Use percentage with background position - javascript

I have an image like you can see below and I want to set the Images Background position for different percentage values (0%, 25%, 50%, ...).
---> Like for example I want to call a function with myfunction(50%) and the Images-background should move about 50% to the left.
Please have a look at my code:
function call(value) {
document.getElementById("img").style.backgroundPositionX = -value + "px"
}
#img {
position: fixed;
left: 0%;
width: 100%;
height: 20%;
top: 0%;
background:url("https://i.stack.imgur.com/fTyE3.png") no-repeat;
background-size:cover;
}
<div id="img"><br></div>
<br><br><br>
<input type="text" oninput="call(this.value)"/>
My idea was to set the to a percent value (in this case "50%")
elem.backgroundPositionX = "50%"
...but is doesn't seems working this way!
I have no clue how to fix this problem. I don't want to use px-values. I want to set the position in percentage.
Any help would be very appreciated. Thanks in advance.

You can do some calculation in order to convert the % value to pixel if you want to consider the % relative to width of the container (or the width of the initial image or any other value).
You can try this:
function call(value) {
var w = document.getElementById("img").offsetWidth;
var v = (value * w)/100
document.getElementById("img").style.backgroundPositionX = -v + "px";
}
#img {
width: 400px;
height: 50px;
background: url("https://i.stack.imgur.com/fTyE3.png") no-repeat;
background-size: cover;
}
input {
margin-top:50px;
}
<div id="img"></div>
<input type="text" oninput="call(this.value)" >
As a side note, percentage value with background position doesn't work like pixel value. 0% means the element is placed on the left (left edge of the image is placed on the left edge of container) and 100% means that the element is on the right (the right edge of the image is placed on the right edge of container). Since you are using cover with background size, you should increase value in order to move the image to the left so you have to consider positive value if you want to use percentage.
Check below to see behavior of px vs %:
#img {
width: 400px;
height: 50px;
background: url("https://i.stack.imgur.com/fTyE3.png") no-repeat;
background-size: cover;
animation:anime 5s alternate infinite linear;
}
#img1 {
margin-top:20px;
width: 400px;
height: 50px;
background: url("https://i.stack.imgur.com/fTyE3.png") no-repeat;
background-size: cover;
animation:anime 5s alternate infinite linear;
}
#keyframes anime {
from {
background-position-x:0%
}
to {
background-position-x:100%
}
}
#keyframes anime1 {
from {
background-position-x:0px
}
to {
background-position-x:-400px
}
}
<div id="img"></div>
<div id="img1"></div>
Related question to get more details: Using percentage values with background-position on a linear gradient

Related

When hovering over image, only display the part where the cursor is over it

Info in advance:
You can see the current code or the live demo (without the working hover image) at https://juek3y.com.
The idea:
I want, when I hover with my cursor (a black circle) over the image, to get displayed only exactly this part of the image (and not the whole image), over which the cursor is hovering.
The problem:
Where do I start? I have seen a few CodePens that work with Z-Index. However, I have not been successful with them so far. Also a sample website that has something like this would be enough for me.
For a better understanding I have two more example pictures.
In the first image, the smaller circle / cursor (black / turquoise circle) hovers over the round text, but it does not yet intersect the image. Therefore this is hidden.
In the second image, the cursor is already hovering a bit above the image, this part of the image is also shown.
You can use CSS mask to 'cut a hole' in an element.
You can put the image that is to be (partially) revealed as background to a div, then overlay that with an after pseudo-element which has as background the image you want at the front, masked with a radial gradient which gets positioned with the mouse position.
This snippet overlays a colored image with a grayscale one as an example:
window.onload = function() {
const div = document.querySelector('.hole');
let isIn = false;
div.addEventListener('mouseover', function() {
isIn = true;
});
div.addEventListener('mouseout', function() {
isIn = false;
});
div.addEventListener('mousemove', function() {
if (isIn) {
div.style.setProperty('--x', event.clientX + 'px');
div.style.setProperty('--y', event.clientY + 'px');
}
});
}
.hole {
background-image: url(https://picsum.photos/id/1016/1024/768);
background-size: cover;
--x: 200px;
--y: 150px;
width: 100vw;
height: 100vh;
position: relative;
}
.hole::after {
content: '';
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
background-image: url(https://picsum.photos/id/1016/1024/768?grayscale);
background-size: cover;
z-index: 1;
-webkit-mask-repeat: no-repeat no-repeat;
mask-repeat: no-repeat no-repeat;
-webkit-mask-image: radial-gradient(200px at var(--x) var(--y), transparent 95%, black 100%);
mask-image: radial-gradient(200px at var(--x) var(--y), transparent 95%, black 100%);
}
<div class="hole"></div>
You can use the CSS clip-path property in conjunction with a mousemove listener to show the front image under the mouse, and clearing the clip-path on mouseleave.
Rough working snippet using a CSS invert filter on the overlay image. You could easily add event delegation for handling multiple overlays etc.
const overlay = document.querySelector('.overlay');
overlay.addEventListener('mousemove', e => {
const {height, width} = e.currentTarget.getBoundingClientRect();
const x = e.offsetX;
const y = e.offsetY;
const xPercent = Math.round((x/width)*100);
const yPercent = Math.round((y/height)*100);
e.currentTarget.style.clipPath = `circle(18% at ${xPercent}% ${yPercent}%)`;
});
overlay.addEventListener('mouseleave', e => {
e.currentTarget.style.clipPath = null;
});
.container {
position: relative;
}
.container img {
width: 200px;
height: 200px;
position: absolute;
top: 0;
left: 0;
}
.overlay {
filter: invert(var(--value, 100%));
clip-path: circle(0 at 49% 45%);
}
<div class='container'>
<img src='https://source.unsplash.com/random' />
<img src='https://source.unsplash.com/random' class='overlay'/>
</div>

Progress- percentage bar for webpage

I am trying to make a loading bar but with percentage. I mean imagine when it’s 50% it will show that number also it will fill until half. If it’s 75% it will go up until 3/4.
I am trying to do this with HTML,CSS and JS. So far I made up everything but at the same time number will increase (by clicking button) and pattern will fill up according to percentage? This part is challenging me.
Can you lead me way if it’s possible? Or even if there is example so I can learn?
UPDATE CODE BELOW
<script>
var i = 0;
function buttonClick5() {
i += 5;
document.getElementById('demo').innerHTML = i + "€";
}
function percentage(per) {
return (100 / 100) * per;
}
</script>
<div class="textContainer">
<p class="perc" id="here"></p>
<script>
document.getElementById('here').textContent = percentage(10) + "%";
</script>
<h2 id="demo">0€</h2>
</div>
and css part
.textContainer {
margin-top:-10%;
margin-left: 30%;
height: auto;
text-align: center;
}
.textContainer h2 {
margin-left: -40%;
font-size: 500px;
color: rgba(225, 225, 225, .1);
background-image: url(color3.jpg);
background-repeat:repeat;
-webkit-background-clip: text;
animation: animateMid 15s linear infinite;
}
#keyframes animateMid {
0% {
background-position: left 0px top 0px;
}
1% {
background-position: left 1200px top 0px;
}
}
basically with those I can just make pattern moving as background of the percentage but always at 100 per cent.
Use your percentage variable as a width of the div that shows progress. Add click even listener to your button that will update that percentage variable and width of the div. If you make a callback function that updates both at the same it would be easy for you. Share your code here so we can help further.

Need some help in creating a visual representation of device orientation using JS

Basically, I am wanting to create a visual representation of the device orientation values alpha, beta, and gamma. So far I have managed to display the values in plain text using innerHTML, but I want to create a series of "bars" for each value. I drew a very crude drawing of what I had in mind:
Basically, I want the bars to move in relation to changes in the alpha, beta and gamma values. This is how my code looks now.
<!DOCTYPE HTML>
<html>
<body>
<p>Alpha: <span id="alpha"></span></p>
<p>Beta: <span id="beta"></span></p>
<p>Gamma: <span id="gamma"></span></p>
<canvas id="myCanvas" width="400" height="400"></canvas>
<script>
// Listen for device orientation event
window.ondeviceorientation = function(eventData)
{
// Show alpha, beta and gamma values
document.getElementById('alpha').innerHTML = Math.round(eventData.alpha);
document.getElementById('beta').innerHTML = Math.round(eventData.beta);
document.getElementById('gamma').innerHTML = Math.round(eventData.gamma);
}
</script>
</body>
</html>
I highly doubt I can do this using inner HTML because I think I would need to use CSS styling. This makes me think that the canvas might work, but I have trouble initializing it using the ondeviceorientation. I would appreciate any help in accomplishing this.
You don't need a canvas. You can do this just by altering the width of your spans along with using CSS to set the colors.
Firstly make sure your spans have a CSS property of display : inline-block or display : blockor else changing the width will do nothing. Alternatively you can make them divs instead of spans. Also make sure it has a height property set such as 30px.
Next you can use css or inline-styles to set the background-color property for alpha, beta, and gamma. Then simply change the Element.style.width property (in px) based on the device orientation using javascript.
Something you might want to consider deeply is what you want the size of the bars to represent and their precise behavior. That design decision is up to you, so I won't explain in excruciating detail how the following code works, but basically I size them relative to the range of the values. I turn the value of alpha, beta, and gamma respectively into a percentage of their total range and then multiply that by the max width I would like for the bars.
I grabbed the ranges from here: https://developer.mozilla.org/en-US/docs/Web/API/Detecting_device_orientation
The general formula is for values in range [a, b] and a maximum bar width of max_w, and alpha, beta, or gamma value of value, the calculated width of the bar is:
width = max_w * ( ( -a + value ) / (b - a) )
And don't forget to add "px" to the end.
// Listen for device orientation event
window.ondeviceorientation = function(eventData)
{
let maxWidth = 200;
// Show alpha, beta and gamma values
document.getElementById('alpha').style.width = Math.round(maxWidth * eventData.alpha / 360) + "px";
document.getElementById('beta').style.width = Math.round(maxWidth * (180 + eventData.beta) / 360) + "px";
document.getElementById('gamma').style.width = Math.round(maxWidth * (90 + eventData.gamma) / 180) + "px";
}
p span{
height : 30px;
display : inline-block;
}
#alpha{
background-color : green;
}
#beta {
background-color : yellow;
}
#gamma {
background-color : purple
}
<p> Alpha: <span id="alpha"> </span> </p>
<p> Beta: <span id="beta"> </span> </p>
<p> Gamma: <span id="gamma"> </span></p>
The previous poster, Khauri McClain, posted a good suggestion for a static representation of your orientation values. If by "move" you mean, however, an animation (and hence refer to canvas), then you can still do it without canvas, but instead using CSS keyframes. Here is quick example.
html,
body {
height: 100%;
}
body {
background-color: #f5f7f9;
color: #6c6c6c;
margin: 0;
position: relative;
}
.container {
width: 30em;
margin: 2em;
}
.label {
float: left;
width: 5em;
height: 2em;
}
.orientation {
float: right;
background-color: #e5e9eb;
height: 2em;
position: relative;
width: 24em;
}
.alpha {
animation-duration: 3s;
animation-name: alpha-anim;
animation-fill-mode: forwards;
background-color: #ff2d55;
height: 100%;
position: relative;
}
.beta {
animation-duration: 3s;
animation-name: beta-anim;
animation-fill-mode: forwards;
background-color: #4cd964;
height: 100%;
position: relative;
}
.gamma {
animation-duration: 3s;
animation-name: gamma-anim;
animation-fill-mode: forwards;
background-color: #007aff;
height: 100%;
position: relative;
}
#keyframes alpha-anim {
0% {
width: 0;
}
100% {
width: 14em;
}
}
#keyframes beta-anim {
0% {
width: 0;
}
100% {
width: 3em;
}
}
#keyframes gamma-anim {
0% {
width: 0;
}
100% {
width: 20em;
}
}
<div class="container">
<div class="label">Alpha:</div>
<div class="orientation">
<div class="alpha"></div>
</div>
</div>
<div class="container">
<div class="label">Beta:</div>
<div class="orientation">
<div class="beta"></div>
</div>
</div>
<div class="container">
<div class="label">Gamma:</div>
<div class="orientation">
<div class="gamma"></div>
</div>
</div>

How to animate image over other image in Css or Javascript? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
Lets say First image is black & white.
Second image is colored.
After some timeout B/W image should change to colored image..with animation
just like loading progress bars? how can I do this using Css or JavaScript ?
[Added for clarity from a comment by the OP, below]
OP: is it possible with some slow linear kind of animation ?? like filling
water in glass..color filling in b/w image ?
first place two images above each other using position: absolute;. With background images you can do it like this:
<div class="container">
<div class="image1"></div>
<div class="image2" id="image_resize"></div>
</div>
CSS:
.container {
position: relative;
width: 300px;
height:200px;
}
.image1 {
position: absolute;
width: 100%;
height: 100%;
background-image: url(http://images.freeimages.com/images/previews/cf6/bird-1394216.jpg);
background-repeat: no-repeat;
}
.image2 {
position: absolute;
height: 100%;
background-image: url(http://images.freeimages.com/images/previews/4f3/apple-1322812.jpg);
background-repeat: no-repeat;
}
To animate the second image, the easiest way is to use jquerys animate. With pure javascript you could do something like this:
var percent = 0; // this will count from 0 to 100, defining the with in percent
/* with setinterval you can call a function periodically, in this example every 50 milliseconds */
var myInterval = window.setInterval(function() {
/* find the image that should get resized by id */
var img = document.getElementById('image_resize');
/* set the with of the image */
img.style.width = percent+"%";
/* increment by 1 percent */
percent ++;
if(percent > 100) {
/* when 100% is reached, stop the interval */
clearInterval(myInterval);
}
}, 50);
Here is a working jsfiddle: https://jsfiddle.net/c51u6r8t/
You can put the black-white image on top of the colored one at full opacity and simply fade out the black-white image when you want.
setTimeout(function() {
document.getElementById("container").className = "revealed";
}, 500);
#container {
position: relative;
}
#container .overlay {
position: absolute;
top: 0px;
left: 0px;
transition: opacity 1.5s ease-in-out;
}
#container.revealed .overlay {
opacity: 0;
}
<div id="container">
<img src="http://www.esa.int/var/esa/storage/images/esa_multimedia/images/2003/10/soho_image_28_october_2003/10098404-2-eng-GB/SOHO_image_28_October_2003_node_full_image_2.jpg">
<img class="overlay" src="http://dawn.jpl.nasa.gov/multimedia/images/dawn-image-070911.jpg">
</div>
Fiddle
Second attempt
I understand better what you are trying to achieve now. This can be achieved with an animation on an ::after pseudo-element.
Working Example:
div {
position: relative;
width: 190px;
height: 190px;
background-image:url('http://placekitten.com/190/190');
}
div::after {
content: '';
display: block;
position: absolute;
top: 0;
left: 0;
width: 190px;
height: 190px;
background-image:url('http://placekitten.com/190/190');
opacity: 0;
filter: grayscale(100%);
animation: waterfill 5s linear;
}
#keyframes waterfill {
0% {height: 190px; opacity: 1;}
20% {height: 190px; opacity: 1;}
100% {height: 0; opacity: 1;}
}
<div></div>
First attempt:
You can use a CSS #keyframes animation like this:
img {
width: 190px;
height: 190px;
filter: grayscale(0%);
animation: colorImage 5s linear;
}
#keyframes colorImage {
0% {filter: grayscale(100%);}
80% {filter: grayscale(100%);}
100% {filter: grayscale(0%);}
}
<img src="http://placekitten.com/190/190" />
The animation takes 5 seconds in total.
For the first 4 seconds, the image is black and white.
During the last second, the image transitions to full color.
I hope this code helps
<script type="text/JavaScript">
var picCount=0; // global
var picArray= ["Header1.png","Header1.jpg"]
// Replace your original image names here
// gets next picture in array
function nextPic()
{ // check if adding 1 exceeds number of pics in array
picCount=(picCount+1<picArray.length)? picCount+1 : 0;
// build the img to write to page using the new pic reference
var build='<img border="0" src="'+picArray[picCount]+'" width="200" height="200">';
document.getElementById("imgHolder").innerHTML=build;
// repeat this after a puse of 2000ms (2sec).
setTimeout('nextPic()',2000)
}
</script>
Add this to your html page
<body onload="setTimeout('nextPic()',2000)">
<div id="imgHolder">
<img border="0" src="Header1.jpg" width="300" height="300">
</div>
If I assumed correctly, the first image is desaturated version of the second image so only one image is needed here: the colored one. To turn it into a bw image simply use grayscale filter:
img.desaturate {
filter: grayscale(100%);
}
and add this class to your image:
<img id="myimage" src="image.jpg" class="desaturate">
if you want an "animation" you can forget the classes and dynamically add the style via jQuery:
$("#myimage").css("style","filter: grayscale("+(bytesLoadeed/bytesTotal*100)+"%);");

Can you get the "state" of cover using element

So was playing around with the idea that I would move my background image around a bit. Very fancy, and relatively easy to do.
Problem is that my background image is currently set to cover. (background-size:cover;)
I can get the css settings as follows:
var pageElement = document.getElementById("page");
var curLeft = pageElement.style.left;
var newLeft = posIndex[current] * 10 ;
In this case I am only getting the css setting for left, but is there a way to figure out what cover have done.
Basically, I would love to get an idea if it made the image taler and wider by 20% or anything like that, so I know how much width I can slide the image.
I guess in theory I could make an educated guess with code. Or maybe just ignore it all together, shift the image based on width alone, hope the rendering takes care of the rest.
If I understand you correctly, you can tell how much the image size has changed based on the known behavior of "cover" and the element with the background as long as you know the original image size:
//Original size
var size={w:120, h:120};
//Check the difference between the element dimensions and the original size
var diff={w:el.offsetWidth/size.w, h:el.offsetHeight/size.h}
//Whichever one is higher is your new image ratio
if(diff.w > diff.h) var ratio = diff.w*100;
var ratio = diff.h*100;
Hope this helps.
You can make it bigger by setting background-size to higher percentage than 100%.
You can move it with position values from 0(left/top edge) to 100% (right/bottom edge).
#keyframes example {
0% {
background-position: 50% 50%;
}
20% {
background-position: 0% 20%;
}
40% {
background-position: 30% 100%;
}
60% {
background-position: 100% 10%;
}
100% {
background-position: 50% 50%;
}
}
.img {
width: 300px;
height: 200px;
animation: example 5s infinite;
background: url(https://upload.wikimedia.org/wikipedia/commons/9/9a/Gull_portrait_ca_usa.jpg) no-repeat;
background-size: 120%;
background-position: 30% 20%;
}
<div class="img">
<div>

Categories