I want to make an image zoom effect on my project. When the user clicks on that image I want image to be zoom. But the problem is that the div which I create dynamically is appended top of the body what I want is append this div above that image.
I try something like this:-
export const imagezoom = () => {
const image = document.querySelectorAll(".zoom");
image.forEach((e) => {
e.addEventListener("click", zoom);
});
};
function zoom(event) {
const div = document.createElement("div");
const container = document.querySelector("body");
div.classList.add("zoomDiv");
const img = document.createElement("img");
img.src = this.src;
img.classList.add("zoomImage");
console.log("added");
div.appendChild(img);
container.appendChild(div);
}
.zoomDiv {
position: absolute;
top: 100%;
left: 0;
width: 100%;
height: 100%;
z-index: 11;
background-color: black;
transition: all 250ms ease-in;
display: flex;
justify-content: center;
align-items: center;
animation-name: zoom;
animation-duration: 0.6s;
}
.zoomImage {
width: 80%;
height: 80%;
z-index: 11;
animation-name: zoom;
animation-duration: 0.6s;
object-fit: contain;
}
#keyframes zoom {
from {
transform: scale(0);
}
to {
transform: scale(1);
}
}
<img class="zoom" src="../../../assets/Subject/physics/8.png" alt="" />
Here's what you do.
Put the image in a div. Make sure the image uses all the space in the containing div.
Set the position of that div to "relative".
Use
var x = evt.pageX - $('#element').offset().left;
var y = evt.pageY - $('#element').offset().top;
To get the position of the mouse relative to the div container you put your image in. Make sure the dynamically generated image position to "absolute".
Use x and y to set the left and top CSS properties dynamically.
I don't probably think I understood what you are trying to do but according to this title How to add dynamic div on that position where i clicked try the following.
Add some JavaScript on your clickable image where you want to zoom
Example
var x = document.querySelector('clickable_image');
x.addEventListener('click', e => {
image.style.setProperty('--x',e.clientX + 'px');
image.style.setProperty('--y',e.clientY + 'px');
});
and if you already done to set the above properties ad them in your CSS first of all add position: absolute; and add the following where --y is for top and --x for left
.clickable_image {
position: absolute;
top: var(--y);
left: var(--x);
}
the above will positioning that div to where you clicked
Related
Ok so here's a challenge: I'm looking to rotate a fixed element when you scroll up and down inside a < div > - and not when you scroll on the entire page. So how do i target the scroll within a specific < div> (my div has classname="elementor")?
My code so far looks like this:
HTML
/* The image i'm trying to rotate */
<img class="portfolio" id="rotatelogo" src="http://jakobnatorp.com/wp-content/uploads/2021/10/cropped-JAKOB-LERCHE-DAA-NATORP.png"/>
/* And a div container with class="elementor" */
CSS
.portfolio {
position: fixed;
width:150px;
height:150px;
margin-top:50px;
margin-bottom:-300px;
margin-left:50px;
}
.elementor {
width: 100vh;
height: 100vw;
overflow-x: scroll;
overflow-y: scroll;
transform: rotate(-90deg) translateX(-100vh);
transform-origin: top left;
-ms-overflow-style: none;
}
JS
var element = document.getElementsByClassName("elementor")[0]
var elem = document.getElementById("rotatelogo");
element.addEventListener('scroll', function() {
var value = element.scrollY * 0.25;
elem.style.transform = `translatex(-50%) translatey(-50%) rotate(${value}deg)`;
});
Edit: I changed the code and it works now. I replaced the "scrollY" with "scrollTop". My new JS looks like this:
var element = document.getElementsByClassName("elementor")[0]
var elem = document.getElementById("rotatelogo");
element.addEventListener('scroll', function() {
var value = element.scrollTop * 0.25;
elem.style.transform = `translatex(-50%) translatey(-50%) rotate(${value}deg)`;
});
If I understand it right, you could select the element you'r adding an event to.
Something like :
const scrollDiv = document.querySelector(".scrollOnMe");
scrollDiv.addEventListener("wheel", () => {
console.log("Scrolling !");
})
div {
height: 30px;
}
.scrollOnMe {
background-color: green;
}
.foo {
background-color: red;
}
<div class="scrollOnMe">Scroll on me !</div>
<div class="foo">Don't :(<div>
I am trying to animate images using CSS on a webpage. The animation is working fine but I want to START the animation it only when user reaches at a particular section of the page. Here is my code:
<div class="sec1-right">
<img class="sec1-dmush1" src ="sec1-dmush1.png">
</div>
CSS
.sec1-right{
position: relative;
width: 50%;
float: right;
box-sizing: border-box;
min-height: 600px;
margin-top: 86px;
}
/* first section animation */
.sec1-dmush1 {
animation: fadeAndScale .9s cubic-bezier(.45,-0.22,.34,1.69);
transform-origin:center bottom;
max-width: 150px;
width: 100%;
position: absolute;
left: 180px;
top: 300px;
z-index: 0;
}
Animation
#keyframes fadeAndScale{
from{
opacity:0;
transform: scale3d(0,0,1);
}
to{
opacity: 1;
transform: scale3d(1,1,1);
}
}
How can I achieve
You need to write scroll event in javascript. element offsetTop minus window height. So as soon as element comes in viewport event starts.
Javascript:
var scrollpos = window.scrollY; // window scroll position
var wh = window.innerHeight-50; // as soon as element touches bottom with offset event starts
var element = document.querySelector(".sec1-dmush1"); //element
window.addEventListener('scroll', function(){
if(scrollpos > (element.offsetTop - wh)){
element.classList.add("onScroll");
}
});
JsFiddle
jQuery:
$(window).scroll(function(){
var wh = $(window).height()-50;
if($(window).scrollTop() > $('.sec1-dmush1').offset().top-wh){
$('.sec1-dmush1').addClass('onScroll');
}
});
jsFiddle
If you have multiple elements to animate. You can use waypoint js to reduce some efforts.
var wh = $(window).height();
var waypoints = $('.sec1-dmush1').waypoint(function(direction) {
$(this.element).addClass('onScroll');
console.log(11);
}, {
offset: wh-50
});
jsFiddle
using javascript you can find the scroll event . After the specific px(height). You can add a class to the existing class(jquery) for which you trying to animate.
The problem with my slider is that when it gets to the last slide and i click next it jumps over the two slides to get to the first one. Similarly when i am on the first slide and click previous, it jumps over slides to get to the last one. I would like to make it that when i get to the last slide and click NEXT the first slide would come from the right to left. (similar concept for the PREVIOUS button on first slide). I tried using insertBefore() and appendChild() for the slides but couldn't figure it out...
Here is my code:
// Slider
const slider_wrapp = document.querySelector('.tract-slider');
const slider = document.querySelector('.tract-slider-wrapp');
var slide = document.getElementsByClassName('tract-slide');
const leftBtn = document.querySelector('.slide-left');
const rightBtn = document.querySelector('.slide-right');
let swWidth = slider_wrapp.clientWidth;
let sliderWidth = swWidth * slide.length;
let slideWidth = 0;
slider.style.width = sliderWidth + "px";
for (var i = 0; i < slide.length; i++) {
slide.item(i).style.width = swWidth + "px";
}
function moveRight() {
slideWidth === sliderWidth - swWidth ? slideWidth = 0 : slideWidth += swWidth;
slider.style.transform = "translateX(" + (-slideWidth) + "px)";
}
function moveLeft() {
slideWidth === 0 ? slideWidth = sliderWidth - swWidth : slideWidth -= swWidth;
slider.style.transform = "translateX(" + (-slideWidth) + "px)";
}
rightBtn.addEventListener("click", function() {
moveRight();
});
leftBtn.addEventListener("click", function() {
moveLeft();
});
.tract-slider {
width: 100%;
height: 75vh;
position: relative;
overflow: hidden;
}
.tract-slider-wrapp {
height: 100%;
position: relative;
-webkit-transition: all 350ms cubic-bezier(.08, .13, 0, .81);
-o-transition: all 350ms cubic-bezier(.08, .13, 0, .81);
transition: all 350ms cubic-bezier(.08, .13, 0, .81);
}
.tract-slide {
height: 100%;
float: left;
position: relative;
display: block;
background-position: center;
-webkit-background-size: cover;
background-size: cover;
}
.tract-slide:nth-child(1) {
background-image: url("https://static.pexels.com/photos/126282/pexels-photo-126282.jpeg");
}
.tract-slide:nth-child(2) {
background-image: url("https://static.pexels.com/photos/29017/pexels-photo-29017.jpg");
}
.tract-slide:nth-child(3) {
background-image: url("https://static.pexels.com/photos/70760/dandelion-dandelion-seeds-taraxacum-fluffy-70760.jpeg");
}
.tract-slider-control {
position: absolute;
left: 0;
bottom: 0;
background: #ffffff;
padding: 1em;
}
.tract-slider-btn {
display: inline-block;
cursor: pointer;
margin-left: 1em;
}
.tract-slider-btn:nth-child(1) {
margin-left: 0;
}
<div class="tract-slider">
<div class="tract-slider-wrapp">
<div class="tract-slide"></div>
<div class="tract-slide"></div>
<div class="tract-slide"></div>
</div>
<div class="tract-slider-control">
<div class="tract-slider-btn slide-left">Prev</div>
<div class="tract-slider-btn slide-right">Next</div>
</div>
</div>
PS. Please use JavaScript for solution
Creating an infinite slider means you need to move your slides around in DOM so they give the impression of a continuous track.
The first thing you need to change is having their backgrounds tied up to their position in DOM. If we want to slide back from first slide to the last one, we need to take the last slide, prepend it before the first one but, considering your current CSS, that will change the backgrounds of all slides, as they are currently bound to their position in DOM (...:nth-child {background-image:...}...).
The second thing that needs changing is positioning the slides into the slider track. If they're floated, whenever we change their order, all the rest of the slides will be affected. By positioning them with position:absolute each slide moves independently, without affecting the others, so it's easier to rearrange them while keeping control.
Long story short, I started from scratch and placed all methods inside a single object: theSlider.
The reset() function does the heavy lifting: it puts before class on first element, current on second and after on all the rest. So you have to put the "last" slide first, because the slider will start with it appended before the "current" one.
The sliding is done by applying go-left and go-right classes to the track. After the transition is done, I just move the first/last slide into the new position, depending on case, and run reset() again (which strips all classes and reapplies them based on new positions).
Animations are handled by CSS. All JavaScript does is apply/remove classes and move the slides in DOM.
var theSlider = {
track : document.querySelector('.tract-slider-wrapp'),
// has to match `transition-duration` in CSS:
duration : 600,
reset : function() {
var slides = document.querySelectorAll('.tract-slider-wrapp > div');
for (var i = 0; i < slides.length; i++) {
slides[i].className = '';
slides[i].classList.add(i > 1? 'after' : (i ? 'current':'before'))
}
},
init : function() {
theSlider.reset();
theSlider.track.classList.remove('not-loaded')
},
next : function() {
theSlider.track.classList.add('go-right');
setTimeout(function(){
var firstSlide = document.querySelector('.tract-slider-wrapp > div:first-child');
theSlider.track.appendChild(firstSlide);
theSlider.reset();
theSlider.track.classList.remove('go-right')
},theSlider.duration)
},
prev : function() {
theSlider.track.classList.add('go-left');
setTimeout(function() {
var lastSlide = document.querySelector('.tract-slider-wrapp > div:last-child');
theSlider.track.insertBefore(lastSlide, theSlider.track.firstChild);
theSlider.reset();
theSlider.track.classList.remove('go-left')
},theSlider.duration)
},
prevButton : document.querySelector('.slide-left'),
nextButton : document.querySelector('.slide-right')
};
window.addEventListener("load", theSlider.init);
theSlider.prevButton.addEventListener('click', theSlider.prev);
theSlider.nextButton.addEventListener('click', theSlider.next);
.tract-slider {
width: 100%;
height: 75vh;
position: relative;
overflow: hidden;
background-color: #f5f5f5;
}
.tract-slider-wrapp {
height: 100%;
transition: all 350ms cubic-bezier(.08, .13, 0, .81);
opacity: 1;
}
.tract-slider-wrapp.not-loaded {
opacity: 0;
}
.tract-slider-wrapp>div {
height: 100%;
position: absolute;
background: transparent no-repeat 50% 50% /cover;
width: 100%;
}
.tract-slider-wrapp > div.before {
margin-left: -100%;
}
.tract-slider-wrapp > div.current + div {
margin-left: 100%;
}
.tract-slider-wrapp > div.after ~ div {
opacity: 0;
}
.tract-slider-control {
position: absolute;
width: 100%;
z-index: 1;
top: 50%;
display: flex;
justify-content: space-between;
transform: translateY(-50%);
}
.tract-slider-control div {
background-color: rgba(0,0,0,.35);
padding: .5rem 1rem;
color: white;
cursor: pointer;
}
.tract-slider-control :first-child {
border-radius: 0 17px 17px 0;
}
.tract-slider-control :last-child {
border-radius: 17px 0 0 17px;
}
body {
margin: 0;
}
.go-right div {
transform: translateX(-100%);
}
.go-left div {
transform: translateX(100%);
}
.go-right div, .go-left div {
transition-property: transform;
transition-timing-function: cubic-bezier(.4,0,.2,1);
/* has to match `duration` in js: */
transition-duration: 600ms;
}
<div class="tract-slider">
<div class="tract-slider-wrapp not-loaded">
<div style="background-image:url('https://static.pexels.com/photos/126282/pexels-photo-126282.jpeg')"></div>
<div style="background-image:url('https://static.pexels.com/photos/29017/pexels-photo-29017.jpg')"></div>
<div style="background-image:url('https://static.pexels.com/photos/70760/dandelion-dandelion-seeds-taraxacum-fluffy-70760.jpeg')"></div>
</div>
<div class="tract-slider-control">
<div class="tract-slider-btn slide-left">Prev</div>
<div class="tract-slider-btn slide-right">Next</div>
</div>
</div>
If you want to change the animation duration you need to change it in both js and css.
The only current limitation is it needs at least 3 slides to work. I guess it could be adjusted to work with only two slides by: cloning the "inactive" slide into third position, removing the clone after transition and cloning the other one.
ToDo's:
prefix CSS so it works in more browsers
replace .classList.add('whatever') with .className += ' whatever' and
.classList.remove('whatever') with .className.replace('whatever', '') if you want to show IE some love.
I told the above just to tell you this: if you want to get going, don't reinvent the wheel.
It's great you use vanilla javascript. But sooner or later you'll end up writing your own wrappers for common things. Depending on how good you are/have become, you'll write your own, limited, custom version of jQuery. Allow me to put things into perspective: Google included a lite version of jQuery into AngularJS. It's that good.
You, as an single developer, do not stand a chance at writing a better, more streamlined and tested version of it. And besides, you don't have to. Use your skill and abilities to go forward, not sideways.
I am developing a chrome extension which on any hover over an image it should popout a box over the image and the image should be zoomed to 1.5 times the original image.
So I started working on examples and found a similar example like this.
.zoomin img {
height: 200px;
width: 200px;
-webkit-transition: all 2s ease;
-moz-transition: all 2s ease;
-ms-transition: all 2s ease;
transition: all 2s ease;
}
.zoomin img:hover {
width: 300px;
height: 300px;
}
<div class="zoomin">
<img src="http://www.corelangs.com/css/box/img/zimage.png" title="All you need to know about CSS Transitions " />
</div>
But instead i need to create a box without zooming the image on hover. So in my exercise using this Using only CSS, show div on hover over <a> i have developed this.
main.js
div {
display: none;
}
img:hover + div {
display: block;
height : 200px;
width : 300px;
}
But the problem is that the size of the image should be dynamically adjusted based on the image we are hovering.
Is there a way to make this work when we hover over an image it should automatically make a div which should hold 1.5 times the dimensions of the image.Any suggestions.?Please help
I have included the screenshot below for reference.
img:hover div {
display: block;
var img = document.getElementById('imageid');
// get the image dimensions using this id
var width1 = img.clientWidth;
var height1 = img.clientHeight;
height : width * 1.5;
width : height * 1.5;
}
You need to just remove
+
because it selects immediate next div element to img.
I guess you should try:
img:hover ~ div
{
//your height and width goes here
}
I think this is the sort of thing you wanted.
I don't think you can do this with CSS only (though would love to be wrong)
I've done a for loop to add an event listener on for when you mouse over and off an image in .zoomin. Then it sets the image source accordingly.
var zoominSel = document.querySelectorAll(".zoomin img");
var zoomContSel = document.querySelector(".zoomcont img")
for (let i = 0; i < zoominSel.length; i++) {
zoominSel[i].addEventListener("mouseover", function(event) {
zoomContSel.setAttribute('src', event.target.getAttribute('src'));
zoomContSel.style.width = event.target.offsetWidth + "px";
zoomContSel.style.height = event.target.offsetHeight + "px";
zoomContSel.parentElement.style.top = event.target.offsetTop + "px";
zoomContSel.parentElement.style.left = (event.target.offsetLeft + event.target.offsetWidth + 2) + "px";
});
zoominSel[i].addEventListener("mouseout", function(event) {
zoomContSel.setAttribute('src', '');
});
}
body {
margin: 0;
}
.zoomin img {
max-width: 200px;
}
.zoomcont img[src=""] {
display: none;
}
.zoomcont {
z-index: 1000;
position: absolute;
transform: scale(1.5);
transform-origin: 0 0;
}
<div class="zoomin">
<img src="http://www.corelangs.com/css/box/img/zimage.png" />
</div>
<div class="zoomin">
<img src="http://usabilitygeek.com/wp-content/uploads/2013/07/free-fonts-for-commercial-personal-use.jpg" />
</div>
<div class="zoomcont">
<img src="" />
</div>
Hope you find this helpful.
I have a hamburger (three horizontal bars) icon I want to change from float: left to float:right but with a smooth animation.
I can't use jQuery but I can use JavaScript so I have this small function that changes float state when the image is clicked:
var menuButton = document.getElementById('menu-button');
menuButton.onclick = function () {
menuButton.style.float = "right";
}
So this works but not smooth animation how can I make it a smooth animation?
A running demo:
var menuButton = document.getElementById('menu-button');
menuButton.onclick = function () {
menuButton.style.float = "right";
}
nav {
background: pink;
height: 60px;
}
nav #menu-button {
margin: 20px 24px;
display: inline;
float: left;
}
<nav id="nav-bar">
<img id="menu-button"alt="menu icon" src="images/toggle-open.svg">
</nav>
If you know the width of your container, do not use float properties but margin-left :
a {
margin-left: 0;
transition: margin-left 1s ease-in-out;
}
a.right{
margin-left: 400px; /* change for good value */
}
Then add right class to your a element with javascript
https://jsfiddle.net/rd4h4s5h/
Unfortunately, changing left-to-right float can't be simply animated with any current tech, because an animation requires a relative anchor-point from which to perform calculations.
What you could do is animate the relative left-floated position, to an approximated right-floated position (by increasing left-margin, for example), and upon completion, change to a right-float. But really, the last step isn't necessary, except to handle future layout changes to the page (e.g. window resize, for a fluid-width site).
I was able to get this working using CSS3 transitions and marginLeft.
There's a little hackery in the parentElement.parentElement (to climb two levels of the DOM tree), and in the -44px to account for the icon width plus margin width, but if you wanted to, you could write more complex coded solutions to these (handling the element's actual width / margin on the fly).
var menuButton = document.getElementById('menu-button');
menuButton.onclick = function () {
var left = menuButton.parentElement.parentElement.clientWidth - 44;
menuButton.style.marginLeft = left+"px";
window.setTimeout(function() {
menuButton.style.float = "right";
}, 1000);
}
nav {
background: pink;
height: 60px;
}
nav #menu-button {
margin: 20px 24px;
display: inline;
float: left;
/* Width and height hack to represent missing image's height and width */
width: 20px;
height: 20px;
/* CSS Transition added */
-webkit-transition: margin-left 1s;
transition: margin-left 1s;
}
<nav id="nav-bar">
<img id="menu-button"alt="menu icon" src="images/toggle-open.svg">
</nav>
I would do it this way:
<style>
nav {
position: relative;
}
nav a {
position: absolute;
left: 0;
transition: left 1s linear;
}
</style>
<nav id="nav-bar">
<a id="box" href="#/index"><img id="menu-button" alt="menu icon" src="images/toggle-open.svg"></a>
</nav>
<script>
const navBar = document.getElementById("nav-bar");
const box = document.getElementById("box");
const menuButton = document.getElementById("menu-button")
menuButton.addEventListener("click", (e) => {
box.style.left = (navBar.offsetWidth - box.offsetWidth) + "px";
});
</script>