不一样的前端手指操

看见题目可能有点好奇,不过看下去你就知道什么叫手指操了~

目录

  • 写在前面(特别注意)

在移动端上做动画,一定不能用top,bottom,background-position等元素做动画,不管是JS动画还是CSS动画。主要是浏览器重排,重绘,合成等,只能用4个(需要加translateZ(0)开启GPU加速):translate,scale,opacity,rotate
详细资料参考:

<a name="intro"></a>

  • 引言

毕业季没事做,一直都对视差滚动感兴趣,感觉很新鲜(虽然现在已经不火了)不过还是决定试试看,先看看效果。

第一部分

第二部分

第三部分

第四部分

<a name="thory"></a>

  • 原理

用了一点视差滚动的效果,可能不明显,关于视差滚动,与很多资料,本质是不同层的移动速度不同,比如坐火车时,远处的物体移动得慢,近处的物体移动的很快,我们就人为的实现这种速度的差异参考demo

**参考资料: **

如果再结合一些动画,就可以得到如下的比较cool的页面:

参考demo:


<a name="lib"></a>

  • 核心库

为了实现上述的效果,选择了skrollr这个库,使用这个库,懂CSS就可以玩出这个效果了,用关键帧加CSS就可以了

<section class="scene1 fullpage" 
            data-6300="transform:translate3d(0,0%,0);display:block"  
            data-10000="transform:translate3d(0,-100%,0);display:block" 
            data-30000="transform:translate3d(0,-100%,0);display:block" 
            data-33000="transform:translate3d(0,-130%,0);display:none">
</section>

总的来说,共使用了


<a name="impl"></a>

  • 实现
    <a name="keyframe"></a>
    • 关键帧/图片调整
    skrollr初始化之前,需要对图片进行一些调整,首先选好了图片之 后,得保证显示在手机上不变形,因而需要根据不同的手机屏幕大小调整 图片的大小,然后再根据所得的图片设置一下结束的关键帧。

    background是设置结束关键帧
    ratio是设置背景图片的比例

$.plug.background(true,".scene1-1",6700,$.plug.ratio(true,1080,1920,".scene1-1"));
$.plug.background(false,".scene2-1",18000,$.plug.ratio(false,4500,1667,".scene2-1"));
$.plug.background(false,".scene2-2",22000,$.plug.ratio(false,4500,1667,".scene2-2"));
$.plug.background(false,".scene3-1",42000,$.plug.ratio(false,3840,2160,".scene3-1"));
$.plug.background(false,".scene3-2",48000,$.plug.ratio(false,3840,2160,".scene3-2"));
$.plug.background(false,".scene4-1",58000,$.plug.ratio(false,2560,1496,".scene4-1"));
$.plug.background(false,".scene4-2",62000,$.plug.ratio(false,2560,1496,".scene4-2"));
$.plug.background(false,".scene5-1",76000,$.plug.ratio(false,2857,1216,".scene5-1"));
$.plug.background(false,".scene6-1",112000,$.plug.ratio(false,800,800,".scene6-1"));
$.plug.background(true,".scenev-1-1",94000,$.plug.ratio(true,600,1200,".scenev-1-1"));
$.plug.background(true,".scenev-1-2",98000,$.plug.ratio(true,600,1200,".scenev-1-2"));
$.plug.background(true,".scenev-1-3",102000,$.plug.ratio(true,600,1200,".scenev-1-3"));
 如下所示,对于横向图片,以手机高度为准,先根据手机高度设置图片高 度,再根据图片比例设置图片的长度,对于纵向显示的图片,以屏幕宽度为准,手法类似,代码非常简单。    
横向图片
 (function($){
    function ratio(iswidth,width,height,dom,scale,isback){
        var ratioo=scale||1;
        var ratio=width/height;
        if(iswidth){        
            var wi=window.innerWidth*ratioo;
            var numb=Math.round(wi/ratio);
            var _pxheight=numb+"px";
            document.querySelector(dom).style.height=_pxheight;
            return numb;
        }
        else{
            var he=window.innerHeight*ratioo;
            var numb=Math.round(he*ratio);
            var _pxwidth=numb+"px"; 
            document.querySelector(dom).style.width=_pxwidth;
            return numb;
        }       
}
     if(!$.plug)$.plug={};
     $.plug.ratio=ratio;        
 })($)

一开始确定好容器大小,初始化一些白色的小型div,再通过CSS3动画让他们不停旋转,即是星星的感觉。
再根据前景和背景的运动速度不同,造成视差滚动。
对于动画,大多使用transform:translate3d,且以百分比做动画,
以百分比做动画意味着是以自身元素为参照,不是父级元素,因而为了避免有些小型元素移动100%的距离只相当于移动了它自身大小的问题,将所有的元素都套在一个fullpage的div中:

.fullpage{
    width: 100%;
    height: 100%;   
    position: absolute;
    left: 0;
    top:0
}

对这个嵌套元素进行移动,下面是各背景与前景,使他们以不同速度移动,可以通过设置不同的data-number值实现。

前景
背景
前景
背景

<a name="spritesheet"></a>
  • spritesheet

对游戏制作的同学不会肯定不会陌生

行走

这样的代码一大堆,我贴个自己实现的,简单再说一下
对于这个5793*158的spritesheet,如果在手机上显示高度为100px,则宽度为5793/1.58=3666px,则每次spritesheet移动的距离为3666px/36(动画一共有36帧)=102px,对应下面的JS代码中的interval参数,同时为了停止有个缓冲,加了个停止帧stopframe参数。

