Flickr 首页效果分析

07 Nov 2013

Flickr(http://www.flickr.com),雅虎旗下图片分享网站。为一家提供免费及付费数位照片储存、分享方案之线上服务,也提供网络社群服务的平台。其重要特点就是基于社会网络的人际关系的拓展与内容的组织。这个网站的功能之强大,已超出了一般的图片服务,比如 图片服务、联系人服务、组群服务。

首页截图1

首页截图1

首页截图2

首页截图1

首页截图3

首页截图1

这里有几个有趣的功能:

  1. 截图3中的弹出的注册提示框,这个是在页面滚动到一定程度后才会出现的。

    function checkCTA() {
        // show or hide CTA, depending on whether user is looking at the Justified view.
        var frameContentInView = frameContent.vis.isVisible();
    
        if (!ctaVisible && !frameContentInView) {
                ctaWrapper.addClass('transitioning');
                window.setTimeout(function() {
                    ctaWrapper.removeClass('hidden');
                    ctaWrapper.addClass('visible');
                    ctaVisible = true;
                }, 20);
    
                window.setTimeout(function() {
                    ctaWrapper.removeClass('transitioning');
                }, 300);
    
        } else if (ctaVisible && frameContentInView) {
            ctaWrapper.addClass('transitioning');
            ctaWrapper.removeClass('visible');
            window.setTimeout(function() {
                // additional CSS to actually hide element, post-transition
                if (!ctaVisible) {
                    ctaWrapper.addClass('hidden');
                }
    
                // in either event, remove transitioning.
                ctaWrapper.removeClass('transitioning');
            }, 300);
    
            ctaVisible = false;
        }
    }
    

    注意到显示和消失的过程中,有一个很短的动画,这是通过下面的CSS来实现的。

    #huge-cta-wrapper .bd {
        position: relative;
        display: inline-block;
    
        /* lazy transition-all */
        -moz-transition: all 0.225s ease-out;
        -ms-transition: all 0.225s ease-out;
        -webkit-transition: all 0.225s ease-out;
        transition: all 0.225s ease-out;
    
        /* specifics */
        -moz-transition-property: -moz-transform, opacity;
        -ms-transition-property: -ms-transform, opacity;
        -webkit-transition-property: -webkit-transform, opacity;
    
        /* default state */
        -webkit-transform: scale(1.1);
        -ms-transform: scale(1.1);
        -moz-transform: scale(1.1);
        transform: scale(1.1);
        opacity: 0;
    }
    
  2. 截图1中的背景,在页面滚动时会有相应的变化,比如图中的相机镜头,会上下移动。

    function refresh(docScrollY) {
        var i, j, scroll, transformParam;
        i = 0;
        bgElements.each(function(bgElement) {
            scroll = -Math.round(((docScrollY - offset) / containerHeight)
                    * maxScrolls[i]);
            scroll = Math.max(scroll, maxScrolls[i]);
            var transformParam;
            if (!use2DTransform) {
                transformParam = 'translate3d(0px,' + scroll + 'px, 0px)';
            } else {
                transformParam = 'translateY(' + scroll + 'px)';
            }
            if (transform && transformParam) {
                bgElement.setStyle(transform, transformParam);
                bgElement.setStyle(prefixes.w3c, transformParam);
            } else {
                bgElement.setStyle('marginTop', scroll + 'px');
            }
            i++;
        });
    }
    
  3. 截图3中的图片,会自动根据浏览器的大小进行排列。这里在浏览器缩放时,根据一定的算法计算图片的大小(同一行的高度相等,宽度的和等于浏览器的宽度,图片按比例缩放),然后进行重排(图片墙):

+ 从第一个张图片开始遍历图片。遍历到图片的时候,先把它等比例缩放到高度为一个特定的高度ROWHEIGHT,也就是让所有图片的高度统一下来,宽度根据高度的缩放比例来缩放;
+ 把宽度累加起来(包括margin)。直到宽度超出容器的宽度时候,这样,就有了一行的数据;
+ 这时候要判断,是否应该就把超出的部分在每张图片中等比缩小回去,还是去掉这行的最后一张图片之后把每这行张图片等比放大,这两个状态哪个更接近满行就用哪个。这个操作,还需要记录这一行与满行的差,这个数据在计算图片需要缩放多少时候会用到;
+ 得到一行的数据之后,就要去计算超出的部分在高度中应该调整多少。可以把图片看作是一个高度为自变量,宽度为因变量的函数。这样只要把这一整行的所有图片的导数相加就可以得到整行的导数了。然后把上面记录的行与满行的差除以这个数字就可以得到高度需要变化的量了;
+ 在ROWHEIGHT中修正这个变化量,再计算等比缩放的宽度就可以得到图片最终的显示宽度了。

[这里](/data/imagewall.js)是一个简单的实现,基本实现功能。但是对于最后一行,如果只分配到1、2 张图片, 那么就有可能被拉得很高.