I am trying to position text within a viewport so that as the user scrolls along the viewport the text in the column remains visible for as long as possible. The issue is that the view port may be smaller than the width of the column in the table. So I have something close to working here: http://jsfiddle.net/Deterus/6eU24/15/
$rowDiv.scroll(function (e) {
$headerDiv.css({
left: -$rowDiv[0].scrollLeft + 'px'
});
var thresh = $('.peek').width();
$.leftofscreen("#lookInMe", ".peek", {
threshold: thresh
}).removeClass("textAdjustTL").addClass("textAdjustTR");
$.rightofscreen("#lookInMe", ".peek", {
threshold: thresh
}).removeClass("textAdjustTR").addClass("textAdjustTL");
$.inviewportCenter("#lookInMe", ".peek", {
threshold: 0
}, thresh);
});
This is where I am able to add or manipulate the css needed to keep the row elements at the edge of the viewport. Currently the classes just align the text to the right or left and doesnt allow the sliding nature I need. Any leads would be appreciated.
Related
There's a fixed container that serves as the viewport to my content. The content is a <div> element of a fixed size. The viewport size is bound to the window and may change if the user resizes the window. I'm using the jQuery.panzoom library to handle panning and zooming to let the user view the parts of the content they want. Now I need the following features and can't find them:
The content must never be smaller than required to be completely visible within the viewport. This seems to be done with the minScale option. I just need to wire up the resize events to update the minscale value then.
The content must never be dragged out to one edge if there would be an empty space on the opposite edge. That means, if the content is small enough to be completely visible, it must be completely visible. This must be centered so that the content is always at the same position when zoomed out.
It's like a picture viewer that initially zooms the image to fit and centers it. The user can zoom in, but not zoom out further than the initial view. Only that my content is not an image but a more complex HTML element.
Here's what I've done so far:
<div id="room-wrapper" style="position: fixed; top: 0; left: 150px; right: 0; bottom: 0;">
<div id="room" style="width: 800px; height: 600px;">
Content here.
</div>
</div>
<script>
var roomWrapper = $("#room-wrapper");
// Set up options
var minScaleX = roomWrapper.innerWidth() / 800;
var minScaleY = roomWrapper.innerHeight() / 600;
var minScale = Math.min(minScaleX, minScaleY);
var panzoom = $("#room").panzoom({
startTransform: "scale(" + minScale + ")",
minScale: minScale,
//contain: "invert",
increment: 0.1
});
// Compensate strange offset, doesn't work
panzoom.panzoom("pan", 150, 0, {
animate: false,
silent: true
});
// Mouse wheel zooming
panzoom.parent().on("mousewheel.focal", function (e) {
e.preventDefault();
var delta = e.delta || e.originalEvent.wheelDelta;
var zoomOut = delta ? delta < 0 : e.originalEvent.deltaY > 0;
panzoom.panzoom("zoom", zoomOut, {
animate: true,
focal: e
});
});
</script>
The content is initially zoomed correctly, but offset somewhere to the top and left. I have no idea where that offset comes from. Also, there's no panning contraint yet. The commented out contain may be related but I don't understand any of its documentation.
What do I need to fix in my code to make it meet the above requirements? I guess these are pretty basic and many people would need them but there's no example for that.
I want to move a bootstrap "navbar" header off the page when the navbar's position on the page reaches 400px.
If you look at this jsfiddle, I want the .navbar to leave the top of the page when the blue block begins (at 400px). The navbar would stay on the page through the red div, then leave the top of the page when the blue block begins.
I have tried to do this with scrollorama (jquery plugin), but have not had success yet:
$(document).ready(function() {
var scrollorama = $.scrollorama({ blocks:'.scrollblock' });
scrollorama.animate('#fly-in',{ delay: 400, duration: 300, property:'top', start:-1400, end:0 });
});
I am looking for either a pure javascript solution, or with the scrollorama plugin. Thanks for any ideas!
I'm not very familiar with the scrollorama plugin but you can get this done simply with jQuery via the scroll() event:
$(window).scroll(function () {
var winTop = $(this).scrollTop();
var redHeight = $('#red').height();
if (winTop >= redHeight) {
/*if the scroll reaches the bottom of the red <div> make set '#move' element
position to absolute so it will move up with the red <div> */
$('#move').css({
'position': 'absolute',
'bottom': '0px',
'top': 'auto'
});
} else {
//else revert '#move' position back to fixed
$('#move').css({
'position': 'fixed',
'bottom': 'auto',
'top': '0px'
});
}
});
See this updated jsfiddle: jsfiddle.net/52VtD/1945/
Edit: make it so that the navbar disappears at the same point that the red div ends
I noticed that earlier as well but I'm having trouble locating the problem so I removed your imported style sheet and created a basic style for the navbar. To get the navbar disappears at the same point that the red div ends you need to subtract the navbar's height to the condition:
if (winTop >= redHeight - $('#move').height()) {
I've also restructured the markup to get this working properly. I've nested the navbar inside the red div and set the red div's position to relative.
See this jsfiddle: jsfiddle.net/52VtD/1981/
listen to the scroll event using jquery to find if the navbar overlaps with the red or blue div
Assign a class to the red div
<div class="redDiv" style="height:400px; background-color: red;">
Then listen to the scroll event and use the getBoundingClientRect() to find the co-ord of the navbar and the div in the view port to check for overlap
$(document).scroll(function(event)
{
var rect1 = $('.navbar').get(0).getBoundingClientRect();
var rect2 = $('.redDiv').get(0).getBoundingClientRect();
var overlap = !(rect1.right < rect2.left ||
rect1.left > rect2.right ||
rect1.bottom < rect2.top ||
rect1.top > rect2.bottom)
if(!overlap)
{
if ( $(".navbar").is(":visible") ) {
$('.navbar').hide();
}
}
else
{
if ( !$(".navbar").is(":visible") ) {
$('.navbar').show();
}
}
});
Here is a working fiddle
http://jsfiddle.net/SXzf7/
How can I detect if a piece of text would wrap?
So imagine I have a UI with a header that has largish text. I want the biggest text here that fits vertically in a menu bar. It displays numerical data like this:
LABEL: 9999 LABEL2: 99999
The number parts can get larger. On some screens - e.g. phones - it causes the element to overflow and wrap below the bar that it is supposed to stay in. I don't want to do overflow:hidden. I want the user to see the whole thing.
I'd like to be able to somehow calculate how big the element would be, and if it would wrap pre-emptively shrink the font, possibly move the element left to make space.
You can detect the difference between the different width properties of the containing element's width and scroll width if you set the white-space css handling to nowrap.
Here is a jsFiddle to demonstrate, and the code:
$(document).ready(function(){
$("#messages").append($("#aa").width() + " " + $("#aa").outerWidth() + " " + $("#aa")[0].scrollWidth);
});
#aa {
white-space: nowrap;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.1/jquery.min.js"></script>
<div id="aa">lksjdlakj dla ldakjl skajd lkasjlkdas dlaskdjl aksjd laksdj laks djlkas dlkasjd lkasjdl alkdj laksdj alsklkajlksjad lkajsld kasjldkasjd lkjlsk djlkasdj llaskjdl aksdjlaksjd lkasjdlak sdl</div>
<div id="messages"></div>
Once you know that the scroll width is wider than the width, you can then resize the text or do what you need to do until it isn't.
Nice #WooCaSh. Here is an application in CoffeeScript:
autoGrow = ->
(scope, element, attrs) ->
update = ->
if element[0].scrollWidth > element.outerWidth isBreaking = true else isBreaking = false
element.css 'height', 'auto' if isBreaking
height = element[0].scrollHeight
element.css 'height', height + 'px' if height > 0
scope.$watch attrs.ngModel, update
attrs.$set 'ngTrim', 'false'
# Register
App.Directives.directive 'autoGrow', autoGrow
I'm trying to set the opacity of a series of divs based on their individual proximity to scrollbar position.
This is what I have so far - http://jsfiddle.net/jGeYg/1/
I've managed to set the opacity to 0 when you are at the top of the window and it raise to 1 as you get to the top of div.
What I'm trying to acheive is for it not to start raising in opacity until you are 50px above the div and hit full opacity when you are at the top of the div. Essentially it's range where opacity changes is
$('div').position().top - 50 -> $('div').position().top //psuedo code
I don't want to use a plugin. I'm having trouble with the math rather than the code.
http://jsfiddle.net/b9ZCk/3/
I've added some debug text to show the position and opacity.
I am not sure if this is the desired effect that you want.. but try and let me know,
$(window).scroll(function() {
var st = $(this).scrollTop();
$('.block').each(function(index) {
if (($(this).offset().top-st) < 50) {
$(this).css({
'opacity': (0 + (st / $(this).offset().top))
});
} else {
$(this).css({'opacity': 0.1});
}
})
});
DEMO: http://jsfiddle.net/skram/jGeYg/5/
Edit#1:
Since I asked this problem, I made a script which allows the elements to move together, but with problems. :(
$(this).append(
$('<div class="elem '+classes+'" style="width: 210px; height: 30px" data-modby="'+ui.draggable.attr("data-for")+'"><p>'+text+'</p></div>')
.resizable({
grid: 10,
maxHeight: 120,
maxWidth: 600,
minHeight: 30,
minWidth: 210,
containment: ".box-section"
})
.draggable({
grid: [10,10],
containment: ".box-section",
scroll: false,
helper: "original",
start: function(event, ui) {
posTopArray = [];
posLeftArray = [];
if ($(this).hasClass("r-active")) {
$(".elem.r-active").each(function(i) {
thiscsstop = $(this).css('top');
if (thiscsstop == 'auto') thiscsstop = 0;
thiscssleft = $(this).css('left');
if (thiscssleft == 'auto') thiscssleft = 0;
posTopArray[i] = parseInt(thiscsstop);
posLeftArray[i] = parseInt(thiscssleft);
});
}
begintop = $(this).offset().top;
beginleft = $(this).offset().left;
},
drag: function(event, ui) {
var topdiff = $(this).offset().top - begintop;
var leftdiff = $(this).offset().left - beginleft;
if ($(this).hasClass("r-active")) {
$(".elem.r-active").each(function(i) {
$(this).css('top', posTopArray[i] + topdiff);
$(this).css('left', posLeftArray[i] + leftdiff);
});
}
}
})
);
The actual problem is the moved elements have to stay in the containment box (called .box-section and if I have a single element it works fine. Also if i have two elements has not the same width, if i pick the sorter one and drag, I can pull out the longer of the container.
Also, if I move them fast (like a ninja) they will slip, and they won't be in the same grid they used to be.
30 percent solved since:
I'm going to make a new thingy which can drag and drop items to a box, and resize them.
My problem is that, I can't make them move together. But with some rules.
Rule one: They must move based on a 10x10px grid.
Rule two: They can't move outside their frame.
(Resize is an issue which i simply can't imagine, so I don't care about it, resize will be later)
I made a fiddle for it here: http://jsfiddle.net/9fueY/ you can see this.
In the right side, you can see inputs and a and a checkbox (and on hover a button).
The checkbox is the draggable object, drag it to the image. Now you have some text or a star appeared on the left.
If you type anything to the inputs, it refreshes the text.
OnHover the right boxes you can see a button. By clicking on it, will make a clone of the first element. Drag it inside.
If you click to a right-side box, it will glow blue. Click to two boxes on the right, makes all the two textfields glow blue in the image.
Now this is the case when i want them to move together. :D
What's your opinion, what should I do with this?
Thank you very much. - Répás
There is a plugin i developed for dragging elements together. Please do use it if it makes sense.
https://github.com/someshwara/MultiDraggable