(function($){
        function animate(totaltime,dom,parts,interval,stopframe){
                var temp=0;
                var stop_flag=false;
                var timer=null;
                    var num=temp*(interval);
                    $(dom).css({"background-position-x":num+"px"});
                    temp++;
                    if(stop_flag&&temp===stopframe){
                        clearInterval(timer),timer=null
                        stop_flag=false;
                    }
                    if(temp===parts)temp=0;
                
                return {
                    animating:function(){return timer!==null?true:false},
                    stop:function(va){
                        stop_flag=true;
                        //clearInterval(timer),timer=null
                    },
                    resume:function(){
                            if(timer!==null)return
                            var str=$(dom).css("background-position-x");
                            var matched=str.match(/-?[0-9]+/);
                            var num=parseInt(matched[0]);
                            temp=num/interval;
                            timer=setInterval(function(){
                            var num=temp*(interval);
                            $(dom).css({"background-position-x":num+"px"});
                            temp++;
                            if(stop_flag&&temp===stopframe){
                                clearInterval(timer),timer=null
                                stop_flag=false;
                            }
                            if(temp===parts)temp=0
                        },totaltime/parts);
                    }
                    
                }
                //$(dom)
            }       
            if(!$.plug)$.plug={};
            $.plug.animate=animate;
    
   })($)

<a name="progressbar"></a>

  • progressbar
    progressbar的实现使用了2个半圆的形式
    利用border-radius:50%做一个圆,再利用clip: rect(0,auto,auto,50px)裁切为半圆。

右半圆旋转
之后再从垂直正中开始裁切clip: rect(0,auto,auto,50px);
clip裁切

左半圆类似:
左半圆旋转

clip裁切

将2个区域合并:
饼图效果

加一个背景色相同的mask覆盖在中间,这样的好处是圆环宽度可以方便调整:
加个背景颜色相同的覆盖在中间

 之后就可以通过代码设置其百分比:
 ```js
          (function($){
              function circleprogress(dom,value){                                    
                $(dom).each(function(index, el) {
                var num = value * 3.6;
                num=Math.round(num);
                if (num<=180) {
                    $(this).find('.right').css('-webkit-transform', "rotate(" + num + "deg) translateZ(0px)");
                    $(this).find('.right').css('transform', "rotate(" + num + "deg) translateZ(0px)");
                    $(this).find('.left').css('-webkit-transform', "rotate("+0+ "deg) translateZ(0px)");
                    $(this).find('.left').css('transform', "rotate("+0+ "deg) translateZ(0px)");
                } else {
                    $(this).find('.right').css('-webkit-transform', "rotate(180deg) translateZ(0px)");
                    $(this).find('.left').css('-webkit-transform', "rotate(" + (num - 180) + "deg) translateZ(0px)");
                    $(this).find('.right').css('transform', "rotate(180deg) translateZ(0px)");
                    $(this).find('.left').css('transform', "rotate(" + (num - 180) + "deg) translateZ(0px)");
                };
            });
        }       
        if(!$.plug)$.plug={};
        $.plug.circleprogress=circleprogress;

})($)
    在滑动的过程中,配置好滑动的区间即可:
    ```js
                    if(data.curTop>=20000 && data.curTop<25000){
                            var num=Math.round((data.curTop-20000)/55);
                            $('.circle-1').find('span.value').text(num);
                            $.plug.circleprogress('.circle-1',num);
                        }   
    ```
* * *
   
<a name="problem"></a>
* ##### 可能会遇到的问题
     对于配置稍低的手机,比如我的4S,在场景越来越多,图片越来越多的情况下,不管是在微信中打开还是原生浏览器中打开,都会把微信和浏览器弄崩溃。。期间尝试了各种优化,把所有关于**layout**和**paint**的动画部分都替换,情况稍微好一些,但是还是有崩溃的现象。最后发现网页加载时要对所有的场景进行渲染,即便这些场景一开始并不需要出现。所以根据动画情况,将需要出现的场景动态显示,且在css中加入下面的语句,让所有场景及信息一开始都不渲染。
```css
      .scene1,.scene2,.scene3,.scene4,.scene5,.scene6,.infomation{
        display: none;
        }

最后根据skrollr的值来选择显示的场景。

通过这样的做,我的4s终于再也不崩溃了,即便在有些低配手机还是有点卡。


<a name="tool"></a>

  • 相关工具

再贴几个图像处理工具,都是在线的,相当不错

这些图像处理网站后台可能用的的是[imagemagick](http://www.imagemagick.org/script/index.php)(瞎猜的)
  • 作为一个程序员如何找图片及配色
    • 图片:

都是免费无水印,但是还是自己用就好了

  • 配色:

本人喜欢flat扁平化的风格,所以都是相关的颜色

先在上面的网站找些喜欢的颜色 然后再去下面的网站生成相关的互补色等
colorhexa:颜色分析,输入一个颜 色,分析其各属性
paletton:相当 好用的选色工具,还可以看效果


<a name="visit"></a>

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

推荐阅读更多精彩内容

  • 1. tab列表折叠效果 html: 能源系统事业部 岗位名称: 工作地点 岗位名...
    lilyping阅读 1,824评论 0 1
  • <a name='html'>HTML</a> Doctype作用?标准模式与兼容模式各有什么区别? (1)、<...
    clark124阅读 3,453评论 1 19
  • 前几天上海回来一个牧师在教会讲道,我调休了两三天就去了。坐在我左边的是一个老奶奶,听的很是认真,边听边记笔记。不知...
    叫我松哥阅读 302评论 0 1
  • 听了宇彤老师讲的胸腹式联合呼吸法才发现,无论以前自己怎么努力都没有成效是因为没有找到专业的方法,真是方法不对努...
    瑗泽妈妈阅读 177评论 0 0
  • 世界上只有一种真正的英雄主义,那就是在认清生活的真相后依然热爱生活。 那日从同衡出来,赶上了高峰期的北京地铁。 爆...
    兔子王粥粥阅读 214评论 0 0