花潮論壇歡迎您
<style>.bgDiv {/* 帖子主體 */
margin: auto;
width: 1275px;
height: 717px;
left: -339.5px;
background: url('https://638183.freep.cn/638183/Pic/2022/ysjn.jpg') no-repeat center/cover;
border: 1px solid;
position: relative;
perspective: 1000px;
}
.bgDiv::before {/* 煙霧 */
content: '';
position: absolute;
width: inherit;
height: inherit;
background: url('https://638183.freep.cn/638183/Pic/2022/smoke1.gif') no-repeat center/cover;
opacity: .2;
}
.btf {/* 蝴蝶 */
width: 200px;
height: 113px;
position: absolute;
left: 20px;
bottom: 40px;
filter: blur(1px);
animation: fly 40s ease infinite alternate;
}
.stage {/* 字幕wrap */
--len: 80px;
margin: 200px auto 0;
position: relative;
width: var(--len);
height: var(--len);
transform-style: preserve-3d;
animation: rot 15s linear infinite;
}
.stage div {/* 字幕面板統一樣式 */
position: absolute;
width: inherit;
height: inherit;
color: #eee;
text-shadow: 1px 1px 3px #111;
font: 2em / var(--len) Arial;
text-align: center;
left: 0; top: 0;
}
/* 蝴蝶動畫 */
@keyframes fly { to { left: 1050px; } }
/* 字幕動畫 */
@keyframes rot { to { transform: rotateY(-360deg); } }
</style>
<div class="bgDiv">
<div class="stage"></div>
<img class="btf" src="https://638183.freep.cn/638183/Pic/2022/btf.gif" alt="" />
</div>
<script>
//加載網易云音樂
let wyy = document.createElement('iframe');
wyy.src = 'https://music.163.com/outchain/player?type=2&id=548814997&auto=1&height=66';
wyy.style.display = 'none';
document.querySelector('.bgDiv').appendChild(wyy);
//加載字幕
let stage = document.querySelector(".stage");
let txt = "花潮論壇歡迎您";
let angle = 360 / txt.length;
let w = stage.clientWidth;
let trz = Math.ceil(Math.tan(Math.PI / 180 * (180 - angle) /2 ) *w / 2);
let str = "";
for(j=0; j<txt.length; j++){
let cc = `#${Math.random().toString(16).substr(-6)}`;
let ry = Math.floor(j*angle);
str += `<div style="transform:rotateY(${ry}deg) translateZ(${trz}px); background: ${cc};">${txt.charAt(j)}</div>\n`;
}
stage.innerHTML = str;
</script>
原創代碼:
<style>
.bgDiv {/* 帖子主體 */
margin: auto;
width: 1275px;
height: 717px;
left: -339.5px;
background: url('https://638183.freep.cn/638183/Pic/2022/ysjn.jpg') no-repeat center/cover;
border: 1px solid;
position: relative;
perspective: 1000px;
}
.bgDiv::before {/* 煙霧 */
content: '';
position: absolute;
width: inherit;
height: inherit;
background: url('https://638183.freep.cn/638183/Pic/2022/smoke1.gif') no-repeat center/cover;
opacity: .2;
}
.btf {/* 蝴蝶 */
width: 200px;
height: 113px;
position: absolute;
left: 20px;
bottom: 40px;
filter: blur(1px);
animation: fly 40s ease infinite alternate;
}
.stage {/* 字幕wrap */
--len: 80px;
margin: 200px auto 0;
position: relative;
width: var(--len);
height: var(--len);
transform-style: preserve-3d;
animation: rot 15s linear infinite;
}
.stage div {/* 字幕面板統一樣式 */
position: absolute;
width: inherit;
height: inherit;
color: #eee;
text-shadow: 1px 1px 3px #111;
font: 2em / var(--len) Arial;
text-align: center;
left: 0; top: 0;
}
/* 蝴蝶動畫 */
@keyframes fly { to { left: 1050px; } }
/* 字幕動畫 */
@keyframes rot { to { transform: rotateY(-360deg); } }
</style>
<div class="bgDiv">
<div class="stage"></div>
<img class="btf" src="https://638183.freep.cn/638183/Pic/2022/btf.gif" alt="" />
</div>
<script>
//加載網易云音樂
let wyy = document.createElement('iframe');
wyy.src = 'https://music.163.com/outchain/player?type=2&id=548814997&auto=1&height=66';
wyy.style.display = 'none';
document.querySelector('.bgDiv').appendChild(wyy);
//加載字幕
let stage = document.querySelector(".stage");
let txt = "花潮論壇歡迎您";
let angle = 360 / txt.length;
let w = stage.clientWidth;
let trz = Math.ceil(Math.tan(Math.PI / 180 * (180 - angle) /2 ) *w / 2);
let str = "";
for(j=0; j<txt.length; j++){
let cc = `#${Math.random().toString(16).substr(-6)}`;
let ry = Math.floor(j*angle);
str += `<div style="transform:rotateY(${ry}deg) translateZ(${trz}px); background: ${cc};">${txt.charAt(j)}</div>\n`;
}
stage.innerHTML = str;
</script>
本帖最后由 马黑黑 于 2022-4-10 11:23 编辑
幾點說明:
帖子的元素:①主體:底圖;②飾品:煙霧、蝴蝶、字幕以及兩個@keyframes動畫,還有網易云音樂(感謝網易云)。
飾品技巧一:煙霧是一幅GIF動圖,用主體元素的偽元素加載并完整覆蓋在主體元素之上,設置opacity為0.2;
飾品技巧二:蝴蝶是img圖片元素,所用圖片亦為GIF動圖,@keyframes令其改變left值從左飛到右(再返回有 alternate實現);
飾品技巧三:字幕為半成品多面體,屬於環形標語系列,是3d效果,由CSS和JS共同完成。景深設在主體元素,3d渲染聲明寫在字幕內包裝(舞台),CSS還定義組成字幕的各個面板的統一樣式,然後在JS環節根據欲要顯示的文本,且圍繞CSS設定的字幕舞台尺寸進行相關計算,最後加載字幕。
飾品技巧四:網易云音樂因為HTML代碼不規範,所以用JS對之進行加工然後加載。根據控制台報告,網易云音樂的warning級別的錯誤還存在,但不影響播放器的運行,網易云的程序員及其工作是偉大的,向他們致敬!
最後提一下:字幕的文本,字數不宜太多,一個類似圓環的東東,字數過多會大的嚇人。 嗯?按怎么用了繁体输入? 两点补充说明:
其一,本帖字幕位置的设定,是通过 margin 值调整——
margin: 200px auto 0;
上下外边距 200px,左右为0;auto为居中。可以取消掉这句,通过设置left、top来定位。
其二,设置字幕尺寸只需修改一个值,下面这行——
--len: 80px; 黑黑朋友早晨好!谢谢你制作的精美作品。我来到花潮论坛后,真切地感受到这里朋友的真诚和热情。花潮论坛是一个和谐热情的集体。谢谢黑黑朋友! 这里最难的事字幕那段吧,还要截取字幕长度,然后一个个面地安放。这个好像是多面体,有多少个字,就有多少面的吧。字幕底色还是变色的呢。这个帖子真美,黑黑真棒{:4_199:} 梦油 发表于 2022-4-10 10:19
黑黑朋友早晨好!谢谢你制作的精美作品。我来到花潮论坛后,真切地感受到这里朋友的真诚和热情。花潮论坛是 ...
上午好!喝茶{:4_190:} 红影 发表于 2022-4-10 10:30
这里最难的事字幕那段吧,还要截取字幕长度,然后一个个面地安放。这个好像是多面体,有多少个字,就有多少 ...
是个真3d多面体,但这个多面体只有正面和侧面,没有底部和顶部。如果给面板统一样式定义恰当的 opacity 值,则立体效果更佳。
有多少个字就有多少个面,不过不建议有太多字,字多多面体会变得很大。 let trz = Math.ceil(Math.tan(Math.PI / 180 * (180 - angle) /2 ) *w / 2);
这个计算有点复杂,先换算成弧度,然后和文字的长度以及长度换算成的角度相关,竟然是作用于Z轴的。 只有黑黑能做出这么复杂的帖子,对于这个帖子,我最多是不动脑筋地套用了{:4_173:} 本帖最后由 马黑黑 于 2022-4-10 11:19 编辑
红影 发表于 2022-4-10 10:56
let trz = Math.ceil(Math.tan(Math.PI / 180 * (180 - angle) /2 ) *w / 2);
这个计算有点复杂,先换算成 ...
关于算法,与原始面板元素的堆叠有关。首先,未发生立体之前,它们是统一堆叠放在一处的,默认的left和top都是0,基于平面的堆叠。然后,安排每块面板的去向,先沿着Y轴旋转一定角度,再往后一定距离摆放(这个距离是固定的,后面还会谈到)。往后平移面板,用到的当然只能是Z轴。
Z轴是屏幕和用户之间的轴,之所以用它,那是因为我们要构成一个圆环多面体。面板转动一定角度后,它的水平位置还不会跟着会发生变化,但往后平移之后,x方向的位置就有了变化,是基于 perspective-origin(而不是transform-origin但与之有关,是3d的旋转基点)的运动基点,本例用默认值(因为元素固定堆叠),这样最终就能产生多面体圆环。
面板在Z方向应拉开的距离要精准计算,它应该是基于弧度单位的,所以计算式子显得很复杂,这里就不解释了。这个值针对所有的面板都一样。 红影 发表于 2022-4-10 10:58
只有黑黑能做出这么复杂的帖子,对于这个帖子,我最多是不动脑筋地套用了
理解其中可以理解的,这对将来的长进有作用 马黑黑 发表于 2022-4-10 10:36
上午好!喝茶
你好,黑黑朋友。你的制作巧夺天工啊。 老黑的这个制作好复杂,得慢慢学习了。这个画面真漂亮,很立体的制作。{:4_199:} 加林森 发表于 2022-4-10 11:33
老黑的这个制作好复杂,得慢慢学习了。这个画面真漂亮,很立体的制作。
那个圆环多面体是立体的 梦油 发表于 2022-4-10 11:27
你好,黑黑朋友。你的制作巧夺天工啊。
过奖了,一般般,过得去,差不多…… 马黑黑 发表于 2022-4-10 12:00
那个圆环多面体是立体的
嗯嗯,知道的。 马黑黑 发表于 2022-4-10 12:01
过奖了,一般般,过得去,差不多……
羡慕、羡慕啊! 梦油 发表于 2022-4-10 13:36
羡慕、羡慕啊!
{:5_108:}