马黑黑 发表于 2024-2-28 11:52

《千灯展卷》关键帧动画制作演示

本帖最后由 马黑黑 于 2024-2-28 15:24 编辑 <br /><br /><style>
.mama p { margin: 10px 0; }
.tzpa {
        margin: 10px auto 0;
        position: relative;
        width: 740px;
        height: 400px;
        background: url('https://638183.freep.cn/638183/t24/1/bbce.jpeg') no-repeat center/cover;
}
.tzpa svg { position: absolute; width: 740px; height: 400px; }

li-zi {
    position: absolute;
    width: 60px;
    height: 60px;
    background: url('https://638183.freep.cn/638183/t23/btn/y5j.png') no-repeat center/cover;
    offset-path: path('M0,200 Q390,-180 780,200');
    offset-distance: 0;
}

.ani { animation: move 10s linear infinite; }

.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; }

@keyframes move { to { offset-distance: 100%; } }
</style>

<div class="mama">

<p>《千灯展卷》一帖本在正月十五发布,当天没空错过了,后来不想再发出来,昨天空闲时翻来看看,觉得还是可以发的。下面谈谈动画部分的制作。</p>
<p>当时根据预设主题,相中如下这张图片:</p>

<div class="tzpa"></div>

<p>根据上面图片特点,我想设计一组五角星,按照图中的五角星的方向自左向右飞行。最快捷的路径设计是使用 offset-path,用三次贝塞尔曲线实现路径。这里以在 740*400 为例,路径从(0,200)起步,到(740,200)终止,控制点在(370,-180),路径效果示意如下:</p>
<div class="tzpa">
        <svg><path d="M0,200 Q370,-180 740,200" fill="none" stroke="green" stroke-width="4" /></svg>
</div>
<p>路径偏上了,没关系,使用该路径的元素是绝对定位,它们会以路径为导向,但可以偏移路径。现在,来写一个五角星元素,试着把它放到路径看看。先看代码:</p>

<div class='mum'>
<cl-cd data-idx="1"><span class="tGreen">&lt;!-- css&nbsp;: 粒子 --&gt;</span></cl-cd>
<cl-cd data-idx="2">li-zi {</cl-cd>
<cl-cd data-idx="3">    <span class="tBlue">position:</span> absolute;</cl-cd>
<cl-cd data-idx="4">    <span class="tBlue">width:</span> 60px;</cl-cd>
<cl-cd data-idx="5">    <span class="tBlue">height:</span> 60px;</cl-cd>
<cl-cd data-idx="6">    <span class="tBlue">background:</span> url(<span class="tMagenta">'https://638183.freep.cn/638183/t23/btn/y5j.png'</span>) no-repeat center/cover;</cl-cd>
<cl-cd data-idx="7">    <span class="tBlue">offset-path:</span> path(<span class="tMagenta">'M0,200 Q370,-180 700,200'</span>);</cl-cd>
<cl-cd data-idx="8">    <span class="tBlue">offset-distance:</span> 0;</cl-cd>
<cl-cd data-idx="9">}</cl-cd>
<cl-cd data-idx="10"><br></cl-cd>
<cl-cd data-idx="11"><span class="tGreen">&lt;!-- html&nbsp;: 粒子元素 --&gt;</span></cl-cd>
<cl-cd data-idx="12">&lt;li-zi&gt;&lt;/li-zi&gt;</cl-cd>
</div>

<p>效果:</p>
<div class="tzpa">
        <li-zi id="lz1"></li-zi>
        <svg><path d="M0,200 Q370,-180 740,200" fill="none" stroke="green" stroke-width="4" /></svg>
</div>

<p>借助 offset-distance,新加入的五角星现在在弧线路径的最左端,需要将其往下放,设置好top值就可以。绝对定位的元素left和top值均为0,现在把 top 值改为100看看:</p>
<p><button onclick="lz1.style.top='100px'" value="lz">点我改五角星top值为100px</button></p>
<p>没问题吧?最后的工作是用JS随机生成五角星,让它们在一定的top值区间布排,随机设置其大小以及运行关键帧动画的提前时间等等。以下完整示例,考虑到五角星的宽度占位,路径控制点和终点略作改动。看看代码和效果:</p>

