看見題目可能有點(diǎn)好奇蜻直,不過看下去你就知道什么叫手指操了~
目錄
-
寫在前面(特別注意)
在移動端上做動畫,一定不能用top,bottom,background-position等元素做動畫,不管是JS動畫還是CSS動畫照宝。主要是瀏覽器重排掰曾,重繪署海,合成等氛琢,只能用4個(需要加translateZ(0)開啟GPU加速):translate,scale,opacity,rotate产艾。
詳細(xì)資料參考:
<a name="intro"></a>
-
引言
畢業(yè)季沒事做疤剑,一直都對視差滾動感興趣滑绒,感覺很新鮮(雖然現(xiàn)在已經(jīng)不火了)不過還是決定試試看,先看看效果隘膘。
- 片段演示(完整版訪問地址在最后)
第一部分
第二部分
第三部分
第四部分
<a name="thory"></a>
-
原理
用了一點(diǎn)視差滾動的效果疑故,可能不明顯,關(guān)于視差滾動弯菊,與很多資料纵势,本質(zhì)是不同層的移動速度不同,比如坐火車時管钳,遠(yuǎn)處的物體移動得慢钦铁,近處的物體移動的很快,我們就人為的實(shí)現(xiàn)這種速度的差異參考demo
才漆。
**參考資料: **
如果再結(jié)合一些動畫牛曹,就可以得到如下的比較cool的頁面:
參考demo:
<a name="lib"></a>
-
核心庫
為了實(shí)現(xiàn)上述的效果,選擇了skrollr這個庫醇滥,使用這個庫躏仇,懂CSS就可以玩出這個效果了,用關(guān)鍵幀加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>
總的來說腺办,共使用了
-
** skrollr **
- 多用于桌面端焰手,用在了移動端效果也不錯,用起來很方便
-
** zepto **
- 不用多說
-
** imagesloaded **
- 圖片預(yù)加載 相當(dāng)簡單nice
<a name="impl"></a>
-
實(shí)現(xiàn)
<a name="keyframe"></a>-
關(guān)鍵幀/圖片調(diào)整
skrollr
初始化之前怀喉,需要對圖片進(jìn)行一些調(diào)整书妻,首先選好了圖片之 后,得保證顯示在手機(jī)上不變形躬拢,因而需要根據(jù)不同的手機(jī)屏幕大小調(diào)整 圖片的大小
躲履,然后再根據(jù)所得的圖片設(shè)置一下結(jié)束的關(guān)鍵幀。background
是設(shè)置結(jié)束關(guān)鍵幀
ratio
是設(shè)置背景圖片的比例 -
$.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"));
如下所示聊闯,對于橫向圖片工猜,以手機(jī)高度為準(zhǔn),先根據(jù)手機(jī)高度設(shè)置圖片高 度菱蔬,再根據(jù)圖片比例設(shè)置圖片的長度篷帅,對于縱向顯示的圖片,以屏幕寬度為準(zhǔn)拴泌,手法類似魏身,代碼非常簡單。
(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動畫讓他們不停旋轉(zhuǎn)箭昵,即是星星的感覺。
再根據(jù)前景和背景的運(yùn)動速度不同回季,造成視差滾動家制。
對于動畫正林,大多使用transform:translate3d
,且以百分比做動畫颤殴,
以百分比做動畫意味著是以自身元素為參照觅廓,不是父級元素,因而為了避免有些小型元素移動100%的距離只相當(dāng)于移動了它自身大小的問題诅病,將所有的元素都套在一個fullpage
的div中:
.fullpage{
width: 100%;
height: 100%;
position: absolute;
left: 0;
top:0
}
對這個嵌套元素進(jìn)行移動,下面是各背景與前景粥烁,使他們以不同速度移動贤笆,可以通過設(shè)置不同的data-number
值實(shí)現(xiàn)。
前景
背景
前景
背景
<a name="spritesheet"></a>
-
spritesheet
對游戲制作的同學(xué)不會肯定不會陌生
這樣的代碼一大堆讨阻,我貼個自己實(shí)現(xiàn)的芥永,簡單再說一下
對于這個5793*158的spritesheet,如果在手機(jī)上顯示高度為100px钝吮,則寬度為5793/1.58=3666px埋涧,則每次spritesheet移動的距離為3666px/36(動畫一共有36幀)=102px,對應(yīng)下面的JS代碼中的interval參數(shù)奇瘦,同時為了停止有個緩沖棘催,加了個停止幀stopframe參數(shù)。
(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的實(shí)現(xiàn)使用了2個半圓的形式
利用border-radius:50%
做一個圓耳标,再利用clip: rect(0,auto,auto,50px)
裁切為半圓醇坝。
之后再從垂直正中開始裁切右半圓旋轉(zhuǎn)clip: rect(0,auto,auto,50px);
clip裁切
左半圓類似:
左半圓旋轉(zhuǎn)
clip裁切
將2個區(qū)域合并:
餅圖效果
加一個背景色相同的mask覆蓋在中間,這樣的好處是圓環(huán)寬度可以方便調(diào)整:
加個背景顏色相同的覆蓋在中間
之后就可以通過代碼設(shè)置其百分比:
```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;
})($)
在滑動的過程中次坡,配置好滑動的區(qū)間即可:
```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>
* ##### 可能會遇到的問題
對于配置稍低的手機(jī)呼猪,比如我的4S,在場景越來越多砸琅,圖片越來越多的情況下宋距,不管是在微信中打開還是原生瀏覽器中打開,都會把微信和瀏覽器弄崩潰症脂。谚赎。期間嘗試了各種優(yōu)化,把所有關(guān)于**layout**和**paint**的動畫部分都替換诱篷,情況稍微好一些沸版,但是還是有崩潰的現(xiàn)象。最后發(fā)現(xiàn)網(wǎng)頁加載時要對所有的場景進(jìn)行渲染兴蒸,即便這些場景一開始并不需要出現(xiàn)视粮。所以根據(jù)動畫情況,將需要出現(xiàn)的場景動態(tài)顯示橙凳,且在css中加入下面的語句,讓所有場景及信息一開始都不渲染蕾殴。
```css
.scene1,.scene2,.scene3,.scene4,.scene5,.scene6,.infomation{
display: none;
}
最后根據(jù)skrollr的值來選擇顯示的場景笑撞。
通過這樣的做,我的4s終于再也不崩潰了钓觉,即便在有些低配手機(jī)還是有點(diǎn)卡。
<a name="tool"></a>
-
相關(guān)工具
- 圖片壓縮
- 圖像處理:不管是jpg還是 gif都能去除背景荡灾,強(qiáng)烈推薦,特別是gif功能批幌,相當(dāng)好用
- 字體
- webfont/icon
- 圖片處理:國內(nèi)工具
再貼幾個圖像處理工具,都是在線的荧缘,相當(dāng)不錯
- http://animizer.net/en/gif-apng-converter 很強(qiáng)大,有自動根據(jù) gif生成spritesheet的功能信姓,不過有時候生成的效果不大好
- http://www190.lunapic.com/editor/?action=transparent
- http://ezgif.com/
這些圖像處理網(wǎng)站后臺可能用的的是[imagemagick](http://www.imagemagick.org/script/index.php)(瞎猜的)
-
作為一個程序員如何找圖片及配色
-
圖片:
-
都是免費(fèi)無水印,但是還是自己用就好了
- 設(shè)計(jì)導(dǎo)航
- wallhaven: 高分辨率大圖
- dribbble:不用多說 很多素材都來自這意推,也有很多gif
- freepik
- gif: gif集合
- vectorhq
- 站酷
- freevectors
- icon
- freevec
-
配色:
本人喜歡flat扁平化的風(fēng)格珊蟀,所以都是相關(guān)的顏色
- flat ui colors
- [coolors](https://coolors.co/app/090c08-474056-757083- 8a95a5-b9c6ae)
- flatuicolorpick
- [material design](http://www.materialpalette.com/pink/deep- orange)
- flatcolors
先在上面的網(wǎng)站找些喜歡的顏色 然后再去下面的網(wǎng)站生成相關(guān)的互補(bǔ)色等
colorhexa:顏色分析左痢,輸入一個顏 色,分析其各屬性
paletton:相當(dāng) 好用的選色工具系洛,還可以看效果
<a name="visit"></a>