【Copy攻城獅日誌】踩坑小程序之使用svg做爲圖標

Created 2019-4-4 22:02:27 by huqi
Updated 2019-4-4 23:12:34 by huqicss

clipboard.png
↑開局一張圖,故事全靠編↑前端

本地資源沒法經過 WXSS 獲取

都9102年了,我竟然還會犯如此低級的錯誤。不經想起去年犯的一個更低級的錯誤,事情的通過是這樣的,去年@肖蜀黍 在某個羣裏丟了一個小程序連接--tell心語,這個小程序自己就具備傳奇色彩,背後的故事更是感動人心,就是現實版的解憂雜貨店;主要的功能是寫信,也就是文字輸入。而後,我竟然腦殘地去測試xss!!!不學無術,還要自命不凡,像我這樣的沒被祭天就是萬幸了。此次,又是基本的常識都沒掌握,直接淹死在淺坑裏。background-image:能夠使用網絡圖片,或者 base64,或者使用<image/>標籤。這個是常識,連入門級小程序員都知道的。那我究竟寫了個什麼B.U.G?毫無疑問,必定是在BG中直接引用了本地圖片。
乳此低級的錯誤,必定要貼出來,示衆以鞭策!git

.refresh-icon{
  background: url('refresh.svg');
}
.del-icon{
  background: url('del.svg');
}

獲取iconfont的svg圖

做爲老司機的「幼兒班程序員」,應該是沒有資格拿到切好的圖標了,沒辦法,技不如人,只能本身動手去啥都有的網上找找。關於圖標,我最早想到的是阿里巴巴矢量圖標庫,這個由阿里媽媽MUX傾力打造的矢量圖標管理、交流平臺,設計師能夠將圖標上傳到這個平臺,用戶能夠自定義下載多種格式的icon,平臺也可將圖標轉換爲字體,便於前端工程師自由調整與調用。雖然能夠將圖標轉化爲字體應用,但對於我來講,就使用那麼幾個圖標,實在是不想引用一大堆css、ttf等文件,只想用下svg。具體怎麼操做,胸中天然有了竹子。程序員

  • 搜索和UI圖如出一轍的圖標,建議按照英文關鍵字查詢,如del、refresh等
  • 點擊下載進入下載模態詳情頁,選擇合適的顏色下載svg

clipboard.png

轉換svg爲background

既然官方文檔說了,不讓直接引用本地圖片,但給了三條路,那我就隨便遠一條嘍,反正我不想用網絡圖片,我也不想用image標籤,那就只有轉成base64嘍,至於什麼是base64,我也不知道,那就超度一下嘍:☛base64。可是怎麼快速將svg轉換成這個base64甚至直接輸出成css樣式呢?我說,首先您得有工具獲得svg源碼,我用vscode,直接打開svg就是svg源代碼;而後轉base64,偶然發現了國外大佬在codepan上的在線實現,文章的話能夠參考下「優化數據uris中的svgs」 ,我特地fork了一份來學習,感興趣的能夠看下源碼。有了這個工具,svg生成background也就是我專門乾的事=copy&pastegithub

  • 獲取svg源碼
  • 生成background

clipboard.png

重寫background

既然base64已經手到擒來了,那麼實現圖標按鈕還會遠嗎,來來來,有請代碼說話:
超級簡單!!!搜衣滋!小程序

