你還在用圖片作引導蒙層?

做者:深山螞蟻css

引導蒙層一般在新業務上線、或者業務有變動時的給新用戶的一個操做指引。下圖頁面便是一個蒙層,會在某個局部位置高亮咱們須要重點突出的內容:html

陰影

當前發現不少頁面作蒙層引導,仍是使用圖片形式來作。html5

圖片引導蒙層有幾大缺點:

  1. 圖片大,影響加載
  2. 圖片的內容都是假的,和真實的底部內容沒對上
  3. 全屏蒙層圖片,圖片的寬高和屏幕寬高不一致,顯示兩邊留黑,或者有壓縮的效果。
  4. 圖片的引導位置不能點擊。
  5. low ? not cool ?

本文講述六種思路來實現引導蒙層

  • z-index實現蒙層
  • 動態opacity實現
  • border實現
  • box-shadow實現
  • 節點複製實現
  • canvas實現

以上六種引導蒙層實現思路,在必定狀況下都能知足業務需求,從不一樣角度來實現了引導蒙層。z-index最簡單,canvas最靈活,就我的而言,更加喜歡骨架屏式的動態opacity蒙層實現,更有趣更酷!!!canvas

思路一:使用z-index

  • 新增一個div,設置爲半透明區域,大小覆蓋整個頁面
  • 半透明蒙層區域z-index大於頁面元素
  • 引導內容區域大於半透明蒙層區域z-index

這個好理解,頁面元素都是有層級的,咱們只須要把引導內容區域設置爲最頂層的層級,在引導內容區域之下設置一個遮罩層,其餘內容元素的z-index都地域這個遮罩層便可。 咱們來看一個簡單例子。微信

.z1{
  position:absolute;
  left:50px;
  top:50px;
  width:50px;
  height:50px;
  background:blue;
  z-index:1;
}
.z2{
  position:absolute;
  left:60px;
  top:60px;
  width:50px;
  height:50px;
  background:red;
  z-index:2;
}
.z3{
  position:absolute;
  left:70px;
  top:70px;
  width:50px;
  height:50px;
  background:yellow;
  z-index:3;
}
複製代碼

z-index

咱們修改一下z2的樣式。markdown

.z2{
  position:absolute;
  left:50px;
  top:50px;
  width:50px;
  height:50px;
  background:black;
  opacity:0.5;
  z-index:2;
  animation:z_index 2s linear infinite alternate;
}
@keyframes z_index {
    from {
      left:50px;
      top:50px;
      width:50px;
      height:50px;
    }
    to {
      left:0px;
      top:0px;
      width:200px;
      height:200px;
    }
  }
複製代碼

z-index

只要在佈局頁面元素的時候,把須要作蒙層的元素肯定好,配合js,動態的設置元素的z-index + opacity,就能夠很好的作到頁面的引導蒙層效果。oop

思路二:使用opacity將非蒙層元素半透明

  • 引導內容區域無需改動
  • 頁面其餘節點元素半透明

咱們再也不新增蒙層,而是徹底操做頁面節點,將須要遮罩的節點都設置爲半透明,引導蒙層顯現內容則徹底顯示出來。頁面的效果和蒙層不太同樣,對於空白地方,咱們仍然是徹底顯示,只是將有內容的元素給半透明,相似骨架屏的效果。
爲了演示效果,咱們看以下例子:
頁面設置6個元素。佈局

<div class="wrap">
    <div class="z z1"></div>
    <div class="z z2"></div>
    <div class="z z3"></div>
    <div class="z z4"></div>
    <div class="z z5"></div>
    <div class="z z6"></div>
  </div>
複製代碼

將元素內容用flex並排佈局。測試

.wrap{
  display:flex;
  flex-wrap:wrap;
  width:150px;
}
.z{
  width:50px;
  height:50px;
  transition:all 1s;
}
.z1{
  background:blue;
}
.z2{
  background:black;
}
.z3{
  background:yellow;
}
.z4{
  background:red;
}
.z5{
  background:green;
}
.z6{
  background:orange;
}
複製代碼

使用js操做,依次半透明其餘元素,顯示當前元素來模擬蒙層。flex

