日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

css繪制聲吶超聲波圖的詳細步驟

1、需求簡述;

2、CSS繪制90度扇形;

3、添加分隔線繪制成一個超聲波圖樣式的聲吶圖;

4、添加聲吶圖深水樣式的背景;

5、根據(jù)聲吶探測器返回數(shù)據(jù)計算魚的位置;

6、根據(jù)聲吶探測器返回數(shù)據(jù)繪制水深標尺;

7、完整代碼;

8、知識點學習。

1.需求簡述:

最近做一個項目有這么一個需求,根據(jù)聲吶探測器返回水下魚的位置數(shù)據(jù),把魚顯示到扇形內(nèi),聲吶數(shù)據(jù)包含總水深、n條魚的水深二維數(shù)組(如:[[3452,8569,…],[...],[...],[...],[...]],單位毫米),隨機顯示到扇形相應(yīng)的深度處即可。為什么是二維數(shù)組呢?因為聲吶探測器有5個探頭(如圖1所示),返回的數(shù)據(jù)是包含了5個探頭的回波數(shù)據(jù),回波數(shù)據(jù)數(shù)組里的一個數(shù)字就代表一條魚的深度位置,現(xiàn)要把1、2、3探頭的數(shù)據(jù)展示到聲吶圖中間那格,4、5號探頭數(shù)據(jù)分別顯示到聲吶圖左右兩格。

圖1:聲吶探頭示意圖

下面是最終效果圖

最終效果圖

看到這里的前端同學可以先暫停想想怎么實現(xiàn)哦,看完的同學們可以在評論區(qū)自己的方法哦,我也想借鑒一下,我覺得可能用canvas可能會更好。

這里用的是 Vue2+Less。

CSS繪制一個90度扇形

這是第一個難點,這里我嘗試過svg的方式,但是沒搞定,最后還是回到css來吧。

首先css是沒辦法直接畫一個扇形的,因為我們的html元素都是四邊形的,就算加了圓角,也只能顯示個圓形。這里就要用的css高階一點點的寫法了:css clip-path屬性。clip-path 用法將在文章底部總結(jié)知識點介紹。

html

<section ref="sona" class="maxbox fxbox" style="background: #ccc;">
    <div class="sx_cp">
        <div class="round1 path"></div>
    </div>
</section>

section 標簽為一個正方形,用于為扇形可以絕對定位,div class="sx_cp" 為扇形容器,div class="round1 path" 為扇形主體。

css

.fxbox {
    display: flex;
    align-items: center;
    justify-content: center;
}
.sx_cp {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 6%;
}
.round1 {
    width: 140%;
    height: 140%;
    position: absolute;
    top: -70%; // -140/2
    left: -20%; // (100-140)/2
}
.path {
    clip-path: polygon(0% 0%, 100% 0%, 50% 50%, 100% 100%);
    border-radius: 50%;
    background-color: rgba(0, 225, 239, .1);
    box-shadow: inset 0 0 40px 1px rgba(1, 240, 255, 0.85);
    border: rgba(1, 240, 255, 1) solid 1px;
    transform: rotateZ(180deg);
}

這段代碼得到一個扇形雛形效果:

扇形雛形效果

有了這個雛形,接下來就明了了,再加3個逐漸縮小的扇形就可以了。

html

<div class="sx_cp">
    <div class="round1 path"></div>
    <div class="round2 path"></div>
    <div class="round3 path"></div>
    <div class="round4 path"></div>
</div>

css

.round2 {
    width: 100%;
    height: 100%;
    position: absolute;
    top: -50%; // -100/2
		left: 0%; // (100-100)/2
		z-index: 2;
}
.round3 {
    width: 60%;
    height: 60%;
    position: absolute;
    top: -30%;
    left: 20%; // (100-60)/2
		z-index: 3;
}
.round4 {
    width: 20%;
    height: 20%;
    position: absolute;
    top: -10%;
    left: 40%; // (100-80)/2
		z-index: 3;
}

添加以上代碼后,得到效果:

超聲波效果

添加分隔線繪制成一個超聲波圖樣式的聲吶圖

添加兩條傾斜的虛線作為分隔線,把扇形分成三格,虛線的傾斜和定位很關(guān)鍵。

html

......

<div class="round4 path"></div>

<div class="line1"></div>

<div class="line2"></div>

css

.line1 {
    border-left: rgba(0, 225, 239, .6) dashed 1px;
    width: 0;
    height: 70%;
    position: absolute;
    transform: rotateZ(165deg);
    top: -1%;
    left: 59%;
}
.line2 {
    border-left: rgba(0, 225, 239, .7) dashed 1px;
    width: 0;
    height: 70%;
    position: absolute;
    transform: rotateZ(195deg);
    top: -1%;
    left: 41%;
}

添加后得到以下效果:

效果

添加聲吶圖深水樣式的背景

從上面圖可以看出,扇形最大的半徑就是最外面那個圓的半徑,那就直接給最外面的圓添加一個背景圖,就是整個扇形超聲波圖的背景了。