.my-icon{
  background-size: cover;
  display: inline-block;
  width: 50rpx;
  height: 50rpx;
  vertical-align: middle;
  margin-right: 4px;
}
.refresh-icon{
  background-image: url("data:image/svg+xml,%3C?xml version='1.0' standalone='no'?%3E%3C!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'%3E%3Csvg t='1554354671724' class='icon' style='' viewBox='0 0 1024 1024' version='1.1' xmlns='http://www.w3.org/2000/svg' p-id='1543' xmlns:xlink='http://www.w3.org/1999/xlink' width='200' height='200'%3E%3Cdefs%3E%3Cstyle type='text/css'%3E%3C/style%3E%3C/defs%3E%3Cpath d='M936.571429 603.428571q0 2.857143-0.571429 4-36.571429 153.142857-153.142857 248.285715T509.714286 950.857143q-83.428571 0-161.428572-31.428572T209.142857 829.714286l-73.714286 73.714285q-10.857143 10.857143-25.714285 10.857143t-25.714286-10.857143-10.857143-25.714285v-256q0-14.857143 10.857143-25.714286t25.714286-10.857143h256q14.857143 0 25.714285 10.857143t10.857143 25.714286-10.857143 25.714285l-78.285714 78.285715q40.571429 37.714286 92 58.285714t106.857143 20.571429q76.571429 0 142.857143-37.142858t106.285714-102.285714q6.285714-9.714286 30.285714-66.857143 4.571429-13.142857 17.142858-13.142857h109.714285q7.428571 0 12.857143 5.428572t5.428572 12.857142z m14.285714-457.142857v256q0 14.857143-10.857143 25.714286t-25.714286 10.857143h-256q-14.857143 0-25.714285-10.857143t-10.857143-25.714286 10.857143-25.714285l78.857142-78.857143q-84.571429-78.285714-199.428571-78.285715-76.571429 0-142.857143 37.142858T262.857143 358.857143q-6.285714 9.714286-30.285714 66.857143-4.571429 13.142857-17.142858 13.142857H101.714286q-7.428571 0-12.857143-5.428572T83.428571 420.571429v-4q37.142857-153.142857 154.285715-248.285715T512 73.142857q83.428571 0 162.285714 31.714286T814.285714 194.285714l74.285715-73.714285q10.857143-10.857143 25.714285-10.857143t25.714286 10.857143 10.857143 25.714285z' p-id='1544' fill='%23ffffff'%3E%3C/path%3E%3C/svg%3E");
}
.del-icon{
  background-image: url("data:image/svg+xml,%3C?xml version='1.0' standalone='no'?%3E%3C!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'%3E%3Csvg t='1554355910565' class='icon' style='' viewBox='0 0 1024 1024' version='1.1' xmlns='http://www.w3.org/2000/svg' p-id='2306' xmlns:xlink='http://www.w3.org/1999/xlink' width='200' height='200'%3E%3Cdefs%3E%3Cstyle type='text/css'%3E%3C/style%3E%3C/defs%3E%3Cpath d='M817.968553 215.897142l-169.357176 0 0-58.869782c0-25.391297-20.657482-46.048779-46.048779-46.048779l-181.125197 0c-25.391297 0-46.048779 20.657482-46.048779 46.048779l0 58.869782-169.357176 0c-25.391297 0-46.048779 20.657482-46.048779 46.048779l0 71.631434c0 25.391297 20.657482 46.048779 46.048779 46.048779l28.321022 0 0 425.947112c0 59.246359 48.200792 107.447151 107.447151 107.447151l340.40076 0c59.246359 0 107.447151-48.200792 107.447151-107.447151L789.647531 379.626133l28.321022 0c25.391297 0 46.048779-20.657482 46.048779-46.048779l0-71.631434C864.017332 236.554624 843.35985 215.897142 817.968553 215.897142zM426.553932 162.14389l170.892135 0 0 53.753251-170.892135 0L426.553932 162.14389zM738.482221 805.574269c0 31.033807-25.248034 56.281841-56.281841 56.281841L341.79962 861.85611c-31.033807 0-56.281841-25.248034-56.281841-56.281841L285.517779 379.626133l452.964442 0L738.482221 805.574269zM812.852022 328.460824l-601.704045 0 0-61.398372 203.227588 0c2.302439 0.356111 4.66116 0.542352 7.061836 0.542352l181.125197 0c2.400676 0 4.759397-0.186242 7.062859-0.542352l203.226564 0L812.852022 328.460824zM513.023306 783.320429c14.128789 0 25.582655-11.453866 25.582655-25.582655l0-288.572348c0-14.128789-11.453866-25.582655-25.582655-25.582655-14.128789 0-25.582655 11.453866-25.582655 25.582655l0 288.572348C487.440651 771.866562 498.894518 783.320429 513.023306 783.320429zM645.541459 783.320429c14.128789 0 25.582655-11.453866 25.582655-25.582655l0-288.572348c0-14.128789-11.453866-25.582655-25.582655-25.582655s-25.582655 11.453866-25.582655 25.582655l0 288.572348C619.958804 771.866562 631.41267 783.320429 645.541459 783.320429zM380.505154 783.320429c14.128789 0 25.582655-11.453866 25.582655-25.582655l0-288.572348c0-14.128789-11.453866-25.582655-25.582655-25.582655s-25.582655 11.453866-25.582655 25.582655l0 288.572348C354.922499 771.866562 366.376365 783.320429 380.505154 783.320429z' p-id='2307' fill='%23ffffff'%3E%3C/path%3E%3C/svg%3E");
}

