How can I trigger on mouse movement Variable font in different section? - javascript

I was looking to trigger different sections with a variable font based on my mouse movement.
For the first section, everything looks great, but when I tried to trigger the second section, it does not work as I expected since is connected to the first one I guess.
I would need to make the section working independently and in the correct way (to have an idea see section one how react in debug mode)
I was wondering what I have to modify in my Javascript code to make my snippet work with all the sections I want, working independently with their respective variable font interaction. Any ideas?
$('.square').on('mousemove', function(e) {
var x = e.pageX - $(this).offset().left;
var y = e.pageY;
var $tlSquare = $('.division--top.division--left');
var $trSquare = $('.division--top.division--right');
var $blSquare = $('.division--bottom.division--left');
var $brSquare = $('.division--bottom.division--right');
var squareWidth = $(this).width(),
squareHeight = $(this).height();
$tlSquare.width(x).height(y);
$trSquare.width(squareWidth - x).height(y);
$blSquare.width(x).height(squareHeight - y);
$brSquare.width(squareWidth - x).height(squareHeight - y);
stretchLetter(false);
});
stretchLetter(false);
$('.square').on('mouseleave', function() {
$('.division').width('50%').height('50%');
$('.letter').css('transform', '');
stretchLetter(false);
});
function stretchLetter(animation) {
$('.letter').each(function() {
var parentWidth = $(this).parent().width();
var parentHeight = $(this).parent().height();
var thisWidth = $(this).width();
var thisHeight = $(this).height();
var widthPercent = parentWidth / thisWidth;
var heightPercent = parentHeight / thisHeight;
var timing = animation == true ? .5 : 0;
TweenMax.to($(this), timing, {
scaleX: widthPercent,
scaleY: heightPercent
})
//$(this).css('transform', 'scalex('+ widthPercent +') scaley('+ heightPercent +')');
});
}
body,
html {
margin: 0;
padding: 0;
font-weight: bold;
font-family: helvetica;
}
section {
height: 200px;
background: blue;
color: white;
font-size: 28px;
}
.wrapper {
display: flex;
justify-content: center;
/*justify-content: flex-end;*/
width: 100%;
height: 100vh;
//background-color: blue;
overflow: hidden;
}
.square {
display: flex;
flex-wrap: wrap;
width: 100vh;
height: 100vh;
background-color: black;
}
.square-2 {
display: flex;
flex-wrap: wrap;
width: 100vh;
height: 100vh;
background-color: yellow;
}
.division {
//display: flex;
//align-items: center;
//justify-content: center;
width: 50%;
height: 50%;
//background-color: red;
//border: 1px solid white;
box-sizing: border-box;
}
.letter {
cursor: -webkit-grab;
cursor: grab;
}
.letter {
display: inline-block;
font-size: 50vh;
margin: 0;
padding: 0;
line-height: .8;
transform-origin: top left;
color: white;
}
/* .division:nth-child(1){
background-color: blue;
}
.division:nth-child(2){
background-color: red;
}
.division:nth-child(3){
background-color: green;
}
.division:nth-child(4){
background-color: orange;
} */
.circle {
width: 100%;
height: 100%;
border-radius: 50%;
border: 1px solid white;
background-color: blue;
box-sizing: border-box;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section>SECTION-01</section>
<main>
<div class="wrapper">
<div class="square">
<div class="division division--top division--left">
<div class="letter">L</div>
</div>
<div class="division division--top division--right">
<div class="letter">A</div>
</div>
<div class="division division--bottom division--left">
<div class="letter">S</div>
</div>
<div class="division division--bottom division--right">
<div class="letter">T</div>
</div>
</div>
</main>
<section>SECTION-02</section>
<div class="wrapper">
<div class="square">
<div class="division division--top division--left">
<div class="letter">F</div>
</div>
<div class="division division--top division--right">
<div class="letter">A</div>
</div>
<div class="division division--bottom division--left">
<div class="letter">S</div>
</div>
<div class="division division--bottom division--right">
<div class="letter">T</div>
</div>
</div>
</main>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.0.2/TweenMax.min.js"></script>
https://jsfiddle.net/CAT999/ohaf61qp/5/

See working FIDDLE
You had to change the y variable because you were calculating with the offset top of the mouse position inn the document. This is always bigger than the element, so you have to extract the offset top of the element you were scrolling on, to get the right value.
var y = e.pageY - $(this).offset().top;

Related

Add height to css

I'm trying to add height to original value in CSS.
But so far I had no luck.
html,
body {
width: 100%;
height: 100vh;
margin: 0px 0px 0px 0px;
overflow: hidden;
background-color: #FFF;
}
#Header1 {
background-color: green;
width: 100vw;
height: 10vh;
margin-bottom: 0%;
z-index: 100;
}
#Header2 {
background-color: blue;
width: 100%;
height: 4vh;
margin-bottom: 0%;
z-index: 100;
}
#Main {
height: 82vh;
width: 100%;
}
if (Header1Check == 1) {
document.getElementById("Header1").style.display = "block";
} else {
document.getElementById("Header1").style.display = "none";
document.querySelector('#Main').style.height = "initial" + "10vh";
}
if (Header2Check == 1) {
document.getElementById("Header2").style.display = "block";
} else {
document.getElementById("Header2").style.display = "none";
document.querySelector('#Main').style.height = "initial" + "4vh";
}
Basicly if the check = 0 it stops showing HEADER1/Header2, but the Main content (center) does not auto size to this.
To counteract this I just tried to add that value to the CSS but it does not appear to work.
Is there a way to achieve this?
edit:
<body>
<div id="wrapper">
<div id="Header1">
</div>
<div id="Header2">
</div>
<div id="portraitContent">
</div>
<div id="landscapeContent">
</div>
<div id="Footer">
</div>
</div>
</body>
You can use display:flex on the #wrapper element, and then set the content divs with flex:1 which means they will take up the remaining space
(see more about flexbox at: https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox)
Something like
*{box-sizing:border-box;}
html,
body {
width: 100%;
height: 100vh;
margin: 0px 0px 0px 0px;
overflow: hidden;
background-color: #FFF;
}
#wrapper {
display: flex;
flex-direction: column;
height: 100vh;
}
#wrapper > * {
border: 1px solid black;
}
#Header1 {
background-color: green;
height: 10vh;
z-index: 100;
}
#Header2 {
background-color: blue;
height: 4vh;
}
#Footer {
background-color: tomato;
height: 4vh;
}
#portraitContent,
#landscapeContent {
flex: 1;
background: teal;
}
#media (orientation: landscape) {
#portraitContent {
display: none
}
}
#media (orientation: portrait) {
#landscapeContent {
display: none
}
}
<div id="wrapper">
<div id="Header1"> header 1
</div>
<div id="Header2">header 2
</div>
<div id="portraitContent">
portrait
</div>
<div id="landscapeContent">
landscape
</div>
<div id="Footer">footer
</div>
</div>
Assuming you want to change size of an image for example you can do this simple example below
Also the property you added for height is incorrect syntax
The correct property values are from
https://www.w3schools.com/jsref/prop_style_height.asp
Property Values
Value Description
auto The browser sets the height. This is default
length Defines the height in length units
% Defines the height in % of the parent element
initial Sets this property to its default value. Read about initial
inherit Inherits this property from its parent element. Read about inherit
#HaoWu comment is correct you cannot use both properties together either or
you can assign another
//Syntax : object.style.height("")
appImg.style.height = "inital";
Refernces
prop style height w3schools
js-conventions w3schools
I have prepared a simple Example answer for your question .
const appImg = document.getElementById("appImg");
//console.log(appImg);
function minimizeImage(){
const hideImgBtn = document.getElementById("hideImgBtn");
if(!hideImgBtn){
appImg.style.display = "block";
}else {
appImg.style.height = "10vh";
};
};
.app__img{
max-width: 10vw;
max-height: 150px;
width: 100%;
height: 100%;
}
<div>
<img
src ="https://images.pexels.com/photos/12999041/pexels-photo-12999041.jpeg?auto=compress&cs=tinysrgb&w=300&lazy=load" class="app__img" id="appImg" alt="appImage"/>
</div>
<button onclick="minimizeImage()" id="hideImgBtn">
Min image size with js
</button>
html,
body {
width: 100%;
height: 100vh;
margin: 0px 0px 0px 0px;
overflow: hidden;
background-color: #FFF;
}
#wrapper {
display: flex;
flex-direction: column;
height: 100vh;
}
#wrapper > * {
border: 1px solid black;
}
#Header1 {
background-color: green;
height: 10vh;
z-index: 100;
}
#Header2 {
background-color: blue;
height: 4vh;
}
#Footer {
background-color: tomato;
height: 4vh;
}
#portraitContent,
#landscapeContent {
flex: 1;
background: teal;
}
#media (orientation: landscape) {
#portraitContent {
display: none
}
}
#media (orientation: portrait) {
#landscapeContent {
display: none
}
}
<div id="wrapper">
<div id="Header1"> header 1
</div>
<div id="Header2">header 2
</div>
<div id="portraitContent">
portrait
</div>
<div id="landscapeContent">
landscape
</div>
<div id="Footer">footer
</div>
</div>
document.querySelector('#Main').style.height = "initial" + "10vh";
"initial" + "10vh" is not valid. You can do it like this:
document.querySelector('#Main').style.height += "10vh";
Good luck!

