Invert scroll on rotate(180d) - javascript

Having a small problem. (Refer to fiddle)
I've got a container in my project that has been rotated 180 deg, with a container inside that has been rotated another 180 back to the original state.
I need to invert the scroll.
How would i go about this?
Dont mind wasting your time with a method, that reverts the basic setup.
The basic setup has to stay.
http://jsfiddle.net/vavxy36s/
Description of fiddle:
"Start" marks the initial string and "end" ofcourse the last one.
If you try scrolling you will realize, that it's inverted as to how one would normally scroll.
.class1 {
height: 200px;
background-color: blue;
color: white;
width: 100px;
overflow-y: scroll;
overflow-x: hidden;
direction: rtl;
-webkit-transform: rotate(180deg);
}
.class2 {
direction: ltr;
-webkit-transform: rotate(180deg);
}
EDIT: Just mousewheel scroll, has to be inverted.

Edit: Your original setup has different behaviors in Chrome and in [IE & Firefox]. In Chrome, the scroll is already inverted, but in FF and IE, the scroll remains normal. My solution reverts it in both cases, but the behaviors remain different across browsers.
You could add these styles:
/* ...
Your original styles
...
*/
.class1 {
overflow: hidden;
position: relative;
}
.class2 {
position: absolute;
bottom: 0;
}
And then, using jQuery, modify the bottom CSS property of .class2:
var scrollPos = 0,
diff = $('.class2').height() - $('.class1').height();
$('.class1').on('mousewheel', function(e) {
scrollPos = Math.min(
0,
Math.max(
-diff,
scrollPos + e.originalEvent.wheelDelta
)
);
$('.class2').css('bottom', scrollPos);
});
JS Fiddle Demo

You could use the mousewheel library to catch and invert the scroll movement.
$(".class1").mousewheel(function(event) {
event.preventDefault();
this.scrollTop -= (event.deltaY * event.deltaFactor * -1);
});
You can view a demo here: http://jsfiddle.net/fduu20df/1/

Related

iPhone 6 - position: fixed - not loading until stop scrolling

