How to use setInterval to enlarge image - javascript

I want to achieve when an image is clicked then it will enlarge for a set amount of time. So far I'm up to here in my JS but it doesn't work
var image = document.getElementById('pic');
function enlarge() {
image.style.height="600px";
}
image.onclick =enlarge;
After I tried to implement.
var image = document.getElementById('pic');
function enlarge() {
image.style.height="600px";
}
image.onclick = setInterval(enlarge; 1000);
How should I implement this? JSFIDDLE

Using setInterval
We want 60fps, so each frame would be 1000 / 60 which equals about 16.667ms long. We need to enlarge the height by 500px. 500 / 60 equals to 8.334. So we need an interval of 16.667 ms, and every iteration, enlarge the image by 8.334px, and stop when the height reaches 600px:
var images = document.querySelectorAll('.pic');
images.forEach(function(image) {
image.addEventListener('click', enlarge);
});
function enlarge(e) {
var image = e.target;
var interval;
var height = 100;
interval = setInterval(function() {
height += 8.334;
if(height >= 600) {
height = 600;
clearInterval(interval);
}
image.style.height = height + 'px';
}, 16.667);
}
.pic {
width: 100px;
height: 100px;
vertical-align: top;
}
<img src='https://placehold.it/100x100' class='pic'>
<img src='https://placehold.it/100x100' class='pic'>
Using requestAnimationFrame
A better way of doing it, will use requestAnimationFrame() that produces smoother animations. According to MDN:
The window.requestAnimationFrame() method tells the browser that you
wish to perform an animation and requests that the browser call a
specified function to update an animation before the next repaint.
The math stays the same, but requestAnimationFrame will handle the calling the next frame after 16.667ms.
var images = document.querySelectorAll('.pic');
images.forEach(function(image) {
image.addEventListener('click', enlarge);
});
function enlarge(e) {
var image = e.target;
var interval;
var height = 100;
function enlargeInner() {
height += 8.334;
if(height >= 600) {
height = 600;
}
image.style.height = height + 'px';
height < 600 && requestAnimationFrame(enlargeInner);
}
enlargeInner();
}
.pic {
width: 100px;
height: 100px;
vertical-align: top;
}
<img src='https://placehold.it/100x100' class='pic'>
<img src='https://placehold.it/100x100' class='pic'>

You just assign same height in an interval. You need to increment it, like:
image.style.height = (+image.style.height + 600) + "px";
But I guess it is not your goal, as it will make your image grow 600px every second. I think what you are looking for is just making it bigger to actual point of size? If so, try using CSS transition combined with javascript, like:
CSS:
img {
width: 300px;
height: 300px;
-webkit-transition: width 1s linear, height 1s linear;
transition: width 1s linear, height 1s linear;
}
.enlarged {
width: 600px;
height: 600px;
}
JS:
document.getElementById('pic').addEventListener("click", function(e){
this.classList.toggle("enlarged");
}

setInterval() only won't work.
Basically what your code is doing, that it waits 1000 milliseconds, and runs the enlarge function.
(by the way, you have a typo, at the last line, there should be a comma between enlarge and 1000)
The way I would do it is to add a css class with an animation, and then add that class to the image on click.
let myImg = document.getElementById("img1");
myImg.addEventListener("click", () => myImg.classList.toggle("enlarge"));
/*
The code above is using ES6 (the newest version of JavaScript) and and a thing called an arrow function. If you don't get it, here is the "normal way" to do it. It will do exactly the same as the above code.
var myImg = document.getElementById("img1");
myImg.addEventListener("click", function(){
myImg.classList.toggle("enlarge")
});
*/
#img1 {
transition: 1s
}
.enlarge {
width: 300px;
height: 300px;
}
<img id="img1" src="https://foswiki.org/pub/Support/Glossary/600px-Example.svg.png" width="100px" height="100px">

I forked your fiddle.
You need to change the way you're approaching the click event like so:
function enlarge() {
setInterval(function() {
// do stuff
}, 1000)
}
image.onclick = enlarge;

Related

Zoom on Scroll Down & Scroll up the zoomed element when scale is more than full screen

