藍色的秋風

藍色的秋風 查看完整檔案

杭州編輯  |  填寫畢業院校美團  |  web前端 編輯 qiufeng.blue 編輯
編輯

JavaScript開發愛好者。全棧工程師。

??微信公眾號:秋風的筆記
??博客主頁:https://qiufeng.blue

個人動態

藍色的秋風 回答了問題 · 3月1日

給body添加全屏背景圖(backgroung-size:cover),如何給圖片上某一個區域添加點擊事件,適應各個分辨率

使用 background-size: cover

縮放背景圖片以完全覆蓋背景區,可能背景圖片部分看不見。和 contain 值相反,cover 值盡可能大的縮放背景圖像并保持圖像的寬高比例(圖像不會被壓扁)。該背景圖以它的全部寬或者高覆蓋所在容器。當容器和背景圖大小不同時,背景圖的 左/右 或者 上/下 部分會被裁剪。

我們可以看到他的有一點,寬高比例是不變的。所以你直接獲取你的點擊區域百分比就行,因為相同比例下,放大縮小位置百分比位置都是不變的。例如某個預取是 left: 50%, top: 50%,就直接渲染在你的圖上。

關注 6 回答 5

藍色的秋風 發布了文章 · 2月19日

2021前端學習路徑書單—自我成長之路

正式學習前端大概 3 年多了,接觸前端大概 4 年了,很早就想整理這個書單了,因為常常會有朋友問,前端該如何學習,學習前端該看哪些書,我就講講我學習的道路中看的一些書,雖然整理的書不多,但是每一本都是那種看一本就秒不絕口的感覺。

以下大部分是我看過的,或者說身邊的人推薦的書籍,每一本我都有些相關的推薦語,如果你有看到更好的書歡迎推薦呀。

前端學習書籍導圖-1

JS

《JavaScript高級程序設計(第4版)》

第三版:豆瓣評分9.3

第四版:豆瓣評分8.5

現在建議學習第四版,因為第三版很多還是以ES5的語法進行講解的,目前主流都是 ES6 語法了。當年我入門這是我看的第一本JS書籍,也是實驗室的導師推薦的,這本書很厚,真的需要耐著性子看完,DOM、BOM、JS基礎語法,我先是把這些大概的過了一下,然后去實踐項目,有不懂的點再來回味這本書,以我的性子,還是比較喜歡動手進行實踐。

《你不知道的JavaScript(上卷)》

豆瓣評分 9.3

這本書,真的是神書,我先看的高級程序設計,但是看完我對一些作用域啊,閉包,原型鏈還是懵懵懂懂,看完這本書瞬間打通了任督二脈,豁然開朗。

《ECMAScript 6 入門電子版》

《ECMAScript 6 入門》

豆瓣評分 8.8

這本書屬于工具書,建議電子版,翻翻常用的一些 ES6 語法就好了,當年我準備實習的時候就看了常用的一些語法例如(Map、Set、Proxy、Promise、Generator、async、Module等)。(當然如果對你有幫助還是可以買一下實體書,支持一下作者,畢竟電子版可以免費看,寫書需要花很多精力。)

《JavaScript忍者秘籍(第2版)》

豆瓣評分 8.5

這本書是我工作上的導師推薦,我暫時還沒看,據說幫助他解了很多疑惑。

CSS

《CSS世界》

作者是張鑫旭,可以說是 CSS領域的鼻祖了。我買了這本書,但是還沒有看,不看的原因不是他不好,是最近不常寫CSS了,哈哈哈。當初買它的時候,我是看它的目錄,可以說它把CSS中一些比較重要的場景都包含到了。目錄名字也取得非常有吸引力。塊級元素、盒子模型、浮動、層疊規則等等基礎的用法都講到了。

《CSS揭秘》

豆瓣評分 9.4

作者是Lea Verou,W3C CSS工作組特邀專家,設計CSS語言的委員之一,此前曾在W3C擔任開發者代言人。目前,她在麻省理工學院從事人機交互領域的研究。

作者來頭真的太大了...又是W3C CSS專家又是MIT的...看過這本書的人都會驚嘆,原來 CSS 還能這么玩?如果你想精進 CSS,這本書不能錯過。這本書剛出的時候就買了,后來畢業送給了實驗室的小伙伴。

框架

Vue

vue2文檔

vue3文檔

如果出個豆瓣評分估計是9.9分,那0.1分怕它驕傲。

vue的學習建議直接看官網吧,寫的太詳細了,像一本書一樣。

React

React官網

官網教程真的很貼心,會一步一步教你如果構建一個 React 應用,并且還會說有些哲學思想。

《React小書》

這本書是一本開源的書籍,面向的對象是有一點前端基礎的并且是 React.js 零基礎的同學而作。

《深入React技術?!?/a>

豆瓣評分 8.1

大概是 17 年的時候買的,算是買的第一本 React 書籍也是唯一一本 React 書籍,

Node

《七天學會NodeJS》

開源書,書只有大概只有200頁左右,一下子就能看完,通過例子能夠快速熟悉一些 Node 的 API,也許現在來說很多 API 已經過時了(畢竟Node版本迭代太快了,現在都15x了),但是安裝舊版本的 Node來入門,仍然是一本和不錯的書。

《深入淺出Node.js》

豆瓣評分 8.6

清晰地講解了Node.js 底層原理,以及如何使用 Node.js 進行工程項目開發,是進階的首選。

《Node.js設計模式》

原書英文版豆瓣評分9.5,買了中文版...看的云里霧里,可以試試英文版。

《Node.js:來一打 C++ 擴展》

剛出的時候就買了這本書... 但是功力不夠啊,看這本書需要一些 C++ 的底蘊,還特地買了 C++ Primer 準備好好學習,但是發現...周期太長了沒有堅持下來,又因為公司也沒有這方便的場景應用,所以自己草草寫了一個 C++ 插件(https://github.com/hua1995116/LRU-node-addon)之后,這本書就擱置了。

工程化

Webpack

《深入淺出Webpack》

《深入淺出 Webpack電子版》

這本書很多人吐槽,說寫的很基礎,深度不夠,也比較落后了。確實是這樣,但是我覺得webpack官方文檔雖然很全很前沿,但是還沒有那種一下子就能讓人整明白的。跟著這本書 + 配套github示例,寫完全部示例(花不了很多時間),可以說對 webpack 會有一個大概的了解。

學習webpack難點在于什么?

各種周邊插件版本不配套??!

想加個loader/plugin,各種版本不兼容,各種報錯!因為新手安裝 webpack 的插件大多數人都是會安裝到最新版本,但是最新版本大多數會有各種問題,真的是勸退...

webpack經過幾個飛速的迭代,webpack3x和4x的插件機制就不一樣,現在又是5x了。

所以能有一個固定的版本,跟著走完全流程對它有一個整體的認識,看完一本書能了解這些也算是值了。有了這些整體的認知,相信你不管是學 4x還是5x都能行云流水了。

TypeScript

深入理解 TypeScript》

開源電子書,是一個學習 TypeScript 不錯的開始吧,我快速過了一下這本書和官網示例,有了大概的了解,想要深入學習 TS 可能還是需要實踐吧~

《重學TS》

阿寶哥寫的重寫 TS 也很不錯,其實我TS用的并不多,偶然在寫一些高級泛型的時候查到了阿寶哥寫的文章,感覺受益良多。

計算機基礎

設計模式

JavaScript設計模式》

以故事線的模式來風趣地講解JS的設計模式。

算法基礎

《圖解算法》

豆瓣評分 8.4

小白也能看懂的算法,對于初學者可以說非常有幫助,我看完了電子版,但是對于想真正在算法領域有所精進那就看下面這本書吧。

《算法導論》

豆瓣評分 9.2

這本書很數學,看的令人頭禿,但是真的很全,里面的示例全部是偽代碼所寫,理解起來也有一定的難度,跟著實驗做一遍會有很大的收獲。

網絡基礎

《圖解 HTTP》

豆瓣評分 8.1

這本書也是看了電子版,主要是圍繞TCP/IP來進行講解,瀏覽完對HTTP常用的一些屬性以及網絡會有一個大概的概念。

《TCP/IP詳解 卷1:協議》

豆瓣評分 9.2

如果要精進計算機網絡,可以看這本。

編譯原理

《編程語言與實踐》

買了龍書啊虎書啊什么的,看了都犯困,而這本書只看了前幾章,就能自己實現了一個ll(1)的解釋器 common-comment-parser

代碼規范

《重構》

豆瓣評分 9.4

第2版和第1版我都買了,看完確實對寫代碼有幫助,其中重構前最重要的就是保證不破壞原先的代碼的邏輯,這就要求我們有足夠的測試用例情況下再進行重構。

技術探索

Three.js

《Three.js 入門指南》

可能對于大佬來說比較基礎,但是對于小白入門來說,是不錯的選擇。能了解三維世界中的照相機、材質、網格和動畫等特性。

《Three.js 開發指南(第三版)》

還正在看中,買了當當的電子版。

Serverless

《深入淺出Serverless》

這本書我是在微信讀書看的,看了一半,可以對 Serverless 到底是什么東西有所了解,Faas 并不是代表 Serverless,Serverless 是由 Faas + Baas 組成的,容器化發展過程,Serverless的特點都在本書進行了講解。

為了證明以上大部分書我確實都是自己讀過才推薦的,曬一下我的書柜(像你不知道的JS以及深入React技術棧在畢業的時候送給實驗室小伙伴了,還有一些看的電子書~)

IMG_1394

結語

??關注+點贊+收藏+評論+轉發??,原創不易,鼓勵筆者創作更好的文章

關注公眾號秋風的筆記,一個專注于前端面試、工程化、開源的前端公眾號 ![]

  • 關注后回復簡歷獲取100+套的精美簡歷模板
  • 關注后回復好友拉你進技術交流群+面試交流群
  • 歡迎關注秋風的筆記
查看原文

贊 29 收藏 22 評論 2

藍色的秋風 發布了文章 · 2月15日

JS也可以這么浪漫,用JS寫下一個世界(VR)

先上圖感受一下,以迪士尼城堡為例。

640-1

640-4

心動了嗎?你以為實現這個炫酷特效會很復雜?

不不不,實現這個特效只有兩個步驟

  • 需要一張全景圖
  • 使用 photo-sphere-viewer.js 進行配置 (一個用來來顯示全景圖JavaScript庫)

可以從這里免費下載全景圖片

https://pixabay.com/zh/images...

在線演示地址(手機打開效果更佳) https://qiufeng.blue/frontend...

1613375898884

源碼地址: https://github.com/hua1995116...

代碼詳解

<style>
#photosphere {
    width: 100%;
    height: 100%;
}
</style>
</head>
<body>

