clone代碼後查看運行時效果,或當即訪問這裏查看效果https://moshuying.top倉庫連接,點個免費的星星感激涕零。javascript
主題文件默認狀況下彷佛不會自動clone能夠切到主題目錄下下載主題,能夠自行clone主題
最近想在hexo中嵌入一些shader,折騰了一些時間後終於完善,實際上用這種方法不只能夠在hexo中嵌入shader,也能夠嵌入babylonjs,pxixjs,Layabox,Egret,Cocos2等,先看效果,原理什麼的其實很簡單。css
因爲一些shader特別消耗顯卡性能,在
glsl_snippets.js
中斷定若是第一幀渲染時間超過
0.4秒就再也不渲染了。
也能夠點擊shader暫停渲染html
shader來源shaderToy
徹底支持shadertoy的代碼,參考自大神的代碼stackoverflow,在這位大神的代碼裏獲取到徹底兼容shaderToy的思路。並將其改爲更適用在hexo中。前端
示例代碼java
<!-- 至少須要一個div來放置iframe,這樣能夠方便的將代碼移入文章底部 --> <div id="three"></div> <script type="module" id="threeMain"> if (!(self.frameElement && self.frameElement.tagName == "IFRAME")) { import("http://localhost:4000/uploads/createTHREE.js").then((result) => result.initHexoThreeModule(document.getElementById("three"),document.getElementById("threeMain"))); } else { // 這裏的代碼會被直接執行,window指向iframe內的window(其實就是把代碼整個移動到了iframe內) import('http://localhost:4000/uploads/glsl_snippets.js').then(async res=>res.glsl_snippets(res.anotherGlsl)) } </script>
通常狀況下不建議在一個頁面放多個效果若有必要,能夠經過交互時渲染,在視圖內渲染等方法優化,避免頁面卡死node
建議clone下這個倉庫並運行起來,這兩個效果都是能夠交互的,也能夠直接訪問個人小站查看效果https://moshuying.topgit
緣由就是hexo對md文件中的script會渲染到頁面上,可是不會顯示出來,這就有充足的操做空間了。github
這裏使用iframe的主要緣由就是防止來回切換頁面致使的webgl上下文問題。否則也不至於這麼麻煩。web
// 建立iframe並返回iframe內的window對象 function createIframe(divNode) { return new Promise((resolve) => { let iframe = document.createElement("iframe"); // ... iframe.style = "position: absolute; width: 100%; height: 100%; left: 0; top: 0;border:none;"; iframe.onload = () => resolve(iframe.contentWindow); divNode.style = "position: relative; width: 100%; height: 0; padding-bottom: 75%;"; divNode.appendChild(iframe); }); }
建立完iframe後能夠爲iframe中加載對象了,以前使用的是經典前端的script src加載方式,考慮到可能會被用到,這裏保留了函數方便後續修改。
實際使用中利用module中的import()
函數直接引入在線文件便可hexo
function cdnLoadTHREE(divNode) { return createIframe(divNode).then((iframe_window) => { // 建立完iframe纔有了iframe內的iframe_window對象 let link = document.createElement('link') link.href = createCss() // 這裏對一些樣式作了簡單修改。 link.rel = 'stylesheet' link.type = 'text/css' iframe_window.document.head.appendChild(link); return new Promise((resolve)=>resolve(iframe_window)); }); }
最後將整個script標籤複製到iframe內,代碼會在複製完後當即執行,因爲代碼已經在iframe內了,因此window也指向了iframe中,這一步才使得能夠方便的使用module保證了向前兼容的同時,也能對老式的代碼向下兼容。不至於出現一些奇奇怪怪的問題。
function initHexoThreeModule(divNode,scriptNode) { let link = document.createElement("link"); link.href = createCss(); link.rel = "stylesheet"; link.type = "text/css"; document.head.appendChild(link); if(divNode && scriptNode){ cdnLoadTHREE(divNode).then((iframe_window)=>{ let script = document.createElement('script') script.src = createBlob(scriptNode.text,'application/javascript') iframe_window.document.head.appendChild(script) }) } }