let arry = Array.from(document.querySelectorAll(".z"));
let index = -1;
let direct = 1;
setInterval(()=>{
  if(index>=5) direct = -1;
  else if(index<=0) direct = 1;
  index = index+direct;
  arry.forEach((d,i)=>{
    d.style.opacity = 1;
  });
  setTimeout(()=>{
    arry.forEach((d,i)=>{
      if(i==index) return;
      d.style.opacity = 0.1;
    });
  },1000);
},2000)
複製代碼

z-index

看了這個例子,咱們清晰的看到這個引導蒙層的實現過程。這種引導蒙層其實更好玩有趣,有點相似當前流行的骨架屏,其餘已有元素須要遮罩的內容就是骨架屏的灰色部分,須要顯現的就是重點的蒙層內容。
有趣!!!

思路三:使用border的方式來實現

沒錯,就是廣泛不能在廣泛的border了,且看以下:

div {
    border:1px solid #red;
}
複製代碼

那用border怎麼實現引導蒙層呢?

一、先了解下三角形

先看一個簡單的例子:

<div class="border_1"></div>
複製代碼
.border_1{
    width: 100px;
    height: 100px;
    border-top:50px solid red;
    border-right: 50px solid transparent;
    border-bottom: 50px solid transparent;
    border-left: 50px solid transparent;
    box-sizing:border-box;
}
複製代碼

border_1

實現了一個倒三角,這個應用場景是否是就比較多了,不少tips的指引,標註等都會用到。我就看到過這種倒三角使用一張圖片代替的作法。
仔細看這段代碼,主要有實現了三點:

  1. 四邊都設置了邊框
  2. 寬高都爲100px,即上下、左右表框之和,其實小於等於這個值都行。
  3. 只有頂部邊框是紅色,其餘邊框是透明的。

爲了理解上面的實現,咱們來看下以下代碼:

.border_2{
    width: 100px;
    height: 100px;
    background-color:green;
    border-style:solid;
    border-color:red yellow blue black;
    border-width:50px;
    animation:border_ani 2s linear infinite alternate;
    box-sizing:border-box;
}
@keyframes border_ani {
    from {
        border-width:50px;
    }
    to {
      border-width:0;
    }
  }
複製代碼

animation

從圖中咱們能夠清晰的看到,隨着border-width的變化,整個div的綠色背景在跟隨變化。

  • 當border-width=0的時候,整個頁面只有綠色背景,即都是內容的大小
  • 當border-width=50的時候,整個div的大小都被border給充滿了,上下左右均分1/4,就是四個倒三角。

這樣咱們就清晰的能獲得:

當border-right,border-left,border-bottom都transparent透明,border-top是紅色的時候,所看到的就是一個倒三角。

同理咱們還能夠設置邊框的大小不一致,能夠實現斜三角:

.border_3{
    width: 0;
    height: 0;
    border-top:30px solid red;
    border-right: 10px solid transparent;
    border-bottom: 20px solid transparent;
    border-left: 100px solid transparent;
    box-sizing:border-box;
}
複製代碼

斜三角

還能夠實現工做中常常碰到的梯形:

.border_4{
    width: 150px;
    height: 150px;
    border-top:50px solid red;
    border-right: 50px solid transparent;
    border-bottom: 50px solid transparent;
    border-left: 50px solid transparent;
    box-sizing:border-box;
}
複製代碼

梯形

好了,這裏不累贅了,感興趣的能夠各類嘗試。遇到這種簡單邊線圖,就不要動不動使用圖片了。

二、再看實現引導蒙層

  • 新增一個div,做爲蒙層元素
  • div中間大小和引導內容元素大小徹底一致,且位置剛好重疊
  • div的border設置爲半透明且無限放大

瞭解了上面的三角形的實現以後,估計你也能想出怎麼作引導蒙層了。一個div有四個邊框,若是咱們把邊框都設置成半透明,而後中間的區域(上面border_2的green)設置成全透明會不就能夠實現區域引導蒙層了嗎?而後再把邊框設置成超過屏幕的大小呢,就是全景引導蒙層了!