<div id="photosphere"></div>

<script data-original="three.js"></script>
<script data-original="browser.js"></script> /*uEvent 的瀏覽器版本*/
<script data-original="photo-sphere-viewer.js"></script>

<script>
  const PSV = new PhotoSphereViewer.Viewer({
    container : 'photosphere', // 容器id
    panorama  : '360.jpg', // 全景圖地址
    caption   : '',
    loadingImg: 'assets/photosphere-logo.gif', // loading的gif
    defaultLong: Math.PI/2 + Math.PI/12, // 默認角度
    defaultZoomLvl: 30,
  });
</script>
<script data-original="./snow.js"></script> /*下雪的場景*/

實現上面場景的代碼非常簡單,主要是有photo-sphere-viewer.js實現的,自己不需要加任何代碼。

photo-sphere-viewer.js 也支持了非常多的控件,例如 mark 標記、自動漫游以及設置分辨率等。

由于 photo-sphere-viewer.js 是基于 Three.js ,因此必須引入 Three.js 的依賴,還依賴 uEvent 事件訂閱相關的 API。

我再來看看增加插件會有哪些不一樣的變化。

我們可以通過 mark插件來標記一些特殊的地點,并且還有標記列表,可以直達對應的地點。通過增加對應的點位來實現呈現出特殊意義的位置,可以是第一次相遇或者是第一次做了不可描述畫面的地點(小朋友捂臉)...

PSV = new PhotoSphereViewer.Viewer({
  ...
    plugins: [
      [PhotoSphereViewer.MarkersPlugin, {
        markers: (function () {
          var a = [];

          a.push({
            id: '#123',
            tooltip: '第一次相遇的地點',
            latitude: -0.3988129280019779,
            longitude: 1.7374233460711157,
            image: 'assets/pin-red.png',
            width: 32,
            height: 32,
            anchor: 'bottom center',
          })
          return a;
        }())
      }]
    ]
    ...
})

var markers = PSV.getPlugin(PhotoSphereViewer.MarkersPlugin);
markers.toggleAllTooltips();

1613375926141

mark 不僅可以標記地點,還可以通過列表來進行引導

640-3

關于這個 snow特效是我隨便找的一個js特效,你也可以通過不同的場景,換成雨、下星星啊,各種浪漫的場景~

趕緊收藏這個效果吧~

結語

??關注+點贊+收藏+評論+轉發??,原創不易,鼓勵筆者創作更好的文章

關注公眾號秋風的筆記,一個專注于前端面試、工程化、開源的前端公眾號

  • 關注后回復簡歷獲取100+套的精美簡歷模板
  • 關注后回復好友拉你進技術交流群+面試交流群
  • 歡迎關注秋風的筆記
查看原文

贊 12 收藏 10 評論 0

藍色的秋風 發布了文章 · 2月14日

Github域名加上`1s`,在線VS Code閱讀源碼神器誕生

近日,一款域名為 github1s 開源項目誕生了,正如他的名字所說,只要在 github 地址上面加上 1s,就能秒級用在線 VS Code 打開 github 項目,這可以說為開發者帶來了巨大的便利?。?!

我們來看看這個項目打開后長什么樣子~

以大家廣為知道的 React 為例,只要將 github 替換成github1s

http://github.com/facebook/react

http://github1s.com/facebook/react

然后我們來談談這個項目的優缺點

優點

幾乎擁有和本地 VS Code 一樣的界面

在在線 VS Code 中打開,同樣的款式同樣的配方,這樣閱讀起來非常有親切感,這種親切感,可以更好地提高我們閱讀代碼的效率。

支持 VS Code 中的部分快捷鍵

能夠 command + 單擊 (window 應該是 ctrl + 單擊)自動跳轉到對應的函數。

支持 hover 后能夠推導類型

支持代碼收起和展開

這個功能對閱讀源碼非常有幫助,可以幫助我們收起一些不重要的函數,讓我們摸清代碼的主干。

支持代碼在線比較

選中兩個文件右鍵,就可以進行在線比較

一鍵下載單文件

對于 Github 站點上閱讀整體目錄不便的情況下,并且下載文件總是需要點擊 Raw 再下載源文件,可以說這個功能方便太多了。(當然你也可以下載一些其他的插件)

缺點

不能點擊文件跳轉至其他文件

目前的版本中是無法直接點擊引用文件自動打開其他文件

無法全局搜索

只有當我們打開了當前的文件,才會從當前打開的頁面中進行全局搜索,沒有打開的頁面沒辦法全局搜索,這樣對大型庫的源碼閱讀還是造成了一定的影響。

技術探索

在 api 層面看到主要還是走了 github 的開放接口,這樣有個問題就是我們國內用戶,訪問起來還是沒法達到1s那么快,但是我的網絡基本上3s初次渲染也完成了。

總結

帶來了一定的便利,比純用 github好用多了,也比 sourcegraph 插件使用起來體驗更好!但是想要完全替代本地編輯器閱讀源碼,任然需要完善,例如上述說到的缺點。

綜上源碼閱讀體驗排名:

本地VS Code > Github1s > sourcegraph > Github站點。

如果還有什么我沒有發現的優缺點,歡迎留言中指出~

最后

回看筆者往期高贊文章,也許能收獲更多喔!

結語

??關注+點贊+收藏+評論+轉發??,原創不易,鼓勵筆者創作更好的文章

關注公眾號秋風的筆記,一個專注于前端面試、工程化、開源的前端公眾號

  • 關注后回復簡歷獲取100+套的精美簡歷模板
  • 關注后回復好友拉你進技術交流群+面試交流群
  • 歡迎關注秋風的筆記
查看原文

贊 14 收藏 5 評論 5

藍色的秋風 贊了文章 · 2月11日

JParticles 2.0 發布,打造炫酷的粒子特效

JParticles 2.0 發布,打造炫酷的粒子特效。
不好意思哈,在這么繁花似錦的世界里,標題不得不取得吸引眼球一點哈,
不然...還是不啰嗦了,我們進入正題吧圖片描述

簡單介紹一下

JParticles 2.0 版本之前還叫 Particleground.js,相信在用的朋友應該不會陌生,關于 1.x 版本的宣傳文案可以移步看這里哈,或許可以幫助你了解 JParticles 2.0 的一些東西。

我們一貫的理念

我們(我/笑哭)一貫的理念是信仰:"The Write Less, Do More""Keep It Simple And Stupid"。
希望插件工具什么的使用起來非常的簡單便捷,上手快,不耽誤人們寶貴的時間,尤其是在變化迅速的前端,
希望我們的 代碼寫得簡潔,簡單,易懂,API設計的簡潔,簡單,易用, 最后 強大,易擴展!

此次版本更新日志

看看我們這次版本更新了哪些東西吧,biubiu...貼圖:

圖片描述

貌似挺多的,主要我們還是只講三點吧,剩下的可以看官網慢慢了解,哈哈。

第一點:視差粒子

https://codepen.io/barrior/pe...

幾行 JavaScript 代碼:

為了看起來更簡潔,定義視差粒子層數的屬性就省略了,因為本身它就是 3 層,也挺好的。
CodePen 演示四層,為了讓大家能更了解屬性的使用方法。

new JParticles.particle('#demo', {
  // 開啟視差效果
  parallax: true,
  
  // 定義視差強度
  parallaxStrength: 1
});

是不是好少...少到想哭有木有,但是很酷炫~

第二點:模擬語音搜索

學習于京東APP的搜索,上圖:

圖片描述

https://codepen.io/barrior/pe...

JavaScript 代碼:

如果你使用過 1.x, 相信你對 wave 的參數配置很理解,
我們刪除了之前的舊方法 setOffsetTop(),添加了新方法:setOptions(),
這個方法就更加強大與自由了,可以控制更多的屬性的變化,達到我們想要的效果。
這里我們主要的控制就是這個方法了,只是按住這個自定義事件是用戶自己的行為,
所以這里貼上自定義代碼把我們簡潔的 API,弄的好像很復雜了一樣,冤枉~
其實一共就兩處,見下面標注。

var settings = {
  crestHeight: [10, 14, 18],
  speed: .1
};