I tried to make zoom in Zoom out on scroll. The element is zooming on scrolling but I want to make it(the zoomed element) go up once it reached the full width of the screen.
Here's my code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
.zoom{
height:100vh;
width:100%;
display:grid;
place-items:center;
position:fixed;
top:0;
left:0;
background: url('img/bg.png');
}
.afterzoom{
height: 200vh;
background: red;
}
</style>
</head>
<body>
<div class="zoom">
<!-- <h1>Zoom meeeee</h1> -->
<img src="img/square.png" alt="">
</div>
<div class="afterzoom"></div>
<script>
const zoomElement = document.querySelector(".zoom");
let zoom = 1;
const ZOOM_SPEED = 0.1;
document.addEventListener("wheel", function(e) {
if(e.deltaY > 0){
if (zoomElement.style.transform >= `scale(5)`) {
console.log("now scroll down");
return false;
}
zoomElement.style.transform = `scale(${zoom += ZOOM_SPEED})`;
}else{
if (zoomElement.style.transform == `scale(1)`) {
// console.log("minus");
return false;
}
zoomElement.style.transform = `scale(${zoom -= ZOOM_SPEED})`; }
});
</script>
</body>
</html>
Fiddle: https://jsfiddle.net/mayureshpitale/6etpn0vs/3/
I am trying to make something like this: http://truegossiper.com/vilson17/
A bit of a different approach using the scroll event and window.scrollY for positioning together with requestAnimationFrame (RAF).
This also works, if the image (or other content) is not squared.
The problem with the wheel event is, that it does not trigger when the user uses the scrollbar or arrow keys to scroll the page.
The problem with the scroll event is, that it executes a lot... that's why RAF is used, to only execute necessary zoom changes.
Keep in mind, this exact code works with the document width when the page is loaded. If the user resizes the window or changes the browsers zoom, the element will resize to the same scale as before. You could fix this with some extra code by using a ResizeObserver. (Remove the existing event listener, resize the Image and execute parts of the code again, every time the document is resized...)
You will notice this, when you try to view the below snippet as full page.
const zoomElement = document.querySelector('.zoom')
const fadeElement = document.querySelector('.fade')
const afterZoomElement = document.querySelector('.afterzoom')
const imgElement = document.querySelector('img')
const WIDTH = document.body.clientWidth
const HEIGHT = zoomElement.clientHeight
const IMAGE_WIDTH = imgElement.clientWidth
const IMAGE_HEIGHT = imgElement.clientHeight
const ZOOM_SPEED = 100 // Lower is faster
const ZOOM_BREAKPOINT = WIDTH / IMAGE_WIDTH // When it should stop zooming in
const IMAGE_HEIGHT_MAX = IMAGE_HEIGHT * ZOOM_BREAKPOINT
const ABSOLUTE = ZOOM_BREAKPOINT * ZOOM_SPEED // Absolute position, when the Element reached maximum size
// Fade --------------------------------------------------------------------------------------
const FADE_SPEED = 500 // Lower is faster
let fade = 1
let prev = 0
// -------------------------------------------------------------------------------------- Fade
function anim() {
let scroll = window.scrollY
let temp = scroll / ZOOM_SPEED
let zoom = temp > 1 ? temp : 1
// Only update the Elements scale, when we are below the breakpoint
if (zoom < ZOOM_BREAKPOINT) {
// Only scale the Image, so the Zoom element does not mess with the document width
imgElement.style.transform = `scale(${zoom})`
// Sets the Elements position to fixed, so it can resize without scrolling away
zoomElement.style.top = '0px'
zoomElement.style.position = 'fixed'
} else {
// Makes sure the Element always reaches Max Size
imgElement.style.transform = `scale(${ZOOM_BREAKPOINT})`
// Sets the elements position to absolute, so it will scroll with the rest of the document
zoomElement.style.position = 'absolute'
zoomElement.style.top = ABSOLUTE + 'px'
}
// Fade --------------------------------------------------------------------------------------
let dif = prev - scroll
if (zoom < ZOOM_BREAKPOINT - FADE_SPEED / ZOOM_SPEED) {
fade = 1
} else if (zoom > ZOOM_BREAKPOINT) {
fade = 0
} else {
fade += dif / FADE_SPEED
}
fadeElement.style.opacity = fade
prev = scroll
// -------------------------------------------------------------------------------------- Fade
}
// Resets scroll position on every reload
if ('scrollRestoration' in history) {
history.scrollRestoration = 'manual'
}
document.addEventListener('scroll', () => window.requestAnimationFrame(anim))
// Fade --------------------------------------------------------------------------------------
zoomElement.style.opacity = 1
// -------------------------------------------------------------------------------------- Fade
// Positions the afterZoom element right below the zoomed image
afterZoomElement.style.top = ABSOLUTE + IMAGE_HEIGHT_MAX / 2 + HEIGHT / 2 + 'px'
body {
margin: 0;
}
img {
width: 150px;
height: 150px;
background-color: black;
}
.fade {
height: 100vh;
width: 100%;
position: fixed;
top: 0;
left: 0;
background: blue;
}
.zoom {
height: 100vh;
width: 100%;
display: grid;
place-items: center;
position: fixed;
top: 0;
left: 0;
}
.afterzoom {
position: absolute;
height: 200vh;
width: 100%;
background: red;
overflow-x: auto;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<div class="fade"></div>
<div class="zoom">
<img src="https://via.placeholder.com/150" alt="">
</div>
<div class="afterzoom">
<p>This should appear after the above element is fully zoomed.</p>
</div>
</body>
I got a bit carried away during coding and added some fading-in and -out to the blue background. Not necessary, but looks nice. You can remove the Fade ----- Fade parts of the code, without affecting functionality.
To alter zoom and fade speed, simply change the ZOOM_SPEED and FADE_SPEED variables.

Stuttery CSS animation for enlarging images in Safari

I am trying to create an animation which takes a image that is anywhere on a page and moves it to the middle while resizing it to full width of the browser window. My solution works, but has some stutters/jumps in it, which I can't really explain. Is there anyone who has tried creating a similar animation already? EDIT: I noticed that the stutter problem only seems to appear in macOS Safari. In other browsers this animation appears to run perfectly smooth.
Here is my js code:
function getWindowWidth() {
return document.documentElement.clientWidth
}
function getWindowHeight() {
return document.documentElement.clientHeight;
}
//at the moment this is hacky and only supports one image to be enlarged
let en_img_left = null;
let en_img_top = null;
function enlargeImage(img) {
let boundingClientRect = img.getBoundingClientRect();
img.style.position = "fixed";
en_img_top = boundingClientRect.y + "px";
img.style.top = en_img_top;
en_img_left = boundingClientRect.x + "px";
img.style.left = en_img_left;
img.style.width = boundingClientRect.width + "px";
img.style.zIndex = "1000";
setTimeout(function() {
img.style.transition = "1s ease-in-out";
setTimeout(function() {
let scaleFactor = getWindowWidth() / boundingClientRect.width;
img.style.transform = "scale(" + scaleFactor + ")";
img.style.left = getWindowWidth() / 2 - (boundingClientRect.width / 2) + "px";
img.style.top = getWindowHeight() / 2 - boundingClientRect.height / 2 + "px";
}, 1);
}, 1);
return img;
}
function delargeImage(img) { //sorry for the function name
img.style.transition = "1s ease-in-out";
setTimeout(function() {
img.style.transform = "scale(1)";
img.style.left = en_img_left;
img.style.top = en_img_top;
}, 1);
return img;
}
example HTML+CSS code, but it can be any image with an ID on a website:
HTML:
<div class="container">
<img id="example" style="width: 100%" src="https://images.pexels.com/photos/1361815/pexels-photo-1361815.jpeg?cs=srgb&dl=blur-bokeh-close-up-1361815.jpg&fm=jpg">
</div>
CSS:
.container {
width: 200px;
}
I also made a jsfiddle displaying the stutter problem quite nicely:
https://jsfiddle.net/robske_110/vhz5Ln4o/11/
You are not using CSS animations or transitions!
The animation itself is executed through JavaScript in your example. Instead of computing every single step of an animation in JS and setting a new CSS property on each iteration, you should setup a CSS animation with the desired start- and end-states or define the properties, that should be transitioned. This way the animation should look smooth while transitioning.
Your example using a CSS transition (without any JS code):
.container {
width: 200px;
transition: width ease-in 1s;
}
.container:hover {
width: 80vw;
}
.container img {
width: 100%;
}
<div class="container">
<img id="example" src="https://images.pexels.com/photos/1361815/pexels-photo-1361815.jpeg?cs=srgb&dl=blur-bokeh-close-up-1361815.jpg&fm=jpg">
</div>

Javascript transition works only after second hover

I am new to Javascript. I want to make my image gradually get smaller, and then resize back to its original size. What I have works, but only after hovering over the image 2 times or more.
To be clearer, when I hover my mouse over the image for the first time, it makes a very abrupt transition, but works after that. It did the same thing when using CSS instead.
What I have is this:
function enlargeImage() {
var logo = document.getElementById('logoname');
logo.style.opacity = '0.7';
logo.style.height = 'auto';
logo.style.width = '800px';
logo.style.transition = '0.7s';
}
function resizeImage() {
var logo = document.getElementById('logoname');
logo.style.opacity = '1';
logo.style.height = 'auto';
logo.style.width = '900px';
}
Should this work? Or have I coded in a way in which I shouldn't have?
Personally I like to leave animations and effects like these to CSS and leave the functionality to Javascript.
#yourImage {
width: 150px;
height: 150px;
transition: transform .25s ease, opacity .5s ease;
}
#yourImage:hover {
opacity: 0.5;
transform: scale(0.5);
}
<img src="http://www.w3schools.com/css/trolltunga.jpg" alt="" id="yourImage">
When the image is hovered over I transform and resize the image to 0.5% of it's original size and 0.5% of it's original opacity.
I am also using the transition property to set how fast the image transitions when it is resized or when the opacity is changed.
The abruption was because of the height tag inside javascript code. change this
height: auto
Into height:400px or some value instead of auto.
function enlargeImage() {
var logo = document.getElementById('logoname');
logo.style.opacity = '0.7';
logo.style.height = '300px';
logo.style.width = '400px';
logo.style.transition = '0.7s';
}
function resizeImage() {
var logo = document.getElementById('logoname');
logo.style.opacity = '1';
logo.style.height = '600px';
logo.style.width = '600px';
logo.style.transition = '0.7s';
}
img {
height:300px;
width:400px;
}
<img onmouseover="resizeImage()" onmouseout="enlargeImage()" src='http://imgsv.imaging.nikon.com/lineup/lens/zoom/normalzoom/af-s_dx_18-140mmf_35-56g_ed_vr/img/sample/sample1_l.jpg' id="logoname">

