How to process data attribute which is the number of negative? - javascript

Welcome! Help me please! Blocks .left when scrolling change a space from 300 to 0; moving from the center to the left. And how to make blocks .right when scrolling changed indent from -300 to 0, moving from the center to the right? Thank you very much for your help!
$(function() {
var $win = $(window),
$rev = $('[data-tr]'),
winH2 = 0,
winSt = 0;
function reveal() {
winSt = $win.scrollTop();
winH2 = $win.height()/2;
$rev.each(function(i, el){
var y = el.getBoundingClientRect().top,
toMiddleMax = Math.max(0, y-winH2),
idealMarg = Math.min(+el.dataset.val, toMiddleMax),
margMin = Math.min(idealMarg, idealMarg * (toMiddleMax/winH2));
$(this).css({transform: el.dataset.tr+"("+ margMin +"px)"});
});
}
$win.on({
"load resize scroll" : reveal
});
});
*{box-sizing:border-box; -webkit-box-sizing:border-box;}
html, body{height:100%; margin:0;}
p {height:250px;}
.left,
.right,
.top {
height: 100px;
width: 100px;
padding: 40px;
margin: 10px;
}
.left {background:red;float:left;}
.right {background:green;float:right;}
.top {background:blue;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p></p>
<div class="left" data-tr="translateX" data-val="300"></div>
<p></p>
<div class="left" data-tr="translateX" data-val="300"></div>
<p></p>
<div class="right" data-tr="translateX" data-val="-300"></div>
<p></p>
<div class="right" data-tr="translateX" data-val="-300"></div>
<p></p>
<div class="top" data-tr="translateY" data-val="300"></div>
<p></p>
<div class="top" data-tr="translateY" data-val="300"></div>
<p></p>

Related

How to use Hammer.js for swiping?

So i've got hammer.js swipe to work on my div. the swipe region looks like this
https://imgur.com/ncW4nDB
so basically, i want the orange area to be able to swipe left/right and when it reaches the end (on both sides), it halts swiping.
the script and etc :
var containerDiv = document.getElementById('list-container');
var listDiv = document.getElementById('train-line-list');
// Create a manager to manager the element
var manager = new Hammer.Manager(listDiv);
// Create a recognizer
var Swipe = new Hammer.Swipe();
// Add the recognizer to the manager
manager.add(Swipe);
// Declare global variables to swiped correct distance
var deltaX = 0;
var deltaY = 0;
// Subscribe to a desired event
manager.on('swipe', function(e) {
deltaX = deltaX + e.deltaX;
var direction = e.offsetDirection;
var translate3d = 'translate3d(' + deltaX + 'px, 0, 0)';
if (direction === 4 || direction === 2) {
e.target.innerText = deltaX;
e.target.style.transform = translate3d;
}
});
<div id="list-container">
<div id="train-line-list">
<img id="" src="">
<img id="" src="">
</div>
#list-container{
z-index: 10;
position:fixed;
top:60%;
left:0;
width:100%;
height:40%;
}
#train-line-list{
width: 95%;
height: 95%;
top: 2%;
margin: 0 auto;
position: relative;
}
like i said, the swiping sort of works but the images disappear. why does this happen and how can i fix it? Also, the swiping is not very "reactive" in a way, like its slow. not natural. is there an alternative? or a better way to implement? Also, just realized, the images can be swiped as well ?? how do i "lock" the images. i just want the container of the images to be swiped.
Here is a working example
<html>
<head>
<style>
#box {
background-color: red;
height: 100px;
width: 100px;
margin-right: 10px;
}
#collection {
display: flex;
flex-direction: horizontal;
}
#container {
display: flex;
background-color: aqua;
padding: 50px 0px 50px 0px;
overflow: scroll;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.js"></script>
</head>
<body>
<div id="container">
<div id="collection">
<div id="box"></div>
<div id="box"></div>
<div id="box"></div>
<div id="box"></div>
<div id="box"></div>
<div id="box"></div>
</div>
</div>
<script>
var container = document.getElementById("container");
var content = document.getElementById("collection");
var hammer = new Hammer(container);
var initialX = 0;
var deltaX = 0;
var offset = initialX + deltaX;
hammer.on("panleft panright", function(ev) {
deltaX = ev.deltaX;
offset = initialX + deltaX;
container.scroll(-offset, 0);
});
Hammer.on(container, "mouseup", function(e) {
initialX = offset;
});
</script>
</body>
</html>
You could replace the squares with your images.