.border_5{
    width: 150px;
    height: 150px;
    border-top:50px solid rgba(0,0,0,.5);
    border-right: 50px solid rgba(0,0,0,.5);
    border-bottom: 50px solid rgba(0,0,0,.5);
    border-left: 50px solid rgba(0,0,0,.5);
    box-sizing:border-box;
}
複製代碼

蒙層

這是一個150px的區域蒙層,咱們看下以下示例就能很明白了:

.border_6{
    width: 20px;
    height: 20px;
    border-style:solid;
    border-color:rgba(0,0,0,.5);
    border-width:20px;
    animation:border_ani 2s linear infinite alternate;
    box-sizing:content-box;
}
@keyframes border_ani {
    from {
        border-width:20px;
    }
    to {
      border-width:100px;
    }
  }
複製代碼

蒙層

固然,咱們還能夠設置border-radius來實現圓形的蒙層區域,以下:

border-radius

固然,這裏的邊框大小值都是寫死的,具體實現須要根據頁面內容修改或者動態修改便可。

若是是橢圓呢?

總結:

border能夠實現各類邊線的形狀,能夠實現引導蒙層,頁面指定區域透明,以外的都半透明來實現便可。

思路4、使用box-shadow來實現

  • 新增一個div,做爲蒙層元素
  • div大小和內容元素大小徹底一致,且位置剛好重疊
  • div的box-shadow的陰影尺寸設置爲半透明且設置爲比較大的約2000px大小

box-shadow,大夥都不陌生,就是盒子的陰影,咱們先來了解下它的基本用法:

.boxshadow_1{
    width:50px;
    height:50px;
    background:blue;
    box-shadow: 10px 10px 5px 4px #000;
}
複製代碼

陰影

在寬高爲50px的div,它的陰影水平和垂直都是10px,陰影模糊距離是5px,陰影的尺寸是4px,陰影是#000的顏色(這裏給body增長了一個yellow的背景色以便於區分)。

首先咱們把陰影透明:

.boxshadow_2{
    width:50px;
    height:50px;
    background:blue;
    box-shadow: 10px 10px 5px 4px rgba(0,0,0,.5);
}
複製代碼

陰影

那怎麼讓陰影遮蓋整個頁面呢?

  • 陰影的水平和垂直距離是指距離原dev的距離,這個調整達不到效果,只會讓陰影更多的偏離元素。
  • 陰影的模糊距離指陰影的邊緣漸變模糊的距離,距離越長,只會讓漸變模糊加長,蒙層大小不會變。
  • 陰影的尺寸,這個是指多大的陰影,那咱們將陰影尺寸設置很大呢?是的,就是這個了

看以下的例子,咱們調整陰影的尺寸:

.boxshadow_3 {
  width:50px;
  height:50px;
  background:blue;
  box-shadow: 0px 0px 5px 0px rgba(0,0,0,.5);
  animation:box_ani 2s linear infinite alternate;
}
@keyframes box_ani {
    from {
        box-shadow: 10px 10px 5px 0px rgba(0,0,0,.5);
    }
    to {
        box-shadow: 10px 10px 5px 100px rgba(0,0,0,.5);
    }
  }
複製代碼

如上,咱們只須要把陰影尺寸加大就能夠實現引導蒙層了。
若是須要引導蒙層狀態下還能響應事件呢?只須要加一個pointer-events屬性便可。

box-shadow的陰影距離切勿盲目設置過大,通過測試這個值若是過大,好比4000px,在部分手機上陰影沒法顯示出來。通過實踐,設置爲2000px爲佳。

思路五:使用頁面節點複製

  • 新增兩個div,一個半透明蒙層元素和一個蒙層內容區域
  • 將頁面節點引導內容拷貝到蒙層內容區域
  • 將蒙層內容區域的大小和位置與原節點引導內容徹底重合

頁面內容已經作好了,咱們須要引導蒙層來顯示某個元素,那麼將元素複製到最外層,頂層增長一層蒙層來實現,須要突出的引導內容在蒙層之上便可實現。

