马黑黑 发表于 2022-4-10 08:37

花潮論壇歡迎您

<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 08:39

原創代碼:
<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 08:54

本帖最后由 马黑黑 于 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級別的錯誤還存在,但不影響播放器的運行,網易云的程序員及其工作是偉大的,向他們致敬!

最後提一下:字幕的文本,字數不宜太多,一個類似圓環的東東,字數過多會大的嚇人。

马黑黑 发表于 2022-4-10 08:57

嗯?按怎么用了繁体输入?

马黑黑 发表于 2022-4-10 09:01

两点补充说明:

其一,本帖字幕位置的设定,是通过 margin 值调整——

margin: 200px auto 0;

上下外边距 200px,左右为0;auto为居中。可以取消掉这句,通过设置left、top来定位。

其二,设置字幕尺寸只需修改一个值,下面这行——

--len: 80px;

梦油 发表于 2022-4-10 10:19

黑黑朋友早晨好!谢谢你制作的精美作品。我来到花潮论坛后,真切地感受到这里朋友的真诚和热情。花潮论坛是一个和谐热情的集体。谢谢黑黑朋友!

红影 发表于 2022-4-10 10:30

这里最难的事字幕那段吧,还要截取字幕长度,然后一个个面地安放。这个好像是多面体,有多少个字,就有多少面的吧。字幕底色还是变色的呢。这个帖子真美,黑黑真棒{:4_199:}

马黑黑 发表于 2022-4-10 10:36

梦油 发表于 2022-4-10 10:19
黑黑朋友早晨好!谢谢你制作的精美作品。我来到花潮论坛后,真切地感受到这里朋友的真诚和热情。花潮论坛是 ...

上午好!喝茶{:4_190:}

马黑黑 发表于 2022-4-10 10:39

红影 发表于 2022-4-10 10:30
这里最难的事字幕那段吧,还要截取字幕长度,然后一个个面地安放。这个好像是多面体,有多少个字,就有多少 ...

是个真3d多面体,但这个多面体只有正面和侧面,没有底部和顶部。如果给面板统一样式定义恰当的 opacity 值,则立体效果更佳。

有多少个字就有多少个面,不过不建议有太多字,字多多面体会变得很大。

红影 发表于 2022-4-10 10:56

let trz = Math.ceil(Math.tan(Math.PI / 180 * (180 - angle) /2 ) *w / 2);
这个计算有点复杂,先换算成弧度,然后和文字的长度以及长度换算成的角度相关,竟然是作用于Z轴的。

红影 发表于 2022-4-10 10:58

只有黑黑能做出这么复杂的帖子,对于这个帖子,我最多是不动脑筋地套用了{:4_173:}

马黑黑 发表于 2022-4-10 11:17

本帖最后由 马黑黑 于 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 11:20

红影 发表于 2022-4-10 10:58
只有黑黑能做出这么复杂的帖子,对于这个帖子,我最多是不动脑筋地套用了

理解其中可以理解的,这对将来的长进有作用

梦油 发表于 2022-4-10 11:27

马黑黑 发表于 2022-4-10 10:36
上午好!喝茶

你好,黑黑朋友。你的制作巧夺天工啊。

加林森 发表于 2022-4-10 11:33

老黑的这个制作好复杂,得慢慢学习了。这个画面真漂亮,很立体的制作。{:4_199:}

马黑黑 发表于 2022-4-10 12:00

加林森 发表于 2022-4-10 11:33
老黑的这个制作好复杂,得慢慢学习了。这个画面真漂亮,很立体的制作。

那个圆环多面体是立体的

马黑黑 发表于 2022-4-10 12:01

梦油 发表于 2022-4-10 11:27
你好,黑黑朋友。你的制作巧夺天工啊。

过奖了,一般般,过得去,差不多……

加林森 发表于 2022-4-10 12:36

马黑黑 发表于 2022-4-10 12:00
那个圆环多面体是立体的

嗯嗯,知道的。

梦油 发表于 2022-4-10 13:36

马黑黑 发表于 2022-4-10 12:01
过奖了,一般般,过得去,差不多……

羡慕、羡慕啊!

马黑黑 发表于 2022-4-10 13:39

梦油 发表于 2022-4-10 13:36
羡慕、羡慕啊!

{:5_108:}
页: [1] 2 3 4
查看完整版本: 花潮論壇歡迎您