马黑黑 发表于 2024-3-31 23:50

canvas动态画圆示例

<style>
#canv { display: block; margin: 20px auto; background: linear-gradient(tan, lightblue); }
</style>

<canvas id="canv" width="200" height="200" style=""></canvas>

<script>
let ctx = canv.getContext('2d');
let deg = 0, raf;

let drawCircle = (deg) => {
        ctx.clearRect(0,0,200,200);
        drawText(Math.floor(deg * 100 / 360) + '%');
        ctx.save();
        ctx.strokeStyle = 'rgba(56,104,32,.8)';
        ctx.lineWidth = 8;
        ctx.lineCap = 'round';
        ctx.beginPath();
        ctx.arc(100, 100, 90, 0, deg * Math.PI/180);
        ctx.stroke();
        ctx.restore();
};

let drawText = (text) => {
        ctx.save();
        ctx.strokeStyle = 'green';
        ctx.font = 'normal 35px sans-serif';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        ctx.strokeText(text,100,100);
        ctx.restore();
};

let render = () => {
        drawCircle(deg);
        deg += 0.5;
        raf = requestAnimationFrame(render);
        if(deg > 360) raf = cancelAnimationFrame(raf);
};

render();

canv.onclick = () => {
        console.log(raf, deg);
        if(raf) return;
        deg = 0;
        render();
};

</script>

马黑黑 发表于 2024-3-31 23:51

