永恒的瞬间
本帖最后由 马黑黑 于 2024-4-28 10:42 编辑 <br /><br /><style>#papa { margin: -60px 0 20px calc(50% - 593px); width: 1024px; height: 640px; background: url('https://638183.freep.cn/638183/t24/2/u30.jpg') no-repeat center/cover; box-shadow: 3px 3px 6px gray; pointer-events: none; z-index: 1; position: relative; }
#papa::after, #vid { position: absolute; left: calc(50% - 125px); top: 55px; width: 200px; height: 200px; border-radius: 0 40%; transform: rotate(45deg); }
#papa::after { content: ''; cursor: pointer; pointer-events: auto; box-shadow: 0 0 8px rgba(255, 255, 255, .2); }
#canv { position: absolute; }
#vid { object-fit: cover; mix-blend-mode: screen; filter: hue-rotate(300deg) opacity(.5); }
</style>
<div id="papa">
<audio id="aud" src="https://music.163.com/song/media/outer/url?id=1316563784" loop autoplay></audio>
<video id="vid" src="https://img.tukuppt.com/video_show/2402760/00/01/83/5b4abcfb3acff.mp4" loop muted></video>
<canvas id="canv" width="1024" height="640"></canvas>
</div>
<script>
var ctx = canv.getContext('2d', {willReadFrequently: true});
var ww = canv.width, hh = canv.height, pixels = [];
for (var x = -400; x < 400; x += 5) {
for (var z = -250; z < 250; z += 5) {
pixels.push({ x: x, y: 100, z: z });
}
}
let render = (ts) => {
var imageData = ctx.getImageData(0, 0, ww, hh), len = pixels.length, fov = 250;
var pixel, scale, x2d, y2d, c;
for (var i = 0; i < len; i++) {
pixel = pixels[ i ];
scale = fov / (fov + pixel.z);
x2d = pixel.x * scale + ww / 2;
y2d = pixel.y * scale + hh / 2;
if (x2d >= 0 && x2d <= ww && y2d >= 0 && y2d <= hh) {
c = (Math.round(y2d) * imageData.width + Math.round(x2d)) * 4;
imageData.data = 20;
imageData.data = 200;
imageData.data = 200;
imageData.data = 245;
}
pixel.z -= 0.4;
pixel.y = hh / 14 + Math.sin(i / len * 15 + (ts / 450)) * 10;
if (pixel.z < -fov) pixel.z += 2 * fov;
}
ctx.putImageData(imageData, 0, 0);
};
(function drawFrame(ts) {
requestAnimationFrame(drawFrame);
if(!aud.paused) {
ctx.clearRect(0, 0, ww, hh);
render(ts);
}
})();
aud.onplaying = aud.onpause = () => aud.paused ? vid.pause() : vid.play();
papa.onclick = () => aud.paused ? aud.play() : aud.pause();
</script>
本帖最后由 马黑黑 于 2024-4-28 10:43 编辑 <br /><br /><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> 20px 0 20px 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/2/u30.jpg'</span>) no-repeat center/cover; <span class="tBlue">box-shadow:</span> 3px 3px 6px gray; <span class="tBlue">pointer-events:</span> none; <span class="tBlue">position:</span> relative; }</cl-cd>
<cl-cd data-idx="3"> #papa::after, #vid { <span class="tBlue">position:</span> absolute; <span class="tBlue">left:</span> calc(50% - 125px); <span class="tBlue">top:</span> 55px; <span class="tBlue">width:</span> 200px; <span class="tBlue">height:</span> 200px; <span class="tBlue">border-radius:</span> 0 40%; <span class="tBlue">transform:</span> rotate(45deg); }</cl-cd>
<cl-cd data-idx="4"> #papa::after { <span class="tBlue">content:</span> <span class="tMagenta">''</span>; <span class="tBlue">cursor:</span> pointer; <span class="tBlue">pointer-events:</span> auto; <span class="tBlue">box-shadow:</span> 0 0 8px rgba(255, 255, 255, .2); }</cl-cd>
<cl-cd data-idx="5"> #canv { <span class="tBlue">position:</span> absolute; }</cl-cd>
<cl-cd data-idx="6"> #vid { <span class="tBlue">object-fit:</span> cover; <span class="tBlue">mix-blend-mode:</span> screen; <span class="tBlue">filter:</span> hue-rotate(300deg) opacity(.5); }</cl-cd>
<cl-cd data-idx="7"><<span class="tDarkRed">/style</span>></cl-cd>
<cl-cd data-idx="8"> </cl-cd>
<cl-cd data-idx="9"><<span class="tDarkRed">div</span> <span class="tRed">id</span>=<span class="tMagenta">"papa"</span>></cl-cd>
<cl-cd data-idx="10"> <<span class="tDarkRed">audio</span> <span class="tRed">id</span>=<span class="tMagenta">"aud"</span> src=<span class="tMagenta">"https://music.163.com/song/media/outer/url?<span class="tRed">id</span>=1316563784"</span> loop autoplay><<span class="tDarkRed">/audio</span>></cl-cd>
<cl-cd data-idx="11"> <<span class="tDarkRed">video</span> <span class="tRed">id</span>=<span class="tMagenta">"vid"</span> src=<span class="tMagenta">"https://img.tukuppt.com/video_show/2402760/00/01/83/5b4abcfb3acff.mp4"</span> loop muted><<span class="tDarkRed">/video</span>></cl-cd>
<cl-cd data-idx="12"> <<span class="tDarkRed">canvas</span> <span class="tRed">id</span>=<span class="tMagenta">"canv"</span> width=<span class="tMagenta">"1024"</span> height=<span class="tMagenta">"640"</span>><<span class="tDarkRed">/canvas</span>></cl-cd>
<cl-cd data-idx="13"><<span class="tDarkRed">/div</span>></cl-cd>
<cl-cd data-idx="14"> </cl-cd>
<cl-cd data-idx="15"><<span class="tDarkRed">script</span>></cl-cd>
<cl-cd data-idx="16"><span class="tBlue">var</span> ctx = canv.getContext(<span class="tMagenta">'2d'</span>, {<span class="tBlue">willReadFrequently:</span> true});</cl-cd>
<cl-cd data-idx="17"><span class="tBlue">var</span> ww = canv.width, hh = canv.height, pixels = [];</cl-cd>
<cl-cd data-idx="18"> </cl-cd>
<cl-cd data-idx="19"><span class="tBlue">for</span> (<span class="tBlue">var</span> x = -400; x < 400; x += 5) {</cl-cd>
<cl-cd data-idx="20"> <span class="tBlue">for</span> (<span class="tBlue">var</span> z = -250; z < 250; z += 5) {</cl-cd>
<cl-cd data-idx="21"> pixels.push({ <span class="tBlue">x:</span> x, <span class="tBlue">y:</span> 100, <span class="tBlue">z:</span> z });</cl-cd>
<cl-cd data-idx="22"> }</cl-cd>
<cl-cd data-idx="23">}</cl-cd>
<cl-cd data-idx="24"> </cl-cd>
<cl-cd data-idx="25"><span class="tBlue">let</span> render = (ts) => {</cl-cd>
<cl-cd data-idx="26"> <span class="tBlue">var</span> imageData = ctx.getImageData(0, 0, ww, hh), len = pixels.length, fov = 250;</cl-cd>
<cl-cd data-idx="27"> <span class="tBlue">var</span> pixel, scale, x2d, y2d, c;</cl-cd>
<cl-cd data-idx="28"> <span class="tBlue">for</span> (<span class="tBlue">var</span> i = 0; i < len; i++) {</cl-cd>
<cl-cd data-idx="29"> pixel = pixels[ i ];</cl-cd>
<cl-cd data-idx="30"> scale = fov / (fov + pixel.z);</cl-cd>
<cl-cd data-idx="31"> x2d = pixel.x * scale + ww / 2;</cl-cd>
<cl-cd data-idx="32"> y2d = pixel.y * scale + hh / 2;</cl-cd>
<cl-cd data-idx="33"> <span class="tBlue">if</span> (x2d >= 0 && x2d <= ww && y2d >= 0 && y2d <= hh) {</cl-cd>
<cl-cd data-idx="34"> c = (<span class="tRed">Math</span>.round(y2d) * imageData.width + <span class="tRed">Math</span>.round(x2d)) * 4;</cl-cd>
<cl-cd data-idx="35"> imageData.data = 20;</cl-cd>
<cl-cd data-idx="36"> imageData.data = 200;</cl-cd>
<cl-cd data-idx="37"> imageData.data = 200;</cl-cd>
<cl-cd data-idx="38"> imageData.data = 245;</cl-cd>
<cl-cd data-idx="39"> }</cl-cd>
<cl-cd data-idx="40"> pixel.z -= 0.4;</cl-cd>
<cl-cd data-idx="41"> pixel.y = hh / 14 + <span class="tRed">Math</span>.sin(i / len * 15 + (ts / 450)) * 10;</cl-cd>
<cl-cd data-idx="42"> <span class="tBlue">if</span> (pixel.z < -fov) pixel.z += 2 * fov;</cl-cd>
<cl-cd data-idx="43"> }</cl-cd>
<cl-cd data-idx="44"> ctx.putImageData(imageData, 0, 0);</cl-cd>
<cl-cd data-idx="45">};</cl-cd>
<cl-cd data-idx="46"> </cl-cd>
<cl-cd data-idx="47">(<span class="tBlue">function</span> drawFrame(ts) {</cl-cd>
<cl-cd data-idx="48"> requestAnimationFrame(drawFrame);</cl-cd>
<cl-cd data-idx="49"> <span class="tBlue">if</span>(!aud.paused) {</cl-cd>
<cl-cd data-idx="50"> ctx.clearRect(0, 0, ww, hh);</cl-cd>
<cl-cd data-idx="51"> render(ts);</cl-cd>
<cl-cd data-idx="52"> }</cl-cd>
<cl-cd data-idx="53">})();</cl-cd>
<cl-cd data-idx="54"> </cl-cd>
<cl-cd data-idx="55">aud.onplaying = aud.onpause = () => aud.paused ? vid.pause() : vid.play();</cl-cd>
<cl-cd data-idx="56">papa.onclick = () => aud.paused ? aud.play() : aud.pause();</cl-cd>
<cl-cd data-idx="57"> </cl-cd>
<cl-cd data-idx="58"><<span class="tDarkRed">/script</span>></cl-cd>
</div>
说明:粒子波浪代码来源于网络,帖子根据需要 ① 做了一些必要的优化;② 改动相关数值;③ 加入运行条件。 原来波浪是粒子做的呢,太美了{:4_199:} 视频小播也很漂亮,border-radius: 0 40%;再扭转45度,就能得到这么漂亮的外形呢{:4_199:} 视频配合着粒子波浪,让这个帖子的意境十分悠远{:4_199:} 粒子波动,太美了{:4_187:} 神识修炼到这个层次,基本上就可永生了{:4_203:} 樵歌 发表于 2024-4-28 11:12
神识修炼到这个层次,基本上就可永生了
夸张,夸张 红影 发表于 2024-4-28 11:01
视频配合着粒子波浪,让这个帖子的意境十分悠远
不算太差 马黑黑 发表于 2024-4-28 11:49
不算太差
这个真的太美了{:4_199:} 漂亮,视觉美{:4_199:} 欣赏黑黑新的效果,黑黑辛苦了 构思巧妙,设计精美 。。
波浪粒子优雅流动,看得人目不转睛~~{:4_204:} 视频和粒子动态和音乐节拍相合,
这些细节合起来令人观感舒适。。{:4_199:} 南无月 发表于 2024-4-28 12:38
视频和粒子动态和音乐节拍相合,
这些细节合起来令人观感舒适。。
{:4_190:} 南无月 发表于 2024-4-28 12:37
构思巧妙,设计精美 。。
波浪粒子优雅流动,看得人目不转睛~~
挺漂亮的 小辣椒 发表于 2024-4-28 12:31
欣赏黑黑新的效果,黑黑辛苦了
{:4_190:} 小辣椒 发表于 2024-4-28 12:31
漂亮,视觉美
{:4_180:} 红影 发表于 2024-4-28 12:16
这个真的太美了
俺做的时候,咋就左看右看都不满意呢?差一点不敢发出来{:4_170:}