Click toggle with multiple targets

I have a two images and when you click on one, text (relevant to image) slides into view below the image. Currently the method for closing/toggling the text is to click on the image again.
If I click on the second image while the text on the first image is still visible, it closes the text. I then have to click on the second image again to see its text content appear.
I'd like to be able to click on the second image and either the text content just swaps OR it closes the text for the first image and opens the text for the second image (in just one click, not two).
Any input appreciated!
I have a fiddle here
JS:
var teamMember = document.getElementsByClassName("team-member");
var teamRow = document.getElementsByClassName("team-row");
var bioContainer = $( "<div class='container' id='bio-container'></div>" );
$(bioContainer).hide();
$(teamMember).click(function() {
$(this).toggleClass('member-selected');
$('.team-grid').toggleClass('member-active');
$(bioContainer).html("");
var thisBio = $(this).find(".team-bio");
var thisRow = $(this).parent(teamRow);
$(thisRow).after(bioContainer);
var bioHTML = $(thisBio).html();
$height = $(thisBio).outerHeight(true)
$(bioContainer).css('height', $height);
$(bioContainer).slideToggle( "slow", function() {
$(this).html(bioHTML);
});
});
HTML:
<section class="team-grid">
<div class="team-row">
<div class="col-sm-6 team-member">
<img src="https://www.catster.com/wp-content/uploads/2017/11/A-Siamese-cat.jpg">
<div class="team-bio">
<div class="team-bio-inner">
JOHN'S Bio
</div>
</div>
</div>
<div class="col-sm-6 team-member">
<img src="https://r.hswstatic.com/w_907/gif/tesla-cat.jpg">
<div class="team-bio">
<div class="team-bio-inner">
SALLY'S Bio
</div>
</div>
</div>
</div>
</section>
CSS:
.col-sm-6 {
width:50%;
float:left;
}
img {
width:100%;
height:200px;
object-fit:cover;
cursor:pointer;
}
.close-bio {
color:pink;
font-weight:bold;
}
.team-bio {
visibility: hidden;
padding: 80px 20%;
position: fixed;
top: 0;
left: 0;
width: 100%;
}
#bio-container {
background: #666;
width: 100%;
max-width: none;
position: relative;
float: left;
padding: 25px;
color:#fff;
font-size:20px;
}
Please check this answer,
Js Fiddle
var teamMember = document.getElementsByClassName("team-member");
var teamRow = document.getElementsByClassName("team-row");
var bioContainer = $( "<div class='container' id='bio-container'></div>" );
var bioContainerExpanded = false;
$(bioContainer).hide();
$(teamMember).click(function() {
if(bioContainerExpanded){
$(bioContainer).slideToggle( "slow", function() {});
bioContainerExpanded = false;
}
$('.team-grid').toggleClass('member-active');
// Resets bioContainer html to blank
$(bioContainer).html("");
$(this).toggleClass('member-selected');
// Assign 'this' team bio to variable
var thisBio = $(this).find(".team-bio");
// Assign 'this' row to variable (find teamRow parent of this teamMember)
var thisRow = $(this).parent(teamRow);
// Place bio after row
$(thisRow).after(bioContainer);
// Assign 'this' bio html to variable
var bioHTML = $(thisBio).html();
// Dynamically calculte height of the bio including padding
$height = $(thisBio).outerHeight(true)
//assign height to bioContainer before the toggle so that it slides smoothly
$(bioContainer).css('height', $height);
// Slide toggle the bioContainer
$(bioContainer).slideToggle( "slow", function() {
// Insert bioHTML into 'this' bioContainer
$(this).html(bioHTML);
});
bioContainerExpanded = true;
});
.col-sm-6 {
width:50%;
float:left;
}
img {
width:100%;
height:200px;
object-fit:cover;
cursor:pointer;
}
.close-bio {
color:pink;
font-weight:bold;
}
.team-bio {
visibility: hidden;
padding: 80px 20%;
position: fixed;
top: 0;
left: 0;
width: 100%;
}
#bio-container {
background: #666;
width: 100%;
max-width: none;
position: relative;
float: left;
padding: 25px;
color:#fff;
font-size:20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="team-grid">
<div class="team-row">
<div class="col-sm-6 team-member">
<img src="https://www.catster.com/wp-content/uploads/2017/11/A-Siamese-cat.jpg">
<div class="team-bio">
<div class="team-bio-inner">
JOHN'S Bio
</div>
</div>
</div>
<div class="col-sm-6 team-member">
<img src="https://r.hswstatic.com/w_907/gif/tesla-cat.jpg">
<div class="team-bio">
<div class="team-bio-inner">
SALLY'S Bio
</div>
</div>
</div>
</div>
</section>

