I am trying to detect when a user scrolls up or down on an fixed height element and update the element's transform: translateX CSS value accordingly to scroll the contents either to the left or two the right. However, I can't figure out how to get the proper value from the delta.
document.getElementById("list").addEventListener("wheel", myFunction);
function myFunction(event) {
var matrix = $('.gallery-list').css('transform').split(/[()]/)[1];
var y = parseInt(event.deltaY);
var posX = parseInt(matrix.split(',')[4]);
console.log(y);
console.log(posX);
console.log(y + posX);
//$('.gallery-list').css('transform', 'translateX('+posX + y+'px)');
}
Here is a Codepen here: https://codepen.io/kylehagler/pen/OKxMGr
Add this to your css:
.outside {
width: 100vw;
height: 100vh;
top: 0;
left: 0;
position: absolute;
}
Surround the gallery-list div with:
<div id="outside" class="outside">
Finally, here is the JS:
document.getElementById("outside").addEventListener("wheel", myFunction);
var total = 0;
function myFunction(event) {
var y = parseInt(event.deltaY);
total += y;
$(".gallery-list").css('transform', 'translateX(' + total + 'px)');
}
Related
I trying to create a map framework for some games and i have a problem with recalc position of marker. Look url to test, with wheel you can resize div with image but the dot red not come back to own position. Sorry but im new on this y trying to learn more about js and css. Thanks
$('.map-live').css('width', "928px");
$('.map-live').css('height', "928px");
$('.map-live').css('background-size', "100%");
$('.map-live').bind('mousewheel DOMMouseScroll', function(event) {
var divSize = $('.map-live').css('width');
console.log(divSize);
divSize = divSize.replace('px', '')
divSize = parseInt(divSize);
console.log("oldSize: " + divSize);
var delta_px = event.originalEvent.wheelDelta > 0 ? (divSize + (divSize * 0.15)) : (divSize - (divSize * 0.15));
console.log("NewSize: " + delta_px);
$(this).css('width', delta_px + "px");
$(this).css('height', delta_px + "px");
$(this).css('background-size', "100%");
UpdatePoints();
});
$(function() {
$("#map-live").draggable();
});
document.getElementById('map-live').addEventListener('click', printPosition)
function getPosition(e) {
var rect = e.target.getBoundingClientRect();
var x = e.clientX - rect.left;
var y = e.clientY - rect.top;
return {
x,
y
}
}
function printPosition(e) {
var position = getPosition(e);
console.log('X: ' + position.x + ' Y: ' + position.y);
var divX = parseInt($('.map-live').css('width').replace('px', ''));
var divY = parseInt($('.map-live').css('height').replace('px', ''));
var vhX = (position.x / divX) * 100;
var vhY = (position.y / divY) * 100;
console.log('vhX: ' + vhX + ' vhY: ' + vhY);
}
function UpdatePoints() {
$('.point').css('top', '2.477565353101834vh');
$('.point').css('left', '2.477565353101834vh');
$('.point').css('position', 'absolute');
}
body {
margin: 0;
overflow: hidden;
}
.map-live {
position: absolute;
left: 10px;
z-index: 9;
background-image: url(https://i.ibb.co/d2y5G1y/map.jpg);
width: 222px;
height: 222px;
transition: all 0.2s linear;
}
.point {
position: absolute;
left: 2.477565353101834vh;
top: 2.477565353101834vh;
width: 10px;
height: 10px;
background-color: red;
border-radius: 50%;
}
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="map-live ui-widget-content" id="map-live">
<div class="point"></div>
</div>
jsfiddle.net/f84mto52
Someone can correct me, but I believe your use of position: absolute is what is making the <div class="point"></div> stay in place.
Your UpdatePoints is setting always the same position in the div. With 'vh' you are calculating and absolute position proportional to viewport, no to parent container.
So, you are zooming the background image but the position (x, y) will be always be (x, y), positions are not zoomed. You need to recalculate which is the new position.
So you need to calculate new position.
function UpdatePoints(){
var divW = parseInt($('.map-live').css('width').replace('px',''));
var divH = parseInt($('.map-live').css('height').replace('px',''));
var topPosition = (2.477565353101834 / 928) * divH;
var leftPosition = (2.477565353101834 / 928) * divW;
$('.point').css('top', topPosition+'vh');
$('.point').css('left', leftPosition+'vh');
$('.point').css('position', 'absolute');
}
Also, instead using 'vh' I recommend to calculate the px position instead. I have added the already calculated delta_px parameter to UpdatePoints function:
<style>
.point {
position: absolute;
left: 22.99180647678502px;
top: 22.99180647678502px;
width: 10px;
height: 10px;
background-color: red;
border-radius: 50%;
}
</style>
<script>
function UpdatePoints(delta_px){
var position = (delta_px/100)*2.477565353101834;
$('.point').css('top', position+'px');
$('.point').css('left', position+'px');
$('.point').css('position', 'absolute');
}
</script>
Also, here we are calculating the top-left position of the .point element, not the position for the center. As it is a circle, it work fine, but if you use any other shape the position translation should be calculated from its center.
I recommend to do some research about how to translate elements. You can start here:
Calculating relative position of points when zoomed in and enlarged by a rectangle!
Zoom in on a point (using scale and translate)!
How do I effectively calculate zoom scale?!
I am using the smooth scrollbar plugin and am having issues with elements with position fixed.
I have a div ID 'scroll', the nav, footer and content are inside this
Since transform creates a new local coordinate system(W3C Spec), position: fixed is fixed to the origin of scrollbar content container, i.e. the left: 0, top: 0 point.
Therefore, you may need to register a scroll listener and apply offsets to the fixed element.
I am having issues with the getting the footer (#footer) to work, the nav (#fixed) is working correctly
Any suggestions?
var fixedElem = document.getElementById('fixed');
var footerElem = document.getElementById('footer');
var scrollbar = Scrollbar.init(
document.getElementById('scroll'),
);
scrollbar.addListener(function(status) {
var offset = status.offset;
fixed.style.top = offset.y + 'px';
fixed.style.left = offset.x + 'px';
footer.style.bottom = offset.y + 'px';
footer.style.left = offset.x + 'px';
});
CSS
#fixed {
position: fixed;
top: 0
left: 0;
}
#footer {
position: fixed;
bottom: 0
left: 0;
}
I was playing around with JavaScript/canvas and I want my objects color to depend on the distance to its center from current mouse position.This is my current function that gets color every mousemove event:
function getColorFromDistance(node1,node2){
var dist = getDist(node1,node2); //Getting distance;
var cl = (Math.round(255/dist*255)).toString(16); //this needs to be a propper formula
return "#" + cl + cl + cl; //converting to hex
}
Currently I get a blink effect when the distance gets 255.
I need a way to get the colors strength be depended on the distance, so that the further mouse is away from object the more its darken and when mouse is on the objects center its fully white.Well you get the idea.I just need the formula
The formula would be calculate the distance between the two points and get a percentage based on the maximum value (width of canvas/window)
//this would need to be recalulated on resize, but not doing it for demo
var targetElem = document.querySelector("div.x span");
box = targetElem.getBoundingClientRect(),
x = box.left + box.width/2,
y = box.top + box.height/2,
winBox = document.body.getBoundingClientRect(),
maxD = Math.sqrt(Math.pow(winBox.width/2, 2) + Math.pow(winBox.height/2, 2));
document.body.addEventListener("mousemove", function (evt) {
var diffX = Math.abs(evt.pageX-x),
diffY = Math.abs(evt.pageY-y),
distC = Math.sqrt(Math.pow(diffX, 2) + Math.pow(diffY, 2)),
strength = Math.ceil(255 - (distC/maxD*255)).toString(16),
color = "#" + strength + strength + strength;
targetElem.style.backgroundColor = color;
});
html, body { height: 100%; }
div.x { position: absolute; top: 50%; left:50%; }
span { display: inline-block; width: 20px; height: 20px; border-radius: 50%; border: 1px solid black; overflow: hidden; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p>Test</p>
<div class="x"><span> </span></div>
I have a few elements positioned in my HTML. The body has a max-width from 1280px with margin auto. And there are a few elements, which I floated right. In the middle of the page there should be 70 images go from left to right (and then dissapear). I have tried to make those elements position absolute with display: inline, but since the start and the end position should always be the same, and the images have a width and a height, I didn't know how to make it dynamically.. Thats my code so far:
HTML
<body>
<h1>Sweets</h1>
<div class="images"></div>
<div id="display"></div>
<div class="clear"></div>
<div id="maracons"></div>
<div id="cupCake"></div>
</body>
JQUERY
for (var i = 0; i < 10; i++) {
$('.images').append('<img class="image' + i.toString() + '" src="img/' + arr[i][5] + '">');
}
CSS
$leftPos: 1100px;
$widthImage: 200px;
.images{
width: $widthProducts;
height: 200px;
position: absolute;
left: 1100px;
top: 0px;
}
.image-1{
left: $leftPos;
}
.image-2{
left: $leftPos - $widthImage;
}
.image-3{
left: $leftPos - $widthImage*2;
}
Here is how it looks like:
Confusing question but from what I gather you want the images to have dynamic height/width when you are appending them? If so what do you want to make the width/height equal?
If thats the case here is the answer:
var imgWidth = 10, imgHeight = 10;
for (var i = 0; i < 10; i++) {
imgWidth = 100; //Set width
imgHeight = 100; //Set height
$('.images').append('<img style="width:' + imgWidth +'px!important; height:' + imgHeight + 'px !important; " class="image' + i.toString() + '" src="img/' + arr[i][5] +'">');
}
the !important keyword will force the width/height specified to ignore the width/height specified in the class..
sorry if this is not what you mean, a jsfiddle would be great.
UPDATE
Check this fiddle:
http://jsfiddle.net/xP8Qb/
Here is the kinda thing you were looking for:
$(document).ready(function () {
var endpoint = 800; //you can set left+top endpoints and ref them in loop below..
for (var i = 0; i < 3; i++) {
var html = '<div class="imgs img'+i+'"></div>';
setTimeout(function() {
$('.images').append(html);
$('.images>.imgs:last').animate({"left" : "300px"}, endpoint);
}, i * 1000);
}
});
i can work on it more if needed, but hopefully this is enough to put you on the right track..
I have implemented a parallax scrolling effect based on a tutorial I found. The effect works great. However, when I specify the background images, I am unable to control the y (vertical) axis. This is causing problems because I'm trying to set locations on multiple layered images.
Any thoughts on what's causing the problem?
Here is one external script:
$(document).ready(function(){
$('#nav').localScroll(800);
//.parallax(xPosition, speedFactor, outerHeight) options:
//xPosition - Horizontal position of the element
//inertia - speed to move relative to vertical scroll. Example: 0.1 is one tenth the speed of scrolling, 2 is twice the speed of scrolling
//outerHeight (true/false) - Whether or not jQuery should use it's outerHeight option to determine when a section is in the viewport
$('#mainimagewrapper').parallax("50%", 1.3);
$('#secondaryimagewrapper').parallax("50%", 0.5);
$('.image2').parallax("50%", -0.1);
$('#aboutwrapper').parallax("50%", 1.7);
$('.image4').parallax("50%", 1.5);
})
This is another external script:
(function( $ ){
var $window = $(window);
var windowHeight = $window.height();
$window.resize(function () {
windowHeight = $window.height();
});
$.fn.parallax = function(xpos, speedFactor, outerHeight) {
var $this = $(this);
var getHeight;
var firstTop;
var paddingTop = 0;
//get the starting position of each element to have parallax applied to it
$this.each(function(){
firstTop = $this.offset().top;
});
if (outerHeight) {
getHeight = function(jqo) {
return jqo.outerHeight(true);
};
} else {
getHeight = function(jqo) {
return jqo.height();
};
}
// setup defaults if arguments aren't specified
if (arguments.length < 1 || xpos === null) xpos = "50%";
if (arguments.length < 2 || speedFactor === null) speedFactor = 0.1;
if (arguments.length < 3 || outerHeight === null) outerHeight = true;
// function to be called whenever the window is scrolled or resized
function update(){
var pos = $window.scrollTop();
$this.each(function(){
var $element = $(this);
var top = $element.offset().top;
var height = getHeight($element);
// Check if totally above or totally below viewport
if (top + height < pos || top > pos + windowHeight) {
return;
}
$this.css('backgroundPosition', xpos + " " + Math.round((firstTop - pos) * speedFactor) + "px");
});
}
$window.bind('scroll', update).resize(update);
update();
};
})(jQuery);
Here is the CSS for one section:
#aboutwrapper {
background-image: url(../images/polaroid.png);
background-position: 50% 0;
background-repeat: no-repeat;
background-attachment: fixed;
color: white;
height: 500px;
width: 100%;
margin: 0 auto;
padding: 0;
}
#aboutwrapper .image4 {
background: url(../images/polaroid2.png) 50% 0 no-repeat fixed;
height: 500px;
width: 100%;
margin: 0 auto;
padding: 0;
}
.image3{
margin: 0 auto;
min-width: 970px;
overflow: auto;
width: 970px;
}
Both of these are being called to achieve the parallax scrolling. I really just want to more specifically control the background image locations. I've tried messing with the CSS background position and I've messed with the first javascript snippet as well. No luck.
just a quick shot, have you tried actually placing the images, either in a div or just using the img src tag to actually move the element rather than manipulating the y axis of a background image?