// 這里是第 ① 處
// JParticles.utils.extend 等同于 jQuery.extend,你也可以使用 Object.assign 替代。
var effect = new JParticles.wave('.instance .demo', JParticles.utils.extend({
  num: 3,
  lineColor: ['#e53d27', '#42e527', '#27C9E5'],
  lineWidth: [.7, .9, 1],
  offsetTop: .65,
  rippleNum: 2
}, settings));

// 線條波動效果
document.querySelector('.voice').onmousedown = function () {
  clearInterval(this.timer);
  this.timer = setInterval(function () {
    var crestHeight = settings.crestHeight.map(function (item) {

      // 獲取隨機波動值
      item += JParticles.utils.limitRandom(20, -20);

      // 處理 (0, 1) 之間的值為整數
      if (item < 1 && item > 0) {
        item = Math.ceil(item);
      }

      return item;
    });

    // 這里是第 ② 處
    // 通過 setOptions() 來控制線條的波動
    effect.setOptions({
      crestHeight: crestHeight,
      speed: [.2, .14, .1]
    });
  }, 100);

  // 復原
  var self = this;
  document.onmouseup = function () {
    document.onmouseup = null;
    clearInterval(self.timer);
    effect.setOptions(settings);
  };
};

第三點:waveLoading 模擬進度條加載

這是一個封裝好的,簡單易用的模擬加載進度條動畫。

1.x 版本是通過 wave 這個波浪運動來手寫加載進度條的內容,并不是很方便,參數的控制也麻煩,
于是 2.0 著重封裝了這個模擬加載進度條的動畫,這個特效在單頁應用首次加載什么的還是很需要的吧。
又高大上,又可以緩解加載的等待心情。

現在就來看看是怎么簡單的使用這個功能特效吧,我們以加載 baidu.com 首頁為示例,貌似其他的不允許 iframe 加載:

https://codepen.io/barrior/pe...

簡單的 JavaScript 代碼(CodePen 的代碼是有對細節進行調整,而核心內容就是下面這么簡單):

var demo = document.querySelector('.demo');

// 生成 loading 動畫
var loading = new JParticles.waveLoading(demo);

// 當你告訴 loading 加載完了,loading 就加載結束,并觸發這個事件
loading.onFinished(function () {
    
    // 這時,你就可以刪除 loading 動畫了,讓頁面顯示出來
    demo.parentNode.removeChild(demo);
});

// 加載完,告訴 loading 加載完了,讓 loading 結束
// 因為這是模擬進度條,所以你得告訴 loading,它才知道頁面此時已經加載完了
window.onload = function () {
    loading.done();
};

致歉

這個還是得致歉,之前承諾的會在新版增加QQ登錄背景效果(Delaunay三角的實現),由于時間也挺趕的,
現在還沒研究出Delaunay三角的實現,當然其實也可以用等研究好三角函數做出效果來了再發,但是這樣就耽誤的新版的發布,還不如先把能用的發出來,先用著能用的,后續再慢慢添加其他有意思的東西進來。
此處,對看過更新日志并滿懷期待的同志表示深深的歉意!

最后

官網(我想這應該是一個非常棒的文檔,因為很用心在寫):jparticles.js.org
如果你喜歡這個插件庫并能幫助到你的實際工作中,希望它能發展的更好,提供更多有趣實用的特效,支持作者,煩請點個 Star O(∩_∩)O謝謝~。

查看原文

贊 12 收藏 16 評論 10

藍色的秋風 發布了文章 · 2月8日

教你實現微信8.0『炸裂』的??表情特效

寫在開頭

最近微信更新了8.0,其中之一最好玩的莫過于表情包的更新了,大家都在群里紛紛玩起了表情包大戰。

作為一個前端程序員,這就勾起了我的好奇心,雖然我從來沒有實現過這樣的動畫,但是我還是忍不住想要去實現,最終我花了2天時間去看一些庫的源碼到我自己實現一個類似的效果,在這里我總結一下,并且手把手地教大家怎么學習實現。而??有一個自己的名字,叫做五彩紙屑,英文名字叫 confetti。

聊天室+五彩紙屑特效 在線地址: https://www.qiufengh.com/#/

聊天室Github地址: https://github.com/hua1995116/webchat

五彩紙屑Github地址: https://github.com/hua1995116/node-demo/tree/master/confetti

特效預覽,時間原因我只實現了平行四邊形的彩色小塊,其他形狀的原理也是類似。

還可以設置方向

前期研究

在寫這個特效前,我幾乎不會用canvas,雖然說現在也不太會用,很多 API 也不太清楚,因此這篇教程也是基于零基礎 canvas 寫的,大家不用擔心這個教程難度太高而被勸退。我會通過零基礎 canvas 的基礎上來一步步實現的。不過學習這個特效之前需要一點點高中數學的知識,如果你還記得 sin 和 cos 函數,那么以下的內容對于你來說都會非常簡單,不會也沒關系~

我個人比較喜歡探索研究,對有意思的玩意兒就會去研究,因此我也是站在巨人的基礎上,去 codepen 查了好多個類似的實現進行研究。

最終將目標定位在了 canvas-confetti ,為什么是這個庫呢?因為他的效果對于我們來說非??梢粤?,而且它是一個開源庫,并且擁有了 1.3K star(感覺改天可以分析分析大佬實現庫的原理了~),維護頻率也非常高。

核心實現

切片場景

首先拿到這個庫的時候,我有點開心,因為這個庫只有一個單文件。

但是,當我打開這個文件的時候,發現不對...1個文件500行代碼,我通過剝離層層的一些自定義配置化的代碼,最后抽離出單個紙屑的運動軌跡。我就開始不斷地在觀察它的運動軌跡...無限循環的觀察...

可以看到它在做一個類似于拋物線的運動,然后我一一將源碼中的變量進行標注,再結合源碼。

fetti.x += Math.cos(fetti.angle2D) * fetti.velocity;
fetti.y += Math.sin(fetti.angle2D) * fetti.velocity + fetti.gravity; 

以上代碼看不懂也沒事,我只是證明一下源碼中的寫法,并且提供學習源碼的一些思路,以下才是真正的開講實現!

平行四邊形的實現

實現這個特性前,我們需要知道 canvas 幾個函數。更多查看(https://www.runoob.com/jsref/dom-obj-canvas.html)

beginPath

方法開始一條路徑,或重置當前的路徑。

moveTo

把路徑移動到畫布中的指定點,不創建線條。

lineTo

添加一個新點,然后在畫布中創建從該點到最后指定點的線條。

closePath

創建從當前點回到起始點的路徑。

fill

填充當前繪圖(路徑)。

fillStyle

設置或返回用于填充繪畫的顏色、漸變或模式。

既然我們要實現五彩紙屑,那么我肯定得先實現一個紙屑,我們就來實現一個平行四邊形的紙屑吧!

我們都知道在 css 中實現平行四邊形就是一個div,默認就是一個盒子,而在 canvas 中并沒有那么方便,那么怎么實現一個平行四邊形呢?

四個點,我們只需要知道四個點,就能確定一個平行四邊形。而canvas中的坐標系和我們普通的寫網頁略有不同,它是從左上角作為起始點,但是并不影響。

我可以來畫一個寬為20的平行四邊形,(0, 0), (0, 20), (20,20), (20,0)。

...(省略了一些前置初始化代碼)
var context = canvas.getContext('2d');
// 清除畫布
context.clearRect(0, 0, canvas.width, canvas.height);
// 設置顏色并開始繪制
context.fillStyle = 'rgba(2, 255, 255, 1)';
context.beginPath();
// 設置幾個點
var point1 = { x: 0, y: 0 }
var point2 = { x: 0, y: 20 }
var point3 = { x: 20, y: 20 }
var point4 = { x: 20, y: 0 }
// 畫4個點
context.moveTo(Math.floor(point1.x), Math.floor(point1.y));
context.lineTo(Math.floor(point2.x), Math.floor(point2.y));
context.lineTo(Math.floor(point3.x), Math.floor(point3.y));
context.lineTo(Math.floor(point4.x), Math.floor(point4.y));
// 完成路線,并填充
context.closePath();
context.fill(); 

我們總結一下,我們其實只需要一個點就能確定這個平行四邊形的初始位置(0, 0),如果再知道一個角度(90度)、以及平行四邊形的變長(20)就能確定整個平行四邊形的位置了!(僅僅只需要初中知識就能定位整個平行四邊形)。

好了,你學會畫這個已經離成功邁向了一大步!是不是挺簡單的~

大佬們內心OS: 就這?

嗯,就這。

運動軌跡

通過不斷地調試 canvas-confetti 每一幀的軌跡運動,發現它始終做的是一個x軸變減速運動(直到速度為0就不繼續運動了),而y軸也是一個先變減速運動再是一個均速運動,以下是大致的軌跡圖。

這就是他的運動軌跡,別以為看著挺難的,但是核心代碼只有三句。

// fetti.angle2D為一個角度(這個角度確定了運動軌跡 3 / 2 * Math.PI - 2 * Math.PI之間的一個值,由于要讓軌跡往左上角移動,就是都要往負方向運動,因此選了以上范圍),
// fetti.velocity 為一個初始為50長度的值。
// fetti.gravity = 3
fetti.x += Math.cos(fetti.angle2D) * fetti.velocity; // fetti.x 第一個點的x坐標
fetti.y += Math.sin(fetti.angle2D) * fetti.velocity + fetti.gravity; // fetti.y 第一個點的y坐標
fetti.velocity *= 0.8; 

總結起來就是,第一個坐標點的 x 周始終在增加一個負值(Math.cos(3 / 2 Math.PI - 2 Math.PI) 始終為負值),這個值在不斷減小。而第一個點的y軸也始終在加一個負值Math.cos(3 / 2 Math.PI - 2 Math.PI) 始終為負值),但是由于 fetti.gravity始終為正值,因此到了某個臨界點,y的值會不斷增加。

