clone代码后查看运行时成果,或立刻拜访这里查看成果https://moshuying.top仓库链接,点个收费的星星感激不尽。
主题文件默认状况下仿佛不会主动clone能够切到主题目录下下载主题,能够自行clone主题
最近想在hexo中嵌入一些shader,折腾了一些工夫后终于欠缺,实际上用这种办法不仅能够在hexo中嵌入shader,也能够嵌入babylonjs,pxixjs,Layabox,Egret,Cocos2等,先看成果,原理什么的其实很简略。
因为一些shader特地耗费显卡性能,在glsl_snippets.js
中断定如果第一帧渲染工夫超过0.4秒就不再渲染了。
也能够点击shader暂停渲染
嵌入shader
shader起源shaderToy
齐全反对shadertoy的代码,参考自大神的代码stackoverflow,在这位大神的代码里获取到齐全兼容shaderToy的思路。并将其改成更实用在hexo中。
示例代码
<!-- 至多须要一个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>
显示成果
嵌入threejs3D场景
个别状况下不倡议在一个页面放多个成果如有必要,能够通过交互时渲染,在视图内渲染等办法优化,防止页面卡死
倡议clone下这个仓库并运行起来,这两个成果都是能够交互的,也能够间接拜访我的小站查看成果https://moshuying.top
实现原理
起因就是hexo对md文件中的script会渲染到页面上,然而不会显示进去,这就有短缺的操作空间了。
这里应用iframe的次要起因就是避免来回切换页面导致的webgl上下文问题。不然也不至于这么麻烦。
// 创立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()
函数间接引入在线文件即可
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) }) }}
加载iframe到hexo中的残缺代码
在iframe中加载shader的残缺代码