Scroll function on hover won't work unless resizing screen

I miss 1% to finish my script, I just don't know how to do it :D
When you hover over the target to the left, you can see the image will scroll. But after clicking on a new image it won't. I then have to resize the window to make it work again. How to fix that? Below is my code but for a working example, here's a CodePen
(function($) {
// virables
var layoutContainer = '.container';
var layoutTarget = '#target';
var layoutTargetIMG = '#target img';
var layoutIMG = '.container .gallery .item img';
var layoutIMGFirst = '.container .gallery .item:first-child img';
// Add first image to target
$(layoutIMGFirst).clone().appendTo(layoutTarget);
// Add image to target when click on gallery image
$(layoutIMG).click(function() {
$(this).closest(layoutContainer).find(layoutTarget).empty();
$(this).clone().appendTo(
$(this).closest(layoutContainer).find(layoutTarget)
);
});
// Image scroll on hover
// This won't work after clicking on an image unless resizing the browser
$(window).resize(function() {
// If i remove this it won't work on the start image.
// Any other solution?
setTimeout(function() {
$('#target img').each(function() {
var itemHeight = $('#target').outerHeight();
var imgHeight = $(this).outerHeight();
// Work out what percentage the image is of the item and remove 100% from that
var topHeight = (imgHeight / itemHeight) * 100 - 100;
//Make the animation speed proptional to that ratio
var animationSpeed = (imgHeight / itemHeight) / 1; //change 2 to tweak the speed
$(this).css({
transition: 'all ease ' + animationSpeed + 's'
});
$(this).mouseleave(function() {
$(this).css({
top: '0'
});
})
// The 'top' property of the image needs
// to be set as as a percentage of the parent
$(this).mouseenter(function(e) {
$(this).css({
top: '-' + topHeight + '%',
});
})
});
}, 200);
});
$(document).ready(function() {
setTimeout(function() { // Add delay after resize so function will load
$(window).triggerHandler('resize');
}, 200);
});
})(jQuery);
.container {
display: flex;
flex-flow: row wrap;
align-items: flex-start;
margin-left: -40px;
max-width: 1000px;
background: lightblue;
padding: 20px;
.column {
flex: 1;
min-width: 30%;
margin-left: 40px;
.target {
height: 400px;
background: pink;
position: relative;
overflow: hidden;
img {
position: absolute;
top: 0;
left: 0;
width: 100%;
}
}
.cta {
display: flex;
a {
background: lightgreen;
width: 50%;
padding: 16px 8px;
;
text-align: center;
justify-content: center;
text-decoration: none;
&:last-child {
background: orange;
}
}
}
.gallery {
display: flex;
flex-flow: row wrap;
margin-left: -4px;
.item {
flex: 1;
margin-left: 4px;
position: relative;
overflow: hidden;
&::before {
content: '';
padding-top: 80%;
display: block;
}
img {
position: absolute;
min-width: 100%;
min-height: 100%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
cursor: pointer;
}
}
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="column">
<div id="target" class="target"></div>
<div class="cta">
SE DEMO
KØB LAYOUT
</div>
</div>
<div class="column">
<div class="gallery">
<div class="item">
<img src="https://picsum.photos/600/1200" alt="">
</div>
<div class="item">
<img src="https://picsum.photos/500/1600" alt="">
</div>
<div class="item">
<img src="https://picsum.photos/400/2000" alt="">
</div>
</div>
</div>
</div>
Just change this
$(layoutIMG).click(function() {
$(this).closest(layoutContainer).find(layoutTarget).empty();
$(this).clone().appendTo(
$(this).closest(layoutContainer).find(layoutTarget)
);
});
to
$(layoutIMG).click(function() {
$(this).closest(layoutContainer).find(layoutTarget).empty();
$(this).clone().appendTo(
$(this).closest(layoutContainer).find(layoutTarget)
);
$(window).triggerHandler('resize'); // added this line
});

Scroll issue on .animate() and .prop()?

I have two divs with same class. If I scroll one div the other divs scroll comes to 0. I am able to achieve this with .prop() property easily. But when I use .animate() the occurrence just happens once and then it stops working(Commented the code in my example snippet) . What I want is the scroll when comes to zero should animate i.e the scroll comes to 0 with a animation like its showing with .animate().
Note: Classes of divs will be same and there can be more divs too.
Here is the code I have tried, please tell me where I am wrong.
$(document).ready(function() {
$('.swipe_div').scroll(function() {
// $(this).siblings(".swipe_div").animate({scrollLeft: 0},100);
$(this).siblings(".swipe_div").prop({
scrollLeft: 0
});
});
});
body,
html {
width: 100%;
height: 100%;
background-color: green;
padding: 0;
margin: 0;
}
.swipe_div {
display: block;
float: left;
width: 100%;
height: 100px;
overflow-x: scroll;
background-color: white;
}
.content,
.operation,
.swipe_container {
display: block;
float: left;
height: 100%;
}
.swipe_container {
width: 150%;
}
.content {
display: flex;
align-items: center;
justify-content: flex-end;
flex-direction: row;
text-align: right;
font-size: 30pt;
width: 67%;
background-color: grey;
}
.operation {
width: 33%;
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="swipe_div">
<div class="swipe_container">
<div class="content">
>
</div>
<div class="operation">
</div>
</div>
</div>
<div class="swipe_div">
<div class="swipe_container">
<div class="content">
>
</div>
<div class="operation">
</div>
</div>
</div>
When you're animating scrollLeft you're activating scroll() on the sibling, which is trying to animate scroll on the div you're actively scrolling. So you need to mark when you start scrolling and throttle() all subsequent calls on scroll() until you're done scrolling.
trailing:true calls it one more time after it hasn't been called for throttle_interval (250 in this example), turning scrolling marker back to false:
$(document).ready(function() {
var scrolling;
$('.swipe_div').scroll(_.throttle(function() {
if (!scrolling) {
scrolling = true;
$(this).siblings(".swipe_div").animate({scrollLeft: 0},150);
} else {
scrolling = false;
}
}, 250, {leading:true,trailing:true}));
});
body,
html {
width: 100%;
height: 100%;
background-color: green;
padding: 0;
margin: 0;
}
.swipe_div {
display: block;
float: left;
width: 100%;
height: 100px;
overflow-x: scroll;
background-color: white;
}
.content,
.operation,
.swipe_container {
display: block;
float: left;
height: 100%;
}
.swipe_container {
width: 150%;
}
.content {
display: flex;
align-items: center;
justify-content: flex-end;
flex-direction: row;
text-align: right;
font-size: 30pt;
width: 67%;
background-color: grey;
}
.operation {
width: 33%;
background-color: red;
}
<script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="swipe_div">
<div class="swipe_container">
<div class="content">
>
</div>
<div class="operation">
</div>
</div>
</div>
<div class="swipe_div">
<div class="swipe_container">
<div class="content">
>
</div>
<div class="operation">
</div>
</div>
</div>
I tested it for a bit and actually discovered a small glitch/limitation: the throttle interval has to be smaller than the animation time. If it is not, the animation will outlast the throttle interval and trigger, in turn, the closing animation for the original scrolled element.
But this is web (impossible is nothing): if and when your animation has to be longer than the throttle interval, you will have to mark the initial element with a class that will exclude it from being animated. The class will be removed using a timeout on completion of animate, equal to the throttle interval:
$(document).ready(function() {
var scrolling;
$('.swipe_div').scroll(_.throttle(function() {
if (!scrolling) {
scrolling = true;
$(this).addClass('original');
$(this).siblings(".swipe_div:not(.original)").animate(
{scrollLeft:0},
250,
function(){
setTimeout(function() {
$('.swipe_div').removeClass('original')
}, 150)
}
);
} else {
scrolling = false;
}
}, 150, {leading:true,trailing:true}));
});

Hide Sticky Div Once Scrolling Past Next Parent Div

I'm trying to hide a "sticky" div once it scrolls past the next parent div. I've currently successfully have it so it appears after scrolling "y > 100" but I'm having a lot of trouble getting the "Sticky Note" to disappear after scrolling past #break.
Example below.
http://codepen.io/anon/pen/BojKBx
$(document).scroll(function() {
var y = $(this).scrollTop();
if (y > 100) {
$('.bottomMenu').fadeIn();
} else {
$('.bottomMenu').fadeOut();
}
});
.bottomMenu {
display: none;
position: fixed;
bottom: 0;
width: 50%;
height: 60px;
border-bottom: 1px solid #000;
z-index: 1;
margin: 0 auto;
left: 50%;
margin-left: -500px;
text-align: center;
}
#header {
font-size: 50px;
text-align: center;
height: 60px;
width: 100%;
background-color: red;
}
#container {
height: 2500px;
}
#break {
text-align: center;
font-size: 30px;
margin-bottom: 300px;
width: 100%;
background-color: yellow;
}
#footer {
height: 60px;
background-color: red;
width: 100%;
bottom: 0;
}
<div id="header">Home</div>
<div class="bottomMenu">
<h2>Sticky Note</h2>
</div>
<div id="container"></div>
<div id="break">Should Not Be Seen After This Point</div>
<div id="footer"></div>
You can get Y position of a div (its vertical offset starting from the top of the page), and then add condition to show sticky note only when you're below the required "Y" coordinate, and above the required div. Example:
http://codepen.io/anon/pen/EVPKyP
Javascript code:
$(document).scroll(function () {
var bodyRect = document.body.getBoundingClientRect(),
elemRect = document.getElementById("break").getBoundingClientRect(),
offset = elemRect.top - bodyRect.top - window.innerHeight;
var y = $(this).scrollTop();
if (y > 100 && y < offset) {
$('.bottomMenu').fadeIn();
} else {
$('.bottomMenu').fadeOut();
}
});
Sources:
Retrieve the position (X,Y) of an HTML element
screen width vs visible portion

