fsgo测试
本帖最后由 马黑黑 于 2024-3-16 08:19 编辑 <br /><br /><style>#papa { margin: 30px 0 0 calc(50% - 593px); width: 1024px; height: 640px; background: url('https://638183.freep.cn/638183/t24/1/purple.jpg') no-repeat center/cover; box-shadow: 3px 3px 20px #000; position: relative; z-index: 1000; }
#btnplay { position: absolute; left: 200px; top: 200px; width: 80px; height: 80px; transition: 5s; cursor: pointer; opacity: .9; animation: rot 6s linear infinite; }
#papa:fullscreen #btnplay { width: 120px; height: 120px; }
#btnFs { position: absolute; bottom: 10px; left: 48%; color: white; background: transparent; border: 2px solid white; border-radius: 6px; padding: 4px; transition: opacity 1s; cursor: pointer; opacity: 0; z-index: 10; }
#msg22 { margin: 40px; color: white; padding: 50px; }
@keyframes rot { to { transform: rotate(360deg); } }
</style>
<div id="papa">
<div id="msg22">Message Box</div>
<div id="btnFs">进入全屏</div>
<img id="btnplay" src="https://638183.freep.cn/638183/small/purple.png" alt="" title="测试按钮" />
</div>
<script>
let go = {x: true, y: true}, timerId = null, movTimer = null, fs = false, rect = papa.getBoundingClientRect();
papa.addEventListener('mousemove', () => {
clearTimeout(timerId);
btnFs.style.opacity = '1';
timerId = setTimeout('btnFs.style.opacity = "0"', 3000);
});
document.addEventListener('fullscreenchange', () => {
if (document.fullscreenElement !== null) {
fs = true;
btnFs.innerText = '退出全屏';
} else {
fs = false;
btnFs.innerText = '进入全屏';
}
});
let correctPos = (son) => {
let left = parseInt(son.style.left), top = parseInt(son.style.top);
if(left < 0) left = 0;
if(top < 0) top = 0;
if(left + son.clientWidth > papa.clientWidth) left = papa.clientWidth - son.clientWidth;
if(top + son.clientHeight > papa.clientHeight) top = papa.clientHeight - son.clientHeight;
son.style.left = left + 'px';
son.style.top = top + 'px';
};
document.onmousemove = function(e) {
if(e.target.id === 'btnplay') return;
clearTimeout(movTimer);
let x, y;
movTimer = setTimeout(function() {
//if(document.fullscreenElement && e.target.id === 'btnFs') return;
x = document.fullscreenElement ? e.offsetX || e.layer.x : e.pageX - rect.x;
y = document.fullscreenElement ? e.offsetY || e.layer.y : e.pageY - rect.y;
if(document.fullscreenElement && e.target.id === 'btnFs') {
x = e.pageX;
y = e.pageY;
}
let left = go.x === true ? x + 'px': '', top = go.y === true ? y + 'px' : '';
btnplay.style.cssText += `left: ${left}; top: ${top};`;
msg22.innerHTML = `x: ${x} / rect.x: ${rect.x}<br>y: ${y} / rect.y : ${rect.y}<br>papa: ${papa.clientWidth} / ${papa.clientHeight}`;
correctPos(btnplay);
}, 400);
};
btnFs.onclick = () => fs ? document.exitFullscreen() : papa.requestFullscreen();
</script>
《紫色》一帖,使用 fsgo 实现,小播可以响应鼠标指针在帖子内外的悬停动作(0.4秒有响应),小播的活动范围限制在帖子范围内。本地复杂环境测试通过,在站点上测试通过。但在Discuz!3.4环境下测试通过,在在花潮论坛水土不服,需要将实际代码拿来测试,因此有本帖。
fsgo的中,fs是全屏,这已经经过考验了,不说;go是小播游荡,实现思路是酱紫:
在 document 的 mousemove 事件时间中获取 e.pageX 和 e.pageY 坐标点,它们是基于浏览器window即浏览区域左上角的;通过 element.getBoundingRect() 方法获取帖子的左、上边缘偏移数据;再通过 element.clientWidth/Height 获取会动态变化的帖子宽高(正常和全屏模式间的变化)。这些数据拿到后,设计一套计算方法,用以驱使小播的 left 和 top 值使之相应鼠标指针的悬停和手机上的点按动作。
在设计之时,觉得理论上不成问题,写完测试,确实可以正常工作,效果与预期的一致。唯独到了这里,在全屏模式,e.pageX/Y 所获得的鼠标点数据不正确,坐标系仍是使用非全屏状态下的坐标系,这相当没有道理,具体原因不明,估计是相对老旧版本的一个bug。
那么,fsgo要入驻花潮,就需要修改一下。方法简单,获取点坐标数据时区分正常模式和全屏模式,正常显示模式下用 e.pageX/Y,全屏模式用 e.offsetX/Y 加兼容Firefox的 e.layerX/Y,本帖就是测试这个,感谢大家帮忙验证。 <style>
.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>
<h2>一楼代码</h2>
<div class='mum'>
<cl-cd data-idx="1"><<span class="tDarkRed">style</span>></cl-cd>
<cl-cd data-idx="2">#papa { <span class="tBlue">margin:</span> 30px 0 0 calc(50% - 593px); <span class="tBlue">width:</span> 1024px; <span class="tBlue">height:</span> 640px; <span class="tBlue">background:</span> url(<span class="tMagenta">'https://638183.freep.cn/638183/t24/1/purple.jpg'</span>) no-repeat center/cover; <span class="tBlue">box-shadow:</span> 3px 3px 20px #000; <span class="tBlue">position:</span> relative; <span class="tBlue">z-index:</span> 1000; }</cl-cd>
<cl-cd data-idx="3">#btnplay { <span class="tBlue">position:</span> absolute; <span class="tBlue">left:</span> 10px; <span class="tBlue">top:</span> 10px; <span class="tBlue">width:</span> 80px; <span class="tBlue">height:</span> 80px; <span class="tBlue">transition:</span> 5s; <span class="tBlue">cursor:</span> pointer; <span class="tBlue">opacity:</span> .9; <span class="tBlue">animation:</span> rot 6s linear infinite; }</cl-cd>
<cl-cd data-idx="4">#<span class="tBlue">papa:</span>fullscreen #btnplay { <span class="tBlue">width:</span> 120px; <span class="tBlue">height:</span> 120px; }</cl-cd>
<cl-cd data-idx="5">#btnFs { <span class="tBlue">position:</span> absolute; <span class="tBlue">bottom:</span> 10px; <span class="tBlue">left:</span> 48%; <span class="tBlue">color:</span> white; <span class="tBlue">background:</span> transparent; <span class="tBlue">border:</span> 2px solid white; <span class="tBlue">border-radius:</span> 6px; <span class="tBlue">padding:</span> 4px; <span class="tBlue">transition:</span> opacity 1s; <span class="tBlue">cursor:</span> pointer; <span class="tBlue">opacity:</span> 0; <span class="tBlue">z-index:</span> 10; }</cl-cd>
<cl-cd data-idx="6">#msg22 { <span class="tBlue">margin:</span> 40px; <span class="tBlue">color:</span> white; <span class="tBlue">padding:</span> 50px; }</cl-cd>
<cl-cd data-idx="7">@keyframes rot { to { <span class="tBlue">transform:</span> rotate(360deg); } }</cl-cd>
<cl-cd data-idx="8"><<span class="tDarkRed">/style</span>></cl-cd>
<cl-cd data-idx="9"> </cl-cd>
<cl-cd data-idx="10"><<span class="tDarkRed">div</span> <span class="tRed">id</span>=<span class="tMagenta">"papa"</span>></cl-cd>
<cl-cd data-idx="11"> <<span class="tDarkRed">div</span> <span class="tRed">id</span>=<span class="tMagenta">"msg22"</span>>Message Box<<span class="tDarkRed">/div</span>></cl-cd>
<cl-cd data-idx="12"> <<span class="tDarkRed">div</span> <span class="tRed">id</span>=<span class="tMagenta">"btnFs"</span>>进入全屏<<span class="tDarkRed">/div</span>></cl-cd>
<cl-cd data-idx="13"> <<span class="tDarkRed">img</span> <span class="tRed">id</span>=<span class="tMagenta">"btnplay"</span> src=<span class="tMagenta">"https://638183.freep.cn/638183/small/purple.png"</span> alt=<span class="tMagenta">""</span> title=<span class="tMagenta">"测试按钮"</span> /></cl-cd>
<cl-cd data-idx="14"><<span class="tDarkRed">/div</span>></cl-cd>
<cl-cd data-idx="15"> </cl-cd>
<cl-cd data-idx="16"><<span class="tDarkRed">script</span>></cl-cd>
<cl-cd data-idx="17"> </cl-cd>
<cl-cd data-idx="18"><span class="tBlue">let</span> go = {<span class="tBlue">x:</span> true, <span class="tBlue">y:</span> true},</cl-cd>
<cl-cd data-idx="19"> timerId = null,</cl-cd>
<cl-cd data-idx="20"> movTimer = null,</cl-cd>
<cl-cd data-idx="21"> fs = false,</cl-cd>
<cl-cd data-idx="22"> rect = papa.getBoundingClientRect();</cl-cd>
<cl-cd data-idx="23"> </cl-cd>
<cl-cd data-idx="24">papa.addEventListener(<span class="tMagenta">'mousemove'</span>, () => {</cl-cd>
<cl-cd data-idx="25"> clearTimeout(timerId);</cl-cd>
<cl-cd data-idx="26"> btnFs.style.opacity = <span class="tMagenta">'1'</span>;</cl-cd>
<cl-cd data-idx="27"> timerId = setTimeout(<span class="tMagenta">'btnFs.style.opacity = "0"'</span>, 3000);</cl-cd>
<cl-cd data-idx="28">});</cl-cd>
<cl-cd data-idx="29"> </cl-cd>
<cl-cd data-idx="30"><span class="tRed">document</span>.addEventListener(<span class="tMagenta">'fullscreenchange'</span>, () => {</cl-cd>
<cl-cd data-idx="31"> <span class="tBlue">if</span> (<span class="tRed">document</span>.fullscreenElement !== null) {</cl-cd>
<cl-cd data-idx="32"> fs = true;</cl-cd>
<cl-cd data-idx="33"> btnFs.innerText = <span class="tMagenta">'退出全屏'</span>;</cl-cd>
<cl-cd data-idx="34"> } <span class="tBlue">else</span> {</cl-cd>
<cl-cd data-idx="35"> fs = false;</cl-cd>
<cl-cd data-idx="36"> btnFs.innerText = <span class="tMagenta">'进入全屏'</span>;</cl-cd>
<cl-cd data-idx="37"> }</cl-cd>
<cl-cd data-idx="38">});</cl-cd>
<cl-cd data-idx="39"> </cl-cd>
<cl-cd data-idx="40"><span class="tBlue">let</span> correctPos = (son) => {</cl-cd>
<cl-cd data-idx="41"> <span class="tBlue">let</span> left = parseInt(son.style.left), top = parseInt(son.style.top);</cl-cd>
<cl-cd data-idx="42"> <span class="tBlue">if</span>(left < 0) left = 0;</cl-cd>
<cl-cd data-idx="43"> <span class="tBlue">if</span>(top < 0) top = 0;</cl-cd>
<cl-cd data-idx="44"> <span class="tBlue">if</span>(left + son.clientWidth > papa.clientWidth) left = papa.clientWidth - son.clientWidth;</cl-cd>
<cl-cd data-idx="45"> <span class="tBlue">if</span>(top + son.clientHeight > papa.clientHeight) top = papa.clientHeight - son.clientHeight;</cl-cd>
<cl-cd data-idx="46"> son.style.left = left + <span class="tMagenta">'px'</span>;</cl-cd>
<cl-cd data-idx="47"> son.style.top = top + <span class="tMagenta">'px'</span>;</cl-cd>
<cl-cd data-idx="48">};</cl-cd>
<cl-cd data-idx="49"> </cl-cd>
<cl-cd data-idx="50"><span class="tRed">document</span>.onmousemove = <span class="tBlue">function</span>(e) {</cl-cd>
<cl-cd data-idx="51"> <span class="tBlue">if</span>(e.target.<span class="tRed">id</span> === <span class="tMagenta">'btnplay'</span>) <span class="tBlue">return</span>;</cl-cd>
<cl-cd data-idx="52"> clearTimeout(movTimer);</cl-cd>
<cl-cd data-idx="53"> <span class="tBlue">let</span> x, y;</cl-cd>
<cl-cd data-idx="54"> movTimer = setTimeout(<span class="tBlue">function</span>() {</cl-cd>
<cl-cd data-idx="55"> <span class="tBlue">if</span>(<span class="tRed">document</span>.fullscreenElement && e.target.<span class="tRed">id</span>.toUpperCase() === <span class="tMagenta">'BTNFS'</span>) <span class="tBlue">return</span>;</cl-cd>
<cl-cd data-idx="56"> x = <span class="tRed">document</span>.fullscreenElement ? e.offsetX || e.layer.x : e.pageX - rect.x;</cl-cd>
<cl-cd data-idx="57"> y = <span class="tRed">document</span>.fullscreenElement ? e.offsetY || e.layer.y : e.pageY - rect.y;</cl-cd>
<cl-cd data-idx="58"> <span class="tBlue">let</span> left = go.x === true ? x + <span class="tMagenta">'px'<!--<span class='tBlue'-->span>:</span> <span class="tMagenta">''</span>, top = go.y === true ? y + <span class="tMagenta">'px'</span> : <span class="tMagenta">''</span>;</cl-cd>
<cl-cd data-idx="59"> btnplay.style.cssText += `<span class="tBlue">left:</span> ${left}; <span class="tBlue">top:</span> ${top};`;</cl-cd>
<cl-cd data-idx="60"> msg22.innerText = `<span class="tBlue">x:</span> ${x} / <span class="tBlue">left:</span> ${left}\<span class="tBlue">ny:</span> ${y} / <span class="tBlue">top:</span> ${top}\<span class="tBlue">npapa:</span> ${papa.clientWidth} / ${papa.clientHeight}`;</cl-cd>
<cl-cd data-idx="61"> correctPos(btnplay);</cl-cd>
<cl-cd data-idx="62"> }, 400);</cl-cd>
<cl-cd data-idx="63">};</cl-cd>
<cl-cd data-idx="64">btnFs.onclick = () => fs ? <span class="tRed">document</span>.exitFullscreen() : papa.requestFullscreen();</cl-cd>
<cl-cd data-idx="65"> </cl-cd>
<cl-cd data-idx="66"><<span class="tDarkRed">/script</span>></cl-cd>
</div>
测试反馈,全屏模式下小花也跟着鼠标移动,并且完到达鼠标所在位置。。{:4_173:} 这个鼠标点不同的地方,数字坐标也会随着变化,太高级了。。{:4_199:} 南无月 发表于 2024-3-15 18:10
这个鼠标点不同的地方,数字坐标也会随着变化,太高级了。。
那是验证用 本帖最后由 马黑黑 于 2024-3-15 20:36 编辑
南无月 发表于 2024-3-15 18:09
测试反馈,全屏模式下小花也跟着鼠标移动,并且完到达鼠标所在位置。。
{:4_190:} 试了一下,按钮在全屏和非全屏状态下,都是完美响应鼠标。
只是在退出全屏时,有按钮溢出背景的瞬间。别的都没问题{:4_187:} 红影 发表于 2024-3-15 21:26
试了一下,按钮在全屏和非全屏状态下,都是完美响应鼠标。
只是在退出全屏时,有按钮溢出背景的瞬间。别的 ...
切换时按钮从外面归位,这是正常的 马黑黑 发表于 2024-3-15 20:33
紫色全屏问题已完美解决~~{:4_191:} 马黑黑 发表于 2024-3-15 20:32
那是验证用
跟科幻片里的外星人角度看到人类,屏幕上出现的参数似的。。{:4_173:} 马黑黑 发表于 2024-3-15 20:33
这个是第二个方案。。。已有第三个方案代替。。
这解决问题的能力,简直了。。多角度多种思维。。
你真是我偶像,佩服的五体投地。。{:4_199:} 南无月 发表于 2024-3-16 17:03
这个是第二个方案。。。已有第三个方案代替。。
这解决问题的能力,简直了。。多角度多种思维。。
你真 ...
大小上课爱开小差的人歪主意就是多{:4_170:} 南无月 发表于 2024-3-16 16:33
跟科幻片里的外星人角度看到人类,屏幕上出现的参数似的。。
我只验证几个关键数据,还有更多的数据也应验证,我心中有数就算了 南无月 发表于 2024-3-16 16:31
紫色全屏问题已完美解决~~
{:4_181:} 马黑黑 发表于 2024-3-16 17:09
大小上课爱开小差的人歪主意就是多
小时候咋这么可爱捏。。。{:4_170:} 南无月 发表于 2024-3-16 17:19
小时候咋这么可爱捏。。。
注意力不集中,因为老师教的东东太容易 马黑黑 发表于 2024-3-16 17:10
我只验证几个关键数据,还有更多的数据也应验证,我心中有数就算了
关键数据给大家看,勉强能看懂。。。
有些数心里看。。估计是想整出来小白也看不懂。{:4_170:} 马黑黑 发表于 2024-3-16 17:10
每次更新换代{:4_173:},不超过24小时的节奏 。 南无月 发表于 2024-3-16 17:21
每次更新换代,不超过24小时的节奏 。
那也不是,看看有木有空还有烟酒