Archive for January 25th, 2013

Not sure when this happened, but google.load('jquery', '1') is frozen at 1.7.1. Now the official Google Libraries recommends loading the version explicitly: <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>. That means I have to edit my pages by hand every time they come out with a new version. I suppose that makes things stabler; I don't upgrade until I want to. Annoying for me. Ah, well.

tl;dr: use $.screenfade(callback) to gently fade the screen to white, have the callback make changes, then fade the screen back in.

Download the code.

See the demo.

I like WordPress's full screen editor mode for distraction-free editing, and I especially liked how gradually it fades the full screen in and out. Making a text box fill the screen width is straightforward as long as you remember to set the box-sizing as follows: textarea { width: 100%; box-sizing: border-box; -moz-box-sizing: border-box;}. There's no way to make the box fill the available screen height, though, with CSS alone and we have to resort to Javascript:

	var defaultHeight = $('#editor').height();
$(window).on('resize', function(){
	var restHeight = $('body').outerHeight(true)-$('#editor').height();
	$('#editor').height(Math.max($(window).height()-restHeight, editorHeight));
});

And then use CSS to remove the distractions:

body.fullscreen head, body.fullscreen footer, body.fullscreen nav {display: none}
body.fullscreen article {width: 100%; margin: 0; background: white}

And use $('body').toggleClass('fullscreen'); $(window).trigger('resize') to switch between full screen and full distractions modes.

But the other thing WordPress does is make the transition gradual, fading out the screen then fading the new mode back in, which I find much more pleasant. I initially used CSS3 transitions, which work wonderfully for the CSS changes but we need to trigger the Javascript as well. There is a transitionend event that we could bind to, but that would mean having the height adjust after the other transitions. I didn't like that.

Then I tried fadeOut of the entire body then fading back in, but jQuery adds a display: none at the end of fading out via opacity, so that ended up being too jerky. $('body').animate{opacity: 0} was smooth enough, but left the body background color in place, which then changed abruptly to the new color. $('html').animate{opacity: 0} worked beautifully, almost.

There's a weird Chrome bug (seems to be http://code.google.com/p/chromium/issues/detail?id=131588 but they claim to have fixed it) where the scroll bars lose their alpha-channel when the opacity is less than 1, so they turn black rather than transparent. Ugly (demo page).

So I decided instead of fading out the real elements, I'd fade in a covering element, make my changes, then fade the cover out.

The plugin is called as $.screenfade(callback, [options]) where callback is a function to be called after the fadeout and before the fadein, and options is a bit of a hack: it is passed both as the CSS of the covering element, and as the options object for the animation. Since the two do not have overlapping parameters, it should work. Thus $.screenfade(callback, {background: black, duration: 2000 }) will fade the screen to black over 2 seconds, execute the callback, then fade back to normal over two seconds.