<h2>代码:</h2>
<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; }
</style>
<div class='mum'>
<cl-cd data-idx="1">&lt;<span class="tDarkRed">style</span>&gt;</cl-cd>
<cl-cd data-idx="2">#canv { <span class="tBlue">display:</span> block; <span class="tBlue">margin:</span> 20px auto; <span class="tBlue">background:</span> linear-gradient(tan, lightblue); }</cl-cd>
<cl-cd data-idx="3">&lt;<span class="tDarkRed">/style</span>&gt;</cl-cd>
<cl-cd data-idx="4">&nbsp;</cl-cd>
<cl-cd data-idx="5">&lt;<span class="tDarkRed">canvas</span> <span class="tRed">id</span>=<span class="tMagenta">"canv"</span> width=<span class="tMagenta">"200"</span> height=<span class="tMagenta">"200"</span> style=<span class="tMagenta">""</span>&gt;&lt;<span class="tDarkRed">/canvas</span>&gt;</cl-cd>
<cl-cd data-idx="6">&nbsp;</cl-cd>
<cl-cd data-idx="7">&lt;<span class="tDarkRed">script</span>&gt;</cl-cd>
<cl-cd data-idx="8"><span class="tBlue">let</span> ctx = canv.getContext(<span class="tMagenta">'2d'</span>); </cl-cd>
<cl-cd data-idx="9"><span class="tBlue">let</span> deg = 0, raf;</cl-cd>
<cl-cd data-idx="10">&nbsp;</cl-cd>
<cl-cd data-idx="11"><span class="tBlue">let</span> drawCircle = (deg) =&gt; {</cl-cd>
<cl-cd data-idx="12">&nbsp; &nbsp; ctx.clearRect(0,0,200,200);</cl-cd>
<cl-cd data-idx="13">&nbsp; &nbsp; drawText(<span class="tRed">Math</span>.floor(deg * 100 / 360) + <span class="tMagenta">'%'</span>);</cl-cd>
<cl-cd data-idx="14">&nbsp; &nbsp; ctx.save();</cl-cd>
<cl-cd data-idx="15">&nbsp; &nbsp; ctx.strokeStyle = <span class="tMagenta">'rgba(56,104,32,.8)'</span>;</cl-cd>
<cl-cd data-idx="16">&nbsp; &nbsp; ctx.lineWidth = 8;</cl-cd>
<cl-cd data-idx="17">&nbsp; &nbsp; ctx.lineCap = <span class="tMagenta">'round'</span>;</cl-cd>
<cl-cd data-idx="18">&nbsp; &nbsp; ctx.beginPath();</cl-cd>
<cl-cd data-idx="19">&nbsp; &nbsp; ctx.arc(100, 100, 90, 0, deg * <span class="tRed">Math</span>.PI/180);</cl-cd>
<cl-cd data-idx="20">&nbsp; &nbsp; ctx.stroke();</cl-cd>
<cl-cd data-idx="21">&nbsp; &nbsp; ctx.restore();</cl-cd>
<cl-cd data-idx="22">};</cl-cd>
<cl-cd data-idx="23">&nbsp;</cl-cd>
<cl-cd data-idx="24"><span class="tBlue">let</span> drawText = (text) =&gt; {</cl-cd>
<cl-cd data-idx="25">&nbsp; &nbsp; ctx.save();</cl-cd>
<cl-cd data-idx="26">&nbsp; &nbsp; ctx.strokeStyle = <span class="tMagenta">'green'</span>;</cl-cd>
<cl-cd data-idx="27">&nbsp; &nbsp; ctx.font = <span class="tMagenta">'normal 35px sans-serif'</span>;</cl-cd>
<cl-cd data-idx="28">&nbsp; &nbsp; ctx.textAlign = <span class="tMagenta">'center'</span>;</cl-cd>
<cl-cd data-idx="29">&nbsp; &nbsp; ctx.textBaseline = <span class="tMagenta">'middle'</span>;</cl-cd>
<cl-cd data-idx="30">&nbsp; &nbsp; ctx.strokeText(text,100,100);</cl-cd>
<cl-cd data-idx="31">&nbsp; &nbsp; ctx.restore();</cl-cd>
<cl-cd data-idx="32">};</cl-cd>
<cl-cd data-idx="33">&nbsp;</cl-cd>
<cl-cd data-idx="34"><span class="tBlue">let</span> render = () =&gt; {</cl-cd>
<cl-cd data-idx="35">&nbsp; &nbsp; drawCircle(deg);</cl-cd>
<cl-cd data-idx="36">&nbsp; &nbsp; deg += 0.5;</cl-cd>
<cl-cd data-idx="37">&nbsp; &nbsp; raf = requestAnimationFrame(render);</cl-cd>
<cl-cd data-idx="38">&nbsp; &nbsp; <span class="tBlue">if</span>(deg &gt; 360) raf = cancelAnimationFrame(raf);</cl-cd>
<cl-cd data-idx="39">};</cl-cd>
<cl-cd data-idx="40">&nbsp;</cl-cd>
<cl-cd data-idx="41">render();</cl-cd>
<cl-cd data-idx="42">&nbsp;</cl-cd>
<cl-cd data-idx="43">canv.onclick = () =&gt; {</cl-cd>
<cl-cd data-idx="44">&nbsp; &nbsp; console.log(raf, deg);</cl-cd>
<cl-cd data-idx="45">&nbsp; &nbsp; <span class="tBlue">if</span>(raf) <span class="tBlue">return</span>;</cl-cd>
<cl-cd data-idx="46">&nbsp; &nbsp; deg = 0;</cl-cd>
<cl-cd data-idx="47">&nbsp; &nbsp; render();</cl-cd>
<cl-cd data-idx="48">};</cl-cd>
<cl-cd data-idx="49">&nbsp;</cl-cd>
<cl-cd data-idx="50">&lt;<span class="tDarkRed">/script</span>&gt;</cl-cd>
</div>


马黑黑 发表于 2024-3-31 23:52

一楼,画完后,点击画布,会触发重绘事件

马黑黑 发表于 2024-4-1 00:04

绘制文本函数对文本的定位值得学习参考:
let drawText = (text) => {
      ctx.save();
      ctx.strokeStyle = 'green';
      ctx.font = 'normal 35px sans-serif';
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';
      ctx.strokeText(text,100,100);
      ctx.restore();
};


