admin管理员组文章数量:1297024
How can I make a div scroll diagonally? A regular scroll would go up/down or left/right, but I'd like to make the div scroll up and to the right or down and to the left.
See visual representation
How can I make a div scroll diagonally? A regular scroll would go up/down or left/right, but I'd like to make the div scroll up and to the right or down and to the left.
See visual representation
Share Improve this question edited Feb 4, 2013 at 22:02 Jeromy French 12.1k19 gold badges78 silver badges135 bronze badges asked Feb 4, 2013 at 21:46 supersizesupersize 14.8k19 gold badges85 silver badges144 bronze badges 5- I am not sure I understand. The image just shows to rectangles askew, not tited... – user1477388 Commented Feb 4, 2013 at 21:52
- I know many people don't like W3 Schools, but take a look at this to see if it answers your question w3schools./css3/css3_2dtransforms.asp – user1477388 Commented Feb 4, 2013 at 21:55
- dont know who was so kind and corrected me that but, yeah i was a lil bit wrong with my explanation! have another look to the top :) – supersize Commented Feb 4, 2013 at 22:04
- What do you mean when you say scrolling? Do you mean a jQuery animation? – ylysyym Commented Feb 4, 2013 at 22:05
- no i mean scrolling with the scrollbar or mousewheel. not jquery events... – supersize Commented Feb 4, 2013 at 22:08
3 Answers
Reset to default 6EDIT: as required by the OP, I've updated the example code to introduce a correction factor, required to change the diagonal movement direction and degree.
If you want to use jQuery you'll have to download the MouseWheel plugin.
Then, you can write a simple function binded to the mousewheel
event, such as:
HTML
<div id="block"></div>
CSS
#block {
position: absolute;
width: 200px;
height: 150px;
top: 200px;
left: 50px;
background-color: red;
}
Alternative 1: JS using CSS top and left
$(function(){
$(window).on('mousewheel', function(evt,delta){
var $block = $('#block'),
// retrieves the top and left coordinates
top = parseInt($block.css('top')),
left = parseInt($block.css('left')),
// mouse wheel delta is inverted respect to the direction, so we need to
// normalize it against the direction
offset = -1 * delta,
// X and Y factors allows to change the diagonal movement direction and
// degree. Negative values inverts the direction.
factorX = 5,
factorY = 2,
// calculates the new position. NOTE: if integers only are used for factors,
// then `Math.floor()` isn't required.
newTop = top + Math.floor(offset * factorY),
newLeft = left - Math.floor(offset * factorX);
// moves the block
$block.css({
top: newTop + 'px',
left: newLeft + 'px'
});
});
});
Alternative 2: JS using offset()
$(function(){
$(window).on('mousewheel', function(evt,delta){
var $block = $('#block'),
// retrieves the top and left coordinates
position = $block.offset(),
// mouse wheel delta is inverted respect to the direction, so we need to
// normalize it against the direction
offset = -1 * delta,
// X and Y factors allows to change the diagonal movement direction and
// degree. Negative values inverts the direction.
factorX = 5,
factorY = 2,
// calculates the new position. NOTE: if integers only are used for factors,
// then `Math.floor()` isn't required.
newTop = position.top + Math.floor(offset * factorY),
newLeft = position.left - Math.floor(offset * factorX);
// moves the block
$block.offset({ top: newTop, left: newLeft });
});
});
Now you can move the box up&right by scrolling up and vice-versa by scrolling down.
In this example, on every mousewheel
event, the callback function:
- retrieves the current element position (
top
andleft
CSS properties) - inverts the delta value returned by the
mousewheel
event, so that scrolling up we have a negative delta, and scrolling down we have a positive delta - set the factor values required to define diagonal movement direction and degree
- calculates the new position
- moves the object.
To change degree and direction, just change factorX
and/or factorY
values, so that:
- negative values inverts the direction, and
- different values change the degree (for example, X = 2 and Y = 5 makes the element moving with a much more closed angle, respect to X = 5 and Y = 2).
Here's a demo you can test.
Alternative 3: JS using cos() and sin()
$(function(){
$(window).on('mousewheel', function(evt,delta){
var $block = $('#block'),
// read current block position
position = $block.offset(),
// inverts the delta; scroll up == -1 - scroll down == +1
direction = -1 * delta,
// sets the angle and converts it in radians
angle = 45 * Math.PI / 180,
// set displacememt factor
factorX = Math.cos(angle) * direction,
factorY = Math.sin(angle) * direction,
// calculate the new position
newTop = position.top + factorY,
newLeft = position.left - factorX;
// moves the block
$block.offset({ top: newTop, left: newLeft });
});
});
In this example, what to change is the value in angle
(45 in this example). Everything else works just like the others examples.
Last thing, if it's required to change the velocity of the movement, just multiply factorX
and/or factorY
by the wanted coefficient (for example, 1.5 for one and half time of the velocity, or 2 for twice the velocity, etc.).
It's possibile to try it in a demo.
EDIT
Just for the sake of knowledge, you can reach the same goal using CSS Transform. This allows you to take advantage from GPU accelerated hardware. (Further informations can be found in the article of Smashing Magazine and Paul Irish).
HTML
<div id="block"></div>
CSS
#block {
width: 200px;
height: 150px;
background-color: red;
transform: translate3d(0, 0, 0);
}
JS
$(function(){
var blockOffsetX = 50,
blockOffsetY = 200;
$('#block').css({
transform: 'translate3d(' + blockOffsetX + 'px' + ', ' + blockOffsetY + 'px, 0)'
});
$(window).on('mousewheel', function(evt,delta){
var $block = $('#block'),
offset = -1 * delta;
factorX = 5,
factorY = 2;
blockOffsetX -= offset * factorX;
blockOffsetY += offset * factorY;
$block.css({
transform: 'translate3d(' + blockOffsetX + 'px, ' + blockOffsetY + 'px, 0)'
});
});
});
However, as you can see in this example, you'll need to keep track of the element X,Y position, because it's a little bit plicated to retrieve these values directly from the CSS. Moreover, this example is kept easier, but in production you'll have to support every vendor specific CSS property (-webkit-
, -moz-
, -o-
, -ms-
, etc.).
Here's a working demo (if it doesn't work, you probably will have to edit the code according to the specific prefixed CSS property for your browser).
EDIT: Since the OP has seen that listening to the scroll
event it was the better choice for him, I've added the relative code (only the JS code is reported here, since HTML and CSS are pretty the same as the first example):
$(function(){
var lastScrollYPos = 0;
$(window).on('scroll', function(){
var $this = $(this),
$block = $('#block'),
// retrieves the top and left coordinates
position = $block.offset(),
// X and Y factors allows to change the diagonal movement direction and
// degree. Negative values inverts the direction.
factorX = 1,
factorY = 1,
// retrieves current vertical scrolling position and calculate the
// relative offset
scrollYPos = $this.scrollTop(),
offset = Math.abs(scrollYPos - lastScrollYPos),
// mouse wheel delta is inverted respect to the direction, so we need to
// normalize it against the direction
direction = scrollYPos > lastScrollYPos ? -1 : 1,
// calculates the new position. NOTE: if integers only are used for factors,
// then `Math.floor()` isn't required.
newTop = position.top + Math.floor(direction * offset * factorY),
newLeft = position.left - Math.floor(direction * offset * factorX);
// moves the block
$block.offset({ top: newTop, left: newLeft });
lastScrollYPos = scrollYPos;
});
});
Here's a working demo.
BONUS: IDEA
Instead of use mon local variables for every element, HTML5 data-*
properties could be used to store element's data (for example: correction factor, last position, etc.), then jQuery .data()
method could be used to retrieve these data and process them.
PRO:
- Decouple the callback function from the element
- Customize every element on the page to act differently from each other
CONS:
- It will probably affect the rendering performance in some way, especially whether many elements have to be managed at same time by the callback function.
You can use the onScroll event, detect if the user is scrolling vertically or horizontally and then appropriately scroll the other direction.
Example:
JS
var lastScrollTop = 0;
$("#diagonalscroller").scroll(function(e) {
var scrollTop = $(this).scrollTop();
if (scrollTop === lastScrollTop) {
// Vertical scroll position is unchanged, so we're scrolling horizontal.
$(this).scrollTop($(this).scrollLeft());
} else {
// Vertical scroll position has changed, so we're scrolling vertical.
$(this).scrollLeft($(this).scrollTop());
}
lastScrollTop = scrollTop;
});
HTML
<h1>Try scrolling using the scrollbars</h1>
<div id="diagonalscroller">
<img src="http://dummyimage./800/" />
</div>
CSS
#diagonalscroller {
width: 200px;
height: 200px;
overflow: scroll;
}
Watch the Demo.
Old question.. but who ever es across this question might like
this pen
It's a concept for a diagonal webpage layout.
The code is to big to post here and it is probably more than the OP asked.
Gotta post code so. here's the part that does the magic. (using Modernizr for cross browser support)
var $window = $(window);
var con = $('#content');
$window.on('touchmove scroll', function() {
var winScroll = $window.scrollTop() * -1;
if (!Modernizr.csstransforms3d && Modernizr.csstransforms) {
con.css({
transform: 'translate(' + winScroll + 'px,' + winScroll + 'px)'
});
} else if (Modernizr.csstransforms3d) {
con.css({
transform: 'translate3d(' + winScroll + 'px,' + winScroll + 'px,0)'
});
} else {
con.css({
left: winScroll,
top: winScroll
});
}
});
本文标签: javascriptscrolling a div diagonallyStack Overflow
版权声明:本文标题:javascript - scrolling a div diagonally - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741632129a2389427.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论