我模擬了以下的坐標,由于為了讓大家能明白這個軌跡,以下坐標軸和canvas中相反,數據我也做了相應的處理,進行了反方向處理。

用一個邊上為10的正方形,實現軌跡。

const fetti = {
  "x": 445,
  "y": 541,
  "angle2D": 3 / 2 * Math.PI + 1 / 6 * Math.PI,
  "color": {r: 20, g: 30, b: 50},
  "tick": 0,
  "totalTicks": 200,
  "decay": 0.9,
  "gravity": 3,
  "velocity": 50
}
var animationFrame = null;
const update = () => {
  context.clearRect(0, 0, canvas.width, canvas.height);
  context.fillStyle = 'rgba(2, 255, 255, 1)';
  context.beginPath();
  fetti.x += Math.cos(fetti.angle2D) * fetti.velocity; // 第一個點
  fetti.y += Math.sin(fetti.angle2D) * fetti.velocity + fetti.gravity; // 第一個點

  var x1 = fetti.x;
  var y1 = fetti.y;

  var x2 = fetti.x;// 第二個點
  var y2 = fetti.y + 10; // 第二個點

  var x3 = x1 + 10;
  var y3 = y1 + 10;

  var x4 = fetti.x + 10;
  var y4 = fetti.y;

  fetti.velocity *= fetti.decay;

  context.moveTo(Math.floor(x1), Math.floor(y1));
  context.lineTo(Math.floor(x2), Math.floor(y2));
  context.lineTo(Math.floor(x3), Math.floor(y3));
  context.lineTo(Math.floor(x4), Math.floor(y4));

  context.closePath();
  context.fill();
  animationFrame = raf.frame(update);
} 

是不是除了顏色和形狀,有那味了?

反轉特效

那么如何實現讓這個下落更加自然,會有一種飄落的感覺呢?

其實,他就是一直在做一個翻轉特效.

將他們拆解就是在做繞著一個點的旋轉運動,整個過程就是一邊自我翻轉一邊按照運動軌跡進行移動。

實現這個特效,其實之前在實現正方形的時候提到過,實現一個正方形。滿足以下三個點能實現一個平行四邊形。

  • 知道一個點的位置
  • 知道一個角度
  • 知道一邊邊長

目前我能確定的有,一個點的位置很容易確定,就是我們的起始點,然后我們邊長也知道,就差一個角度了,只要我們的角度不斷變化,我們就能實現以上特效。

const update = () => {
  context.clearRect(0, 0, canvas.width, canvas.height);
  context.fillStyle = 'rgba(2, 255, 255, 1)';
  context.beginPath();

  fetti.velocity *= fetti.decay;
  fetti.tiltAngle += 0.1 // 不斷給這個四邊形變化角度

  var length = 10;

  var x1 = fetti.x;
  var y1 = fetti.y;

  var x2 = fetti.x + (length * Math.sin(fetti.tiltAngle));// 第二個點
  var y2 = fetti.y + (length * Math.cos(fetti.tiltAngle)); // 第二個點

  var x3 = x2 + 10;
  var y3 = y2;

  var x4 = fetti.x + length;
  var y4 = fetti.y;


  context.moveTo(Math.floor(x1), Math.floor(y1));
  context.lineTo(Math.floor(x2), Math.floor(y2));
  context.lineTo(Math.floor(x3), Math.floor(y3));
  context.lineTo(Math.floor(x4), Math.floor(y4));

  context.closePath();
  context.fill();
  animationFrame = raf.frame(update);
} 

這樣我們就實現了以上的特效。

組合運動

然后把我們以上寫的組合在一起就是一個完整的特效啦。

const update = () => {
  context.clearRect(0, 0, canvas.width, canvas.height);
  context.fillStyle = 'rgba(2, 255, 255, 1)';
  context.beginPath();
  fetti.x += Math.cos(fetti.angle2D) * fetti.velocity; // 第一個點
  fetti.y += Math.sin(fetti.angle2D) * fetti.velocity + fetti.gravity; // 第一個點

  fetti.velocity *= fetti.decay;
  fetti.tiltAngle += 0.1 // 不斷給這個四邊形變化角度

  var length = 10;

  var x1 = fetti.x;
  var y1 = fetti.y;

  var x2 = fetti.x + (length * Math.sin(fetti.tiltAngle));// 第二個點
  var y2 = fetti.y + (length * Math.cos(fetti.tiltAngle)); // 第二個點

  var x3 = x2 + 10;
  var y3 = y2;

  var x4 = fetti.x + length;
  var y4 = fetti.y;


  context.moveTo(Math.floor(x1), Math.floor(y1));
  context.lineTo(Math.floor(x2), Math.floor(y2));
  context.lineTo(Math.floor(x3), Math.floor(y3));
  context.lineTo(Math.floor(x4), Math.floor(y4));

  context.closePath();
  context.fill();
  animationFrame = raf.frame(update);
} 

最終形態

如果想要實現最后的狀態,就差多個小塊、漸變消失以及隨機顏色了!

設置多少幀消失,這里搞了兩個變量totalTickstick,自定義來控制多少幀后小塊消失。

至于多個小塊,我們只需要搞一個 for 循環。

而隨機顏色,搞了一個colors列表。

const colors = [
  '#26ccff',
  '#a25afd',
  '#ff5e7e',
  '#88ff5a',
  '#fcff42',
  '#ffa62d',
  '#ff36ff'
];
var arr = []
for (let i = 0; i < 20; i++) {
  arr.push({
    "x": 445,
    "y": 541,
    "velocity": (45 * 0.5) + (Math.random() * 20),
    "angle2D": 3 / 2 * Math.PI + Math.random() * 1 / 4 * Math.PI,
    "tiltAngle":  Math.random() * Math.PI,
    "color": hexToRgb(colors[Math.floor(Math.random() * 7)]),
    "shape": "square",
    "tick": 0,
    "totalTicks": 200,
    "decay": 0.9,
    "random": 0,
    "tiltSin": 0,
    "tiltCos": 0,
    "gravity": 3,
  })
} 

完整代碼請看

https://github.com/hua1995116/node-demo/blob/master/confetti/完整demo.html

加點餐

實現多人對戰形態的表情大戰。在我們微信中表情的發送并不是單點的,而是多人形態,因此我們可以繼續探索,利用 websocket 和多彩小塊結合。

這里我們需要注意幾個點。(由于篇幅原因就不對 websocket 展開講解了,提一下實現要點)。

  • 我們可以通過一個 tag 來區分是歷史消息還是實時消息
  • 區分是自己發出的消息,還是受到別人的消息,來改變五彩紙屑方向。
  • 只有為單個 ??的時候才會進行動畫。
  • 先進行放大縮小的動畫,延遲200ms再出來特效
if(this.msg === '??' && this.status) {
        this.confetti = true;
        const rect = this.$refs.msg.querySelector('.msg-text').getBoundingClientRect();
        if(rect.left && rect.top) {
          setTimeout(() => {
            confetti({
              particleCount: r(100, 150),
              angle: this.isSelf ? 120 : 60,
              spread: r(45, 80),
              origin: {
                x: rect.left / window.innerWidth,
                y: rect.top / window.innerHeight
              }
            });
          }, 200)
        }
} 

更多探索

用 canvas 繪制非常非常多方塊的時候,會比較卡頓,這個時候我們可以利用 web worker 來進行計算,從而提高性能,這個就請讀者們自行探索啦,也可以看 canvas-confetti的源碼~

最后

回看筆者往期高贊文章,也許能收獲更多喔!

結語

??關注+點贊+收藏+評論+轉發??,原創不易,鼓勵筆者創作更好的文章

關注公眾號秋風的筆記,一個專注于前端面試、工程化、開源的前端公眾號

  • 關注后回復簡歷獲取100+套的精美簡歷模板
  • 關注后回復好友拉你進技術交流群+面試交流群
  • 歡迎關注秋風的筆記
查看原文

贊 22 收藏 10 評論 0

藍色的秋風 贊了文章 · 2月3日

50道CSS基礎面試題(附答案)

1 介紹一下標準的CSS的盒子模型?與低版本IE的盒子模型有什么不同的?

標準盒子模型:寬度=內容的寬度(content)+ border + padding + margin
低版本IE盒子模型:寬度=內容寬度(content+border+padding)+ margin

2 box-sizing屬性?

用來控制元素的盒子模型的解析模式,默認為content-box
context-box:W3C的標準盒子模型,設置元素的 height/width 屬性指的是content部分的高/寬
border-box:IE傳統盒子模型。設置元素的height/width屬性指的是border + padding + content部分的高/寬

3 CSS選擇器有哪些?哪些屬性可以繼承?

