马黑黑 发表于 2022-3-9 15:59

HTML5画布:小球模拟marquee水平方向的三种运动方式

<div style="margin: auto; width: 600px; text-align:center;">
        <canvas id="canv" width="500" height="300" style="background:#000;"></canvas><br><br>
        <input type="button" id="btn" value="自左向右" /> &nbsp;
        <span id="bMsg" style="color:red;">行进方向:左右来回</span>
</div>

<script>

var bMsg = document.getElementById('bMsg');
var cc = document.getElementById('canv'); //获得画布
var ct = cc.getContext('2d'); //获得画笔
var flag = 0; //运行方向标识:默认0, 0=来回运动,1=自左向右,2=自右向左
var x = 20; //小球初始时圆心水平位置
var speed = 1; //行进速度
var start = setInterval(draw, 10); //来回运动

//按钮单击事件匿名函数
document.getElementById('btn').onclick = function(){
        clearInterval(start);
        if(this.value == '自左向右'){
                speed = Math.abs(speed); //速度用绝对值处理
                flag = 1; //改变方向标识
                this.value = '自右向左';
                bMsg.innerHTML = '行进方向: 自左向右';
        } else if(this.value == '自右向左') {
                speed = -speed; //倒置速度数值
                flag = 2;
                this.value = '来回运动';
                bMsg.innerHTML = '行进方向: 自右向左';
        } else {
                flag = 0;
                this.value = '自左向右';
                bMsg.innerHTML = '行进方向: 左右来回';
        }
        start = setInterval(draw, 10);
}

//小球运动函数
function draw(){
        ct.clearRect(0, 0, cc.width, cc.height); //清空画布
        ct.beginPath();
        ct.fillStyle = "gray";
        ct.arc(x, 150, 20, 0, 2*Math.PI);
        ct.fill();
        x += speed; //改变x值以令小球运动
        if(flag == 0){ //来回运动
                if(x > cc.width - 20 || x<20){
                        speed = -speed;
                }
        } else if(flag == 1){ //自左向右
                if(x > cc.width ) x = -20;
        } else { //自右向左
                if(x < -20) x = cc.width + 20;
        }
}

</script>

马黑黑 发表于 2022-3-9 16:01

代码分享:

<div style="margin: auto; width: 600px; text-align:center;">
        <canvas id="canv" width="500" height="300" style="background:#000;"></canvas><br><br>
        <input type="button" id="btn" value="自左向右" /> &nbsp;
        <span id="bMsg" style="color:red;">行进方向:左右来回</span>
</div>

<script>

var bMsg = document.getElementById('bMsg');
var cc = document.getElementById('canv'); //获得画布
var ct = cc.getContext('2d'); //获得画笔
var flag = 0; //运行方向标识:默认0, 0=来回运动,1=自左向右,2=自右向左
var x = 20; //小球初始时圆心水平位置
var speed = 1; //行进速度
var start = setInterval(draw, 10); //来回运动

//按钮单击事件匿名函数
document.getElementById('btn').onclick = function(){
        clearInterval(start);
        if(this.value == '自左向右'){
                speed = Math.abs(speed); //速度用绝对值处理
                flag = 1; //改变方向标识
                this.value = '自右向左';
                bMsg.innerHTML = '行进方向: 自左向右';
        } else if(this.value == '自右向左') {
                speed = -speed; //倒置速度数值
                flag = 2;
                this.value = '来回运动';
                bMsg.innerHTML = '行进方向: 自右向左';
        } else {
                flag = 0;
                this.value = '自左向右';
                bMsg.innerHTML = '行进方向: 左右来回';
        }
        start = setInterval(draw, 10);
}

//小球运动函数
function draw(){
        ct.clearRect(0, 0, cc.width, cc.height); //清空画布
        ct.beginPath();
        ct.fillStyle = "gray";
        ct.arc(x, 150, 20, 0, 2*Math.PI);
        ct.fill();
        x += speed; //改变x值以令小球运动
        if(flag == 0){ //来回运动
                if(x > cc.width - 20 || x<20){
                        speed = -speed;
                }
        } else if(flag == 1){ //自左向右
                if(x > cc.width ) x = -20;
        } else { //自右向左
                if(x < -20) x = cc.width + 20;
        }
}

