Jon Chaudhari

The website for the real estate agent included heaps of custom JavaScript, for the filtering of the properties with Angular, for the map page with the overlay calculation and the combination of the data with the map, for the extension of the plugin flexslider to enable the desired in-/off-focus look or the SVG mask animation of the buying process.

The JavaSript was also used to trigger all the nice CSS3 animation for the content loading effects.

The Map

I exported the map overlay as a SVG and mapped the data of the listings with the overlays on the map, the labels are dynamically created and positioned with JavaScript.

I attached a click event handler to the shapes to open a popup with the information about the area.

00:00 / 00:00

The Step animation for the buying process

The percentage based animation of the 5 steps was realized by animating a SVG mask with JavaScript. A scroll listener that moves the SVGs in the scrolled direction, creates an effect of the steps following you down the page.

Example of an animated masked circle 0 - 360 degrees:

5 stepsPROCESS

Example code of an animated mask from 72 to 144 degrees:

 
// initalizing the circleMask for the svg with id "mask2"
// it sets the mask of the svg, radius and start angle
var mask2 = new circleMask();
mask2.init(document.getElementById("mask2"), 121, 72);

// animate from 72 degrees to 144 degrees (when the svg appears on the screen)
...
mask2.draw(144);
...

The SVG with the mask that gets animated:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 242 242" enable-background="new 0 0 242 242" xml:space="preserve"> 
    <defs> 
        <clipPath id="clip2"> 
            <path class="get-steps" id="mask2" data-from="72" data-to="144" d="">
            </path> 
        </clipPath> 
    </defs> 
    <g class="sm-hide" style="clip-path: url(#clip2);"> 
        <linearGradient id="svg_2" gradientUnits="userSpaceOnUse" x1="121" y1="2" x2="121" y2="240" gradientTransform="matrix(1 0 0 -1 0 242)"> 
            <stop offset="0" style="stop-color:#206D9E"/> 
            <stop offset="1" style="stop-color:#3E85B3"/> 
        </linearGradient> 
        <path fill="url(#svg_2)" d="M121,1C54.7,1,1,54.7,1,121s53.7,120,120,120s120-53.7,120-120S187.3,1,121,1z M121,221 c-55.2,0-100-44.8-100-100S65.8,21,121,21s100,44.8,100,100S176.2,221,121,221z"/> 
    </g> 
    <circle class="sm-hide" cx="121" cy="121" r="120" stroke="white" stroke-width="2" fill="transparent"/> 
    <circle cx="121" cy="121" r="100" stroke-width="0" fill="black" fill-opacity="0.4"/> 
</svg>

The code that does the calculations and animations:

// the function that animates the mask
var circleMask = function() {

    this.radius = 1;
    this.angle = 1;
    this.angleTo = 1;
    this.steps = 1;
    this.el = null;
    this.interval = false;
    this.point = {};

    this.init = function(el, radius, angle) {

        this.el = el;
        this.r = radius;
        this.angle = angle;

        this.point = this.polarToCartesian(this.radius, this.radius, this.radius, this.angle);

        var arch_flag = (angle <= 180) ? 0 : 1;

        var d = "M"+this.radius+", "+this.radius+" L"+this.radius+ 
                ",0 A"+this.radius+","+this.radius+" 0 " + arch_flag +
                ",1 " + this.point.x + "," + this.point.y + " z";

        this.el.setAttribute( 'd', d );
    };

    this.polarToCartesian = function (cX, cY, radius, angleInDegrees) {

        var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;

        return {
            x: cX + (radius * Math.cos(angleInRadians)),
            y: cY + (radius * Math.sin(angleInRadians))
        }
    };

    this.draw = function(angleTo) {

        if (this.interval) { clearInterval(this.interval); }

        this.angleTo = angleTo;

        this.steps = (this.angleTo - this.angle) / 100;

        var self = this;

        this.interval = setInterval(function() { self.animate() }, 5);
    };

    this.animate = function() {

        this.angle = this.angle + this.steps;

        // animate and clear interval when done
        ...
    }
};

The Angular app for the listings

I used Angular to filter and paginate the listings data, and CSS3 animations to create a deferred loading effect for each listing.

GET IN TOUCH