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"><<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>><<span class="tDarkRed">/canvas</span>></cl-cd>
<cl-cd data-idx="2"> </cl-cd>
<cl-cd data-idx="3"><<span class="tDarkRed">script</span>></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 < 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 = () => {</cl-cd>
<cl-cd data-idx="18"> <span class="tBlue">for</span>(<span class="tBlue">var</span> j = 0; j < 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 > 0 ? j - 1 : 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"> </cl-cd>
<cl-cd data-idx="37"><span class="tBlue">var</span> rot = () => {</cl-cd>
<cl-cd data-idx="38"> ctx.clearRect(0, 0, canv.width, canv.height);</cl-cd>
<cl-cd data-idx="39"> ctx.save();</cl-cd>
<cl-cd data-idx="40"> ctx.translate(size, size);</cl-cd>
<cl-cd data-idx="41"> ctx.rotate(deg * <span class="tRed">Math</span>.PI / 180);</cl-cd>
<cl-cd data-idx="42"> ctx.translate(-size, -size);</cl-cd>
<cl-cd data-idx="43"> draw5star();</cl-cd>
<cl-cd data-idx="44"> ctx.restore();</cl-cd>
<cl-cd data-idx="45"> deg = (deg + step) % 360;</cl-cd>
<cl-cd data-idx="46"> mov ? raf = requestAnimationFrame(rot) : cancelAnimationFrame(raf);</cl-cd>
<cl-cd data-idx="47">};</cl-cd>
<cl-cd data-idx="48"> </cl-cd>
<cl-cd data-idx="49">canv.onclick = () => {</cl-cd>
<cl-cd data-idx="50"> mov = !mov;</cl-cd>
<cl-cd data-idx="51"> rot();</cl-cd>
<cl-cd data-idx="52">};</cl-cd>
<cl-cd data-idx="53"> </cl-cd>
<cl-cd data-idx="54">rot();</cl-cd>
<cl-cd data-idx="55"> </cl-cd>
<cl-cd data-idx="56"><<span class="tDarkRed">/script</span>></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>
这个没有做成类封装对象,适合画单个五角星。需要扩展的话,还是要将五角星封装成class的好。
动画可以点击画布开启/暂停 在画布中用代码实现旋转,跟时钟一样的边擦边画吧。
这个旋转还自带开关。。比时钟更高级。。。
南无月 发表于 2024-5-9 17:34
这个旋转还自带开关。。比时钟更高级。。。
时钟有点就能走 南无月 发表于 2024-5-9 17:33
在画布中用代码实现旋转,跟时钟一样的边擦边画吧。
canvas动画都是如此 马黑黑 发表于 2024-5-9 18:29
时钟有点就能走
时钟即时时间就很神奇。。{:4_173:} 马黑黑 发表于 2024-5-9 18:29
canvas动画都是如此
{:4_173:}看来当时学那套时钟教锃是基础课。。 这个更好,还把半径设置和转动step都直接设好了,也比前面那个五角星更漂亮呢{:4_199:} 南无月 发表于 2024-5-9 20:00
看来当时学那套时钟教锃是基础课。。
非常基础,有必要多看几遍 红影 发表于 2024-5-9 20:09
这个更好,还把半径设置和转动step都直接设好了,也比前面那个五角星更漂亮呢
这个是模拟3d的,那边那个是纯2d的 南无月 发表于 2024-5-9 19:59
时钟即时时间就很神奇。。
{:4_172:} 这个还是黑黑最后那个立体五角星的画法,另半边也是直接画的那个{:4_187:} 红影 发表于 2024-5-9 20:10
这个还是黑黑最后那个立体五角星的画法,另半边也是直接画的那个
对的 马黑黑 发表于 2024-5-9 20:09
非常基础,有必要多看几遍
{:4_170:}还好从头跟到尾,忘了跟到第几课开始逃学了 南无月 发表于 2024-5-9 20:18
还好从头跟到尾,忘了跟到第几课开始逃学了
难度超出了幼儿园小盆友的接受范围 马黑黑 发表于 2024-5-9 20:10
{:4_173:}我盯着那代码看了好久,心里一直想,这几行就能让时钟运行到天荒地老?真的太妙了。。 马黑黑 发表于 2024-5-9 20:19
难度超出了幼儿园小盆友的接受范围
老师教的,要知难而退{:4_170:} 南无月 发表于 2024-5-9 20:27
老师教的,要知难而退
挺好挺好 南无月 发表于 2024-5-9 20:20
我盯着那代码看了好久,心里一直想,这几行就能让时钟运行到天荒地老?真的太妙了。。
前提是有电、电脑正常、浏览器不崩溃