Smoother scroll transitions in firefox?

I'm trying to create a parallax effect in firefox by modifying the top position of elements using the onscroll event. I throttled the onscroll event so it doesn't overload the browser and I added a transition top property in the css to make things smoother. This works pretty well in every browser, but firefox is extremely choppy for some reason. Is there any way to make this transition smoother?
window.onscroll = throttle(function(){
var scrollDistance = window.pageYOffset || window.document.documentElement.scrollTop || window.document.body.scrollTop;
document.getElementById("back").style.top = -scrollDistance * 0.3 + "px";
document.getElementById("mid").style.top = -scrollDistance * 0.5 + "px";
document.getElementById("fore").style.top = -scrollDistance * 0.9 + "px";
}, 100);
function throttle (callback, limit) {
var wait = false;
return function () {
if (!wait) {
callback.call();
wait = true;
setTimeout(function () {
wait = false;
}, limit);
}
}
}
body{
height: 5000px;
background: url(http://lorempixel.com/output/city-q-c-1920-1920-4.jpg);
}
.parallaxEl {
width: 1920px;
height: 1080px;
position: fixed;
transition: top 0.1s;
}
#back{
background: url(http://wall.rimbuz.com/wp-content/uploads/4K-Wide-Wallpapers.jpg);
}
#mid{
background: url(https://wallpaperscraft.com/image/space_planet_background_83807_3840x2160.jpg);
}
#fore{
background: url(http://wall.rimbuz.com/wp-content/uploads/4K-HD-Background-Wallpapers.jpg);
}
<body>
<div class="parallaxEl" id="back"></div>
<div class="parallaxEl" id="mid"></div>
<div class="parallaxEl" id="fore"></div>
</body>
http://codepen.io/anon/pen/NAzBrX
Using requestAnimationFrame, you'll get a smoother throttler.
requestAnimationFrame has the advantage to be synced with the screen refresh rate.
Here is a code demo :
// your callback
var scrollHandler = function() {
var scrollDistance = window.pageYOffset || window.document.documentElement.scrollTop || window.document.body.scrollTop;
document.getElementById("back").style.top = -scrollDistance * 0.3 + "px";
document.getElementById("mid").style.top = -scrollDistance * 0.5 + "px";
document.getElementById("fore").style.top = -scrollDistance * 0.9 + "px";
};
// the throttle function
// returns the function that should be passed has an event listener
var throttle = function(callback) {
// a simple flag
var active = false;
// to keep track of the last event
var evt;
// fired only when screen has refreshed
var handler = function(){
// release our flag
active = false;
// call the callback
callback(evt);
}
// the actual event handler
return function handleEvent(e) {
// save our event at each call
evt = e;
// only if we weren't already doing it
if (!active) {
// raise the flag
active = true;
// wait for next screen refresh
requestAnimationFrame(handler);
};
}
}
// remember to call the function, we need its returned function
window.onscroll = throttle(scrollHandler);
body {
height: 5000px;
background: url(http://lorempixel.com/output/city-q-c-1920-1920-4.jpg);
}
.parallaxEl {
width: 1920px;
height: 1080px;
position: fixed;
transition: top 0.1s;
}
#back {
background: url(http://wall.rimbuz.com/wp-content/uploads/4K-Wide-Wallpapers.jpg);
}
#mid {
background: url(https://wallpaperscraft.com/image/space_planet_background_83807_3840x2160.jpg);
}
#fore {
background: url(http://wall.rimbuz.com/wp-content/uploads/4K-HD-Background-Wallpapers.jpg);
}
<body>
<div class="parallaxEl" id="back"></div>
<div class="parallaxEl" id="mid"></div>
<div class="parallaxEl" id="fore"></div>
</body>
The event 'onscroll' is caused after a scroll, and the event 'onmousewheel' ('onwheel') is caused after a scroll. For a scroll using a mouse animation will be more smoothly.
Example here: excube.hol.es
When possible you should use CSS 3D Transforms for animation because it has access to a users GPU and allows for smoother animation.
Hardware Acceleration and CSS Animation
https://www.sitepoint.com/introduction-to-hardware-acceleration-css-animations/
Also, here is an example of a basic parallax effect using this technique...
https://css-tricks.com/tour-performant-responsive-css-site/#article-header-id-2

how can we increase the width of an element when the width value is dynamically changing?

first of all i want to say that the following function is by chance and by this i mean that its functioning is very strange:
function x (e,s,v){ // e =element, s = desired size of an element, v = speed
var div = document.getElementById(e),
width = 0;
for(var i =0; width<s; i++){
if(i%v === 0){
width = width+1;
div.setAttribute('style', 'width:'+width+'px;');
}else{
width = width +0;
}
};
};
this function is working perfectly and doing what i want but the problem is that the width is changing at once when the working of this function is finished.
in detail
i want that the width of an element increase smoothly, increase 'one' by 'one' px. so i made this function.
there is an if statement because if i didn't put that there then the width of that element would increase at once. that if statement delay the time between the adding of two pixels
but now the problem is that it is adding pixels one by one but the width is increasing at once after the completion of the function.
for example if i write in console x('aynElement', 500, 100) then it is adding pixels one by one but the width of the element is increasing at once when the function stop functioning
you can see this yourself in console
link to JsFiddle for full code
secondly
the problem is that this is strange. you had absolutely felt weird after reading this function. please anyone explain me this weirdness.
thanks
You can use setTimeout() to do this.
function x(e, s, v) { // e =element, s = size of an element, v = speed
var div = document.getElementById(e),
width = 0;
for (var i = 0; i < (s - width); i++) {
setTimeout(function() {
div.setAttribute('style', 'width:' + width+++'px;');
}, i * (1 / (v * 0.01)));
};
};
x('d1', 400, 10)
#d1 {
width: 100px;
height: 100px;
background-color: #aaa;
}
<body>
<div id="d1" style="width:200px;"></div>
</body>
I think this would solve it better (might need the one or other adjustment, just a quick scrape):
DEMO
setInterval(function(){
grow('id',250) //set your parameters here
}, 100); //this is the speed - the lower the quicker
var width = 1;
function grow(e,s) {
document.getElementById('d1').style.width = width+"px";
width++;
};
setInterval(function(){
grow('id',500)
}, 10);
var width = 250;
function grow(e,s) {
document.getElementById('d1').style.width = width+"px";
width++;
};
#d1{
height: 100px;
background-color: #000;
}
<body>
<div id="d1" ></div>
</body>

Categories

Resources