CSS選擇符:id選擇器(#myid)、類選擇器(.myclassname)、標簽選擇器(div, h1, p)、相鄰選擇器(h1 + p)、子選擇器(ul > li)、后代選擇器(li a)、通配符選擇器(*)、屬性選擇器(a[rel="external"])、偽類選擇器(a:hover, li:nth-child)

可繼承的屬性:font-size, font-family, color

不可繼承的樣式:border, padding, margin, width, height

優先級(就近原則):!important > [ id > class > tag ]
!important 比內聯優先級高

4 CSS優先級算法如何計算?

元素選擇符: 1
class選擇符: 10
id選擇符:100
元素標簽:1000

  1. !important聲明的樣式優先級最高,如果沖突再進行計算。
  2. 如果優先級相同,則選擇最后出現的樣式。
  3. 繼承得到的樣式的優先級最低。

5 CSS3新增偽類有那些?

p:first-of-type 選擇屬于其父元素的首個元素
p:last-of-type 選擇屬于其父元素的最后元素
p:only-of-type 選擇屬于其父元素唯一的元素
p:only-child 選擇屬于其父元素的唯一子元素
p:nth-child(2) 選擇屬于其父元素的第二個子元素
:enabled :disabled 表單控件的禁用狀態。
:checked 單選框或復選框被選中。

6 如何居中div?如何居中一個浮動元素?如何讓絕對定位的div居中?

div:

border: 1px solid red;
margin: 0 auto; 
height: 50px;
width: 80px;

浮動元素的上下左右居中:

border: 1px solid red;
float: left;
position: absolute;
width: 200px;
height: 100px;
left: 50%;
top: 50%;
margin: -50px 0 0 -100px; 

絕對定位的左右居中:

border: 1px solid black;
position: absolute;
width: 200px;
height: 100px;
margin: 0 auto;
left: 0;
right: 0; 

還有更加優雅的居中方式就是用flexbox,我以后會做整理。

7 display有哪些值?說明他們的作用?

inline(默認)--內聯
none--隱藏
block--塊顯示
table--表格顯示
list-item--項目列表
inline-block

8 position的值?

static(默認):按照正常文檔流進行排列;
relative(相對定位):不脫離文檔流,參考自身靜態位置通過 top, bottom, left, right 定位;
absolute(絕對定位):參考距其最近一個不為static的父級元素通過top, bottom, left, right 定位;
fixed(固定定位):所固定的參照對像是可視窗口。

9 CSS3有哪些新特性?

  1. RGBA和透明度
  2. background-image background-origin(content-box/padding-box/border-box) background-size background-repeat
  3. word-wrap(對長的不可分割單詞換行)word-wrap:break-word
  4. 文字陰影:text-shadow: 5px 5px 5px #FF0000;(水平陰影,垂直陰影,模糊距離,陰影顏色)
  5. font-face屬性:定義自己的字體
  6. 圓角(邊框半徑):border-radius 屬性用于創建圓角
  7. 邊框圖片:border-image: url(border.png) 30 30 round
  8. 盒陰影:box-shadow: 10px 10px 5px #888888
  9. 媒體查詢:定義兩套css,當瀏覽器的尺寸變化時會采用不同的屬性

10 請解釋一下CSS3的flexbox(彈性盒布局模型),以及適用場景?

該布局模型的目的是提供一種更加高效的方式來對容器中的條目進行布局、對齊和分配空間。在傳統的布局方式中,block 布局是把塊在垂直方向從上到下依次排列的;而 inline 布局則是在水平方向來排列。彈性盒布局并沒有這樣內在的方向限制,可以由開發人員自由操作。
試用場景:彈性布局適合于移動前端開發,在Android和ios上也完美支持。

11 用純CSS創建一個三角形的原理是什么?

首先,需要把元素的寬度、高度設為0。然后設置邊框樣式。

width: 0;
height: 0;
border-top: 40px solid transparent;
border-left: 40px solid transparent;
border-right: 40px solid transparent;
border-bottom: 40px solid #ff0000;

12 一個滿屏品字布局如何設計?

第一種真正的品字:

  1. 三塊高寬是確定的;
  2. 上面那塊用margin: 0 auto;居中;
  3. 下面兩塊用float或者inline-block不換行;
  4. 用margin調整位置使他們居中。

第二種全屏的品字布局:
上面的div設置成100%,下面的div分別寬50%,然后使用float或者inline使其不換行。

13 常見的兼容性問題?

  1. 不同瀏覽器的標簽默認的margin和padding不一樣。

    *{margin:0;padding:0;}

  2. IE6雙邊距bug:塊屬性標簽float后,又有橫行的margin情況下,在IE6顯示margin比設置的大。hack:display:inline;將其轉化為行內屬性。
  3. 漸進識別的方式,從總體中逐漸排除局部。首先,巧妙的使用“9”這一標記,將IE瀏覽器從所有情況中分離出來。接著,再次使用“+”將IE8和IE7、IE6分離開來,這樣IE8已經獨立識別。

    {
    background-color:#f1ee18;/*所有識別*/
    .background-color:#00deff\9; /*IE6、7、8識別*/
    +background-color:#a200ff;/*IE6、7識別*/
    _background-color:#1e0bd1;/*IE6識別*/
    }
    
  4. 設置較小高度標簽(一般小于10px),在IE6,IE7中高度超出自己設置高度。hack:給超出高度的標簽設置overflow:hidden;或者設置行高line-height 小于你設置的高度。
  5. IE下,可以使用獲取常規屬性的方法來獲取自定義屬性,也可以使用getAttribute()獲取自定義屬性;Firefox下,只能使用getAttribute()獲取自定義屬性。解決方法:統一通過getAttribute()獲取自定義屬性。
  6. Chrome 中文界面下默認會將小于 12px 的文本強制按照 12px 顯示,可通過加入 CSS 屬性 -webkit-text-size-adjust: none; 解決。
  7. 超鏈接訪問過后hover樣式就不出現了,被點擊訪問過的超鏈接樣式不再具有hover和active了。解決方法是改變CSS屬性的排列順序:L-V-H-A ( love hate ): a:link {} a:visited {} a:hover {} a:active {}

14 為什么要初始化CSS樣式

因為瀏覽器的兼容問題,不同瀏覽器對有些標簽的默認值是不同的,如果沒對CSS初始化往往會出現瀏覽器之間的頁面顯示差異。

15 absolute的containing block計算方式跟正常流有什么不同?

無論屬于哪種,都要先找到其祖先元素中最近的 position 值不為 static 的元素,然后再判斷:

  1. 若此元素為 inline 元素,則 containing block 為能夠包含這個元素生成的第一個和最后一個 inline box 的 padding box (除 margin, border 外的區域) 的最小矩形;
  2. 否則,則由這個祖先元素的 padding box 構成。

如果都找不到,則為 initial containing block。

補充:

  1. static(默認的)/relative:簡單說就是它的父元素的內容框(即去掉padding的部分)
  2. absolute: 向上找最近的定位為absolute/relative的元素
  3. fixed: 它的containing block一律為根元素(html/body)

16 CSS里的visibility屬性有個collapse屬性值?在不同瀏覽器下以后什么區別?

當一個元素的visibility屬性被設置成collapse值后,對于一般的元素,它的表現跟hidden是一樣的。

  1. chrome中,使用collapse值和使用hidden沒有區別。
  2. firefox,opera和IE,使用collapse值和使用display:none沒有什么區別。

17 display:none與visibility:hidden的區別?

display:none 不顯示對應的元素,在文檔布局中不再分配空間(回流+重繪)
visibility:hidden 隱藏對應元素,在文檔布局中仍保留原來的空間(重繪)

18 position跟display、overflow、float這些特性相互疊加后會怎么樣?

display屬性規定元素應該生成的框的類型;position屬性規定元素的定位類型;float屬性是一種布局方式,定義元素在哪個方向浮動。
類似于優先級機制:position:absolute/fixed優先級最高,有他們在時,float不起作用,display值需要調整。float 或者absolute定位的元素,只能是塊元素或表格。

19 對BFC規范(塊級格式化上下文:block formatting context)的理解?

BFC規定了內部的Block Box如何布局。
定位方案:

  1. 內部的Box會在垂直方向上一個接一個放置。
  2. Box垂直方向的距離由margin決定,屬于同一個BFC的兩個相鄰Box的margin會發生重疊。
  3. 每個元素的margin box 的左邊,與包含塊border box的左邊相接觸。
  4. BFC的區域不會與float box重疊。
  5. BFC是頁面上的一個隔離的獨立容器,容器里面的子元素不會影響到外面的元素。
  6. 計算BFC的高度時,浮動元素也會參與計算。

滿足下列條件之一就可觸發BFC

  1. 根元素,即html
  2. float的值不為none(默認)
  3. overflow的值不為visible(默認)
  4. display的值為inline-block、table-cell、table-caption
  5. position的值為absolute或fixed

20 為什么會出現浮動和什么時候需要清除浮動?清除浮動的方式?

浮動元素碰到包含它的邊框或者浮動元素的邊框停留。由于浮動元素不在文檔流中,所以文檔流的塊框表現得就像浮動框不存在一樣。浮動元素會漂浮在文檔流的塊框上。
浮動帶來的問題:

  1. 父元素的高度無法被撐開,影響與父元素同級的元素
  2. 與浮動元素同級的非浮動元素(內聯元素)會跟隨其后
  3. 若非第一個元素浮動,則該元素之前的元素也需要浮動,否則會影響頁面顯示的結構。

清除浮動的方式:

  1. 父級div定義height
  2. 最后一個浮動元素后加空div標簽 并添加樣式clear:both。
  3. 包含浮動元素的父標簽添加樣式overflow為hidden或auto。
  4. 父級div定義zoom

21 上下margin重合的問題

在重合元素外包裹一層容器,并觸發該容器生成一個BFC。
例子:

<div class="aside"></div>
<div class="text">
    <div class="main"></div>
</div>
<!--下面是css代碼-->
 .aside {
            margin-bottom: 100px;  
            width: 100px;
            height: 150px;
            background: #f66;
        }
        .main {
            margin-top: 100px;
            height: 200px;
            background: #fcc;
        }
         .text{
            /*盒子main的外面包一個div,通過改變此div的屬性使兩個盒子分屬于兩個不同的BFC,以此來阻止margin重疊*/
            overflow: hidden;  //此時已經觸發了BFC屬性。
        }

22設置元素浮動后,該元素的display值是多少?

自動變成display:block

23 移動端的布局用過媒體查詢嗎?

通過媒體查詢可以為不同大小和尺寸的媒體定義不同的css,適應相應的設備的顯示。

  1. <head>里邊

    <link rel="stylesheet" type="text/css" href="xxx.css" media="only screen and (max-device-width:480px)">

  2. CSS : @media only screen and (max-device-width:480px) {/css樣式/}

24 使用 CSS 預處理器嗎?
Less sass

25 CSS優化、提高性能的方法有哪些?

  1. 避免過度約束
  2. 避免后代選擇符
  3. 避免鏈式選擇符
  4. 使用緊湊的語法
  5. 避免不必要的命名空間
  6. 避免不必要的重復
  7. 最好使用表示語義的名字。一個好的類名應該是描述他是什么而不是像什么
  8. 避免!important,可以選擇其他選擇器
  9. 盡可能的精簡規則,你可以合并不同類里的重復規則

26 瀏覽器是怎樣解析CSS選擇器的?

CSS選擇器的解析是從右向左解析的。若從左向右的匹配,發現不符合規則,需要進行回溯,會損失很多性能。若從右向左匹配,先找到所有的最右節點,對于每一個節點,向上尋找其父節點直到找到根元素或滿足條件的匹配規則,則結束這個分支的遍歷。兩種匹配規則的性能差別很大,是因為從右向左的匹配在第一步就篩選掉了大量的不符合條件的最右節點(葉子節點),而從左向右的匹配規則的性能都浪費在了失敗的查找上面。
而在 CSS 解析完畢后,需要將解析的結果與 DOM Tree 的內容一起進行分析建立一棵 Render Tree,最終用來進行繪圖。在建立 Render Tree 時(WebKit 中的「Attachment」過程),瀏覽器就要為每個 DOM Tree 中的元素根據 CSS 的解析結果(Style Rules)來確定生成怎樣的 Render Tree。

27 在網頁中的應該使用奇數還是偶數的字體?為什么呢?

使用偶數字體。偶數字號相對更容易和 web 設計的其他部分構成比例關系。Windows 自帶的點陣宋體(中易宋體)從 Vista 開始只提供 12、14、16 px 這三個大小的點陣,而 13、15、17 px時用的是小一號的點。(即每個字占的空間大了 1 px,但點陣沒變),于是略顯稀疏。

28 margin和padding分別適合什么場景使用?

何時使用margin:

  1. 需要在border外側添加空白
  2. 空白處不需要背景色
  3. 上下相連的兩個盒子之間的空白,需要相互抵消時。

何時使用padding:

  1. 需要在border內側添加空白
  2. 空白處需要背景顏色
  3. 上下相連的兩個盒子的空白,希望為兩者之和。

兼容性的問題:在IE5 IE6中,為float的盒子指定margin時,左側的margin可能會變成兩倍的寬度。通過改變padding或者指定盒子的display:inline解決。

29 元素豎向的百分比設定是相對于容器的高度嗎?

當按百分比設定一個元素的寬度時,它是相對于父容器的寬度計算的,但是,對于一些表示豎向距離的屬性,例如 padding-top , padding-bottom , margin-top , margin-bottom 等,當按百分比設定它們時,依據的也是父容器的寬度,而不是高度。

30 全屏滾動的原理是什么?用到了CSS的哪些屬性?

  1. 原理:有點類似于輪播,整體的元素一直排列下去,假設有5個需要展示的全屏頁面,那么高度是500%,只是展示100%,剩下的可以通過transform進行y軸定位,也可以通過margin-top實現
  2. overflow:hidden;transition:all 1000ms ease;

31 什么是響應式設計?響應式設計的基本原理是什么?如何兼容低版本的IE?

響應式網站設計(Responsive Web design)是一個網站能夠兼容多個終端,而不是為每一個終端做一個特定的版本。
基本原理是通過媒體查詢檢測不同的設備屏幕尺寸做處理。
頁面頭部必須有meta聲明的viewport。

<meta name=’viewport’ content=”width=device-width, initial-scale=1. maximum-scale=1,user-scalable=no”>

32 視差滾動效果?

視差滾動(Parallax Scrolling)通過在網頁向下滾動的時候,控制背景的移動速度比前景的移動速度慢來創建出令人驚嘆的3D效果。

  1. CSS3實現
    優點:開發時間短、性能和開發效率比較好,缺點是不能兼容到低版本的瀏覽器
  2. jQuery實現
    通過控制不同層滾動速度,計算每一層的時間,控制滾動效果。
    優點:能兼容到各個版本的,效果可控性好
    缺點:開發起來對制作者要求高
  3. 插件實現方式
    例如:parallax-scrolling,兼容性十分好

33 ::before 和 :after中雙冒號和單冒號有什么區別?解釋一下這2個偽元素的作用

  1. 單冒號(:)用于CSS3偽類,雙冒號(::)用于CSS3偽元素。
  2. ::before就是以一個子元素的存在,定義在元素主體內容之前的一個偽元素。并不存在于dom之中,只存在在頁面之中。

:before 和 :after 這兩個偽元素,是在CSS2.1里新出現的。起初,偽元素的前綴使用的是單冒號語法,但隨著Web的進化,在CSS3的規范里,偽元素的語法被修改成使用雙冒號,成為::before ::after

34 你對line-height是如何理解的?

行高是指一行文字的高度,具體說是兩行文字間基線的距離。CSS中起高度作用的是height和line-height,沒有定義height屬性,最終其表現作用一定是line-height。
單行文本垂直居中:把line-height值設置為height一樣大小的值可以實現單行文字的垂直居中,其實也可以把height刪除。
多行文本垂直居中:需要設置display屬性為inline-block。

35 怎么讓Chrome支持小于12px 的文字?

p{font-size:10px;-webkit-transform:scale(0.8);} //0.8是縮放比例

36 讓頁面里的字體變清晰,變細用CSS怎么做?

-webkit-font-smoothing在window系統下沒有起作用,但是在IOS設備上起作用-webkit-font-smoothing:antialiased是最佳的,灰度平滑。

37 position:fixed;在android下無效怎么處理?

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"/>

38 如果需要手動寫動畫,你認為最小時間間隔是多久,為什么?
多數顯示器默認頻率是60Hz,即1秒刷新60次,所以理論上最小間隔為1/60*1000ms = 16.7ms。

39 li與li之間有看不見的空白間隔是什么原因引起的?有什么解決辦法?

行框的排列會受到中間空白(回車空格)等的影響,因為空格也屬于字符,這些空白也會被應用樣式,占據空間,所以會有間隔,把字符大小設為0,就沒有空格了。
解決方法:

  1. 可以將<li>代碼全部寫在一排
  2. 浮動li中float:left
  3. 在ul中用font-size:0(谷歌不支持);可以使用letter-space:-3px

40 display:inline-block 什么時候會顯示間隙?

  1. 有空格時候會有間隙 解決:移除空格
  2. margin正值的時候 解決:margin使用負值
  3. 使用font-size時候 解決:font-size:0、letter-spacing、word-spacing

41 有一個高度自適應的div,里面有兩個div,一個高度100px,希望另一個填滿剩下的高度

外層div使用position:relative;高度要求自適應的div使用position: absolute; top: 100px; bottom: 0; left: 0

42 png、jpg、gif 這些圖片格式解釋一下,分別什么時候用。有沒有了解過webp?

  1. png是便攜式網絡圖片(Portable Network Graphics)是一種無損數據壓縮位圖文件格式.優點是:壓縮比高,色彩好。 大多數地方都可以用。
  2. jpg是一種針對相片使用的一種失真壓縮方法,是一種破壞性的壓縮,在色調及顏色平滑變化做的不錯。在www上,被用來儲存和傳輸照片的格式。
  3. gif是一種位圖文件格式,以8位色重現真色彩的圖像??梢詫崿F動畫效果.
  4. webp格式是谷歌在2010年推出的圖片格式,壓縮率只有jpg的2/3,大小比png小了45%。缺點是壓縮的時間更久了,兼容性不好,目前谷歌和opera支持。

43 style標簽寫在body后與body前有什么區別?

頁面加載自上而下 當然是先加載樣式。
寫在body標簽后由于瀏覽器以逐行方式對HTML文檔進行解析,當解析到寫在尾部的樣式表(外聯或寫在style標簽)會導致瀏覽器停止之前的渲染,等待加載且解析樣式表完成之后重新渲染,在windows的IE下可能會出現FOUC現象(即樣式失效導致的頁面閃爍問題)

44 CSS屬性overflow屬性定義溢出元素內容區的內容會如何處理?

參數是scroll時候,必會出現滾動條。
參數是auto時候,子元素內容大于父元素時出現滾動條。
參數是visible時候,溢出的內容出現在父元素之外。
參數是hidden時候,溢出隱藏。

45 闡述一下CSS Sprites

將一個頁面涉及到的所有圖片都包含到一張大圖中去,然后利用CSS的 background-image,background- repeat,background-position 的組合進行背景定位。利用CSS Sprites能很好地減少網頁的http請求,從而大大的提高頁面的性能;CSS Sprites能減少圖片的字節。

持續更新中...

查看原文

贊 304 收藏 750 評論 55

藍色的秋風 贊了文章 · 1月19日

原來地圖導航結合WebAR技術還能這么玩

本文探索在Web前端實現AR導航效果的前沿技術和難點。

1. AR簡介

增強現實(Augmented Reality,簡稱AR):是一種實時地計算攝影機影像的位置及角度并加上相應圖像、視頻、3D模型的技術,這種技術的目標是在屏幕上把虛擬世界套在現實世界并進行互動。

一般在web中實現AR效果的主要步驟如下:

  1. 獲取視頻源
  2. 識別marker
  3. 疊加虛擬物體
  4. 顯示最終畫面

AR導航比較特殊的地方是,它并非通過識別marker來確定虛擬物體的疊加位置,而是通過定位將虛擬和現實聯系在一起,主要步驟如下:

  1. 獲取視頻源
  2. 坐標系轉換:

    1. 獲取設備和路徑的絕對定位
    2. 計算路徑中各標記點與設備間的相對定位
    3. 在設備坐標系中繪制標記點
  3. 3D圖像與視頻疊加
  4. 更新定位和設備方向,控制Three.js中的相機移動

2. 技術難點

如上文所述AR導航的主要步驟,其中難點在于:

  1. 兼容性問題
  2. WebGL三維作圖
  3. 定位的精確度和軌跡優化
  4. 虛擬和現實單位尺度的映射

2.1 兼容性問題:

不同設備不同操作系統以及不同瀏覽器帶來的兼容性問題主要體現在對獲取視頻流和獲取設備陀螺儀信息的支持上。

2.1.1 獲取視頻流

  1. Navigator API兼容處理

    navigator.getUserMedia()已不推薦使用,目前新標準采用navigator.mediaDevices.getUserMedia()??墒遣煌瑸g覽器對新方法的支持程度不同,需要進行判斷和處理。同時,如果采用舊方法,在不同瀏覽器中方法名稱也不盡相同,比如webkitGetUserMedia。

//不支持mediaDevices屬性
    if (navigator.mediaDevices === undefined) {
      navigator.mediaDevices = {};
    }

//不支持mediaDevices.getUserMedia
    if (navigator.mediaDevices.getUserMedia === undefined) {
        navigator.mediaDevices.getUserMedia = function(constraints) {
            var getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

            if(!getUserMedia) {
                return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
            }

            return new Promise(function(resolve, reject) {
                getUserMedia.call(navigator, constraints, resolve, reject);
            });
        }
    }
  1. 參數兼容處理

    getUserMedia接收一個MediaStreamConstraints類型的參數,該參數包含兩個成員videoaudio。

var constraints = {
        audio: true,
        video: {
            width: { 
                min: 1024,
                ideal: 1280,
                max: 1920
            },
            height: 720,
            frameRate: {
                ideal: 10,
                max: 15
            },
            facingMode: "user" // user/environment,設置前后攝像頭
        }
    }

在使用WebAR導航時,需要調取后置攝像頭,然而facingMode參數目前只有Firefox和Chrome部分支持,對于其他瀏覽器(微信、手Q、QQ瀏覽器)需要另一個參數optional.sourceId,傳入設備媒體源的id。經測試,該方法在不同設備不同版本號的微信和手Q上表現有差異。

if(MediaStreamTrack.getSources) {
        MediaStreamTrack.getSources(function (sourceInfos) {
            for (var i = 0; i != sourceInfos.length; ++i) {
                var sourceInfo = sourceInfos[i];
                //這里會遍歷audio,video,所以要加以區分  
                if (sourceInfo.kind === 'video') {  
                    exArray.push(sourceInfo.id);  
                }  
            }
            constraints = { 
                video: {  
                    optional: [{  
                        sourceId: exArray[1] //0為前置攝像頭,1為后置
                    }]  
                }
            };
        });
    } else {
        constraints = { 
            video: {
                facingMode: {
                    exact: 'environment'
                }
            }
        });
    }
  1. 操作系統的兼容性問題

    由于蘋果的安全機制問題,iOS設備任何瀏覽器都不支持getUserMedia()。所以無法在iOS系統上實現WebAR導航。

  2. 協議

    出于安全考慮,Chrome47之后只支持HTTPS頁面獲取視頻源。