附上效果圖:網絡

clipboard.png

svg轉換核心源碼

//  用於建立優化的svg url的函數
//  Version: 1.0.6
@function svg-url($svg){
    //
    //  補齊命名空間
    //
    @if not str-index($svg,xmlns) {
        $svg: str-replace($svg, '&ltsvg','&ltsvg xmlns="http://www.w3.org/2000/svg"');   
    }        
    //    
    //  避免一大塊的字符串
    //  拋出「堆棧級別太深」錯誤
    //     
    $encoded:'';
    $slice: 2000;
    $index: 0;
    $loops: ceil(str-length($svg)/$slice);
    @for $i from 1 through $loops {
        $chunk: str-slice($svg, $index, $index + $slice - 1); 
        //
        //   編碼
        //
        $chunk: str-replace($chunk, '"', '\'');
        $chunk: str-replace($chunk, '%', '%25');
        $chunk: str-replace($chunk, '#', '%23');       
        $chunk: str-replace($chunk, '{', '%7B');
        $chunk: str-replace($chunk, '}', '%7D');         
        $chunk: str-replace($chunk, '&lt;', '%3C');
        $chunk: str-replace($chunk, '&gt;', '%3E');
        
        // 
        //    預計列表 
        //
        //    保持大小並縮短編譯時間
        //    ... 只添加記錄的失敗 
        // 
        //  $chunk: str-replace($chunk, '&', '%26');        
        //  $chunk: str-replace($chunk, '|', '%7C');
        //  $chunk: str-replace($chunk, '[', '%5B');
        //  $chunk: str-replace($chunk, ']', '%5D');
        //  $chunk: str-replace($chunk, '^', '%5E');
        //  $chunk: str-replace($chunk, '`', '%60');
        //  $chunk: str-replace($chunk, ';', '%3B');
        //  $chunk: str-replace($chunk, '?', '%3F');
        //  $chunk: str-replace($chunk, ':', '%3A');
        //  $chunk: str-replace($chunk, '@', '%40');
        //  $chunk: str-replace($chunk, '=', '%3D');      
        
        $encoded: #{$encoded}#{$chunk};
        $index: $index + $slice; 
    }
    @return url("data:image/svg+xml,#{$encoded}");   
}
        
//  Background svg mixin          
@mixin background-svg($svg){
    background-image: svg-url($svg);        
}        
            
//  替換字符串中的字符的輔助函數
@function str-replace($string, $search, $replace: '') {
    $index: str-index($string, $search); 
    @return if($index, 
        str-slice($string, 1, $index - 1) + $replace + 
        str-replace(str-slice($string, $index + 
        str-length($search)), $search, $replace), 
        $string); 
}

總算是又get了一個知識點,最近作小程序,遇到的難題仍是挺多的,好比尚未解決的wx.redirectTo閃屏問題,有大佬要是剛好遇到過相似的坑,歡迎多多指教!前端工程師

相關文章
相關標籤/搜索