红色行:设置文本水平方向居中。它以文本开始的 x 坐标为界,一半在 x 的坐标,一半在 x 的右边;
红紫色行:设置文本垂直方向居中。此时,文本基线横穿文本(基线在 坐标交叉点 o 即圆心往水平方向的延长线);
蓝色行:绘制描边文本,参数 text 为要绘制的文本,(100,100)分别为文本绘制点的xy坐标值。

马黑黑 发表于 2024-4-1 00:04

绘制文本函数对文本的定位值得学习参考:
let drawText = (text) => {
        ctx.save();
        ctx.strokeStyle = 'green';
        ctx.font = 'normal 35px sans-serif';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        ctx.strokeText(text,100,100);
        ctx.restore();
};


红色行:设置文本水平方向居中。它以文本开始的 x 坐标为界,一半在 x 的坐标,一半在 x 的右边;
红紫色行:设置文本垂直方向居中。此时,文本基线横穿文本(基线在 坐标交叉点 o 即圆心往水平方向的延长线);
蓝色行:绘制描边文本,参数 text 为要绘制的文本,(100,100)分别为文本绘制点的xy坐标值。

马黑黑 发表于 2024-4-1 00:05

4、5楼一炮俩响{:4_189:}

红影 发表于 2024-4-1 09:34

这个同步绘制圆环和数字文本,完全步调一致{:4_187:}

红影 发表于 2024-4-1 09:36

居中的设置,让数字在分别是不同位数的时候能够自动调整呢。

红影 发表于 2024-4-1 09:38

试了一下让deg += 0.05;,画得就慢了许多{:4_173:}

马黑黑 发表于 2024-4-1 12:28

红影 发表于 2024-4-1 09:38
试了一下让deg += 0.05;,画得就慢了许多

当然。这是步幅系数,每次增加多少度。

马黑黑 发表于 2024-4-1 12:29

红影 发表于 2024-4-1 09:36
居中的设置,让数字在分别是不同位数的时候能够自动调整呢。

原理和CSS的文本设置一样,不同的是水平居中,画布的设置特性有所不同

南无月 发表于 2024-4-1 18:09

马黑黑 发表于 2024-3-31 23:52
一楼,画完后,点击画布,会触发重绘事件
好哒,画得又快又好又圆{:4_170:}
看着完美,十分治愈。。。

南无月 发表于 2024-4-1 18:10

马黑黑 发表于 2024-4-1 00:05
4、5楼一炮俩响

{:4_170:}你电脑也会卡一下?不可思议

南无月 发表于 2024-4-1 18:11

马黑黑 发表于 2024-4-1 00:04
绘制文本函数对文本的定位值得学习参考:
let drawText = (text) => {
        ctx.save();


{:4_170:}等会试着看看能不能看懂。
这是个新的演示

马黑黑 发表于 2024-4-1 18:11

南无月 发表于 2024-4-1 18:10
你电脑也会卡一下?不可思议

这可不是卡哟,速度好快的

马黑黑 发表于 2024-4-1 18:12

南无月 发表于 2024-4-1 18:11
等会试着看看能不能看懂。
这是个新的演示

一点一点拆分来看容易看懂

小文 发表于 2024-4-1 19:18

真好,正想它就有了,赶快收藏下备用。问好先生!

南无月 发表于 2024-4-1 20:13

马黑黑 发表于 2024-4-1 18:11
这可不是卡哟,速度好快的

小白无法体会老黑的速度。。
就是太快了,敲一下出两贴。。神十八{:4_170:}

南无月 发表于 2024-4-1 20:14

马黑黑 发表于 2024-4-1 18:12
一点一点拆分来看容易看懂

冰箱搁那还看得懂是冰箱,
拆成零件肯定不知道哪儿是哪儿{:4_170:}

红影 发表于 2024-4-1 20:57

马黑黑 发表于 2024-4-1 12:28
当然。这是步幅系数,每次增加多少度。

无论快慢,看着都是连续的呢。
页: [1] 2 3 4
查看完整版本: canvas动态画圆示例