I am writing this after hundreds of references. I want to create/or Nest Thermostat like scrolling effect. I found this solution https://jsfiddle.net/desandro/daZmA/ but its parent has fixed position. Which I can't use within the website.
window.addEventListener( 'load', function() {
var box = document.getElementById('box'),
docHeight = document.documentElement.offsetHeight;
window.addEventListener( 'scroll', function() {
// normalize scroll position as percentage
var scrolled = window.scrollY / ( docHeight - window.innerHeight ),
transformValue = 'scale('+scrolled+')';
box.style.WebkitTransform = transformValue;
box.style.MozTransform = transformValue;
box.style.OTransform = transformValue;
box.style.transform = transformValue;
}, false);
}, false);
body {
height: 2000px;
}
#container {
width: 200px;
height: 200px;
border: 2px solid;
position: fixed;
}
#box {
width: 100%;
height: 100%;
background: red;
}
<div id="container"><div id="box"></div></div>
Can anybody assist me or suggest a good reference or a existing plugin to use?
Thanks in advance
I highly recommend the GSAP scrollTrigger plugin.
https://greensock.com/scrolltrigger/
https://greensock.com/docs/v3/Plugins/ScrollTrigger
https://codepen.io/GreenSock/pen/gOabMXv
https://greensock.com/st-demos/
It makes animating elements based on scroll position very easy. For example
gsap.timeline({
scrollTrigger: {
trigger: ".thermo",
start: "center center",
end: "bottom top",
scrub: true,
pin: true
}
})
.from(".dial", { y: innerWidth * 1.5 })
Related
I am trying to get google maps to fill out the whole content area minus a fixed header and fixed footer.
I have used the following CSS
.google-maps {width: 100%; height: 100%; margin-left:auto; margin-right:auto;}
.google-maps {position: relative; padding-top: 30px; height: 0; overflow: hidden;}
.google-maps iframe {position: absolute; top: 0; left: 0; width: 100%; height: 100%;}
and this script to calculate the padding-bottom, which would define the height:
<script>
var setHeight = function() {
var topHeight = $('.regular-header').outerHeight();
var bottomHeight = $('.sticky-footer').outerHeight();
var contentHeight = $(window).height() - (topHeight + bottomHeight);
$('.google-maps').css({'padding-bottom': contentHeight + 'px'});
}
$(window).load(function() {
setHeight();
});
$(window).resize(function() {
setHeight();
});
</script>
but I kind of think I am overcomplicating it and also can't get it to work.
What am I doing wrong?
Check my solution on a codepen!
I've changed $(window).load --> $(window).on('load')
var resizeTimer;
var setHeight = function() {
var topHeight = $('.regular-header').outerHeight();
var bottomHeight = $('.sticky-footer').outerHeight();
var contentHeight = $(window).height() - (topHeight + bottomHeight);
$('.google-maps').css({'padding-bottom': contentHeight + 'px'});
}
$(window).on('load', function() {
setHeight();
}).on('resize', function() {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(function() {
setHeight();
}, 250);
});
Also, if you're used to something like jQuery UI resizeable, you get events you can bind to during the resizing, but also at the end of resizing. So, I've added a debounce function.
Note: I've asked this question again because I was not be able to edit my old question. (No idea if this was a SO bug or a bug with my beta safari.)
So I want to generate a joystick, as it is used in many games. The joystick stands out of a background and a movable billet. The billet may only be moved within the background.
Here you can find both images
let background = new Image()
let stick = new Image()
let enableMaxDistance = false
background.onload = function() {
$(this).css({
position: "absolute",
left: "2%",
bottom: "2%",
width: "30%"
}).appendTo(document.body)
}
stick.onload = function() {
$(this).css({
position: "absolute",
left: "2%",
bottom: "2%",
width: "30%"
}).appendTo(document.body)
let zeroPosition = $(this).offset()
$(this).draggable({
drag: function(e, ui) {
let distance = Math.sqrt(Math.pow(zeroPosition.top - $(this).offset().top, 2) + Math.pow(zeroPosition.left - $(this).offset().left, 2));
if (distance > 60 && enableMaxDistance) {
e.preventDefault();
}
},
scroll: false
})
}
background.src = "https://i.stack.imgur.com/5My6q.png"
stick.src = "https://i.stack.imgur.com/YEoJ4.png"
html, body {
overflow: hidden;
height: 100%;
}
input {
margin-top: 10%;
margin-left: 50%;
}
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<input onclick="enableMaxDistance = !enableMaxDistance " value="toggle maximum distance" type="button"/>
But while implementing this joystick some problems occurred:
My idea was to make the stick maneuverable by using jqueryUI and to calculate its distance to the origin with each drag event. If the distance is too large, the event will be stopped (not executed) using e.preventDefault();. --> If the distance in the frame, the stick is wearable.
The problem is that ...
The stick is no longer draggable after moving out the maximum distance.
The stick should be just be movable inside the bounds without canceling the event so that I have to grab the stick again and again if I'm touching the bounds (going out of the maximum distance).
How to implement a working joystick using jQuery + jQueryUI?
The issue with your logic is that as soon as the drag event is prevented the distance value will be over 60 due to the inherent delays in JS processing time. Therefore the logic in the next drag is immediately cancelled as the distance > 60 check is immediately hit. While it would be possible to fix this, a much better solution would be to not allow the value to ever be greater than the limit you set.
To achieve this I would not recommend using jQueryUI. You can do it quite easily using native methods which give you more direct control of the positioning without having to fight against any built in logic.
It's also slightly more performant, which is vital when dealing with game mechanics; especially when dealing with direct user input which needs to be as responsive as possible.
With that said, you can use modify the basic logic as laid out in Twisty's comment on this question. Then it simply becomes a question of changing the size of the relevant elements, which is a trivial task. Try this:
var $canvas = $('#background');
var $pointer = $('#stick');
var $window = $(window);
var settings = {
width: $canvas.prop('offsetWidth'),
height: $canvas.prop('offsetHeight'),
top: $canvas.prop('offsetTop'),
left: $canvas.prop('offsetLeft')
};
settings.center = [settings.left + settings.width / 2, settings.top + settings.height / 2];
settings.radius = settings.width / 2;
let mousedown = false;
$window.on('mouseup', function() { mousedown = false; });
$pointer.on('mousedown', function() { mousedown = true; });
$pointer.on('mouseup', function() { mousedown = false; });
$pointer.on('dragstart', function(e) { e.preventDefault(); });
$window.on('mousemove', function(e) {
if (!mousedown)
return;
var result = limit(e.clientX, e.clientY);
$pointer.css('left', result.x + 'px');
$pointer.css('top', result.y + 'px');
});
function limit(x, y) {
var dist = distance([x, y], settings.center);
if (dist <= settings.radius) {
return {
x: x,
y: y
};
} else {
x = x - settings.center[0];
y = y - settings.center[1];
var radians = Math.atan2(y, x)
return {
x: Math.cos(radians) * settings.radius + settings.center[0],
y: Math.sin(radians) * settings.radius + settings.center[1]
}
}
}
function distance(dot1, dot2) {
var x1 = dot1[0],
y1 = dot1[1],
x2 = dot2[0],
y2 = dot2[1];
return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
}
html,
body {
height: 100%;
}
#background {
background-image: url('https://i.stack.imgur.com/5My6q.png');
position: absolute;
height: 200px;
width: 200px;
top: 50%;
left: 50%;
margin: -100px 0 0 -100px;
border-radius: 200px;
border: dashed #ccc 1px;
}
#stick {
background: transparent url('https://i.stack.imgur.com/YEoJ4.png') 50% 50%;
position: absolute;
width: 100px;
height: 100px;
border-radius: 100px;
margin: -50px 0 0 -50px;
top: 50%;
left: 50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="background"></div>
<div id="stick"></div>
Found a lightway draggable function. How can I lock the draggable black block in parent area? Do i need to do a width and height to limit black block area?
online sample http://jsfiddle.net/zqYZG/
.drag {
width: 100px;
height: 100px;
background-color: #000;
}
.box{
width: 500px;
height: 400px;
background-color:red;
}
jQuery
(function($) {
$.fn.draggable = function(options) {
var $handle = this,
$draggable = this;
options = $.extend({}, {
handle: null,
cursor: 'move'
}, options);
if( options.handle ) {
$handle = $(options.handle);
}
$handle
.css('cursor', options.cursor)
.on("mousedown", function(e) {
var x = $draggable.offset().left - e.pageX,
y = $draggable.offset().top - e.pageY,a
z = $draggable.css('z-index');
$draggable.css('z-index', 100000);
$(document.documentElement)
.on('mousemove.draggable', function(e) {
$draggable.offset({
left: x + e.pageX,
top: y + e.pageY
});
})
.one('mouseup', function() {
$(this).off('mousemove.draggable');
$draggable.css('z-index', z);
});
// disable selection
e.preventDefault();
});
};
})(jQuery);
$('.drag').draggable();
Here is a simple way to do it, using the getBoundingClientRect() function: updated JSFiddle
This just constrains the l and t variables from your original code, to be within the parent node's dimensions.
See containment option!
use :
$( ".selector" ).draggable({ containment: "parent" });
This is the fiddle!
The image should move up until it's bottom edge reaches the bottom of div and then move down until it's top edge reaches the top edge of parent div, to reveal it.
This has to work with different sized images.
$(document).ready(function() {
move();
});
function move() {
$(".image").animate({
bottom: "-=50%"
}, 10000, 'linear', function() {
$(".image").animate({
bottom: "+=50%"
}, 10000, 'linear', move);
});
}
.container {
position: relative;
width: 1100px;
height: 480px;
overflow: hidden;
background-color: #000;
}
.image {
position: absolute;
max-width: 100%;
min-width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<img class="image" src="http://www.hotel-aramis.com/slider/home/notre-dame-de-paris.jpg />
</div>
Something like this seems to work:
$(document).ready(function () {
move();
});
function move() {
$img = $(".image");
var i = new Image();
i.src = $img.attr('src');
var d = i.height - $('.container').height();
$img.animate({
bottom: "+="+d+'px'
}, 10000, 'linear', function () {
$img.animate({
bottom: "-="+d+'px'
}, 10000, 'linear', move);
});
}
This is a little sneaky, it creates a new javascript image Object (non Jquery) using the same src as the selected one and uses its natural height to perform the animation. It seems that if we create a jQuery object its height isn't the same, maybe it needs to be attached to the dom or similar.
Jsfiddle: http://jsfiddle.net/VqzvR/8/
moving the setup code outside of the move() function will mean that the http get (for the img src) will only be performed once:
$(document).ready(function () {
setupMove();
});
function setupMove() {
$img = $(".image");
var i = new Image();
i.src = $img.attr('src');
var d = i.height - $('.container').height();
function move() {
$img.animate({
bottom: "+="+d+'px'
}, 10000, 'linear', function () {
$img.animate({
bottom: "-="+d+'px'
}, 10000, 'linear', move);
});
}
move();
}
Is this the effect you were looking for?
I want to make a small status bar at the bottom right of the screen.
But extjs sets the values of "top" and "left", and The result is stretched in the center window.
var swindow = new Ext.Window({
width:100,
style:'position:fixed; right:0;bottom:0;',
baseCls:'lk-sysstate-spanel',
shadow: false,
closable:false,
hideBorder: false,
plain: true,
items:[
historyPanel,
smallPanel
]
});
css result in a browser
element.style {
bottom: 0;
display: block;
left: 675px;
position: fixed;
right: 0;
top: -5000px;
visibility: visible;
width: 98px;
z-index: 9003;
}
Use ExtJs 3.4
You can add listener to window and remove left/top styles. Example:
var swindow = new Ext.Window({
[...]
listeners: {
show: function() {
this.el.setStyle('left', '');
this.el.setStyle('top', '');
}
}
});
Working sample: http://jsfiddle.net/dnpTt/4/
Test in ExtJS 5.0.1
var w = window.innerWidth;
var h = window.innerHeight;
var swindow = new Ext.Window({
[...]
listeners: {
show: function() {
this.setX(w -this.getWidth());
this.setY(h -this.getHeight());
}
}
});