2.1.2 獲取設備轉動角度

設備的轉動角度代表了用戶的視角,也是連接虛擬和現實的重要參數。HTML5提供DeviceOrientation API可以實時獲取設備的旋轉角度參數。通過監聽deviceorientation事件,返回DeviceOrientationEvent對象。

{
    absolute: [boolean] 是否為絕對轉動值
    alpha: [0-360]
    beta: [-180-180]
    gamma: [-90-90]
}

其中alpha、beta、gamma是我們想要獲取的角度,它們各自的意義可以參照下圖和參考文章:

image
陀螺儀的基本知識

然而iOS系統的webkit內核瀏覽器中,該對象還包括webkitCompassHeading成員,其值為設備與正北方向的偏離角度。同時iOS系統的瀏覽器中,alpha并非絕對角度,而是以開始監聽事件時的角度為零點。

Android系統中,我們可以使用-alpha得到設備與正北方的角度,但是就目前的測試情況看來,該值并不穩定。所以在測試Demo中加入了手動校正alpha值的過程,在導航開始前將設備朝向正北方來獲取絕對0度,雖然不嚴謹但效果還不錯。

image

2.2 WebGL三維作圖

WebGL是在瀏覽器中實現三維效果的一套規范,AR導航需要繪制出不同距離不同角度的標記點,就需要三維效果以適應真實場景視頻流。然而WebGL原生的接口非常復雜,Three.js是一個基于WebGL的庫,它對一些原生的方法進行了簡化封裝,使我們能夠更方便地進行編程。