<div class='mum'>
<cl-cd data-idx="1">&lt;style&gt;</cl-cd>
<cl-cd data-idx="2">#papa {</cl-cd>
<cl-cd data-idx="3">    <span class="tBlue">margin:</span> 10px auto 0;</cl-cd>
<cl-cd data-idx="4">    <span class="tBlue">position:</span> relative;</cl-cd>
<cl-cd data-idx="5">    <span class="tBlue">width:</span> 740px;</cl-cd>
<cl-cd data-idx="6">    <span class="tBlue">height:</span> 400px;</cl-cd>
<cl-cd data-idx="7">    <span class="tBlue">background:</span> url(<span class="tMagenta">'https://638183.freep.cn/638183/t24/1/bbce.jpeg'</span>) no-repeat center/cover;</cl-cd>
<cl-cd data-idx="8">}</cl-cd>
<cl-cd data-idx="9">li-zi {</cl-cd>
<cl-cd data-idx="10">    <span class="tBlue">position:</span> absolute;</cl-cd>
<cl-cd data-idx="11">    <span class="tBlue">width:</span> 60px;</cl-cd>
<cl-cd data-idx="12">    <span class="tBlue">height:</span> 60px;</cl-cd>
<cl-cd data-idx="13">    <span class="tBlue">background:</span> url(<span class="tMagenta">'https://638183.freep.cn/638183/t23/btn/y5j.png'</span>) no-repeat center/cover;</cl-cd>
<cl-cd data-idx="14">    <span class="tBlue">offset-path:</span> path(<span class="tMagenta">'M0,200 Q390,-180 780,200'</span>);</cl-cd>
<cl-cd data-idx="15">    <span class="tBlue">animation:</span> move 10s linear infinite;</cl-cd>
<cl-cd data-idx="16">}</cl-cd>
<cl-cd data-idx="17">@keyframes move { to { <span class="tBlue">offset-distance:</span> 100%; } }</cl-cd>
<cl-cd data-idx="18">&lt;/style&gt;</cl-cd>
<cl-cd data-idx="19"><br></cl-cd>
<cl-cd data-idx="20">&lt;div <span class="tRed">id</span>=<span class="tMagenta">"papa"</span>&gt;&lt;/div&gt;</cl-cd>
<cl-cd data-idx="21"><br></cl-cd>
<cl-cd data-idx="22">&lt;script&gt;</cl-cd>
<cl-cd data-idx="23"><span class="tRed">Array</span>.from({<span class="tBlue">length:</span> all=20}).forEach(star =&gt; {</cl-cd>
<cl-cd data-idx="24">    <span class="tBlue">var</span> size = 30 + <span class="tRed">Math</span>.floor(<span class="tRed">Math</span>.random() * 30);</cl-cd>
<cl-cd data-idx="25">    star = <span class="tRed">document</span>.createElement(<span class="tMagenta">'li-zi'</span>);</cl-cd>
<cl-cd data-idx="26">    star.style.cssText += `</cl-cd>
<cl-cd data-idx="27">      <span class="tBlue">left:</span> 0;</cl-cd>
<cl-cd data-idx="28">      <span class="tBlue">top:</span> ${<span class="tRed">Math</span>.random() * 140 + 60}px;</cl-cd>
<cl-cd data-idx="29">      <span class="tBlue">width:</span> ${size}px;</cl-cd>
<cl-cd data-idx="30">      <span class="tBlue">height:</span> ${size}px;</cl-cd>
<cl-cd data-idx="31">      <span class="tBlue">opacity:</span> ${<span class="tRed">Math</span>.random() * 0.4 + 0.4};</cl-cd>
<cl-cd data-idx="32">      <span class="tBlue">animation-delay:</span> -${<span class="tRed">Math</span>.random() * 10}s, -${<span class="tRed">Math</span>.random() * 5}s;</cl-cd>
<cl-cd data-idx="33">    `;</cl-cd>
<cl-cd data-idx="34">    papa.prepend(star);</cl-cd>
<cl-cd data-idx="35">});</cl-cd>
<cl-cd data-idx="36">&lt;/script&gt;</cl-cd>
</div>

<div id="papa" class="tzpa"></div>

<p>说明:① 演示2和3的绿色路径是使用了svg画出来的,演示4已经去掉了svg,所以看不到路径;② 五角星溢出帖子没有做处理是为了演示五角星运行的完整过程,实际应用时可根据需要设置#papa选择器的overflow 属性 为 hidden;③ 和帖子《千灯展卷》相比,这里的五角星没有旋转,若需要旋转,可以修改@keyframes动画,帖子中是给 li-zi 选择器添加另外加一个关键帧动画。</p>

</div>

<script>
Array.from({length: all=20}).forEach(star => {
        var size = 30 + Math.floor(Math.random() * 30);
        star = document.createElement('li-zi');
        star.className = 'ani';
        star.style.cssText += `
                left: 0;
                top: ${Math.random() * 140 + 60}px;
                width: ${size}px;
                height: ${size}px;
                opacity: ${Math.random() * 0.4 + 0.4};
                animation-delay: -${Math.random() * 10}s, -${Math.random() * 5}s;
        `;
        papa.prepend(star);
});
</script>