</script>

加林森 发表于 2022-3-9 16:21

先来学习学习。

红影 发表于 2022-3-9 19:24

这个可以在中途就直接切换的呢,有趣{:4_187:}

红影 发表于 2022-3-9 19:35

小球运动函数的命令太过简洁,要理解还挺费劲。

红影 发表于 2022-3-9 19:40

比如自左向右,if(x > cc.width ) x = -20; 也就是说,用-20开始加,加到大于宽度了,就重头再来,再一次从-20进行累加。
是每累积一次都自动执行 ct.clearRect(0, 0, cc.width, cc.height)的么?否则画布上将有无数个小球。

红影 发表于 2022-3-9 19:45

自右向左这个没看懂
if(x < -20) x = cc.width + 20从宽度加20的地方动手,还去累加不是越加越大么,这里并没有-speed
永远不可能小于-20 啊

红影 发表于 2022-3-9 19:46

左右移动的懂了,想右的也看明白了,就这个自右向左没看明白。

马黑黑 发表于 2022-3-9 19:54

红影 发表于 2022-3-9 19:45
自右向左这个没看懂
if(x < -20) x = cc.width + 20从宽度加20的地方动手,还去累加不是越加越大么,这 ...

x 变量会小于 - 20的。自右向左,它在右向左出发,最后边界是画布+小球直径,不论右边是多少,它都是用 -speed 方式“累加”到x变量中来,其实这是累减呢。你看按钮单击事件中有一句:

speed = -speed; //倒置速度数值

如果你不是文科生,这句能看懂的

马黑黑 发表于 2022-3-9 19:56

红影 发表于 2022-3-9 19:46
左右移动的懂了,想右的也看明白了,就这个自右向左没看明白。

自右向左,你看9#,还有不明白的,再发问

马黑黑 发表于 2022-3-9 19:58

红影 发表于 2022-3-9 19:40
比如自左向右,if(x > cc.width ) x = -20; 也就是说,用-20开始加,加到大于宽度了,就重头再来,再一次 ...
每隔 10 毫秒执行一次,你也可以理解为时每累加一次执行一次,但是要清楚,主要依据是setInterval的第二个参数

马黑黑 发表于 2022-3-9 19:59

加林森 发表于 2022-3-9 16:21
先来学习学习。

看出名堂木有?

马黑黑 发表于 2022-3-9 20:01

红影 发表于 2022-3-9 19:24
这个可以在中途就直接切换的呢,有趣

变量 x 是整个程序中的“公用”变量,它在值,不论变化与否,都会在各个函数和各个过程中得到承认。因此,变换了flag方式(运动方向标识),x的值就会累加或累减。

加林森 发表于 2022-3-9 20:29

马黑黑 发表于 2022-3-9 19:59
看出名堂木有?

看出来了,还得多研究啊。

马黑黑 发表于 2022-3-9 21:03

加林森 发表于 2022-3-9 20:29
看出来了,还得多研究啊。

那是那是

加林森 发表于 2022-3-9 21:04

马黑黑 发表于 2022-3-9 21:03
那是那是

嗯嗯,谢谢你了。{:4_191:}

马黑黑 发表于 2022-3-9 21:05

加林森 发表于 2022-3-9 21:04
嗯嗯,谢谢你了。

{:4_190:}

加林森 发表于 2022-3-9 21:06

马黑黑 发表于 2022-3-9 21:05


谢茶

红影 发表于 2022-3-9 21:31

马黑黑 发表于 2022-3-9 19:54
x 变量会小于 - 20的。自右向左,它在右向左出发,最后边界是画布+小球直径,不论右边是多少,它都是用 - ...

这个主贴关于运动太简洁,挺难理解的。那个speed = -speed是左右运动里的,怎么会对向右也影响的?

红影 发表于 2022-3-9 21:33

马黑黑 发表于 2022-3-9 20:01
变量 x 是整个程序中的“公用”变量,它在值,不论变化与否,都会在各个函数和各个过程中得到承认。因此 ...

哦哦,公用变量,大概明白后面那一块是怎么回事了。
页: [1] 2 3 4 5
查看完整版本: HTML5画布:小球模拟marquee水平方向的三种运动方式