i want to change the background position on scroll with skrollr.js library , my background image has lots of images ( about 500 images ) and i want to change theme on scrolling , how can i do it ?
i want to do something like this code but with skrollr.js library :
$(function() {
var rotator = $('#rotator');
var container = $(document);
var viewport = $(window);
var images = 72;
var imageHeight = 30000 / images;
var scrollHeight = container.height() - viewport.height() + imageHeight;
var step = images / scrollHeight;
viewport.scroll(function(event) {
var x = -Math.floor(step * viewport.scrollTop()) * imageHeight;
rotator.css('background-position', x + 'px 0');
});
});
body {
height: 2000px;
}
#rotator {
font-size: 416px;
width: 1em;
height: 1em;
position: fixed;
top: 0;
right: 0;
z-index: -1;
background: transparent url(http://www.3sessanta.it/images/polaroid/sprite_polaroid_total.jpg) no-repeat 0 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="rotator"></div>
Example Demo
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'm building a transition where I want to scale up a thumbnail to fill the viewport on click.
Currently I got the calculations right on finding the right scale ratio based on the viewport and it's size, but I'm having problems on centring the image in the viewport after it's scaled/expanded.
I only have the problem when I'm using transform-origin: center center; and the image is centered in a fixed full screen container. Here is a jsfiddle showing my problem.
I've also made a jsfiddle showing how it is without the centering. This is close to what I want, except I want to be able to transition the image from other positions rather than the top left corner.
Here is the code I have so far
// Helper fucntions
const getWindowWidth = () => {
return Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
}
const getWindowHeight = () => {
return Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
}
// Get element
const El = document.getElementById('test');
// Add listener
El.addEventListener('click', () => {
// Viewport size
const viewH = getWindowHeight();
const viewW = getWindowWidth();
// El size
const elHeight = El.offsetHeight;
const elWidth = El.offsetWidth;
// Scale ratio
let scale = 1;
// Get how much element need to scale
// to fill viewport
// Based on https://stackoverflow.com/a/28475234/1719789
if ((viewW / viewH) > (elWidth / elHeight)) {
scale = viewW / elWidth;
} else {
scale = viewH / elHeight;
}
// Center element
const x = ((viewW - ((elWidth) * scale)) / 2);
const y = ((viewH - ((elHeight) * scale)) / 2);
// matrix(scaleX(),skewY(),skewX(),scaleY(),translateX(),translateY())
El.style.transform = 'matrix(' + scale + ', 0, 0, ' + scale + ', ' + x + ', ' + y + ')';
});
And some css:
.Container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
#El {
position: absolute;
top: 50%;
left: 50%;
width: 50%;
transform-origin: center center;
transform: translate(-50%, -50%);
transition: transform .3s ease-in-out;
}
The best solution would be getting the current position of the clicked thumbnail (not always centered) and from that scale it to fill the screen. But I'm not really sure where to start to be able to do that.
Is this the effect you are looking for?
CSS:
.Container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
#test {
position: absolute;
top: 50%;
left: 50%;
width: 50%;
transform: translate(-50%, -50%);
transition: all 3.3s ease-in-out;
}
#test.rdy{
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
JS:
// Helper fucntions
const getWindowWidth = () => {
return Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
}
const getWindowHeight = () => {
return Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
}
const El = document.getElementById('test');
El.addEventListener('click', () => {
const viewH = getWindowHeight();
const viewW = getWindowWidth();
const elHeight = El.offsetHeight;
const elWidth = El.offsetWidth;
let scale = 1;
if ((viewW / viewH) > (elWidth / elHeight)) {
scale = viewW / elWidth;
} else {
scale = viewH / elHeight;
}
El.style.width = elWidth * scale + 'px';
El.style.height = elHeight * scale + 'px';
//Add .rdy class in case that position needs resetting :)
document.getElementById('test').className += ' rdy';
});
//A hack to make height transition work :)
window.onload = function(){
El.style.height = El.offsetHeight + 'px';
};
I have a container and and image inside that container. When the container is not in view - the image must be at translate y 0%. When the container is halfway into the viewport and past halfway - the image must be translate y 50%. The % value must be bound to the position of the container into the viewport (controlled by scrolling). The position of the container also determines the speed the image is being translated at. The problem I'm getting is that when the speed value changes, the image jerks up or down instead of changing the speed from that point onward.
Here is my script:
if (wScroll > $(".largeWindow").offset().top - ($(window).height())) {
var cont = $(".largeWindow");
var img = $(".coffee2");
var top = cont.offset().top - cont.height();
var speed;
// translate the image within the container
var moveImage = function() {
setSpeed();
var scroll = Math.floor((wScroll - top)) * speed;
return img.css("transform", "translate(-50%, " + scroll + "%)");
}
// get the position of the image within the container
var getImagePos = function() {
return img.position().top - img.height()/2;
}
var getContainerPos = function() {
var windowHeight = $(window).height();
var contPos = Math.floor(cont.offset().top + cont.height()/2) - wScroll;
return Math.floor(contPos/windowHeight * 100);
}
// set the speed the image will be translated at
var setSpeed = function() {
if (getContainerPos() < 50) {
speed = 0;
}
else if (getContainerPos() < 60 ) {
speed = 0.5
}
else if (getContainerPos() < 70 ) {
speed = 0.5
}
else {
speed = 0.8
}
}
getContainerPos();
moveImage();
getImagePos();
}
Here is the sass for the container and image:
.largeWindow
position: relative
margin: 0 auto
height: 400px
width: 400px
border-radius: 50%
overflow: hidden
background:
image: url(../images/bgTable.jpg)
size: cover
repeat: no-repeat
position: center
attachment: fixed
.coffee2
position: absolute
height: 200px
width: 200px
left: 50%
transform: translateX(-50%)
top: - 200px
background:
image: url(../images/bgCup.png)
size: contain
repeat: no-repeat
position: center
I'd like to know if there's a way to explore the content of a div by moving mouse? like for example having a 1000px*1000px pic inside a 500px*500px div content in overflow:hidden and being able to see the rest of the picture by putting the cursor in the right-bottom side of the div.
And if there's a way how should I proceed ?
Something nice and smooth?
jQuery(function($) {
const $mmGal = $('#mmGal'),
$mmImg = $('#mmImg'),
damp = 10; // 1 = immediate, higher number = smoother response
let X = 0, Y = 0,
mX = 0, mY = 0,
wDiff = 0, hDiff = 0,
zeno, tOut;
// Get image size after it's loaded
$mmImg.one('load', function() {
wDiff = (this.width / $mmGal.width()) - 1;
hDiff = (this.height / $mmGal.height()) - 1;
}).each(function() {
if (this.complete) $(this).trigger("load");
});
$mmGal.on({
mousemove(ev) {
mX = ev.pageX - this.offsetLeft;
mY = ev.pageY - this.offsetTop;
},
mouseenter() {
clearTimeout(tOut);
clearInterval(zeno);
zeno = setInterval(function() { // Zeno's paradox "catching delay"
X += (mX - X) / damp;
Y += (mY - Y) / damp;
// Use CSS transition
$mmImg.css({transform: `translate(${-X * wDiff}px, ${-Y * hDiff}px)`});
// If instead you want to use scroll:
// $mmGal[0].scrollTo(X * wDiff, Y * hDiff);
}, 26);
},
mouseleave() {
// Allow the image to move for some time even after mouseleave
tOut = setTimeout(function() {
clearInterval(zeno);
}, 1200);
}
});
});
#mmGal {
position: relative;
margin: 0 auto;
width: 500px;
height: 220px;
overflow: hidden;
background: #eee;
}
#mmImg {
display: block;
}
<div id="mmGal">
<img id="mmImg" src="https://i.stack.imgur.com/BfcTY.jpg">
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
Here's another similar approach to mousemove element in opposite direction
http://en.wikipedia.org/wiki/Zeno%27s_paradoxes
give widht and height to div wrapped for the image
here is the DEMO
on :hover add overflow: visible; to the div
This is almost what you want. See this fiddle http://jsfiddle.net/sajith/RM9wK/
HTML
<div id="container"><img src="http://farm4.staticflickr.com/3668/12858161173_8daa0b7e54_b.jpg"/></div>
CSS
#container {
width:300px;
height:300px;
overflow: hidden;
}
#container img {
position: relative;
}
Javascript
$(function() {
$( "#container" ).mousemove(function( event ) {
var width = $("#container img").width();
var height = $("#container img").height();
var divWidth = $("#container").width();
var divHeight = $("#container").height();
var xPos = (width / divWidth - 1) * event.pageX
var yPos = (height / divHeight -1) * event.pageY
$("#container img").css('left', '-'+ xPos+'px');
$("#container img").css('top', '-'+ yPos+'px');
});
});
I would use "triggers" (hot spot) ~ add some small div element and set their position as you want, now when mouse enter trigger some events....
Simple Example: jsfiddle
CSS
div.container {
position:relative;
width:100px;
height:100px;
overflow:hidden;
}
.trigger {
right:0;
bottom:0;
position:absolute;
z-index:2;
width:10px;
height:10px;
background-color:transparent;
}
HTML
<div class='container'>
<img src='http://static.adzerk.net/Advertisers/12f0cc69cd9742faa9c8ee0f7b0d210e.jpg' />
<div class='trigger'></div>
</div>
jQuery
$('.trigger').mouseenter(
function(){
$(this).parent('.container').css({
'width':'220px',
'height':'250px'
});
});
$('.container').mouseleave(
function(){
$(this).css({
'width':'100px',
'height':'100px'
});
});
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?