<div class="content one">我是第一個div,我是第一個div</div>
<div class="content two">我是第二個div,我是第二個div</div>
<div class="content three">我是第三個div,我是第三個div</div>
<div class="content four">我是第四個div,我是第四個div</div>
<div class="mask"></div>
<div id="maskContent"></div>
複製代碼

這裏設置了一個固定蒙層,和一個固定的蒙層內容元素,咱們只須要填充便可。

.content{
    padding:10px;
    z-index:0;
}
.mask{
    position:fixed;
    left:0;
    top:0;
    width:100%;
    height:100%;
    background:rgba(0,0,0,.8);
    z-index:900
  }
  #maskContent{
    position:fixed;
    z-index:999;
    display:inline-block;
    background-color: #fff;
  }
複製代碼

這裏內容區域都是0,而後mask是900,咱們的蒙層元素是999,就是最上層了。

function renderContent(cls){
    let targetNode = document.querySelector(`.${cls}`);
    let maskContent = document.getElementById("maskContent");
    maskContent.innerHTML = targetNode.outerHTML;
    let pos = targetNode.getBoundingClientRect();
    maskContent.style.top=pos.top+"px";
    maskContent.style.left=pos.left+"px";
    maskContent.style.width=pos.width+"px";
    maskContent.style.height=pos.height+"px";
 }
let i = 0;
setInterval(()=>{
    renderContent(['one','two','three','four'][i]);
    if(++i>=4) i = 0;
},1000)
複製代碼

這裏爲了演示效果,增長了一個定時器改變不一樣的遮罩層。易於理解,看下效果:

z-index

思路六:使用canvas實現

  • 新增一個canvas,繪製兩次圖形
  • 第一次:繪製一個全屏的半透明陰影
  • 第二次:使用xor繪製一個和引導內容區域的大小位置徹底重合的區域

第二次繪製的內容區域和第一次重疊,使用xor,因此會透明,該引導內容區域就會徹底顯示出來,這就是咱們想要的效果了。

使用canvas的globalCompositeOperation屬性來實現,內容參考http://www.tutorialspoint.com/html5/canvas_composition.htm

重點看xor:Shapes are made transparent where both overlap and drawn normal everywhere else.
翻譯: canvas繪製的形狀在重疊處都會變成透明的,非重疊處的其餘任何地方都正常繪製內容。

因此咱們就能夠在canvas裏面繪製一個canvas蒙層,而後在蒙層中須要顯示的內容用xor來繪製重疊,而後重疊內容就會被透明,那麼這個透明區域的內容就是咱們想要的引導蒙層突出內容區域。具體看實例:

<div class="content one">我是第一個div,我是第一個div</div>
<div class="content two">我是第二個div,我是第二個div</div>
<div class="content three">我是第三個div,我是第三個div</div>
<div class="conteent four">我是第四個div,我是第四個div</div>
<canvas id="mask"></canvas>
複製代碼

頁面增長一個canvas節點。將canvas總體設置成半透明,而後再用xor來實現內容的繪製。

function mask(cls){
    let targetNode = document.querySelector(`.${cls}`);
    let pos = targetNode.getBoundingClientRect();
    let canvas = document.getElementById("mask");
    let width = window.innerWidth;
    let height = window.innerHeight;;
    canvas.setAttribute("width", width);
    canvas.setAttribute("height",height);
    var ctx = canvas.getContext("2d"); 
    ctx.globalCompositeOperation = 'source-over';
    ctx.fillStyle ='rgba(255, 255, 255, 0.9)';
    ctx.fillRect(0, 0, width, height);
    ctx.fill();
    ctx.fillStyle ='white';
    ctx.globalCompositeOperation="xor";
    ctx.fillRect(pos.left,pos.top,pos.width,pos.height);
    ctx.fill();
 }
let array = ['one','two','three','four'];
let i = 0;
setInterval(()=>{
    mask(array[i]);
    i++;
    if(i>=4) i = 0;
},1000)
複製代碼

z-index

看完以上實現,你最喜歡哪一種實現方式呢?


若是你以爲這篇內容對你有價值,請點贊,並關注咱們的官網和咱們的微信公衆號(WecTeam),每週都有優質文章推送:

WecTeam
相關文章
相關標籤/搜索