Iconista首页背后的故事

Preface

上次的预告这次到来,今天就来扒一扒Iconista的页面。本文篇幅不长,精力投入不多,权当水贴一篇,内容简短,适合饭后阅读。

Iconista 首页

http://urinx.github.io/app/iconista/ ,地址放出,欢迎来踩。

Dock

由于Iconista的性质决定了其不过是一个简单的Mac美化主题工具,所以页面必须要一眼就能突出其特性。

于是乎,最后决定了选择这个Launchpad样式,既能展现给大家其作用,又能直观的演示出最后的效果,并且给人一种耳目一新的感觉。

Launchpad

当方案拍定后,立马就开干。既然是百分百将launchpad复制到浏览器中,总不能直接全部弄张图片就了事,这是绝不能马虎,哥要的就是逼真,高仿。

第一步,就是高仿最具有象征性的Dock。

<div class="dock">
    <div class="dock-container">
        <a class="dock-item" href="#">
            <span class="bubble">Finder</span>
            <img src="res/apps/finder.png" />
        </a>
        ...
    </div>
</div>

这里用的是一个jQuery插件

        $('.dock').Fisheye(
            {
                maxWidth: 50,
                items: 'a',
                itemsText: 'span',
                container: '.dock-container',
                itemWidth: 60,
                proximity: 80,
                alignment : 'left',
                valign: 'bottom',
                halign : 'center'
            }
        );

然后修改其样式,使之成为Yosemite风格——白色磨砂透明的Dock栏。

.dock{
    width: 100%;
    height: 10%;
    position: absolute;
    bottom: 0;
    opacity: 0;
    -webkit-transition: all 3s ease;
       -moz-transition: all 3s ease;
        -ms-transition: all 3s ease;
         -o-transition: all 3s ease;
            transition: all 3s ease;
}
.dock-container {
    position: absolute;
    height: 100%;
    background: rgba(255,255,255,0.3);
    padding-left: 20px;
    border-radius: 8px 8px 0 0;

    -moz-transform: translateX(-10px);
    -webkit-transform: translateX(-10px);
    -o-transform: translateX(-10px);
    -ms-transform: translateX(-10px);
    transform: translateX(-10px);
}
a.dock-item {
    display: block; 
    font: 12px Arial, Helvetica, sans-serif;
    width: 60px;
    bottom: 0px;
    position: absolute;
    text-align: center;
    text-decoration: none;
}
.dock-item span {
    display: none;
    margin-left: 20px;
    color: black;
}
.dock-item img {
    border: none;
    margin: 5px 10px 0px;
    width: 100%;
}
.bubble{
    display: block;
    background: rgba(255,255,255,0.8);
    border-radius: 3px;
    padding: 5px;
}
.bubble:before{
    content: ' ';
    position: absolute;
    top: 24px;
    left: 55px;
    width: 0;
    height: 0;
    border: 10px solid;
    border-color: rgba(255,255,255,0.8) transparent transparent transparent;
}

就连小气泡我们也要加上,绝不含糊,有图有真相!

Dock

Loading

由于页面上的图标太多,再加上一个炫酷的大背景,在网络情况不好的时候的确很尴尬。本来不想搞个什么鬼loading动画,只想让每个icon 图标依次加载然后慢慢坠落下来,就像iPhone解锁屏幕后App坠落的那个动画效果。奈何嫌麻烦,于是就干脆用个loading,等图标全部下载完成后再显示出来。

好吧,我能说连loading画面都不是自己写的,在这里感谢codepen,在codepen上随手一搜找了个——Battlefield 3 Loading Indicator

Battlefield 3 Loading Indicator

一个纯CSS3写的Loading,直接塞进去就行了。

...
<link rel="stylesheet" type="text/css" href="css/loading.css">
...
<div class="wrap">
    <div class="bg">
        <div class="loading">
            <span class="title">loading</span>
            <span class="text">tehran highway</span>
        </div>
    </div>
</div>

我们用js在后面加载图片,这个是加载图片的函数:

