马黑黑 发表于 2024-5-9 17:26

canvas画布:让立体正五角星也转起来

<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; }
.tMid { text-align: center; margin: 12px 0; }
</style>

<h2>效果</h2>
<p class="tMid"><canvas id="canv" width="400" height="400"></canvas></p>
<h2>代码</h2>
<div class='mum'>
<cl-cd data-idx="1">&lt;<span class="tDarkRed">canvas</span> <span class="tRed">id</span>=<span class="tMagenta">"canv"</span> width=<span class="tMagenta">"400"</span> height=<span class="tMagenta">"400"</span>&gt;&lt;<span class="tDarkRed">/canvas</span>&gt;</cl-cd>
<cl-cd data-idx="2"> </cl-cd>
<cl-cd data-idx="3">&lt;<span class="tDarkRed">script</span>&gt;</cl-cd>
<cl-cd data-idx="4"> </cl-cd>
<cl-cd data-idx="5"><span class="tBlue">var</span> ctx = canv.getContext(<span class="tMagenta">'2d'</span>);</cl-cd>
<cl-cd data-idx="6"><span class="tBlue">var</span> size = canv.width / 2, r1 = size - 10, r2 = r1 * 2/5, points = [];</cl-cd>
<cl-cd data-idx="7"><span class="tBlue">var</span> deg = 0, step = 0.5, mov = true, raf = null;</cl-cd>
<cl-cd data-idx="8"> </cl-cd>
<cl-cd data-idx="9"><span class="tBlue">for</span>(<span class="tBlue">var</span> i = 0; i &lt; 5; i ++) {</cl-cd>
<cl-cd data-idx="10">    <span class="tBlue">var</span> x1 = <span class="tRed">Math</span>.cos((18 + i * 72) / 180 * <span class="tRed">Math</span>.PI) * r1 + size,</cl-cd>
<cl-cd data-idx="11">      y1 = -<span class="tRed">Math</span>.sin((18 + i * 72) / 180 * <span class="tRed">Math</span>.PI) * r1 + size,</cl-cd>
<cl-cd data-idx="12">      x2 = <span class="tRed">Math</span>.cos((54 + i * 72) / 180 * <span class="tRed">Math</span>.PI) * r2 + size,</cl-cd>
<cl-cd data-idx="13">      y2 = -<span class="tRed">Math</span>.sin((54 + i * 72) / 180 * <span class="tRed">Math</span>.PI) * r2 + size;</cl-cd>
<cl-cd data-idx="14">    points.push({x1: x1, y1: y1, x2: x2, y2: y2});</cl-cd>
<cl-cd data-idx="15">}</cl-cd>
<cl-cd data-idx="16"> </cl-cd>
<cl-cd data-idx="17"><span class="tBlue">var</span> draw5star = () =&gt; {</cl-cd>
<cl-cd data-idx="18">    <span class="tBlue">for</span>(<span class="tBlue">var</span> j = 0; j &lt; 5; j++) {</cl-cd>
<cl-cd data-idx="19">      ctx.beginPath();</cl-cd>
<cl-cd data-idx="20">      ctx.fillStyle = <span class="tMagenta">'red'</span>;</cl-cd>
<cl-cd data-idx="21">      ctx.moveTo(points.x1, points.y1);</cl-cd>
<cl-cd data-idx="22">      ctx.lineTo(size, size);</cl-cd>
<cl-cd data-idx="23">      ctx.lineTo(points.x2, points.y2);</cl-cd>
<cl-cd data-idx="24">      ctx.lineTo(points.x1, points.y1);</cl-cd>
<cl-cd data-idx="25">      ctx.fill();</cl-cd>
<cl-cd data-idx="26">      ctx.beginPath();</cl-cd>
<cl-cd data-idx="27">      ctx.fillStyle = <span class="tMagenta">'darkred'</span>;</cl-cd>
<cl-cd data-idx="28">      <span class="tBlue">var</span> k = j &gt; 0 ? j - 1&nbsp;: 4;</cl-cd>
<cl-cd data-idx="29">      ctx.moveTo(points.x1, points.y1);</cl-cd>
<cl-cd data-idx="30">      ctx.lineTo(size, size);</cl-cd>
<cl-cd data-idx="31">      ctx.lineTo(points.x2, points.y2);</cl-cd>
<cl-cd data-idx="32">      ctx.moveTo(points.x1, points.y1);</cl-cd>
<cl-cd data-idx="33">      ctx.fill();</cl-cd>
<cl-cd data-idx="34">    }</cl-cd>
<cl-cd data-idx="35">};</cl-cd>
<cl-cd data-idx="36">&nbsp;</cl-cd>
<cl-cd data-idx="37"><span class="tBlue">var</span> rot = () =&gt; {</cl-cd>
<cl-cd data-idx="38">&nbsp; &nbsp; ctx.clearRect(0, 0, canv.width, canv.height);</cl-cd>
<cl-cd data-idx="39">&nbsp; &nbsp; ctx.save();</cl-cd>
<cl-cd data-idx="40">&nbsp; &nbsp; ctx.translate(size, size);</cl-cd>
<cl-cd data-idx="41">&nbsp; &nbsp; ctx.rotate(deg * <span class="tRed">Math</span>.PI / 180);</cl-cd>
<cl-cd data-idx="42">&nbsp; &nbsp; ctx.translate(-size, -size);</cl-cd>
<cl-cd data-idx="43">&nbsp; &nbsp; draw5star();</cl-cd>
<cl-cd data-idx="44">&nbsp; &nbsp; ctx.restore();</cl-cd>
<cl-cd data-idx="45">&nbsp; &nbsp; deg = (deg + step) % 360;</cl-cd>
<cl-cd data-idx="46">&nbsp; &nbsp; mov ? raf = requestAnimationFrame(rot) : cancelAnimationFrame(raf);</cl-cd>
<cl-cd data-idx="47">};</cl-cd>
<cl-cd data-idx="48">&nbsp;</cl-cd>
<cl-cd data-idx="49">canv.onclick = () =&gt; {</cl-cd>
<cl-cd data-idx="50">&nbsp; &nbsp; mov = !mov;</cl-cd>
<cl-cd data-idx="51">&nbsp; &nbsp; rot();</cl-cd>
<cl-cd data-idx="52">};</cl-cd>
<cl-cd data-idx="53">&nbsp;</cl-cd>
<cl-cd data-idx="54">rot();</cl-cd>
<cl-cd data-idx="55"> </cl-cd>
<cl-cd data-idx="56">&lt;<span class="tDarkRed">/script</span>&gt;</cl-cd>
</div>
<script>

