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>
<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"><<span class="tDarkRed">style</span>></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"><<span class="tDarkRed">/style</span>></cl-cd>
<cl-cd data-idx="4"> </cl-cd>
<cl-cd data-idx="5"><<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>><<span class="tDarkRed">/canvas</span>></cl-cd>
<cl-cd data-idx="6"> </cl-cd>
<cl-cd data-idx="7"><<span class="tDarkRed">script</span>></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"> </cl-cd>
<cl-cd data-idx="11"><span class="tBlue">let</span> drawCircle = (deg) => {</cl-cd>
<cl-cd data-idx="12"> ctx.clearRect(0,0,200,200);</cl-cd>
<cl-cd data-idx="13"> drawText(<span class="tRed">Math</span>.floor(deg * 100 / 360) + <span class="tMagenta">'%'</span>);</cl-cd>
<cl-cd data-idx="14"> ctx.save();</cl-cd>
<cl-cd data-idx="15"> ctx.strokeStyle = <span class="tMagenta">'rgba(56,104,32,.8)'</span>;</cl-cd>
<cl-cd data-idx="16"> ctx.lineWidth = 8;</cl-cd>
<cl-cd data-idx="17"> ctx.lineCap = <span class="tMagenta">'round'</span>;</cl-cd>
<cl-cd data-idx="18"> ctx.beginPath();</cl-cd>
<cl-cd data-idx="19"> ctx.arc(100, 100, 90, 0, deg * <span class="tRed">Math</span>.PI/180);</cl-cd>
<cl-cd data-idx="20"> ctx.stroke();</cl-cd>
<cl-cd data-idx="21"> ctx.restore();</cl-cd>
<cl-cd data-idx="22">};</cl-cd>
<cl-cd data-idx="23"> </cl-cd>
<cl-cd data-idx="24"><span class="tBlue">let</span> drawText = (text) => {</cl-cd>
<cl-cd data-idx="25"> ctx.save();</cl-cd>
<cl-cd data-idx="26"> ctx.strokeStyle = <span class="tMagenta">'green'</span>;</cl-cd>
<cl-cd data-idx="27"> ctx.font = <span class="tMagenta">'normal 35px sans-serif'</span>;</cl-cd>
<cl-cd data-idx="28"> ctx.textAlign = <span class="tMagenta">'center'</span>;</cl-cd>
<cl-cd data-idx="29"> ctx.textBaseline = <span class="tMagenta">'middle'</span>;</cl-cd>
<cl-cd data-idx="30"> ctx.strokeText(text,100,100);</cl-cd>
<cl-cd data-idx="31"> ctx.restore();</cl-cd>
<cl-cd data-idx="32">};</cl-cd>
<cl-cd data-idx="33"> </cl-cd>
<cl-cd data-idx="34"><span class="tBlue">let</span> render = () => {</cl-cd>
<cl-cd data-idx="35"> drawCircle(deg);</cl-cd>
<cl-cd data-idx="36"> deg += 0.5;</cl-cd>
<cl-cd data-idx="37"> raf = requestAnimationFrame(render);</cl-cd>
<cl-cd data-idx="38"> <span class="tBlue">if</span>(deg > 360) raf = cancelAnimationFrame(raf);</cl-cd>
<cl-cd data-idx="39">};</cl-cd>
<cl-cd data-idx="40"> </cl-cd>
<cl-cd data-idx="41">render();</cl-cd>
<cl-cd data-idx="42"> </cl-cd>
<cl-cd data-idx="43">canv.onclick = () => {</cl-cd>
<cl-cd data-idx="44"> console.log(raf, deg);</cl-cd>
<cl-cd data-idx="45"> <span class="tBlue">if</span>(raf) <span class="tBlue">return</span>;</cl-cd>
<cl-cd data-idx="46"> deg = 0;</cl-cd>
<cl-cd data-idx="47"> render();</cl-cd>
<cl-cd data-idx="48">};</cl-cd>
<cl-cd data-idx="49"> </cl-cd>
<cl-cd data-idx="50"><<span class="tDarkRed">/script</span>></cl-cd>
</div>
一楼,画完后,点击画布,会触发重绘事件 绘制文本函数对文本的定位值得学习参考:
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坐标值。
绘制文本函数对文本的定位值得学习参考:
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坐标值。
4、5楼一炮俩响{:4_189:} 这个同步绘制圆环和数字文本,完全步调一致{:4_187:} 居中的设置,让数字在分别是不同位数的时候能够自动调整呢。 试了一下让deg += 0.05;,画得就慢了许多{:4_173:} 红影 发表于 2024-4-1 09:38
试了一下让deg += 0.05;,画得就慢了许多
当然。这是步幅系数,每次增加多少度。 红影 发表于 2024-4-1 09:36
居中的设置,让数字在分别是不同位数的时候能够自动调整呢。
原理和CSS的文本设置一样,不同的是水平居中,画布的设置特性有所不同 马黑黑 发表于 2024-3-31 23:52
一楼,画完后,点击画布,会触发重绘事件
好哒,画得又快又好又圆{:4_170:}
看着完美,十分治愈。。。 马黑黑 发表于 2024-4-1 00:05
4、5楼一炮俩响
{:4_170:}你电脑也会卡一下?不可思议 马黑黑 发表于 2024-4-1 00:04
绘制文本函数对文本的定位值得学习参考:
let drawText = (text) => {
ctx.save();
{:4_170:}等会试着看看能不能看懂。
这是个新的演示 南无月 发表于 2024-4-1 18:10
你电脑也会卡一下?不可思议
这可不是卡哟,速度好快的 南无月 发表于 2024-4-1 18:11
等会试着看看能不能看懂。
这是个新的演示
一点一点拆分来看容易看懂 真好,正想它就有了,赶快收藏下备用。问好先生! 马黑黑 发表于 2024-4-1 18:11
这可不是卡哟,速度好快的
小白无法体会老黑的速度。。
就是太快了,敲一下出两贴。。神十八{:4_170:} 马黑黑 发表于 2024-4-1 18:12
一点一点拆分来看容易看懂
冰箱搁那还看得懂是冰箱,
拆成零件肯定不知道哪儿是哪儿{:4_170:} 马黑黑 发表于 2024-4-1 12:28
当然。这是步幅系数,每次增加多少度。
无论快慢,看着都是连续的呢。