function loadimg(arr,funLoading,funOnLoad,funOnError){
    var numLoaded=0,
    numError=0,
    isObject=Object.prototype.toString.call(arr)==="[object Object]" ? true : false;
 
    var arr=isObject ? arr.get() : arr;
    for(a in arr){
        var src=isObject ? $(arr[a]).attr("data-src") : arr[a];
        preload(src,arr[a]);
    }
 
    function preload(src,obj){
        var img=new Image();
        img.onload=function(){
            numLoaded++;
            funLoading && funLoading(numLoaded,arr.length,src,obj);
            funOnLoad && numLoaded==arr.length && funOnLoad(numError);
        };
        img.onerror=function(){
            numLoaded++;
            numError++;
            funOnError && funOnError(numLoaded,arr.length,src,obj);
        }
        img.src=src;
    }
 
}

我们把要加载的图片路径全塞进一个数组里,当所有数组里图片全部加载完成后隐藏loading画面,然后给要显示的页面一个淡出的效果(透明度从零到一):

        // ==== Preload images =====
        var imgSrcArr=[
        'res/bg.jpg',
        'res/apps/Safari.app.png',
        'res/apps/Mail.app.png',
        'res/apps/Contacts.app.png',
        'res/apps/Calendar.app.png',
        'res/apps/Reminders.app.png',
        'res/apps/Notes.app.png',
        'res/apps/Maps.app.png',
        'res/apps/Messages.app.png',
        'res/apps/FaceTime.app.png',
        'res/apps/Photo Booth.app.png',
        'res/apps/iTunes.app.png',
        'res/apps/iBooks.app.png',
        'res/apps/App Store.app.png',
        'res/apps/Game Center.app.png',
        'res/apps/Preview.app.png',
        'res/apps/Dictionary.app.png',
        'res/apps/Calculator.app.png',
        'res/apps/Dashboard.app.png',
        'res/apps/iPhoto.app.png',
        'res/apps/GarageBand.app.png',
        'res/apps/iMovie.app.png',
        'res/apps/Numbers.app.png',
        'res/apps/Keynote.app.png',
        'res/apps/Pages.app.png',
        'res/apps/Photos.app.png',
        'res/apps/Mission Control.app.png',
        'res/apps/System Preferences.app.png',
        'res/apps/VirtualBox.app.png',
        'res/apps/Xcode.app.png',
        'res/apps/Evernote.app.png',
        'res/apps/Pocket.app.png',
        'res/apps/feedly.app.png',
        'res/apps/Alfred 2.app.png',
        'res/apps/SystemPal.app.png',
        'res/apps/BetterTouchTool.app.png',
        'res/apps/Pushbullet.app.png',
        'res/apps/Tumblr.app.png',
        'res/apps/Shazam.app.png',
        'res/apps/MPlayerX.app.png',
        'res/apps/Sublime Text.app.png',
        'res/apps/Microsoft Remote Desktop.app.png',
        'res/apps/Google Chrome.app.png',
        'res/apps/VMware Fusion.app.png',
        'res/apps/OmniFocus.app.png',
        'res/apps/7zX.app.png',
        ];

        function setPage(el,a,b){
            var html=[];
            for (var i = a; i < b; i++) {
                var appItem='<a class="app-item" href="#">\
                                <img src="'+imgSrcArr[i]+'" />\
                                <span>'+imgSrcArr[i].replace('res/apps/','').replace('.app.png','')+'</span>\
                            </a>';
                html.push(appItem);
            }
            el.innerHTML=html.join('');
        }

        loadimg(imgSrcArr,null,function(){
            setPage($('.app-list')[0],1,28);
            setPage($('.app-list')[1],28,imgSrcArr.length);
            $('.wrap').css('display','none');
            $('body').css('background','url(res/bg.jpg) no-repeat');
            $('body').css('background-size','100% 100%');
            $('.app').css('opacity','1');
            $('.dock').css('opacity','1');
        },null);

至此,loading部分结束。

Download

话说最后这个简介的部分也是构思了好久,如何用最少的字最大限度的表达出效果的确不容易。在追求简洁这一点上,我们绝不妥协,这一点也让我们十分痛苦,不过最终我们还是做到了。

最后的效果就是下图,我们删繁就简,追求极致。

总共就只有两个按钮,一个提供下载,直截了当,不留任何余地,直接戳中一部分人的痛点(老子就是过来下这个的,那么多文字给谁看啊);剩下的另一部分人更多的则是对细节或是代码感兴趣,一个Github按钮足矣。详细的使用说明都在README.md文档写的很清楚,主页上写那么多干嘛,他们更愿意看的是这个。

Mobile

对于移动端我没什么好说的,前面那些高仿Mac的效果本来就不是给你用手机看的,所以说也管不了那么多兼不兼容的问题。