Detect which section is in view

I have this script that is designed to mention which section is in sight in a overflow div so for example if you see a specific section it will say section 1 is in sight if you see
more than 1 section in sight it will say something like for example section 1 is in sight and section 2 is in sight etc...
How can I do something like this? I can't figure this out I tried many things but I can not be able to do what I want :(
This is my code
document.addEventListener('DOMContentLoaded',function(){
document.querySelector('#building').addEventListener('scroll',whichSectionsAreInSight);
function whichSectionsAreInSight(){
//???
}
});
h1{
margin: 0;
text-align: center;
}
#building{
background-color: gray;
height: 200px;
width: 200px;
overflow: auto;
}
.sections{
height: 225px;
width: 100%;
}
#section-1{
background-color: dodgerblue;
}
#section-2{
background-color: gold;
}
#section-3{
background-color: red;
}
<div id='building'>
<div id='section-1' class='sections'><h1>Section 1</h1></div>
<div id='section-2' class='sections'><h1>Section 2</h1></div>
<div id='section-3' class='sections'><h1>Section 3</h1></div>
</div>
<p id='status'></p><!--------The id call status is responsible
in mentioning which section is in sight-->
Hello this is my version of Mohammad's code and your code James. All credit goes to Mohammad and any up votes should go to Mohammad here it goes with the IE fix, my version
document.addEventListener('DOMContentLoaded',function(){
document.querySelector('#building').addEventListener('scroll',whichSectionsAreInSight);
function whichSectionsAreInSight(){
var building= document.querySelector('#building');
var top = building.scrollTop;
var bottom = top+building.offsetHeight;
var arr = [];
Array.prototype.forEach.call(
building.querySelectorAll('#building .sections'),
function(sections){
if ((sections.offsetTop < top && top <sections.offsetTop+sections.offsetHeight) || (sections.offsetTop < bottom && bottom < sections.offsetTop+sections.offsetHeight)){
arr.push(sections.id);
}
}
);
document.querySelector('#status').innerHTML = arr.join(',')
}
whichSectionsAreInSight();
});
h1{
margin: 0;
text-align: center;
}
#building{
background-color: gray;
height: 200px;
width: 200px;
overflow: auto;
}
.sections{
height: 225px;
width: 100%;
}
#section-1{
background-color: dodgerblue;
}
#section-2{
background-color: gold;
}
#section-3{
background-color: red;
}
<div id='building'>
<div id='section-1' class='sections'><h1>Section 1</h1></div>
<div id='section-2' class='sections'><h1>Section 2</h1></div>
<div id='section-3' class='sections'><h1>Section 3</h1></div>
</div>
<p id='status'></p>
In scroll event of parent loop through childs and check that which one in visible and add id of it to array. Al the end print array content into page
document.querySelector('#building').addEventListener('scroll', function(){
var top = this.scrollTop;
var bottom = top+this.offsetHeight;
var arr = [];
this.querySelectorAll("div").forEach(function(div){
if (
(div.offsetTop < top && top <div.offsetTop+div.offsetHeight) ||
(div.offsetTop < bottom && bottom <div.offsetTop+div.offsetHeight)
){
arr.push(div.id);
}
});
document.getElementById("status").innerHTML = arr.join(",")
});
h1{
margin: 0;
text-align: center;
}
#building{
background-color: gray;
height: 200px;
width: 200px;
overflow: auto;
}
.sections{
height: 225px;
width: 100%;
}
#section-1{
background-color: dodgerblue;
}
#section-2{
background-color: gold;
}
#section-3{
background-color: red;
}
<p id='status'></p>
<div id='building'>
<div id='section-1' class='sections'><h1>Section 1</h1></div>
<div id='section-2' class='sections'><h1>Section 2</h1></div>
<div id='section-3' class='sections'><h1>Section 3</h1></div>
</div>

Categories

Resources