画布上让整首诗自下往上循环移动
本帖最后由 马黑黑 于 2022-8-16 21:26 编辑记得之前讨论canvas画布时提到过,画布处理文本不会自动换行。故此,令一首小诗自下而上循环移动,需要做额外处理,让其分行绘制文本。
文本的绘制,canvas画布里,可以使用 fillText 和 strokeText 方法,语法一样(ctx是画笔句柄):
ctx.fillText('文本', x, y);
ctx.strokeText('文本', x, y);
一般地,X坐标是固定的,我们处理好Y坐标就能分行。第一行,Y坐标是50,则第二行则是 100,第三行150,第四行200。依此原理,我们可以通过for循环语句一口气写好四行诗。假设诗歌已经按行放入了数组 txtAr:
let hy = 0; //Y坐标初始值
for(j = 0; j < txtAr.length; j ++) {
hy += 50; //每次循环代表一行,Y坐标加50
ctx.fillText(txtAr, 10, hy ); //绘在 {10, hy} 处绘制各行文本
}
以上是一次性分行绘制出了全诗。
下一步是移动:我们令一个变量不停地加1,这个变量又去影响 hy 变量,而每一次影响,画布都重新绘制一次全诗文本,达到上升的目的,再加上限制变量处理机制,循环往复的上升就能实现。
下面是完整代码:
<style>
#papa { margin: auto; width: 720px; height: 460px; position: relative; }
#canv { position: absolute; left: 20px; top: 10px; border: 1px solid; }
</style>
<div id="papa">
<canvas id="canv" width="320" height="500"></canvas>
</div>
<script>
let ctx = canv.getContext('2d'); //画笔
let w = canv.width, h = canv.height; //宽高变量
let step = 1, yy = h; //步进、Y坐标变量
let txtAr = [
'荆溪白石出,',
'天寒红叶稀。',
'山路元无雨,',
'空翠湿人衣。'
];
(function moveText() {
ctx.clearRect(0, 0, w, h); //清空画布
ctx.strokeStyle = 'hsl(20, 100%, 50%)'; //也可以用 fillStyle 和其他颜色表达法
ctx.font = 'bold 50px 黑体'; //字号 50 :行距的依据是它
let hy = yy; //hy是Y坐标,书写整诗用(yy变量用于令步幅上升)
for(j = 0; j< txtAr.length; j ++) {
hy +=50; //各行的距离拉开50px(字号值)
ctx.strokeText(txtAr, 10, hy); //画一行字(也可以用fillText)
}
yy -= step; //yy变量自增
if (yy <= -200) yy = h; //200的依据:行数×字号
requestAnimationFrame(moveText); //定时器调用本函数
})();
</script>
效果放在二楼。
本帖最后由 马黑黑 于 2022-8-16 21:27 编辑 <br /><br /><style>
#papa { margin: auto; width: 720px; height: 460px; position: relative; }
#canv { position: absolute; left: 20px; top: 10px; border: 1px solid; }
</style>
<div id="papa">
<canvas id="canv" width="320" height="500"></canvas>
</div>
<script>
let ctx = canv.getContext('2d'); //画笔
let w = canv.width, h = canv.height; //宽高变量
let step = 1, yy = h; //步进、Y坐标变量
let txtAr = [
'荆溪白石出,',
'天寒红叶稀。',
'山路元无雨,',
'空翠湿人衣。'
];
(function moveText() {
ctx.clearRect(0, 0, w, h); //清空画布
ctx.strokeStyle = 'hsl(20, 100%, 50%)'; //也可以用 fillStyle
ctx.font = 'bold 50px 黑体'; //字号 50
let hy = yy; //hy是Y坐标,书写整诗用(yy变量用于令步幅上升)
for(j = 0; j< txtAr.length; j ++) {
hy +=50; //各行的距离拉开50px(字号值)
ctx.strokeText(txtAr, 10, hy); //画一行字(也可以用fillText)
}
yy -= step; //yy变量自增
if (yy <= -200) yy = h; //200的依据:行数×字号
requestAnimationFrame(moveText); //定时器调用本函数
})();
</script>
“山路元无雨”的“元”子取啥意思呢 @红影 如果觉得行高等于字宽显得太紧凑,可以把 hy +=50;的数值加大一点,比如 60,然后,条件语句
if (yy <= -200) yy = h;
的 -200 变为 60×行数 醉美水芙蓉 发表于 2022-8-16 20:39
黑黑老师神速呀!
额,这个原始举手之劳 黑黑这个是专门为红影,樵哥哥诗词制作吧{:4_178:} 小辣椒 发表于 2022-8-16 21:16
黑黑这个是专门为红影,樵哥哥诗词制作吧
也不全是。红影提出来,所以弄了一下,边弄边拖地板 黑黑简直太厉害了,我只是想弄个诗句走马灯,没想到黑黑真的就能弄出来,真太厉害了{:4_199:} 马黑黑 发表于 2022-8-16 20:29
“山路元无雨”的“元”子取啥意思呢
通原字{:4_204:} 红影 发表于 2022-8-16 21:18
黑黑简直太厉害了,我只是想弄个诗句走马灯,没想到黑黑真的就能弄出来,真太厉害了
这个,懂原理的话,弄起来并不难 红影 发表于 2022-8-16 21:18
黑黑简直太厉害了,我只是想弄个诗句走马灯,没想到黑黑真的就能弄出来,真太厉害了
诗句数组我还弄复杂了,可以也最好简化:
let txtAr = [
'荆溪白石出,',
'天寒红叶稀。',
'山路元无雨,',
'空翠湿人衣。'
]; 红影 发表于 2022-8-16 21:19
通原字
就是原的别字 马黑黑 发表于 2022-8-16 21:17
也不全是。红影提出来,所以弄了一下,边弄边拖地板
你也是厉害,拖地的时候脑子想的是这个,一心二用 小辣椒 发表于 2022-8-16 21:22
你也是厉害,拖地的时候脑子想的是这个,一心二用
拖地是最好的运动,也是灵感最容易蹦出来的活动 ctx.strokeStyle =怎样知道是设置的字体的颜色还是设定的画布的颜色? 这个画布是没有底色的,记得字符雨就是有底色的,我看不出是怎么设置的。
画布能设置透明度,是不是字体也能? 红影 发表于 2022-8-16 21:40
这个画布是没有底色的,记得字符雨就是有底色的,我看不出是怎么设置的。
画布能设置透明度,是不是字体也 ...
画布想要底色的话,清空后,
ctx.fillStyle = 'rgba(0,0,0,.6)';
ctx.fillRect(0,0,w,h); //w,h上文已赋值,等于画布的宽高
然后再画别的 小马黑黑是个好老师,仔细看过,俺看懂了。。。