但是话又说回来,总不能让手机不能看吧,那多么尴尬啊,但又不能太麻烦,一切从简出发。所以最后简单粗暴的就直接加了一段:

<div class="mobile">
    <h1>Iconista</h1>
    <span>A super awesome cool icon tool, make your Mac OS X more cute!</span>
    <img src="res/head.jpg">
    <center>
        <a href="https://github.com/Urinx/Iconista/archive/master.zip">Download</a>
        <a href="https://github.com/Urinx/Iconista" target="_blank">Github</a>
    </center>
</div>

然后在css里用一个简单的媒体查询对是否是移动端做了一个判断:

body::before {
    content: 'mobile';
    display: none;
}
@media only screen and (min-width: 770px) {
    body::before {
        content: 'desktop';
    }
}
...

并且为mobile类单独写了一套样式:

.mobile{
    display: none
}
@media only screen and (max-width: 770px) {
    .dock, .search, .app{
        display: none;
    }
    .mobile{
        display: block;
        opacity: 0;
        width: 300px;
        height: 100%;
        margin: auto;

        -webkit-transition: all 3s ease;
        -moz-transition: all 3s ease;
        -ms-transition: all 3s ease;
        -o-transition: all 3s ease;
        transition: all 3s ease;
    }
}
.mobile a{
    ...
}
...

最后在js里也进行了一个判断,那些加载图片的操作之类的在移动端就可以不用进行了(loading这个时候就没有意义了,不过还是留下来了):

    var MQ = window.getComputedStyle(document.querySelector('body'), '::before').getPropertyValue('content').replace(/["']/g, "");

    if (MQ == 'mobile') {
        setTimeout(function(){
            $('.wrap').css('display','none');
            $('.mobile').css('opacity','1');
        },5000);
    }
    else {
        ...
    }

最后效果如图:

手机端

Icon Vibratiton

最后这个纯属无聊蛋疼之举,当然也是为了尽量逼真一下嘛——当你鼠标滑过icon图标时,加了一个抖动的效果,就是那个熟悉的每次你要删除App时出现的抖动。

...
@-webkit-keyframes vibrate {
0% {
    -moz-transform: translate(2px,1px) rotate(5deg);
    -webkit-transform: translate(2px,1px) rotate(5deg);
    transform: translate(2px,1px) rotate(5deg);
}
25% {
    -moz-transform: translate(-2px,-1px) rotate(-5deg);
    -webkit-transform: translate(-2px,-1px) rotate(-5deg);
    transform: translate(-2px,-1px) rotate(-5deg);
}
50% {
    -moz-transform: translate(2px,1px) rotate(5deg);
    -webkit-transform: translate(2px,1px) rotate(5deg);
    transform: translate(2px,1px) rotate(5deg);
}
75% {
    -moz-transform: translate(-2px,-1px) rotate(-5deg);
    -webkit-transform: translate(-2px,-1px) rotate(-5deg);
    transform: translate(-2px,-1px) rotate(-5deg);
}
100% {
    -moz-transform: translate(2px,1px) rotate(5deg);
    -webkit-transform: translate(2px,1px) rotate(5deg);
    transform: translate(2px,1px) rotate(5deg);
}
}
...
Vibratiton

Last

最后的最后,欢迎大家关注我的微信公众号(urinx),满满的干货

如果你有什么建议和想法想和我交流,各种bug想要反馈,或者纯属想要交朋友,这是我的微信(google-2)

wechat
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,753评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,668评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,090评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,010评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,054评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,806评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,484评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,380评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,873评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,021评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,158评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,838评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,499评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,044评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,159评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,449评论 3 374
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,136评论 2 356

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,206评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,109评论 4 62
  • 今日观点:你要是永远只任用比自己水平差的人,那么我们的公司就会沦为侏儒,你要是敢于启用比自己水平高的人,我们就会成...
    杨雪雪阅读 192评论 0 1
  • Nginx介绍 Nginx这是一个在IT界很流行的名字 如果你听说过Nginx那你就应该知道他是什么,干什么用的 ...
    数据革命阅读 487评论 0 0
  • 在我们的生活中,或多或少都会遇到一切灵异事件,有时候我们并无察觉,或是觉得自己在吓唬自己,可是在一些特定的情境,特...
    恶童阅读 1,214评论 2 8