var ctx = canv.getContext('2d');
var size = canv.width / 2, r1 = size - 10, r2 = r1 * 2/5, points = [];
var deg = 0, step = 0.5, mov = true, raf = null;

for(var i = 0; i < 5; i ++) {
    var x1 = Math.cos((18 + i * 72) / 180 * Math.PI) * r1 + size,
      y1 = -Math.sin((18 + i * 72) / 180 * Math.PI) * r1 + size,
      x2 = Math.cos((54 + i * 72) / 180 * Math.PI) * r2 + size,
      y2 = -Math.sin((54 + i * 72) / 180 * Math.PI) * r2 + size;
    points.push({x1: x1, y1: y1, x2: x2, y2: y2});
}

var draw5star = () => {
    for(var j = 0; j < 5; j++) {
      ctx.beginPath();
      ctx.fillStyle = 'red';
      ctx.moveTo(points.x1, points.y1);
      ctx.lineTo(size, size);
      ctx.lineTo(points.x2, points.y2);
      ctx.lineTo(points.x1, points.y1);
      ctx.fill();
      ctx.beginPath();
      ctx.fillStyle = 'darkred';
      var k = j > 0 ? j - 1 : 4;
      ctx.moveTo(points.x1, points.y1);
      ctx.lineTo(size, size);
      ctx.lineTo(points.x2, points.y2);
      ctx.moveTo(points.x1, points.y1);
      ctx.fill();
    }
};