change the margin on each slideToggle() call by x%

I want to reduce my containers magin step by step when using slideToggle()
$(document).ready(function() {
$("#btn").click(function() {
doIt();
});
});
function doIt() {
var container = $("#c2");
var maxMarginTop = container.css("marginTop").replace('px', '');
var maxMarginBottom = container.css("marginBottom").replace('px', '');
container.slideToggle({
duration: 2000,
progress: function(animation, progress, remainingMilliseconds) {
var newMarginTop = maxMarginTop - (maxMarginTop * progress);
var newMarginBottom = maxMarginBottom - (maxMarginBottom * progress);
container.css("margin-top", newMarginTop);
container.css("margin-bottom", newMarginBottom);
},
complete: function() {
container.remove();
}
});
}
.container {
margin-top: 20px;
margin-bottom: 20px;
height: 20px;
width: 100px;
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btn">Do it</button>
<div class="container" id="c1">
</div>
<div class="container" id="c2">
</div>
<div class="container" id="c3">
</div>
I have to execute code on each step within the slide function. I calculate the new margin based on the current progress.
So the margin should go from 100% to 0% represented by the progress.
Within the progress function I calculate the new margin and when logging the new values this works fine.
But as you can see nothing happens. When logging the margin value in the complete function nothing changed.
Is it a wrong scope? What is happening there?
The problem with your code is that you have added both top and bottom margin which causes a collapsing margin - ie you only get 20px of margin. Therefore, you may as well start off with one margin and then it will animate properly
Why not do this with css animation:
$(document).ready(function() {
$("#btn").click(function() {
$("#c2").addClass('closed');
});
});
.container {
margin-top: 20px;
/* do not need the bottom margin due to collapsing margins */
height: 20px;
width: 100px;
background: red;
transition: all 2s ease;
}
.container.closed {
height:0;
margin:0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btn">Do it</button>
<div class="container" id="c1">
</div>
<div class="container" id="c2">
</div>
<div class="container" id="c3">
</div>
If you want to carry on using js animations, just remove one of your margins:
$(document).ready(function() {
$("#btn").click(function() {
doIt();
});
});
function doIt() {
var container = $("#c2");
var maxMarginTop = container.css("marginTop").replace('px', '');
var maxMarginBottom = container.css("marginBottom").replace('px', '');
container.slideToggle({
duration: 2000,
progress: function(animation, progress, remainingMilliseconds) {
var newMarginTop = maxMarginTop - (maxMarginTop * progress);
var newMarginBottom = maxMarginBottom - (maxMarginBottom * progress);
container.css("margin-top", newMarginTop);
},
complete: function() {
container.remove();
}
});
}
.container {
margin-top: 20px;
height: 20px;
width: 100px;
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btn">Do it</button>
<div class="container" id="c1">
</div>
<div class="container" id="c2">
</div>
<div class="container" id="c3">
</div>

Moving a DIV horizontally when scrolling vertically

I'm trying to create a script that moves a div from right to left when the user scrolls vertically. It should do this effect to any div with the class of "sidepara". It should only move the div if it is visible (the user has scrolled to it). I'm having trouble getting the math right.... What is the correct formula to move the div horizontally proportionate to the vertical scroll position?
$(function() {
$(window).scroll(function() {
console.clear();
$(".sidepara").each(function() {
var sY = $(this).position().top - $(window).scrollTop(),
dY = $(this).position().top,
wH = window.innerHeight;
var scrollPercent = (sY / (dY - wH));
var position = (scrollPercent * ($(document).width()));
position = window.innerWidth - position;
$(this).css("margin-left", position);
console.log("scoll Y: " + sY);
console.log("div Y: " + dY);
console.log("div X: " + position);
console.log("window height: " + wH);
console.log("scrollPercent: " + scrollPercent);
console.log("----");
//print number for debugging
$(this).html(position);
});
})
});
html,
body {
margin: 0;
padding: 0;
}
.stretch {
height: 2000px;
}
.sidepara {
color: red;
}
.parallaxContainer {
overflow: hidden;
width: 100%;
height: 256px;
background: black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="stretch"></div>
<div class="parallaxContainer">
<!-- <img src="helloworld.png" class="sidepara" /> -->
<div class="sidepara"></div>
</div>
<div class="stretch"></div>
<div class="parallaxContainer">
<!-- <img src="helloworld.png" class="sidepara" /> -->
<div class="sidepara"></div>
</div>
<div class="stretch"></div>
<div class="parallaxContainer">
<!-- <img src="helloworld.png" class="sidepara" /> -->
<div class="sidepara"></div>
</div>
<div class="stretch"></div>
Finally figured out the math! Here is the code for anyone who may like to do something similar.
$(function () {
$(window).scroll(function () {
$(".sidepara").each(function () {
var sY = $(this).position().top - $(window).scrollTop(),
dY = window.innerHeight,
wH = 0;
var scrollPercent = (sY / (dY - wH));
var position = (scrollPercent * ($(document).width() ));
$(this).css("margin-left", position);
});
})
});
html,
body {
margin: 0;
padding: 0;
}
.stretch {
height: 2000px;
}
.sidepara {
font-size: 5em;
color: red;
white-space: nowrap;
}
.parallaxContainer {
overflow: hidden;
width: 100%;
height: 256px;
background: black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="stretch"></div>
<div class="parallaxContainer">
<div class="sidepara">hello world!</div>
</div>
<div class="stretch"></div>
<div class="parallaxContainer">
<div class="sidepara">hellow world!</div>
</div>
<div class="stretch"></div>
<div class="parallaxContainer">
<div class="sidepara">hello world!</div>
</div>
<div class="stretch"></div>

how to scroll to bottom of a div

I would like to scroll to the bottom of the div content-main, so that the button Button is displayed at the bottom of the window. I tried the following:
<div class="container">
<div class="content-main">
dynamic content dynamic content.....
<button>Button </button>
</div>
<div class ="footer"></div>
</div>
<script>
var mainContentHeight = $(".content-main").height();
var footerHeight = $(".content-footer").height();
window.scrollTo(0, mainContentHeight - footerHeight);
</script>
This works differently, when I test it in two monitors with different size. How to display the button at the bottom of the window?
Instead binding scrollTo to the window object, bind it to the element you want to scroll:
var container = $('.container')[0];
var contentMain = $('.content-main')[0];
var mainContentHeight = $(".content-main").height();
var footerHeight = $(".content-footer").height();
container.scrollTo(0, mainContentHeight - footerHeight);
.container {
overflow: auto;
height: 100px;
}
.content-main {
height: 100%;
position: relative;
border: 1px solid #000;
height: 1000px;
}
.content-footer {
height: 50px;
}
button {
position: absolute;
bottom: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="content-main">
dynamic content dynamic content.....
<button>Button </button>
</div>
<div class="content-footer"></div>
</div>

Categories