How to make a div move with the mouse cursor smoothly? - javascript

I am trying to achieve the mouse effect on carousel (https://advertising.nytimes.com/custom-content/). the cursor should change when I hover over the container. I got it working but it is stutters a lot. How to make it smooth? the stutter occurs when I add the conditional statement. Please help.
<style>
.img {
width: 100px;
height: 100px;
object-fit: cover;
position: fixed;
top: 0;
left: 0;
}
.container {
width: 700px;
height: 900px;
background-color: orangered;
overflow: hidden;
cursor: none;
}
</style>
<div class="container">
<img
class="img"
src="https://images.unsplash.com/photo-1472457897821-70d3819a0e24?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2669&q=80"
/>
</div>
<script>
const container = document.querySelector(".container");
const img = container.querySelector(".img");
document.addEventListener("mousemove", (e) => {
if (event.target == container) {
img.style.transform = `translate3d(${e.clientX}px, ${e.clientY}px, 0)`;
}
});
</script>

It is as simple as adding a Logical OR next to the event.target == container. It was moving weirdly because when your mouse would go over the image it would not be the target anymore.
To fix this we need to add an ID to the image so we can source it in our event.target. So out <img> would look something like this
<img class="img" id"img" src="https://images.unsplash.com/photo-147245789782170d3819a0e24ixlib=rb4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2669&q=80"/>
After we set the id we are able to add the logical OR statement, it would look like this
event.target == container || picture
Hope I could help!

Related

How to cover the thumbnail of an iframe video 100% to the wrapper in 9:16 aspect ratio?

I am using an iframe tag to play a 9:16 aspect ratio video from my google drive. The iframe is wrapped around a div and the div is styled so that there are no black bars. The video is maintaining its aspect ratio but the thumbnail is not. The thumbnail covers all the wrapper's height but not the width. I want the thumbnail to also maintain the aspect ratio of 9:16.
Also, I did not add a custom thumbnail.
.potrait_9by16
{
position: relative;
overflow: hidden;
width: 100%;
padding-bottom: 177.777%; /* 9:16 Aspect Ratio*/
}
.potrait_9by16 iframe
{
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
width: 100%;
height: 100%;
}
<div className="potrait_9by16">
<iframe
width="100%"
height="100%"
frameborder="0"
src={videoObject.src}
allow="fullscreen"
></iframe>
</div>
Here is an image of the wrapper
Try below at https://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_video:
<!DOCTYPE html>
<html>
<body>
<style>
div.outer { overflow: hidden }
div.outer > div.inner { position: relative; margin: 0 -109.7283%; padding: 88.8888888% 0; overflow: hidden }
div.outer > div.inner > iframe { position: absolute; top: 0; right: 0; bottom: 0; left: 0 }
</style>
<div class="outer">
<div class="inner">
<iframe width="100%" height="100%" src="https://drive.google.com/file/d/16iDKGJXBszk2nI9h9BNG3rJ2zD85FSNy/preview">
</iframe>
</div>
</div>
</body>
</html>
It may mess up the video playback, though. The video controls (progress-bar etc.) get cropped when playback starts.
Replace the code there with the one I have provided.
I just checked your code, and looks like what you need is:
.x { overflow: hidden }
.neg { position: relative; margin: 0 -109.7283; padding: 88.8888888% 0 }
.neg > iframe { position: absolute; top: 0; right: 0; bottom: 0; left: 0 }
and use only x class for outer div, only neg class for inner div. That should probably do it.
I thought about removing the negative margin on playback, and was experimenting with something along those lines, but didn't get around to completing it. It should work to some extent, but what I found was that the black bordered thumbnail may be displayed for a short time before the playback starts (at least the way I tried it). If that's Ok, you could try that method. What I thought of was to display an invisible div (transparent overlay) covering the iframe that can capture a click and switch the iframe src to autoplay=1 URL. See if you can get that to work. If I have some time, I may look further into that.
I was adding a div using JavaScript with the same style as the iframe, just after the iframe:
.overlay { position: absolute; top: 0; right: 0; bottom: 0; left: 0 }
If this div is added last, it will already be topmost. Otherwise, use z-index.
Then handle the 'click' event on the div.
The above div overlay technique has it's limitations. The below technique may be better:
<!DOCTYPE html>
<html>
<meta charset="UTF-8">
<title>Player</title>
<div id="player"></div>
body { background: #efe; padding: 2em; color: #575 }
h1:first-child { margin-top: 0 }
.player, #player { overflow: hidden }
.player > div, #player > div { position: relative; padding: 88.88888% 0; overflow: hidden }
.player video, .player iframe,
#player video, #player iframe
{ position: absolute; top: 0; right: 0; bottom: 0; left: 0 }
.player:not(.playing) > div, #player:not(.playing) > div
{ margin: 0 -109.7283% }
((W, D) => {
let $ = a => document.getElementById(a)
class Player {}
Player.play = (id, url) => {
let p = $(id)
, f = D.createElement('iframe')
, d = D.createElement('div')
f.src = url
f.setAttribute('frameborder', 0)
f.height =
f.width = '100%'
f.addEventListener( 'mouseover', e => f.dataset.overMe = 1 )
f.addEventListener( 'mouseout', e => delete f.dataset.overMe )
W.addEventListener( 'blur', e => {
if (f.dataset.overMe === '1')
setTimeout(a => p.classList.add('playing'), 1000)
} )
p.innerHTML = ''
d.appendChild(f)
p.appendChild(d)
}
W.Player = Player
})(window, document);
Player.play('player', 'https://drive.google.com/file/d/16iDKGJXBszk2nI9h9BNG3rJ2zD85FSNy/preview')
See if you can use this latest update with multiple iframes...
Your issue could be because you may be using an id (maybe the same id) with all player divs. When using multiple player divs, you need to use unique ids and use class="player" for the divs instead of id="player":
<div id="player-1" class="player"></div>
<div id="player-2" class="player"></div>
<div id="player-3" class="player"></div>
If it still doesn't work, show me a demo (on your site, maybe), and I'll take a look. Call the play method with the id like
Player.play('player-1', 'https://drive.google.com/file/d/16iDKGJXBszk2nI9h9BNG3rJ2zD85FSNy/preview')
Player.play('player-2', 'https://drive.google.com/file/d/16iDKGJXBszk2nI9h9BNG3rJ2zD85FSNy/preview')

"onmouseout" isn't working. The image doesn't change

I want an image to change when it is hovered on. So far my code is fine. But I want the image to change back to its original image when mouse leaves the image. This is where my code doesn't work properly. What is the problem and how can I fix it? I really appreciate your help.
This is my html code:
<div onmouseover="show_large(this);" onmouseout="show_normal(this);">
<img src="2.JPG">
</div>
<script>
function show_large(element){
element.innerHTML=
'<img src="1.JPG">';
}
function show_normal(element){
element.innerHTML=
'<img src="2.JPG">';
}
</script>
And this is my css code:
div{
width: 25%;
margin: 0;
}
img{
width: 100%;
margin: 0;
}
You can achive this only with CSS and HTML, just add background-image property on your div and change img on :hover, like so:
div{
background-image: url('first-img-src.png');
transition: background-image 1s ease-in-out;
}
div:hover{
background-image: url('second-img-src.png');
}
EDIT:
You can achive same thing using mouseenter and mouseleave with changeing img.src property:
const img = document.querySelector('img');
img.addEventListener('mouseenter', (e) => {
img.src = 'second.png'
})
img.addEventListener('mouseleave', (e) => {
img.src = 'first.png'
})
Since images will have default hover events, you need to disable them for it to work on the parent div. You can disable them by adding pointer-events: none to img tag
function show_large(element) {
element.innerHTML =
'<img src="https://randomuser.me/api/portraits/men/51.jpg">';
}
function show_normal(element) {
element.innerHTML =
'<img src="https://randomuser.me/api/portraits/men/50.jpg">';
}
div {
width: 25%;
margin: 0;
}
img {
width: 100%;
margin: 0;
pointer-events: none;
}
<div onmouseover="show_large(this);" onmouseout="show_normal(this);">
<img src="https://randomuser.me/api/portraits/men/50.jpg">
</div>
You can simply do it using css it self. working jsFiddle
.image-container{
width: 300px;
}
.over{
display: none;
}
.image-container:hover .main{
display: none;
}
.image-container:hover .over{
display: block;
}
<div class="image-container">
<img class="main" src="https://www.rd.com/wp-content/uploads/2019/04/shutterstock_1013848126.jpg" width="100%" />
<img class="over" src="https://www.rd.com/wp-content/uploads/2019/05/shutterstock_671541538-e1557714950453.jpg" width="100%" />
</div>

Trying to create a div with resizable dragger

I'm pretty sure there is already an example for this but I couldn't find one, and I don't know exactly what to search for.
http://imgur.com/a/hHNkZ
I am trying to make a resizable div from the button circled in red above.
The photo behind this div comes from a slick slider ( http://kenwheeler.github.io/slick/ ).
<div class="slider-for">
<img src="images/product0.jpg" alt="">
<img src="images/product1.jpg" alt="">
<img src="images/product2.jpg" alt="">
<img src="images/product3.jpg" alt="">
</div>
I was thinking of making a width 0 div above, and then with the slider, increase its width with js maybe.
In this div, I want to put a recipe for that certain product. I have 4 photos, so the content has to change depending on picture. ( so it's not static content).
Does this need to be made in php?
I think this would be helpful to you:
https://jsfiddle.net/u0Ljnttg/1/
Its little bit complicated, but still good enough. :)
Just for sake of SO:
JS:
var links = document.getElementById("imageLinks");
links.onmousedown = function(e) {
var theSrc = e.target.dataset.src;
if (theSrc) {
str = "url(\"" + theSrc + "\");";
//Sorry for using this:
document.getElementById("imageBack").setAttribute("style", "background-image:" + str)
}
}
var resizer = document.getElementById("content-resize");
resizer.onmousedown = resizableStart;
function resizableStart(e) {
var elem = document.getElementById("content");
elem.originalW = elem.clientWidth;
this.onmousemove = resizableCheck;
this.onmouseup = this.onmouseout = resizableEnd;
}
function resizableCheck(e) {
var elem = document.getElementById("content");
if (elem.clientWidth === elem.originalW) {
elem.originalX = e.clientX;
this.onmousemove = resizableMove;
}
}
function resizableMove(e) {
var elem = document.getElementById("content");
var newW = elem.originalW - e.clientX + elem.originalX;
if (newW < elem.originalW) {
elem.style.width = newW + 'px';
}
}
function resizableEnd() {
this.onmousemove = this.onmouseout = this.onmouseup = null;
}
HTML:
<div class='container'>
<div class='images' id="imageBack" style="background-image: url('http://data.whicdn.com/images/20948152/large.png')">
<div class='content' id="content">
<div id="imageLinks">
<a href="#" data-src='http://ichef.bbci.co.uk/news/660/cpsprodpb/1325A/production/_88762487_junk_food.jpg'>1</a>
<a href="#" data-src='http://i.imgur.com/NhDejjN.jpg'>2</a>
<a href="#" data-src='https://s-media-cache-ak0.pinimg.com/564x/80/40/9d/80409d8c06d21e0c0416a40c2176def3.jpg'>3</a>
<a href="#" data-src='http://data.whicdn.com/images/20948152/large.png'>4</a>
</div>
<span id="content-resize"></span>
</div>
</div>
</div>
CSS:
html,
body {
min-height: 100% !important;
height: 100%;
}
.container {
width: 100%;
min-height: 100%;
height: 100%;
}
.images {
width: 100%;
min-height: 100% !important;
height: 100%;
}
#content {
min-height: 100% !important;
height: 100%;
/*Change this to change width*/
width: 70%;
resize: horizontal;
float: right;
position: relative;
background: white;
}
div {
border: 1px solid black;
}
span {
border: 1px solid black;
border-radius: 50%;
position: absolute;
top: calc(50% - 20px);
left: -10px;
cursor: pointer;
height: 40px;
width: 40px;
display: inline-block;
background: white;
}
I am not sure if you already solved this issue, but since you helped me on the other question, I am interested in helping you with this.
You have some options.
Use pure JavaScript. You can use a lib (eg: this) for that.
Use Jquery $().draggable() propriety. This might help for styling the button..
Using pure HTML & CSS resize. This is not good, since you cannot apply any style to the <div>.
You can make a workaround mixing three <div> elements,
One of them with position: fixed. This is your background.
Another for the container (with a width set manually to hide the page from user). Remove the scrollbar and force the width of your html, body to match your screen.
Another <div> inside the container for your content. This should be able to move horizontally to show and hide the elements.

Scrolling image gallery without jQuery

I have a scrolling image gallery as follows. The CSS lays out the images in a row that scrolls horizontally. Underneath, I have a row of the same images, but as thumbnails. I want to be able to click on a thumbnail, and scroll the correct image into view.
HTML:
<div class="images_container">
<img id="image_1" src="/image1.jpg">
<img id="image_2" src="/image2.jpg">
<img id="image_3" src="/image3.jpg">
</div>
<div class="images_container thumbnails">
<img src="/image1.jpg" class="thumbnail">
<img src="/image2.jpg" class="thumbnail">
<img src="/image3.jpg" class="thumbnail">
</div>
CSS:
.images_container {
overflow-x: scroll;
overflow-y: hidden;
max-height: 50rem;
white-space: nowrap;
}
.images_container.thumbnails {
max-height: 10rem;
}
.images_container img {
vertical-align: top;
height: 50rem;
}
.images_container.thumbnails img {
height: 10rem;
}
This works up to a point, but jumping to the id of the image is problematic. If the larger image is even a few pixels into the visible viewport, it can't 'jump' to it, as it seems to be technically on the screen.
Is there a way I can use Javascript to 'scroll' the whole image into view when I click on it's corresponding thumbnail? I don't have access to jQuery on this project, but am happy to use JavaScript to make this work.
You can try this , no change in CSS, i add an id in html and call to scrollTo function :
<script>
function scrollTo(image_id){
var topLeft = document.getElementById(image_id).offsetTop;
document.getElementById('container').scrollLeft = topLeft;
}
</script>
<div id="container" class="images_container">
<img id="image_1" src="/image1.jpg" height="500px" width="500px">
<img id="image_2" src="/image2.jpg" height="500px" width="500px">
<img id="image_3" src="/image3.jpg" height="500px" width="500px">
</div>
<div class="images_container thumbnails">
<img src="/image1.jpg" class="thumbnail" onclick="scrollIntoView('image_1')">
<img src="/image2.jpg" class="thumbnail" onclick="scrollIntoView('image_2')">
<img src="/image3.jpg" class="thumbnail" onclick="scrollIntoView('image_3')">
</div>
To keep DOM cleaner I got this solution which requires only adding js
var elms = document.getElementsByClassName("thumbnail");
for (var i = 0; i < elms.length; i++) {
elms[i].onclick = function(event) {
event.preventDefault();
event.stopPropagation();
var id = this.parentNode.href.substr(this.parentNode.href.lastIndexOf('/') + 2);
var v = document.getElementById(id).getBoundingClientRect().left;
document.getElementsByClassName("images_container")[0].scrollLeft += v;
}
}
See on jsfiddle
Here's my attempt at a no (well, minimal) JS solution to a scrolling gallery. You could, in fact, remove the Javascript all together if you replaced the .active class with the :target pseudo-selector, allowing you to click your thumbnails to do the scrolling. It's just easier for me to do it this way through a fiddle
function removeClass(element, className) {
var classes = element.className.split(' ');
var key = classes.findIndex(function(name) {
return name == className
});
classes.splice(key, 1);
element.className = classes.join(' ');
}
function addClass(element, className) {
var classes = element.className.split(' ');
classes.push(className);
element.className = classes.join(' ');
}
setInterval(function() {
var current = document.querySelector('.images .image.active');
var next = current.nextElementSibling;
if (!next) {
next = document.querySelector('.images .image:first-child');
}
removeClass(current, 'active');
addClass(next, 'active');
}, 1500);
body {
margin: 0;
padding: 0;
width: 500px;
height: 500px;
}
.images {
width: 100%;
height: 100%;
position: relative;
overflow-x: hidden;
}
.image {
width: 100%;
height: 100%;
top: 0px;
position: absolute;
left: -100%;
float: left;
transition: 1s;
}
.image.active {
left: 0%;
}
.image.active ~ .image {
left: 100%;
}
.black {
background-color: black;
}
.red {
background-color: red;
}
.blue {
background-color: blue;
}
.yellow {
background-color: yellow;
}
<div class='images'>
<div class='image black active'></div>
<div class='image red'></div>
<div class='image blue'></div>
<div class='image yellow'></div>
</div>
Essentially the way it works is by making the div.images container a certain height and width, and therefore all images inside it can be positioned as you want. We initially set all .image to left: -100%, so that they're completely off screen to the left. We then set .image.active as left: 0 so that it's on screen. We then use the ~ selector to say that all siblings that come after the current (.image.current ~ .image) should be left: 100%, so completely to the right. Add in a transition, and you have a completely CSS scrolling gallery. The JS only acts as a way to change what the current active image is, and you can replace that with :target if you want.
I used div's, instead of img tags because it's easier to provide a POC with div's and background colors, but it's worked well with images in the past. Just put an <img> tag inside those <div class='image'></div> tags

JQuery - show hide button when mouse enter / leave an image

In my web page I have an image that has a button positioned over it. I want to show and hide the button as mouse enter and leave the image:
$('#UserImage').mouseenter(function()
{
$('#ButtonChange').show();
}).mouseout(function()
{
$('#ButtonChange').hide();
})
It is working but as the button is contained inside the image when the mouse enters the button it is considered to leave the image so the button is hidden then at tha same moment as the button is hidden the mouseenter event is triggered again and the button is shown causing a flickering effect
any suggestion to solve this?
Edit:
$('#UserImage').mouseenter(function() {
$('#ButtonChange').show();
}).mouseout(function() {
$('#ButtonChange').hide();
})
.imageUser {
width: 150px;
height: 200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div style="position:relative;width=150px">
<img ID="UserImage" class="imageUser" ImageUrl="~/Images/logo.jpg" />
<input type="button" ID="ButtonChange" Text="Change" style="position: absolute;top: 180px;height:25px;left:0px;width:100px;display:none">
</div>
The whole thing is also possible with pure CSS ! for such simple thing, you don't really need Jquery !
.imageUser {
width: 150px;
height: 200px;
}
.img-wrapper {
position: relative;
width: 150px
}
.img-btn {
position: absolute;
top: 180px;
height: 25px;
left: 0px;
right:0; /* gave right, to align the button in center */
margin:0 auto; /* as button as fixed width, margin aligns in center */
width: 100px;
display: none
}
.img-wrapper:hover .img-btn {display:block} /* whenever mouse hovers the image wrapper, the button is shown, other time, its hidden */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="img-wrapper">
<img ID="UserImage" class="imageUser" ImageUrl="~/Images/logo.jpg" />
<input type="button" ID="ButtonChange" Text="Change" class="img-btn">
</div>
Try hover?
$("#UserImage").hover(function () {
$('#ButtonChange').show();
}, function () {
$('#ButtonChange').hide();
});
I don't have an image so I make a div instead. See Fiddle below.
Fiddle: https://jsfiddle.net/9koswww1/1
Change mouseenter to mouseover.
https://api.jquery.com/mouseenter/
Check the bottom of the page for an example.
try this
$('#UserImage').mouseenter(function()
{
$('#ButtonChange').show();
}).mouseleave(function()
{
$('#ButtonChange').hide();
})

Categories

Resources