rainyday插件试用心得
<style>.pap { margin: 12px 0; font-size: 18px;}
.mum { position: relative; margin: 0; padding: 10px; font: normal 16px/20px Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; color: black; background: rgba(240, 240, 240,.95); box-shadow: 2px 2px 4px gray; border: thick groove lightblue; border-radius: 6px; }
.mum ::selection { background-color: rgba(0,100,100,.35); }
.mum div { margin: 0; padding: 0; }
.mum cl-cd { display: block; position: relative; margin: 0 0 0 50px; padding: 0 0 0 10px; white-space: pre-wrap; overflow-wrap: break-word; border-left: 1px solid silver; }
.mum cl-cd::before { position: absolute; content: attr(data-idx); width: 50px; color: gray; text-align: right; transform: translate(-70px); }
.tRed { color: red; }
.tBlue { color: blue; }
.tGreen { color: green; }
.tDarkRed { color: darkred; }
.tMagenta { color: magenta; }
</style>
<div class="pa">
<p>rainyday 是模拟雨天窗玻璃凝结水珠子的一个JS插件,作者 Marek Brodziak,官网 <a href="https://mubaidr.js.org/rainyday.js/" target="_blank">https://mubaidr.js.org/rainyday.js/</a>,当前版本 v0.1.7,16.5KB大小,开源项目。</p>
<p>插件使用canvas画布绘制动态水珠,效果逼真到令人叹为观止。尝试将其用到帖子过程中碰上不少问题,意欲放弃,但实在难舍其浑然天成的特效,牺牲一个午休时间,终将其降服,成功用到帖子中来。</p>
<p>问题出在rainyday的布局上。新版本提供 parentElement 参数,就是canvas画布宿主,如若不配置,默认使用body,这将占用浏览器全部的可视区域乃至更多。若设置了 parentElement 参数,宿主元素相对定位的情况下,canvas画布的自动偏移非常离谱,具体是随宿主元素 margin 属性值偏移。论坛做宽幅帖子,需要宿主元素相对定位,所以不能通过帖子容器元素直接定位canvas画布,需要另外一个绝对定位的子元素来装载rainyday追加的画布,即便如此,rainyday追加的canvas画布仍然受到宿主元素的父元素的 margin 属性所影响,还需要额外处理:通过JS获得对canvas的操作权限,然后将其left和top设置为0。以下是具体处理代码:</p>
<div class='mum'>
<cl-cd data-idx="1"><<span class="tDarkRed">script</span>></cl-cd>
<cl-cd data-idx="2"> <span class="tBlue">var</span> engine;</cl-cd>
<cl-cd data-idx="3"> <span class="tBlue">var</span> sF = <span class="tRed">document</span>.createElement(<span class="tMagenta">'script'</span>);</cl-cd>
<cl-cd data-idx="4"> sF.src = <span class="tMagenta">'https://638183.freep.cn/638183/web/js/rainyday.js'</span>;</cl-cd>
<cl-cd data-idx="5"> <span class="tRed">document</span>.body.appendChild(sF);</cl-cd>
<cl-cd data-idx="6"> sF.onload = <span class="tBlue">function</span>() {</cl-cd>
<cl-cd data-idx="7"> <span class="tBlue">var</span> image = <span class="tBlue">new</span> Image();</cl-cd>
<cl-cd data-idx="8"> image.crossOrigin = <span class="tMagenta">'anonymous'</span>;</cl-cd>
<cl-cd data-idx="9"> image.onload = <span class="tBlue">function</span>() {</cl-cd>
<cl-cd data-idx="10"> engine = <span class="tBlue">new</span> RainyDay({</cl-cd>
<cl-cd data-idx="11"> <span class="tBlue">image:</span> <span class="tBlue">this</span>,</cl-cd>
<cl-cd data-idx="12"> <span class="tBlue">parentElement:</span> mama,</cl-cd>
<cl-cd data-idx="13"> });</cl-cd>
<cl-cd data-idx="14"> <span class="tBlue">var</span> canv = <span class="tRed">document</span>.querySelector(<span class="tMagenta">'#papa canvas'</span>);</cl-cd>
<cl-cd data-idx="15"> canv.style.cssText += <span class="tMagenta">'<span class="tBlue">left:</span> 0; <span class="tBlue">top:</span> 0'</span>;</cl-cd>
<cl-cd data-idx="16"> mState();</cl-cd>
<cl-cd data-idx="17"> };</cl-cd>
<cl-cd data-idx="18"> image.src = <span class="tMagenta">'https://638183.freep.cn/638183/t24/2/f11.jpeg'</span>;</cl-cd>
<cl-cd data-idx="19"> </cl-cd>
<cl-cd data-idx="20"> <span class="tBlue">var</span> mState = () => {</cl-cd>
<cl-cd data-idx="21"> papa.style.setProperty(<span class="tMagenta">'--state'</span>, aud.paused ? <span class="tMagenta">'paused'</span> : <span class="tMagenta">'running'</span>);</cl-cd>
<cl-cd data-idx="22"> aud.paused ? engine.pause() : engine.resume();</cl-cd>
<cl-cd data-idx="23"> };</cl-cd>
<cl-cd data-idx="24"> aud.onplaying = aud.onpause = () => mState();</cl-cd>
<cl-cd data-idx="25"> papa.onclick = () => aud.paused ? aud.play() : aud.pause();</cl-cd>
<cl-cd data-idx="26"> };</cl-cd>
<cl-cd data-idx="27"><<span class="tDarkRed">/script</span>></cl-cd>
</div>
<p>上述代码第14、15行就是强行将rainyday绘制的canvas画布的左上角强行拉回 id="mama" 的div容器的左上角,mama则是帖子容器元素的子元素,宽高100%,绝对定位,与帖子容器元素贴合。</p>
<p>rainyday插件的必填参数 image 支持有背景图片的元素,举例说,如果帖子容器带有背景图片,则可以直接将其 id 作为 image 参数的值,这其实是最理想的做帖子的姿势——水珠特效基本就约束在帖子容器里。但有个前提:图片必须是同源图片,就是说不能是跨域图片。还有一个小问题:margin-top、margin-bottom依然会影响canvas的位置。对于图片跨域,由于 crossOrigin 只针对图片、音视频等媒体,只有通过修改插件源码解决问题,但如果使用的是官网或第三方的资源,我们没有修改权限;对于外边距的上下边距对画布位置的影响,解决方法是不设置这两个值或设为 0 便可。</p>
<p>演示实例地址一:<a href="http://mhh.52qingyin.cn/art/bshow.php?st=3&sd=3&art=mahei_1715127196" target="_blank">http://mhh.52qingyin.cn/art/bshow.php?st=3&sd=3&art=mahei_1715127196</a></p>
<p>演示实例地址二:<a href="http://qhxy.52qingyin.cn/art/bshow.php?st=4&sd=4&art=uvuz_1715127531" target="_blank">http://qhxy.52qingyin.cn/art/bshow.php?st=4&sd=4&art=uvuz_1715127531</a></p>
<p>演示实例地址三:<a href="https://www.huachaowang.com/thread-75822-1-1.html" target="_blank">https://www.huachaowang.com/thread-75822-1-1.html</a>
</div> Rainyday 插件会更改宿主元素相关 CSS 属性,这是问题,理论上不应如此 这个玻璃插件跟之前的动态FLASH效果一模一样,真实自然,太漂亮了 南无月 发表于 2024-5-8 17:48
这个玻璃插件跟之前的动态FLASH效果一模一样,真实自然,太漂亮了
不错的 “但有个前提:图片必须是同源图片,就是说不能是跨域图片。”
也就是说图图需要和插件上传的地方是一样的么? “对于外边距的上下边距对画布位置的影响,解决方法是不设置这两个值或设为 0 便可。”
这样可以解决跨域图图是么{:4_204:} 黑黑辛苦了{:4_187:} 红影 发表于 2024-5-8 19:29
黑黑辛苦了
手掌更辛苦 红影 发表于 2024-5-8 19:27
“但有个前提:图片必须是同源图片,就是说不能是跨域图片。”
也就是说图图需要和插件上传的地方是一样的 ...
image 参数使用帖子容器id的话是酱紫。
同源的意思很好理解,它们在同一个网站。试着比较一下以下三个地址,找出两个同源的URL:
① 'https://www.195.com/2024/1/a102.jpg'
② 'https://www.159.com/2024/1/b102.jpg'
③ 'https://www.195.com/5656/222333.png'
红影 发表于 2024-5-8 19:29
“对于外边距的上下边距对画布位置的影响,解决方法是不设置这两个值或设为 0 便可。”
这样可以解决跨域 ...
这和跨域无关 马黑黑 发表于 2024-5-8 20:24
手掌更辛苦
没有黑黑跨不过的难关,厉害{:4_199:} 马黑黑 发表于 2024-5-8 20:29
image 参数使用帖子容器id的话是酱紫。
同源的意思很好理解,它们在同一个网站。试着比较一下以下三个 ...
嗯嗯,1和3同源。 马黑黑 发表于 2024-5-8 20:32
这和跨域无关
我应该去试试就更明白些了{:4_173:} 红影 发表于 2024-5-8 21:15
我应该去试试就更明白些了
跨域指的是图片源的问题,外边距指的是元素布局的问题 红影 发表于 2024-5-8 21:08
没有黑黑跨不过的难关,厉害
哪里的话 马黑黑 发表于 2024-5-8 21:18
跨域指的是图片源的问题,外边距指的是元素布局的问题
嗯嗯,做了一个,现在知道了。黑黑调整了空间布局的设置,现在的代码很完美{:4_187:} 马黑黑 发表于 2024-5-8 21:18
哪里的话
你的水平摆在那呢,能让你花费心思的,还是有一定难度的呢{:4_187:} 马黑黑 发表于 2024-5-8 13:21
Rainyday 插件会更改宿主元素相关 CSS 属性,这是问题,理论上不应如此
{:4_170:}实际跟理论有差别,或者是有某个隐藏的代码,跟特务一样潜伏者 马黑黑 发表于 2024-5-8 17:59
不错的
当时有很多经典的F,当时水滴效果就是其中之一。
没想到的是代码也可以如此逼真。。{:4_170:} 南无月 发表于 2024-5-8 22:47
当时有很多经典的F,当时水滴效果就是其中之一。
没想到的是代码也可以如此逼真。。
canvas还可以做更多