var rot = () => {
        ctx.clearRect(0, 0, canv.width, canv.height);
        ctx.save();
        ctx.translate(size, size);
        ctx.rotate(deg * Math.PI / 180);
        ctx.translate(-size, -size);
        draw5star();
        ctx.restore();
        deg = (deg + step) % 360;
        mov ? raf = requestAnimationFrame(rot) : cancelAnimationFrame(raf);
};

canv.onclick = () => {
        mov = !mov;
        rot();
};

rot();

</script>

马黑黑 发表于 2024-5-9 17:28

这个没有做成类封装对象,适合画单个五角星。需要扩展的话,还是要将五角星封装成class的好。

动画可以点击画布开启/暂停

南无月 发表于 2024-5-9 17:33

在画布中用代码实现旋转,跟时钟一样的边擦边画吧。

南无月 发表于 2024-5-9 17:34

这个旋转还自带开关。。比时钟更高级。。。

马黑黑 发表于 2024-5-9 18:29

南无月 发表于 2024-5-9 17:34
这个旋转还自带开关。。比时钟更高级。。。

时钟有点就能走

马黑黑 发表于 2024-5-9 18:29

南无月 发表于 2024-5-9 17:33
在画布中用代码实现旋转,跟时钟一样的边擦边画吧。

canvas动画都是如此

南无月 发表于 2024-5-9 19:59

马黑黑 发表于 2024-5-9 18:29
时钟有点就能走

时钟即时时间就很神奇。。{:4_173:}

南无月 发表于 2024-5-9 20:00

马黑黑 发表于 2024-5-9 18:29
canvas动画都是如此

{:4_173:}看来当时学那套时钟教锃是基础课。。

红影 发表于 2024-5-9 20:09

这个更好,还把半径设置和转动step都直接设好了,也比前面那个五角星更漂亮呢{:4_199:}

马黑黑 发表于 2024-5-9 20:09

南无月 发表于 2024-5-9 20:00
看来当时学那套时钟教锃是基础课。。

非常基础,有必要多看几遍

马黑黑 发表于 2024-5-9 20:09

红影 发表于 2024-5-9 20:09
这个更好,还把半径设置和转动step都直接设好了,也比前面那个五角星更漂亮呢

这个是模拟3d的,那边那个是纯2d的

马黑黑 发表于 2024-5-9 20:10

南无月 发表于 2024-5-9 19:59
时钟即时时间就很神奇。。

{:4_172:}

红影 发表于 2024-5-9 20:10

这个还是黑黑最后那个立体五角星的画法,另半边也是直接画的那个{:4_187:}

马黑黑 发表于 2024-5-9 20:12

红影 发表于 2024-5-9 20:10
这个还是黑黑最后那个立体五角星的画法,另半边也是直接画的那个

对的

南无月 发表于 2024-5-9 20:18

马黑黑 发表于 2024-5-9 20:09
非常基础,有必要多看几遍
{:4_170:}还好从头跟到尾,忘了跟到第几课开始逃学了

马黑黑 发表于 2024-5-9 20:19

南无月 发表于 2024-5-9 20:18
还好从头跟到尾,忘了跟到第几课开始逃学了

难度超出了幼儿园小盆友的接受范围

南无月 发表于 2024-5-9 20:20

马黑黑 发表于 2024-5-9 20:10


{:4_173:}我盯着那代码看了好久,心里一直想,这几行就能让时钟运行到天荒地老?真的太妙了。。

南无月 发表于 2024-5-9 20:27

马黑黑 发表于 2024-5-9 20:19
难度超出了幼儿园小盆友的接受范围


老师教的,要知难而退{:4_170:}

马黑黑 发表于 2024-5-9 21:19

南无月 发表于 2024-5-9 20:27
老师教的,要知难而退

挺好挺好

马黑黑 发表于 2024-5-9 21:22

南无月 发表于 2024-5-9 20:20
我盯着那代码看了好久,心里一直想,这几行就能让时钟运行到天荒地老?真的太妙了。。

前提是有电、电脑正常、浏览器不崩溃
页: [1] 2 3 4 5 6 7 8
查看完整版本: canvas画布:让立体正五角星也转起来