Most read posts this month



Oct 30th 2008 × slidingTips: a mootools apple-style tooltip effect

This is not working since blog upgrade, looking into it

Seems that Apple really inspire design… After having done largerBox: a mootools apple-style modal lightbox effect, I thought I’d also do some animated tooltip effects similar to the ones on their site. So, I finally got around to it and just drafted an element method for the fragged tooltips (called, slidingTips or slidingTips) into my dci_core.js collection.

Not much more to say, here it is in action:

You can interact with all form elements in this div to get a tooltip

show on focus / hide o n blur:

show on click / dispose after 5 seconds:

show on mouseover / hide on mouseout:

The code? First, the Element.implement bits, 2 functions:

Element.implement({
    slidingTip: function(what, options) {
        // apple style tooltip
        var _this = this, coords = _this.getCoordinates(), options = $merge({
            eventEnd: "mouseleave",
            eventEndTrigger: _this,     // parent element or self
            topOffset: 90,             // offset when in full view
            topStartOffset: 100,        // offset for animation start
            opacity: .8,                // target opacity in full view
            className: "tooltip",       // linked to css
            morphOptions: {
                duration: 300,
                transition: Fx.Transitions.Sine.easeOut,
            },
            delay: 0,                    // can dispose on a timer, in seconds
            id: "tid" + $random(100, 1000)
        }, options);

        // we only need one tip instance per parent element.
        if ($type(this.tip) != "element") {
            this.tip = new Element("div", {
                "class": options.className,
                id: options.id,
            });
        }

        // if it's an existing one, with an implicit id, pick it up
        if ($(options.id))
            this.tip = $(options.id);

        // set initial options and html
        this.tip.set({
            opacity: 0,
            html: "<div style='padding:20px'>" + what + "</div>",
            styles: {
                left: coords.left + coords.width / 2
            }
        }).inject(document.body).removeEvents();

        // show it. cancel any previous animation instances for tip
        if ($type(this.morph) == "object")
           this.morph.cancel();
        else
            this.morph = new Fx.Morph(this.tip, options.morphOptions);

        // show it. really.
        this.morph.start({
            opacity: options.opacity,
            top: [coords.top - _this.tip.getSize().y - options.topStartOffset, coords.top - options.topOffset]
        }).chain(function() {
            // once done, decide how to exit
            if (options.delay == 0) {
                // based on an event.
                options.eventEndTrigger.addEvent(options.eventEnd, function() {
                    _this.morph.cancel();
                    _this.slidingTipaway();
                });
            }
            else {
                // based on a timed delay
                (function() {
                    _this.slidingTipaway();
                }).delay(options.delay);
            }
        });

        // define the tooltip close animation morph object
        var closeAnimation = {
            opacity: 0,
            top: coords.top - _this.tip.getSize().y - options.topStartOffset
        }

        // ... and save it within the parent element
        this.store("closeAnimation", closeAnimation);

        return this;
    },
    slidingTipaway: function() {
        // animate an slidingTip, opposite on in method.
        if (this.tip) {
            this.morph.start(this.retrieve("closeAnimation"));
        }

        return this;
    }
});

There is some CSS to this:

<
div.tooltip {
    background:transparent url(/images/tooltip-ie.gif) no-repeat scroll 50% 50%;
    height:90px;
    left:50%;
    margin-left:-151px;
    position:absolute;
    text-align:center;
    top:0;
    width:299px;
    z-index:1010000000;
    color: #327bb2;
    font-weight: bold;
}

And finally, the demo code:

window.addEvent("domready", function() {
    $("demofocus").addEvent("focus", function() {
        this.slidingTip("Please enter your first name and your surname", {
            eventEnd: "blur", // on blur, remove tip
            topOffset: 82 // tuck in more (heigh is 90 usually)
        });
    });

    $("demosubmit").addEvent("click", function(e) {
        e.preventDefault(); // stop submit from happening
        this.slidingTip("Sorry, you are required to complete all fields before you can submit", {
            delay: 5 * 1000, // remove tooltip after 5 seconds
            topOffset: 82
        });
    });

    // find all .demo_mouse class elements and tooltip them to show data-tip values
    $$(".demo_mouse").each(function(el, i) {
        el.addEvents({
            mouseenter: function() {
                this.slidingTip(this.get("data-tip"), {
                    id: "demoid"+i, // can assign implicit ids to shadows for scripting
                    morphOptions: {
                        duration: 600
                    }
                });
            },
            click: function(e) {
                // prevent the submit from working....
                e.preventDefault();
            }
        });
    });

});

Now, the fragged apple slidingTips currently uses this image:

tooltip ie friendly

This is a .GIF so it will be IE friendly (as opposed to a .PNG with transparency). Alpha blending/anti aliasing is not perfect but will work on a light background (hence the white around the demo code).

This one:

tooltip ie friendly

... way nicer. But, on IE7 even (which allegedly supports transparency in PNG), there is a nasty bug and alpha bleeding near the pointy arrow. You can try using it by changing the .tooltip css class.


Sep 17th 2008 × largerBox: a mootools apple-style modal lightbox effect

I saw the animation apple do when viewing a trailer (non-HD) on their modal box and decided to replicate the effect for my image viewing in mootools.

Examples of largerBox v3.0 (animations / morphs / tweens don’t work too nice over iframes, mind)


UPDATE – 24/11/2009 largerBox is in the process of being refactored. largerBox v3 – beta 1 is available to look at and play with. It features a totally drag and drop solution – CSS is built into the javascript class, so are the images for next/previous and close. That’s right, there are no files to edit, updated, upload — aside from your images. Check the new source here: /js/largerBox.js

How does it work?
In the normal way, it takes a <a href=’imagename.jpg’> … </a> and attaches itself to the click event, not interfering in any way with your html. All you need to do is add ‘class=”fullimage”‘ to the anchor tag and fraggedBox will do the rest.

What do I need to get this to work?
You need to grab a copy of mootools 1.2.x – core.

You then need to grab the latest beta. Just look at the demo page anyway…


Sep 16th 2008 × My apple powerbook died. I hated it anyway

In a way, I am happy that it died, now I can leave it in front of our local charity shop and make a homeless person very happy. Or… just one of those dodgy twats that keep on stealing from there at night.

This image was created to commemorate the occasion and the launch of my new “Apple for homeless” campaign:


p.s. It was not really mine, I’d never buy Apple – had to use it for Safari testing at work.