There are a lot of posts on this site that I have read but nothing is working for me and I'm not sure why.
I'm trying to make a menu that "sticks" to the top of the page as you scroll past it and vice versa (stops sticking when you scroll back up)
Javascript
$(document).ready(function(){
var top = $('#FloatingMenu').offset().top - parseFloat($('#FloatingMenu').css('marginTop').replace(/auto/,100))
document.addEventListener("scroll",Scroll,false);
document.addEventListener("gesturechange",Scroll,false);
function Scroll() {
var y = $(this).scrollTop();
if (y >= top) {
$('#FloatingMenu').addClass('fixed');
} else {
$('#FloatingMenu').removeClass('fixed');
}
CSS
#FloatingMenu.fixed {
position: fixed;
top: 0;
left: 0;
z-index: 1;
width: 100%;
background-color: black;
color: red;
}
#FloatingMenu {
background-color: red;
color: black;
width: 100%;
text-align: center;
}
I've tried doing repainting, i've tried stopping the "inertia" scrolling (which I can't get to stop on Chrome on iOS) Either way, everything I've tried has the same results. Works perfectly in a PC or on a Android, but on an iPhone, the menu will not repaint and be "stuck" at the top until the scrolling stops AND the finger is removed from the screen.
Is there a fix for this? Everything I'm reading suggests that there is but notn a single solution has changed anything for me.
The strange thing is, if your scrolling back up (the menu is already stuck at the top) and you scroll past it, it auto un-sticks (even while scrolling) and works fine.
The only time its a problem is when its "repainting" the "fixed" menu.
I hope there is a solution. Everything suggests that after iOS 8 it was fixed (and i'm testing on 10+) but It wont show the menu while scrolling until you stop and let go. Tested on an iPhone 6 and and iPad Air 2. safari and chrome, same results across the board.
I think I solved this question.
It's pretty funny.
Just add to style transform
transform: scaleX(1);
Or
transform: translateX(0);
And it's all
.fixedSidebar{
position: fixed;
right:0;
border:1px solid gray;
height:100vh;
width:17%;
max-width:70px;
transform: scaleX(1);
}
The problem is with position:fixed. This seems to have known issues with safari specifically on mobile devices. After doing some searches for hours, I believe that I may have been able to fix this issue.
The solution I used is to use position:-webkit-sticky for iOS safari and use position:sticky for desktop browsers. More documentation on this property can be found here :
http://caniuse.com/#feat=css-sticky
Can you please try the following code:
CSS:
#FloatingMenu.fixed {
top: 0;
left: 0;
z-index: 1;
width: 100%;
background-color: black;
color: white;
}
#FloatingMenu {
position: -webkit-sticky;
position: sticky;
background-color: lightgray;
color: black;
width: 100%;
height: 60px;
text-align: center;
padding-top: 18px;
font-weight: 800;
}
JS :
$(document).ready(function(){
var top = $('#FloatingMenu').offset().top - parseFloat($('#FloatingMenu').css('marginTop').replace(/auto/,100));
window.addEventListener('scroll',Scroll,false);
function Scroll() {
var y = $(this).scrollTop();
if (y > top) {
$('#FloatingMenu').addClass('fixed');
} else if (y<=top) {
$('#FloatingMenu').removeClass('fixed');
}
}
});
Please note that I have removed the fixed property completely and applied the sticky property to the #FloatingMenu selector itself. Seems to work for me on my iOS simulator safari, and iPhone 6 Safari and on Chrome & Safari in my desktop.
A simple working example of this fix can be found here : Link
Hope this helps. Cheers.
You shouldn't add any event listener for scrolling because it can produce several errors - maybe crashing your browser. This is the first thing you need to change:
JS:
$(document).ready(function(){
var top = $('#FloatingMenu').offset().top - parseFloat($('#FloatingMenu').css('marginTop').replace(/auto/,100));
function Scroll() {
var y = $(this).scrollTop();
if (y >= top) {
$('#FloatingMenu').addClass('fixed');
} else {
$('#FloatingMenu').removeClass('fixed');
}
setInterval(function() {
Scroll();
}, 120);
});
The second thing you need to fix is your "function Scroll". It's right: just a function maded to be called by a DOM element. But what if your event isn't triggered by a DOM element? Maybe that's your problem!
So you can even try adding Event Listener for scrolling just fixing that, but I don't recommend.
JS
function Scroll() {
var y = $('body').scrollTop();
if (y >= top) {
$('#FloatingMenu').addClass('fixed');
} else {
$('#FloatingMenu').removeClass('fixed');
}
PAY ATENTION:
If the first scrollable parent of #FloatingMenu isn't the <body>, you should fix that $('body').

Contenteditable height transition: animate after adding (shift+enter) and removing a line of text

It works so far on using the contenteditable attribute on the <div> tag with the autogrow feature of a textbox. Also the height transition of it. It all works good, except for one thing, deleting characters, to be specific, a line, will not animate its height, unlike adding new lines. I have still a little knowledge on CSS.
.autogrow {
border: 1px solid rgb( 0, 0, 0 );
padding: 10px;
}
#keyframes line_insert {
from {
height: 0px;
}
to {
height: 20px;
}
}
.autogrow[contenteditable] > div {
animation-duration: 250ms;
animation-name: line_insert;
}
.autogrow[contenteditable] {
overflow: hidden;
line-height: 20px;
}
<div class="autogrow" contenteditable="true"></div>
When I press Shift + Enter, it doesn't animate either, it does well though while pressing Enter. Just the removing of lines and the Shift + Enter key combination while entering a new line is the problem.
How to make it work? Can it be done using pure CSS? Or adding a javascript function for it?
To avoid these issues, I personally use a solution not based on pure CSS animations / transitions which I found always have problems. For example, in your CSS implementation, there is a bounce back effect if using the Enter too fast (you can slow the animation down to see it better).
Moreover, new lines handling is different between browsers, some will add <div><br></div>, some versions of IE add only <br>, etc.
I've never been able to fix all these problems or found an implementation fixing all of these so I decided to not modify at all the behavior of the contenteditable, let the browser do is magic which works and instead, react to what's happening.
We don't even have to worry about keys events like Shift + Enter or events like deletion, etc., all of these are natively handled by the navigator.
I choose instead to use 2 elements: one for the actual contenteditable and one for the styling of my contenteditable which will be the one having height animations / transitions based on the actual height of the contenteditable.
To do that, I'm monitoring every events that can change the height of a contenteditable and if the height of my styling element is not the same, I'm animating the styling element.
var kAnimationSpeed = 125;
var kPadding = 10;
$('div[contenteditable]').on('blur keyup paste input', function() {
var styleElement = $(this).prev();
var editorHeight = $(this).height();
var styleElementHeight = styleElement.height();
if (editorHeight !== styleElementHeight - kPadding * 2) {
styleElement.stop().animate({ height: editorHeight + kPadding * 2 }, kAnimationSpeed);
}
});
.autogrowWrapper {
position: relative;
}
.autogrow {
border: 1px solid rgb(0, 0, 0);
height: 40px; /* line-height + 2 * padding */
}
div[contenteditable] {
outline: none;
line-height : 20px;
position: absolute;
top: 10px; /* padding */
left: 10px; /* padding */
right: 10px; /* padding */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="autogrowWrapper">
<div class="autogrow"></div>
<div contenteditable="true"></div>
</div>
It's kinda hacky, but it works.
First, modify your CSS
.autogrow {
border: 1px solid rgb( 0, 0, 0 );
padding: 10px;
}
#keyframes line_insert {
from {
height: 0px;
}
to {
height: 20px;
}
}
.autogrow[contenteditable] > div {
animation-duration: 250ms;
animation-name: line_insert;
}
.autogrow[contenteditable] {
overflow: hidden;
line-height: 20px;
}
Then add this jQuery that detects Shift + Enter events and appends a div whenever they occur
$(".autogrow").keydown(function(e){
if (e.keyCode == 13 && e.shiftKey || e.keyCode == 13)
{
$(this).animate({height: $(this).height()+20},200);
$(this).append('<div><br></div>');
}
});
And that should work.
Check fiddle https://jsfiddle.net/wx38rz5L/582/

How to stop a CSS animation when it meets the screen edge?

I created this demo:
http://cristiantraina.altervista.org/boxfall/
When you click, it creates a red falling box.
The problem is that using only css there are no ways to detect the size of the screen, in fact in my demo I specify that the box has to fall for 1000px, regardless of the actual height of the screen.
This is the code of the keyframe:
#include keyframes("fall"){
to{
top: 1000px;
}
}
I can't use bottom:0px; because I wouldn't know from where to start the fall, and I didn't solve my main problem.
This is the FallBox.js script:
function FallBox(x, side, parent){
this.x = x;
this.parent = parent || $("body");
this.side = side || Math.random()*200;
this.createBox();
this.fall();
}
FallBox.prototype.createBox = function(){
box = document.createElement('div');
$box = $(box); // I hate brackets
$box.addClass("box");
$box.css({
width: this.side+"px",
height: this.side+"px",
left: this.x+"px",
top: "-"+(this.side+5)+"px"
});
this.box = $box;
}
FallBox.prototype.fall = function(){
this.parent.append(this.box);
this.box.addClass("fall");
}
I know that I could use overflow:hidden; in the parent div, but I don't think that this is the ideal solution. First because a user can have got a screen with a superior height, then because I want to the box stops when it meets the edge, as the border was ground and it shouldn't pass through.
Another solution that I found on the web, it's to use the CSSOM API, but not even mozilla developers are sure of the compatibilty of these.
So, how can I stop an animation when it meets the screen edge, since javascript fails to inject properties?
Thank you.
If you're looking for a css-only solution, you could use the css calc feature (http://caniuse.com/#feat=calc) in combination with vh (http://caniuse.com/#search=vh).
document.querySelector(".box").addEventListener("click", function() {
this.classList.toggle("is-dropped");
})
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.box {
position: absolute;
top: 0;
left: 200px;
width: 100px;
height: 100px;
background: red;
transition: top 2s;
}
.box.is-dropped {
top: calc(100vh - 100px);
}
<div class="box"></div>
You coul use the translatey() CSS transform function to shift each div up by 100% of its own height. That way you would just need 2 rules to change the value of the top position without having to worry about height in each case.
(function(d,M){
var div=d.createElement("div"),
wait=0,size;
d.body.addEventListener("click",function(){
if(!wait){
wait=1;
div=div.cloneNode(1);
div.classList.remove("go");// necessary so that newly created divs don't just get added to the bottom of the page
size=M.max(M.floor(M.random()*200),50);
div.style.height=div.style.width=size+"px";
div.style.left=M.max(M.floor(M.random()*this.offsetWidth)-size,0)+"px";
this.appendChild(div);
setTimeout(function(){
div.classList.add("go");// adding this class starts the animation.
wait=0;
},5);
}
},0);
})(document,Math);
*{box-sizing:border-box;margin:0;padding:0;}
html,body{height:100%}
div{
background:#000;
border:1px solid #fff;
transition:top 2s linear;
position:absolute;
top:0;
transform:translatey(-100%);
}
div.go{
top:100%;
}
ORIGINAL SOLUTION
As the height of the box is being set dynamically in your JavaScript, your CSS isn't going to know the height of each box but that doesn't stop you using the CSS calc() function to set the top position you want to animate each to, much like you currently do to set its starting top position. Here's a quick, rough example, with an alternative solution in the comments that doesn't use calc(), if you'd prefer.
var div=document.createElement("div"),
wait=0,size;
document.body.addEventListener("click",function(){
if(!wait){
wait=1;
div=div.cloneNode(0);
size=Math.max(Math.floor(Math.random()*200),50);
div.style.height=div.style.width=size+"px";
div.style.left=Math.max(Math.floor(Math.random()*this.offsetWidth)-size,0)+"px";
div.style.top="-"+size+"px";
this.appendChild(div);
setTimeout(function(){
div.style.top="calc(100% - "+size+"px)"; /* This is the important bit */
// div.style.top=document.body.offsetHeight-size+"px"; /* Alternative solution, without using calc() */
wait=0;
},5);
}
},0);
*{box-sizing:border-box;margin:0;padding:0;}
html,body{height:100%}
div{
background:#000;
border:1px solid #fff;
transition:top 2s linear; /* Using a transition instead of an animation */
position:absolute;
}

Can you fix a div and make it change opacity, size and position as you scroll with CSS3

I'm not even sure how to search this question. But effectively I'm trying to figure out how this website is achieving this fixed opacity/size changing effect on their table: http://sqlzoo.net/wiki/SELECT_within_SELECT_Tutorial . If you scroll down you'll see the effect on the table. When you hover over it it pops out having the data more visible.
The only thing I can think of is using a fixed div that when scrolled past a certain point triggers a jquery UI event that shrinks while decreasing opacity and then an on hover event that reverses this effect.
Achieving this animation in the way I described above seems inefficient and I'm not sure if more (or all) can be done with CSS3. So basically can you achieve the effect shown on the page provided completely or almost completely in CSS3.
Also i looked at the source of the page and couldn't fish it out of the css and scripts they include.
Here's a fiddle of what I have so far. Haven't started on scrolling yet:
HTML
<div id="stuff">Blahblah</div>
CSS
div {
width:250px;
height:250px;
border:2px solid #a1a1a1;
}
JavaScript
$( "#stuff" ).click(function() {
$( "#stuff" ).animate({
width: "20%",
height:"20px",
opacity: 0.4
}, 1500 );
});
http://jsfiddle.net/thed0ctor/1kx5jg1e/
You could do this easily with a combination of CSS3 transform and a bit of Javascript / jQuery:
Demo Fiddle: http://jsfiddle.net/abhitalks/hcwyth8n/2/
Relevant CSS:
#hanger {
width: 200px; height: 200px;
background-color: #00f;
position: fixed; /* Position fixed important */
top: 10px; right: 10px;
opacity: 1;
transition: 0.5s all; /* Animate transitions */
}
#hanger.dim { /* Style to make it appear dimmed */
transform: scale(.75); /* Make it smaller */
opacity: 0.5; /* Make it dimmer */
}
#hanger.dim:hover { /* To change back on hover only when it is dimmed */
transform: scale(1); /* Back to original size */
opacity: 1; /* Back to original opacity */
}
Relevant jQuery Code:
$(window).on("scroll", function() { /* When window scrolls, */
if ($(window).scrollTop() > 50) { /* Check if it scrolls more than 50 pixels */
$("#hanger").addClass("dim"); /* Apply class dim */
} else {
$("#hanger").removeClass("dim"); /* Otherwise remove class dim */
}
});
Hope that helps.
.
Pseudo code only:
window.scroll(function(){
if (window.scrolltop > selectedElement.offset().top){
selectedElement.animate({
transform: scale(.75),
opacity: .5
position: fixed
});
}else{
selectElement.animate({
transform: scale(.75),
opacity: 1
position: static
});
}
});
The links provided in the he pseudo code should point you in the right direction.

Show nav dependant on mouse coordinates

I've found this JS fiddle, which does exactly what I'm looking for. However, I can't seem to figure out how to get it to work when I move the navigation to the side.
var hoverMenu = $('#HiddenMenu'),
hoverSpace = $('#HoverSpace');
hoverSpace.on('mousemove', function(event) {
if(35 - event.clientY < 0) {
hoverMenu.css({top: 35 - event.clientY});
} else {
hoverMenu.css({top: 0});
}
}).on('mouseout', function() {
hoverMenu.css({top: -35});
});
http://jsfiddle.net/PaZHH/1/ <-- this is working example of the clientX/Y event I'm wanting
I can't seem to implement this by using clientX & moving the navigation to the right hand side.
This is where I managed to get too http://jsfiddle.net/PaZHH/102/
Make this changes.
Add absolute positioning to hidden menu:
#HiddenMenu {
background-color: #e00;
position: absolute;
right: -35px;
}
Make the hover space position relative:
#HoverSpace {
position: relative;
background-color: #aeaeae;
overflow: hidden;
width: 45px;
height: 500px;
}
Now, you'll be fine. You can check the result here. It currently works by moving in from right, which is a bit different from you horizontal sample.

Categories