Three.js中有三個主要概念:

  1. 場景(scene):物體的容器,我們要繪制標記點就是在場景中添加指定坐標和大小的球體
  2. 相機(camera):模擬人的眼睛,決定了呈現哪個角度哪個部分的場景,在AR導航中,我們主要通過相機的移動和轉動來模擬設備的移動和轉動
  3. 渲染器(renderer):設置畫布,將相機拍攝的場景呈現在web頁面上

在AR導航的代碼中,我對Three.js的創建過程進行了封裝,只需傳入DOM元素(一般為<div>,作為容器)和參數,自動創建三大組件,并提供了Three.addObjectThree.renderThree等接口方法用于在場景中添加/刪除物體或更新渲染等。

function Three(cSelector, options) {
    var container = document.querySelector(cSelector);
    // 創建場景
    var scene = new THREE.Scene();
    // 創建相機
    var camera = new THREE.PerspectiveCamera(options.camera.fov, options.camera.aspect, options.camera.near, options.camera.far);
    // 創建渲染器
    var renderer = new THREE.WebGLRenderer({
        alpha: true
    });
    // 設置相機轉動控制器
    var oriControls = new THREE.DeviceOrientationControls(camera);
    // 設置場景大小,并添加到頁面中
    renderer.setSize(container.clientWidth, container.clientHeight);
    renderer.setClearColor(0xFFFFFF, 0.0);
    container.appendChild(renderer.domElement);

    // 暴露在外的成員
    this.main = {
        scene: scene,
        camera: camera,
        renderer: renderer,
        oriControls: oriControls,
    }
    this.objects = [];
    this.options = options;
}
Three.prototype.addObject = function(type, options) {...} // 向場景中添加物體,type支持sphere/cube/cone
Three.prototype.popObject = function() {...} // 刪除場景中的物體
Three.prototype.setCameraPos = function(position) {...} // 設置相機位置
Three.prototype.renderThree = function(render) {...} // 渲染更新,render為回調函數
Three.prototype.setAlphaOffset = function(offset) {..} // 設置校正alpha的偏離角度

在控制相機的轉動上,我使用了DeviceOrientationControls,它是Three.js官方提供的相機跟隨設備轉動的控制器,實現對deviceorientation的偵聽和對DeviceOrientationEvent的歐拉角處理,并控制相機的轉動角度。只需在渲染更新時調用一下update方法:

three.renderThree(function(objects, main) {
    animate();
    function animate() {
        window.requestAnimationFrame(animate);
        main.oriControls.update();
        main.renderer.render(main.scene, main.camera);
    }
});

2.3 定位的精確度和軌跡優化