開始裁剪圓形得到扇形時,使用transform: rotateZ(180deg)翻轉(zhuǎn)了圓形,使扇形朝下,所以現(xiàn)在我們需要用一個水面朝下的圖片作為背景圖素材。

翻轉(zhuǎn)后的背景圖素材

css

.round1 {
    background-image: url(./bg.jpg);
    background-position: center center;
    background-size: 100% 100%;
    width: 140%;
    height: 140%;
    position: absolute;
    top: -70%; // -140/2
    left: -20%; // (100-140)/2
}

再給section標簽添加個好看協(xié)調(diào)點的背景,得到以下效果:

添加背景后的效果

根據(jù)聲吶探測器返回數(shù)據(jù)計算魚的位置

在vue文件的data模擬探測器回波數(shù)據(jù):

data() {
   // 回波數(shù)據(jù)
    this.snData = {
        depth: 4568,
        temperature: 18,
        echo_data: [[3299, 3299, 3200, 3399, 3299, 4400, 1230], [3333, 2222],
                    			[1234, 3210], [1234], [3210, 1234, 5000, 5000]]
    };
    return {
        XYArr: [], // {left, top, transform: rotateZ(0deg)}
        scale: [], // 參考線刻度
        hh: 0, // 水的總深度
        temperature: 0, // 水溫
        count: 0 // 統(tǒng)計數(shù)
    };
},

 

下面是計算魚的位置的關(guān)鍵代碼,利用了三角函數(shù)的正弦函數(shù)sinθ、余弦函數(shù)cosθ,對應(yīng)的js方法:Math.sin(ag * Math.PI / 180)、Math.cos(ag * Math.PI / 180),在vue文件的methods新增方法:

/*
三角函數(shù),獲取魚在屏幕上的顯示位置
h魚的水深度,
grid=1,2,3 魚屬于扇形的分區(qū)索引,
第一格角度 = 15~45,第二格= 0~15,第二格區(qū)分左右部分,第三格= 15~45,
 */
getXY(h, hh, grid = 2) {
    let ag = 0; // 角度
    let lr = 'L'; // 第二格隨機區(qū)分左右, L/R

    // 1.根據(jù)魚的grid隨機取扇形角度
    if (grid === 1) {
        ag = Math.floor(Math.random() * 15 + 25);
    }
    if (grid === 2) {
        ag = Math.round(Math.random() * 15);
        lr = ag % 2 === 0 ? 'R' : 'L';
    }
    if (grid === 3) {
        ag = Math.floor(Math.random() * 15 + 25);
        lr = 'R';
    }

    // 2.獲取扇形相關(guān)數(shù)據(jù)
    let sona = this.$refs['sona'];
    let L = sona.offsetWidth / 2;
    let r = $('.round1').width() / 2;

    // 3.計算
    let p = hh / r;
    let LL = p * L; // 屏幕像素轉(zhuǎn)換為毫米長度

    let xy = {};

    let x = LL - h * Math.sin(ag * Math.PI / 180);
    let psx = x / (LL * 2);
    if (lr === 'L') {
        xy.left = psx * 100 + '%';
    } else {
        xy.left = (LL * 2 - x) / (LL * 2) * 100 + '%';
    }

    let y = h * Math.cos(ag * Math.PI / 180);
    xy.top = y / (LL * 2) * 100 + '%';

    // 4.隨機取魚圖標的旋轉(zhuǎn)角度
    let st = -60; let end = 240;
    let deg = Math.floor(Math.random() * (st - end) + end);
    xy.transform = 'rotateZ(' + deg + 'deg)';

    this.XYArr.push(xy);
},

遍歷二維數(shù)組生成魚的位置

// 生成魚的位置
createFish() {
    this.XYArr = []; // 清空魚的數(shù)據(jù)
    this.getScale(this.hh, this.snData.depth);
    this.snData.echo_data.forEach((item, idx) => {
        // idx = 0,1,3 為扇形中間格;2為左邊格,4為右邊格
        let gird = 2;
        if (idx === 2) {
            gird = 1;
        } else if (idx === 4) {
            gird = 3;
        }
        item.forEach(fitem => {
            if (fitem > this.hh) fitem = this.hh;
            if (fitem < 600) fitem = 600;
            this.getXY(fitem, this.hh, gird);
        });
    });
},

 

魚的圖標樣式:

css

.fsIcon {
    position: absolute;
    z-index: 5;
    left: 0;
    top: 0;
    width: 26px;
    height: 10px;
    background: url(./yu.png) no-repeat center center;
    background-size: 100% 100%;
    margin-top: -2px;
    margin-left: -13px;
    transform: rotateZ(40deg); // -60~240
    opacity: .9;
}

 

html,for生成魚圖標

    .......
    <div class="line1"></div>
    <div class="line2"></div>
     <i v-for="(item, idx) in XYArr" :key="idx" class="fsIcon"  :style="item"></i> 

得到以下魚的分布效果:

魚的分布效果

