資料視覺化之模組邊框繪製,以及元件開發(一)

TwoKe發表於2020-12-25

專案場景:

在資料視覺化裡面,我們可以發現一個大屏展示,是有多個小的模組組合而成,然而這個小模組又是有模組邊框和圖示構成,大多數情況中,這些小模組的邊框是一樣,然而又有的圖案比較複雜,用css是很難直接寫出來,辦法當然是有的。當然你除了選擇用我說的這種方案,也可以選擇用svg繪製,也是一個不錯的選擇。如下圖,就是我們要實現的效果
在這裡插入圖片描述


解決方案:

1、基礎知識

我們繪製圖片邊框採用的原理是css3中樣式:

描述
border-image-source用於指定要用於繪製邊框的影像的位置
border-image-slice影像邊界向內偏移
border-image-width影像邊界的寬度
border-image-outset用於指定在邊框外部繪製 border-image-area 的量
border-image-repeat用於設定影像邊界是否應重複(repeat)、拉伸(stretch)或鋪滿(round)。

其中border-image-source是表示邊框圖片的位置,border-image-width是表示指定邊的邊框圖片寬度,border-image-outset 用於指定在邊框外部繪製 border-image-area 的量,border-image-repeat 用於設定影像邊界是否應重複(repeat)、拉伸(stretch)或鋪滿(round)。其中最重要的就是border-image-slice屬性,它的作用是來指定邊框的位置如何來劃分。border-image-slice屬性有四個引數top,right,bottom,left。它們分別的意思是:

  • top:從頂部開始的一段距離
  • right:從右側開始的一段距離
  • bottom:從底部開始的一段距離
  • left:從左側開始的一段距離
    用四刀把圖片分為了四個部分,其作用是為了把四個邊角裁剪出來
    在這裡插入圖片描述
    裁剪之後,紅色的部分就為空,而邊角就會和容器的邊角在一起
    在這裡插入圖片描述

2、快速搭建例項

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            box-sizing: border-box;
            padding: 0;
            margin: 0;
        }
        #container {
            border: 1px solid transparent;
            border-width: 27px 27px 28px 29px;
            border-image-source: url("./border.png");
            border-image-slice: 27 27 28 29;
            border-image-width: 27px 27px 28px 29px;
            background: #ddd;
        }
    </style>
</head>
<body>
    <div id="container" style="width: 500px; height: 400px;"> 
    </div>
</body>
</html>

border.png
這就是那一張border.png的圖片
最後渲染出來的效果是
在這裡插入圖片描述
我們可以明顯看出,圖片中間被掏空,然後四個邊角固定在容器的四個角上,而邊則進行了拉伸。從原始碼中,我有個屬性沒有設定border-image-repeat,新增上之後的效果:

  1. border-image-repeat:repeat
    在這裡插入圖片描述
  2. border-image-repeat:round
    在這裡插入圖片描述
  3. border-image-repeat:stretch
    在這裡插入圖片描述
    這樣就可以發現,預設選擇就是拉伸,而鋪滿和重複的區別是:round是進行計算鋪滿,都是完整圖形,repeat是重複,會有不完整圖形存在。

3、繪製邊框,實現資料視覺化模組

我更換了圖片為模組的邊框,測算出模組的邊框為 9 40 9 40
在這裡插入圖片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .container-border {
            width: 300px;
            height: 200px;
            border: 1px solid transparent;
            border-width: 9px 40px 9px 40px;
            border-image-source: url("./border-2.png");
            border-image-slice: 9 40 9 40;
            border-image-width:  9px 40px 9px 40px;
             background-color: rgba(0, 0, 0, .5);
        }
    </style>
</head>
<body>
        <div class="container-border"></div>
</body>
</html>

在這裡插入圖片描述
這個容器看似沒有問題,因為我們的邊框選擇是一個規則圖形,並不會出現很大問題。但是如果是一個不規則的邊框圖形,很有可能圖片的內容區域,還是大小都會出現問題,比如下面的這個
在這裡插入圖片描述
這個如果容器裡面再放一個圖示,就會出現很大的問題。因此我改變了佈局方式

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            box-sizing: border-box;
            padding: 0;
            margin: 0;
        }
        #container {
            position: relative;
        }
        .container-border {
            width: 100%;
            height: 100%;
            border: 9px solid transparent;
            border-width: 9px 40px 9px 40px;
            border-image-source: url("./border-2.png");
            border-image-slice: 9 40 9 40;
            border-image-width:  9px 40px 9px 40px;
            border-image-repeat: stretch;
             background-color: rgba(0, 0, 0, .5);
        }
        .container-content {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%,-50%);
        }
    </style>
</head>
<body>
    <div id="container" style="width:600px;height:300px;">
        <div class="container-border"></div>
        <div class="container-content">123456789</div>
    </div>
</body>
</html>

在這裡插入圖片描述
這樣一個圖表的邊框就繪製好了。只需要在container-content裡繪製圖表及內容即可。

4、實現通用的視覺化模組容器html5

這裡我就先直接上程式碼吧,這裡是呼叫寫好的模組程式碼,在頁面先建立一個container容器,在下面還有一個div是用來展示圖表或者資訊內容用的。js上建立TwokeDatav物件,呼叫createModeContainer方法。

含義
el容器id
src邊框路徑
top邊框圖片頂部到上邊角的有效區
right邊框圖片右側到右邊角的有效區
bottom邊框圖片底部到下邊角的有效區路徑
left邊框圖片左側到左邊角的有效區

注:有效區是指切角時,必須把邊角邊框包含上,以最長的邊角邊框作臨界值

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../dist/index.js"></script>
    <style>
        #container {
            width: 500px;
            height: 300px;
            background-color: #eee;
        }
    </style>
</head>
<body>
    <div id="container">
        <div>
            1234567890
        </div>
    </div>
    <script>
      var datav =  new  $datav.TwoKeDatav()
       datav.createModeContainer({
           el: "container",
           src: './border-2.png',
           top: 9,
           right: 40,
           bottom: 9,
           left: 40,
       })
    </script>
</body>
</html>

碼雲專案地址
其原理和上面的原理是一樣的,只是將一些通用操作封裝了起來。下一講就用vue3實現模組邊框繪製的元件。如果感興趣可以去碼雲看一看原始碼,原理很簡單。

相關文章