樵歌 发表于 2024-2-28 14:44

同学们,精髓来了,过时不补,下面我点名了@小辣椒 @红影 @南无月 @朵拉 @醉美水芙蓉 @某甲,某乙,某吃瓜客

红影 发表于 2024-2-28 16:01

很详细的解说,这么漂亮的星星银河就这么被黑黑制作出来了{:4_199:}

红影 发表于 2024-2-28 16:02

樵歌 发表于 2024-2-28 14:44
同学们,精髓来了,过时不补,下面我点名了@小辣椒 @红影 @南无月 @朵拉 @醉美水芙蓉 @某甲,某乙,某吃瓜 ...

我很认真地学习了啊{:4_173:}

马黑黑 发表于 2024-2-28 17:47

红影 发表于 2024-2-28 16:01
很详细的解说,这么漂亮的星星银河就这么被黑黑制作出来了

貌似而已

马黑黑 发表于 2024-2-28 17:47

樵歌 发表于 2024-2-28 14:44
同学们,精髓来了,过时不补,下面我点名了@小辣椒 @红影 @南无月 @朵拉 @醉美水芙蓉 @某甲,某乙,某吃瓜 ...

{:4_190:}

樵歌 发表于 2024-2-28 20:02

红影 发表于 2024-2-28 16:02
我很认真地学习了啊

学霸之一来了{:4_173:}

小辣椒 发表于 2024-2-28 20:27

我仔细看了二遍,黑黑你这个动画制作开始学习了吗?看起来有难度的,小辣椒缺课肯定又跟不上了

小辣椒 发表于 2024-2-28 20:28

但动画效果肯定会很漂亮的

小辣椒 发表于 2024-2-28 20:30

这个不是用路径了,直接图片比玩路径轻松一点{:4_172:}

马黑黑 发表于 2024-2-28 20:35

小辣椒 发表于 2024-2-28 20:27
我仔细看了二遍,黑黑你这个动画制作开始学习了吗?看起来有难度的,小辣椒缺课肯定又跟不上了

这个很早以前就用上了

马黑黑 发表于 2024-2-28 20:36

小辣椒 发表于 2024-2-28 20:28
但动画效果肯定会很漂亮的

可以的

马黑黑 发表于 2024-2-28 20:36

小辣椒 发表于 2024-2-28 20:30
这个不是用路径了,直接图片比玩路径轻松一点

这是用偏移路径的

朵拉 发表于 2024-2-28 21:15

樵歌 发表于 2024-2-28 14:44
同学们,精髓来了,过时不补,下面我点名了@小辣椒 @红影 @南无月 @朵拉 @醉美水芙蓉 @某甲,某乙,某吃瓜 ...

朵拉收到,樵歌收礼哈{:4_190:}

红影 发表于 2024-2-28 22:41

马黑黑 发表于 2024-2-28 17:47
貌似而已

十分漂亮的制作{:4_199:}

红影 发表于 2024-2-28 22:54

樵歌 发表于 2024-2-28 20:02
学霸之一来了

算不上啊,而且有点忙,需要等空了再跟着学习呢{:4_173:}

马黑黑 发表于 2024-2-28 23:17

红影 发表于 2024-2-28 22:41
十分漂亮的制作

蟹蟹

南无月 发表于 2024-2-29 17:04

从这贴看出老师做贴顺序,先看图再根据图设计动画。。{:4_173:}
这个五星的彩虹桥跟后面图片好搭呀,动静相宜。

马黑黑 发表于 2024-2-29 18:31

南无月 发表于 2024-2-29 17:04
从这贴看出老师做贴顺序,先看图再根据图设计动画。。
这个五星的彩虹桥跟后面图片好搭呀,动静 ...

思路可以是很多种的。你要表达什么,素材要去准备,可以先找音乐,也可以先设计图片,这些都不论。创作过程会调整一些先前的计划,这也正常。

南无月 发表于 2024-2-29 18:38

马黑黑 发表于 2024-2-29 18:31
思路可以是很多种的。你要表达什么,素材要去准备,可以先找音乐,也可以先设计图片,这些都不论。创作过 ...

我现在就是不由自主,
先找个好看的美人儿。
再找个不搭的背景,因为这背景要换好多次才最终定下。。
背景图做个大概后,去老师贴子里挑效果。。。
开始用编辑器看整体。。。东调西调
等把效果调得差不多。。
再定标题字,根据标题字找歌,找歌词。。
再回到背景图排标题和字。。
{:4_170:}
现在看来,我出一贴艰难之极。。

页: [1] 2
查看完整版本: 《千灯展卷》关键帧动画制作演示