我們的調研中目前有三種獲取定位的方案:原生navigator.geolocation接口,騰訊前端定位組件,微信JS-SDK地理位置接口:

  1. 原生接口

    navigator.geolocation接口提供了getCurrentPositionwatchPosition兩個方法用于獲取當前定位和監聽位置改變。經過測試,Android系統中watchPosition更新頻率低,而iOS中更新頻率高,但抖動嚴重。

  2. 前端定位組件

    使用前端定位組件需要引入JS模塊(https://3gimg.qq.com/lightmap/components/geolocation/geolocation.min.js),通過?qq.maps.Geolocation(key, referer)構造對象,也提供getLocationwatchPosition兩個方法。經過測試,在X5內核的瀏覽器(包括微信、手Q)中,定位組件比原生接口定位更加準確,更新頻率較高。

  3. 微信JS-SDK地理位置接口

    使用微信JS-SDK接口,我們可以調用室內定位達到更高的精度,但是需要綁定公眾號,只能在微信中使用,僅提供getLocation方法,暫時不考慮。

    綜上所述,我們主要考慮在X5內核瀏覽器中的實現,所以選用騰訊前端定位組件獲取定位。但是在測試中仍然暴露出了定位不準確的問題:

    1. 定位不準導致虛擬物體與現實無法準確疊加
    2. 定位的抖動導致虛擬標記點跟隨抖動,移動視覺效果不夠平穩

針對該問題,我設計了優化軌跡的方法,進行定位去噪、確定初始中心點、根據路徑吸附等操作,以實現移動時的變化效果更加平穩且準確。

2.3.1 定位去噪

我們通過getLocationwatchPosition方法獲取到的定位數據包含如下信息:

{
    accuracy: 65,
    lat: 39.98333,
    lng: 116.30133
    ...
}

其中accuracy表示定位精度,該值越低表示定位越精確。假設定位精度在固定的設備上服從正態分布(準確來說應該是正偏態分布),統計整條軌跡點定位精度的均值mean和標準差stdev,將軌跡中定位精度大于mean + (1~2) * stdev的點過濾掉?;蛘卟捎孟湫蛨D的方法去除噪聲點。

2.3.2 初始點確定

初始點非常重要,若初始點偏離,則路線不準確、虛擬現實無法重疊、無法獲取到正確的移動路線。測試中我發現定位開始時獲得的定位點大多不太準確,所以需要一段時間來確定初始點。

定位開始,設置N秒用以獲取初始定位。N秒鐘獲取到的定位去噪之后形成一個序列track_denoise = [ loc0, loc1, loc2...],對該序列中的每一個點計算其到其他點的距離之和,并加上自身的定位精度,得到一個中心衡量值,然后取衡量值最小的點為起始點。

image

2.3.3 基于路線的定位校正

基于設備始終跟隨規劃路線進行移動的假設,可以將定位點吸附到規劃路線上以防止3D圖像的抖動。

如下圖所示,以定位點到線段的映射點作為校正點。路線線段的選擇依據如下:

  1. 初始狀態:以起始點與第二路線點之間的線段為當前線段,cur = 0; P_cur = P[cur];
  2. 在第N條線段上移動時,若映射長度(映射點與線段起點的距離)為負,校正點取當前線段的起點,線路回退至上一線段,cur = N - 1; P_cur = P[cur];;若映射長度大于線段長度,則校正點取當前線段的終點,線路前進至下一線段,cur = N + 1; P_cur = P[cur];
  3. 若當前線段與下一線段的有效范圍有重疊區域(如下圖綠色陰影區),則需判斷定位點到兩條線段的距離,以較短的為準,確定校正點和線路選擇。

image

2.4 虛擬和現實的單位長度映射

WebGL中的單位長度與現實世界的單位長度并沒有確定的映射關系,暫時還無法準確進行映射。通過測試,暫且選擇1(米):15(WebGL單位長度)。

3. demo演示

演示視頻:WebAR技術探索-導航中的應用

對地圖感興趣的開發者,歡迎登錄騰訊位置服務體驗~

以下內容轉載自多多洛愛學習的文章《WebAR技術探索-導航中的應用》
作者:多多洛愛學習
鏈接:https://juejin.im/post/5c24252b6fb9a049d975411a
來源:掘金
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
查看原文

贊 5 收藏 4 評論 0

藍色的秋風 關注了用戶 · 1月19日

騰訊位置服務 @tengxunweizhifuwu

立足生態,連接未來

關注 20

藍色的秋風 發布了文章 · 1月14日

2020 全球 JS 調查報告新鮮出爐

完整報告地址: https://2020.stateofjs.com/zh-Hans/
潤色/翻譯: 藍色的秋風(github/hua1995116)

千呼萬喚的全球2020的JS報告終于出來了。順便附上2020全球CSS報告地址 2020年度全球CSS報告新鮮出爐

image-20210114001259007

我們來看看這一個糟糕卻又不平凡的一年,JS發生了什么樣的變化。

image-20210114001739976

盡管2020年很糟糕,但 JavaScript 作為一個整體仍然設法向前發展。隨著語言本身的不斷改進,得益于諸如可選鏈操作符空值合并操作符并等新特性,TypeScript靜態類型的普及更是將JS帶到了一個全新的高度。

在框架方面,就在我們認為一切都已解決的時候,Svelte 橫空出世以全新方式給前端注入新的血液。 在多年的webpack統治下,甚至構建工具也顯示出新活動的跡象。

但是這次的區別是,相對而言,“老”后衛什么都沒走。 Svelte和Snowpack很棒,但是React和webpack也很棒。 可以肯定的是,它們最終也會成為JavaScript大流氓的犧牲品,但是不會持續很多年。

所以,讓我們享受我們所擁有的: 一個不斷變得更好的偉大的生態系統!

訪問對象統計

采樣對象一共為 20744 位開發者。

image-20210114003014449

特性

雖然大多數受訪者都知道調查中提到的大多數JavaScript特性,但很多人還沒有真正使用它們。

這圖表顯示了按類別分組的所有特性的不同采用率。外圈的大小對應于了解某項功能的用戶總數,而內圈則代表實際使用過該功能的用戶。

image-20210114003419236

技術現狀

2016年 - 2020年 趨勢圖

每條線從2016年到2020年(粗部為2020)??v軸越高,表示一項技術被更多的人使用,橫軸越大,表示有更多的用戶想要學習,或者曾經使用過,還會再次使用。

image-20210114004041187

可以看出隨著年限的的增長。webpack、Express、TypeScript、Jest、React 可以說是非常強勢了。

風味(Flavors)

image-20210114011042569

可以看出 TypeScript 依舊獨領風騷,其次就是 Elm ,但是 PureScript 也是一個值得關注的增強類型語言。

image-20210114004722545

對 TypeScript 的熟悉度一片叫好。

其他工具

image-20210114004757675

前端框架

image-20210114011217904

正如開頭所說,svelte 的出現真的是對前端行業的沖擊,原以為三大框架(React、Vue.js、Angular)包攬所有的時候,它出現了,一度成為了第四名(使用量),但是從興趣度和滿意度來看,它未來的潛力不可估量。

興趣度

image-20210114011448248

滿意度

image-20210114011511595

數據層

image-20210114011556857

使用排名比較高的狀態管理依舊是Redux、Vuex、Mobx。 數據管理為 GraphQL 和 Apollo,并且 XState 橫空出世。

其他工具

image-20210114005333559

后端框架

image-20210114011713944

Express 依舊是統治地位,而 Next 和 Nuxt 這些服務端渲染的框架也逐漸成為大家的所選的框架。

其他工具

image-20210114005400642

測試框架

image-20210114011830965

Jest和 Mocha 在使用量上依舊是統治地位,但是新增了 Testing Libray 很強勁。

以下是滿意度排行。

image-20210114005427559

什么是 Testing Library ?用于 DOM 和 UI 組件測試的一系列工具,主要 API 包含 DOM 查詢,更可以和其他測試工具(jest、cypress)配合,用于更多場景(react、vue、svelte)。而它是 React 的官方推薦。

我們推薦使用 React Testing Library,它使得針對組件編寫測試用例就像終端用戶在使用它一樣方便。

----摘自 React 官網(https://zh-hans.reactjs.org/docs/test-utils.html)

打包工具

image-20210114011945951

雖然短時間內 webpack 使用量還處于霸主地位,這一年打包工具的發生了巨大的變化。

以下為滿意度

image-20210114010039881

可以說這里發生了天翻地覆的變化。從 Parcel 到 Snowpack ,再到后來的 esbuild ,每一個都是打包的好手,至于 Vite 為什么沒有在其中,我猜想,Vite 最開始只是為了解決 Vue 單個框架的方向,受眾面不夠廣泛(現在它已經支持了多種框架的打包了)。

放張圖來看看這些 bundleless 工具的速度吧。

image-20210114010649085

其他工具

image-20210114010412943

移動和桌面端

image-20210114012121186

Electron 依舊是桌面端的第一選擇, Cordova 和 React Native 也是移動跨端的熱門選擇。但是新出的 Capacitor 值得關注。

其他工具

常用的工具函數庫有?

image-20210114012305700

其他工具函數庫

image-20210114012350566

JavaScript 運行時選擇

image-20210114012435704

經常使用那(些)文字編輯器?

image-20210114012456227

常用用于開發的瀏覽器有哪些?

image-20210114012519560

資料

常用的 blog 和雜志?

image-20210114012556370

關注了哪些網站和課程?

image-20210114012616128

最后

如果我的文章有幫助到你,希望你也能幫助我,歡迎關注我的微信公眾號 秋風的筆記,回復好友 二次,可加微信并且加入交流群,秋風的筆記 將一直陪伴你的左右。

image

查看原文

贊 11 收藏 4 評論 5

認證與成就

  • 獲得 532 次點贊
  • 獲得 4 枚徽章 獲得 0 枚金徽章, 獲得 0 枚銀徽章, 獲得 4 枚銅徽章

擅長技能
編輯

開源項目 & 著作
編輯

  • webchat

    Websocket project based on vue(基于vue2.0的實時聊天項目)

注冊于 2017-11-12
個人主頁被 8.3k 人瀏覽

一本到在线是免费观看_亚洲2020天天堂在线观看_国产欧美亚洲精品第一页_最好看的2018中文字幕 <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <文本链> <文本链> <文本链> <文本链> <文本链> <文本链>