根據(jù)聲吶探測器返回數(shù)據(jù)繪制水深標尺

最后根據(jù)探測器返回的總水深,生成參考標尺。

html

<div class="ruler">
  <span v-for="item in scale" :key="item">{{ item }}米</span>
</div>

css

.ruler {
       width: 0;
       height: 70%;
       position: absolute;
       transform: rotateZ(45deg);
       top: -10%;
       left: 25%;

   span {
       white-space: nowrap;
       position: absolute;
       right: -100%;
       z-index: 3;
       font-size: 12px;
       color: #eee;

       &:nth-child(1) {
            top: calc(100% - 20px); // 140
        }
       &:nth-child(2) {
            top: 70%;
        }
       &:nth-child(3) {
            top: 40%;
        }
       &:nth-child(4) {
            top: 10%;
        }
   }
}

JAVAScript

// 扇形參考線刻度
getScale(old_hh, new_hh) {
    if (Math.abs(new_hh - old_hh) < 200) return; // 兩次深度小于0.x米不作處理
    this.hh = new_hh;
    this.scale = [];
    for (let i = 0; i <= 3; i++) {
        let item = ((new_hh - new_hh / 4 * i) / 1000).toFixed(1);
        this.scale.push(item);
    }
}

最終效果展示

最終效果展示

完整代碼

上文的css和js代碼是完整的,下面是完整的html:

<div ref="sona" class="maxbox fxbox">
  <div class="sx_cp">
    <div class="round1 path"></div>
    <div class="round2 path"></div>
    <div class="round3 path"></div>
    <div class="round4 path"></div>
    <div class="line1"></div>
    <div class="line2"></div>
    <div class="ruler">
      <span v-for="item in scale" :key="item">{{ item }}米</span>
    </div>
    <i v-for="(item, idx) in XYArr" :key="idx" class="fsIcon"  :style="item"></i>
  </div>
</div>

知識點總結(jié)

1、簡單了解CSS中的路徑裁剪 clip-path

clip-path 屬性使用裁剪方式創(chuàng)建元素的可顯示區(qū)域。區(qū)域內(nèi)的部分顯示,區(qū)域外的隱藏。可以指定一些特定形狀。

語法:clip-source|basic-shape|margin-box|border-box|padding-box|content-box|fill-box|stroke-box|view-box|none|initial|inherit;

屬性值 描述

clip-source 用 URL 表示剪切元素的路徑

basic-shape 將元素裁剪為基本形狀:圓形、橢圓形、多邊形或插圖

margin-box 使用外邊距框作為引用框

border-box 使用邊框作為引用框

padding-box 使用內(nèi)邊距框作為引用框

content-box 使用內(nèi)容框作為引用框

fill-box 使用對象邊界框作為引用框

stroke-box 使用筆觸邊界框(stroke bounding box)作為引用框

view-box 使用最近的 SVG 視口(viewport)作為引用框。

none 這是默認設(shè)置,不剪輯

initial 設(shè)置屬性為默認值。

inherit 屬性值從父元素繼承。

其中basic-shape屬性的值有幾種:

polygon多邊形、circle圓形、ellipse橢圓、inset插圖

三角形

clip-path: polygon(50% 0%, 0% 100%, 100% 100%);

菱形

clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);

梯形

clip-path: polygon(20% 0%, 80% 0%, 100% 100%, 0% 100%);

平行四邊形

clip-path: polygon(25% 0%, 100% 0%, 75% 100%, 0% 100%);

斜角

clip-path: polygon(20% 0%, 80% 0%, 100% 20%, 100% 80%, 80% 100%, 20% 100%, 0% 80%, 0% 20%);

左箭頭

clip-path: polygon(40% 0%, 40% 20%, 100% 20%, 100% 80%, 40% 80%, 40% 100%, 0% 50%);

右箭頭

clip-path: polygon(0% 20%, 60% 20%, 60% 0%, 100% 50%, 60% 100%, 60% 80%, 0% 80%);

五角星

clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);

 

2、簡單了解js三角函數(shù)

Math.sin()
sin 方法返回一個 -1 到 1 之間的數(shù)值,表示給定角度(單位:弧度)的正弦值。

Math.sin(x)   //函數(shù)返回一個數(shù)值的正弦值。x為弧度
Math.sin(0);           // 0
Math.sin(Math.PI / 2); // 1

Math.cos()
cos 方法返回一個 -1 到 1 之間的數(shù)值,表示角度(單位:弧度)的余弦值。

Math.cos(0);           // 1
Math.cos(Math.PI);     // -1
Math.cos(2 * Math.PI); // 1

Math.tan()
表示一個角的正切值。

Math.atan()
函數(shù)返回一個數(shù)值的反正切(以弧度為單位)

Math.atan(0);  // 0

已知兩直角邊Y,X長度,求夾角角度:

180*Math.atan(Y/X)/(Math.PI)

 

*創(chuàng)作不易,轉(zhuǎn)載請注明出處并附上本文鏈接

分享到:
標簽:CSS
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定