百度了一下,找到了一篇链接:https://segmentfault.com/a/1190000000415572。
希望可以帮到你。加油!很多都可以百度一下,而且一些问题也可以在慕课网的搜索框输入,会出现相同的问题。
动态设置clip的长宽呗,不是有个canvas.with吗
function update() { if (searchLight.radius > 700) { isIncrease = false } else if (searchLight.radius < 150) { isIncrease = true; } /* 修改以下部分即可 */ /////////////////////// if (isIncrease) { searchLight.radius += 5; } else { searchLight.radius -= 5; } /////////////////////// }
不太清楚你到底想要什么效果,看看这个行不行吧
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>剪辑区域--demo4</title> <style> * { margin: 0; padding: 0 } canvas { display: block; margin: 50px auto; border: solid 1px grey; } </style> </head> <body> <canvas id="canvas"></canvas> <script> var canvas = document.getElementById('canvas'); canvas.width = 800; canvas.height = 500; var cxt = canvas.getContext('2d'); //探照灯,x,y为鼠标相对canvas的坐标 function drawArc(cxt, x, y, r) { cxt.clearRect(0, 0, canvas.width, canvas.height); drawText(cxt); cxt.save(); cxt.arc(x, y, r, 0, 2 * Math.PI); cxt.fillStyle = '#fff'; cxt.fill(); cxt.clip(); drawText(cxt,'green') cxt.restore(); } //绘制文字 function drawText(cxt,color) { //绘制三行文字 cxt.clearRect(0, 0, canvas.width, canvas.height) cxt.beginPath(); cxt.font = '20px 隶书'; cxt.fillStyle = color || 'black'; cxt.fillText('生命,就像是一张借记卡,从你呱呱坠地,还未有名字的时候,你生命的借记卡就已经毫不延迟的启动了它的业务。', 0, 50) cxt.fillText('储存在生命借记卡上的数字,就是你这一生所有的时光。', 0, 100) cxt.fillText('幸好不知道,我们才会一边消费着卡额,一边无忧无虑的生活。', 0, 150) } canvas.onmousemove = function(event) { //计算出鼠标相对canvas的位置 clientX = event.clientX; clientY = event.clientY; curX = clientX - this.offsetLeft; curY = clientY - this.offsetTop; drawArc(cxt, curX, curY, 50) } canvas.onmouseout = function() { cxt.clearRect(0, 0, canvas.width, canvas.height); drawText(cxt); } </script> </body> </html>
已解决
if( circle.y <=RADIUS ){//如果小球碰到顶部
circle.vy = - Math.abs(circle.vx)//y方向速度反向,
circle.y = RADIUS;
}
if( circle.x <= RADIUS ){//如果小球碰到左
circle.vx = - Math.abs(circle.vx)
circle.x = RADIUS;
}
看看你的 Math.abs() 是什么意思希望你查一下 , 还有 在web里面 X轴和y轴的方向 希望你查一下 (x左边为正,y的下边为正), circle.vx 是本身有正负的 你给加了 Math.abs 后 就把原来的速度全部重置成了正 再去加 (-)负号 ,那么只能对 circle.vx和circle.vx 本身为正的数字起左右 ,本身为负,你添加了 Math.abs 后就变成正的 ,再去加(-)负号 还是他自己本身的速度,而不是相反的速度
可以了,不用回答
<script type="text/javascript">
var searchLight={x:400,y:400,radius:150,vx:Math.random()*5+10,vy:Math.random()*5+10};
window.onload=function(){
var canvas=document.getElementById('canvas');
var context=canvas.getContext('2d');
canvas.width=800;
canvas.height=800;
setInterval(function(){
draw(context);
update(canvas.width,canvas.height);
},50);
}
function draw(cxt){
var canvas=cxt.canvas;
cxt.clearRect(0,0,canvas.width,canvas.height);
cxt.save();
cxt.beginPath();
cxt.fillStyle="#000";
cxt.fillRect(0,0,canvas.width,canvas.height);
cxt.beginPath();
cxt.arc(searchLight.x,searchLight.y,searchLight.radius,0,Math.PI*2);
cxt.fillStyle="#FFF";
cxt.fill();
cxt.clip();
cxt.font="bold 150px Arial";
cxt.textAlign="center";
cxt.textBaseLine="middle";
cxt.fillStyle="#ff6600";
cxt.fillText("CANVAS",canvas.width/2,canvas.width/4);
cxt.fillText("CANVAS",canvas.width/2,canvas.width/2);
cxt.fillText("CANVAS",canvas.width/2,canvas.width*3/4);
cxt.restore();
}
function update(canvasWidth,canvasHeight){
searchLight.x+=searchLight.vx;
searchLight.y+=searchLight.vy;
if(searchLight.x-searchLight.radius<=0){
searchLight.vx=-searchLight.vx;
searchLight.x=searchLight.radius;
}
if (searchLight.x+searchLight.radius>=canvasWidth) {
searchLight.vx=-searchLight.vx;
searchLight.x=canvasWidth-searchLight.radius;
}
if(searchLight.y-searchLight.radius<=0){
searchLight.vy=-searchLight.vy;
searchLight.y=searchLight.radius;
}
if (searchLight.y+searchLight.radius>=canvasHeight) {
searchLight.vy=-searchLight.vy;
searchLight.y=canvasHeight-searchLight.radius;
}
}
</script>
我把完整的给你,你自己对下哪里不同。
问题出在绘制五角星路径,Chrome下ctx.clip();存在问题,绘制多边形如果角度太小ctx.clip();的剪切就会超出路径范围,如果你换成三角形或是圆形四方形 就不存在这些问题。怎么解决我也不知道。
在里面设置就是局部变量,在外面设置就是全局变量,具体视情况而定。
看一下逻辑就知道原因了
当radius大于700时(比方说是705), isIncrease设为了false,接着radius开始缩小执行-5操作,此时radius为700
按原先逻辑,再次执行update时,因为isIncrease是false,radius还是执行-5操作,一直到小于150时,但是你把var isIncrease = true放在了update里面,这时radius为700 ,isIncrease为true,那么radius要执行+5操作,radius变为705,然后超过700,又执行-5操作,变为700,又执行+5操作,所以探照灯放大到700时一直抖动
没问题了,问题解决了......
不好意思,刚刚没有看清楚你注视了代码,重新答一次。drawstar这个函数的功能是根据指定的上下文在特定的位置绘制特定大小的的星星。根据老师前面的例子,我们最好只是规划出一个基本图形的单位路径。具体的位置变换,旋转,缩放都交给外部进行。出错的原因是在外部你进行了旋转,在内部进行了位移,外部的旋转改变了里面的坐标系。将以上的代码改为如下:
var searchlight = { x: 400, y: 400, radius: 150, vx: Math.random() * 5 + 10, vy: Math.random() * 5 + 10 }; var rot = 0; window.onload = function() { var canvas = document.getElementById('canvas'); canvas.width = 800; canvas.height = 600; if (canvas.getContext('2d')) { var context = canvas.getContext('2d'); } else { alert('该浏览器不支持!'); } setInterval(function() { draw(context); update(canvas.width, canvas.height); }, 40); }; function draw(cxt) { var canvas = cxt.canvas; cxt.clearRect(0, 0, canvas.width, canvas.height); cxt.save(); cxt.beginPath(); cxt.fillStyle = 'black'; cxt.fillRect(0, 0, canvas.width, canvas.height); cxt.save(); cxt.beginPath(); // cxt.arc(searchlight.x,searchlight.y,searchlight.radius,0,2*Math.PI); cxt.translate(searchlight.x,searchlight.y); cxt.rotate(rot/180*Math.PI); cxt.scale(searchlight.radius,searchlight.radius); drawstar(cxt); cxt.fillStyle = '#fff'; cxt.fill(); cxt.restore(); cxt.clip(); cxt.font = 'bold 150px Arial'; cxt.textAlign = 'center'; cxt.textBaseline = 'middle'; cxt.fillStyle = '#058'; cxt.fillText('CANVAS', canvas.width / 2, canvas.height / 4); cxt.fillText('CANVAS', canvas.width / 2, canvas.height / 2); cxt.fillText('CANVAS', canvas.width / 2, canvas.height / 4 * 3); cxt.restore(); } //星星 function drawstar(cxt) { cxt.beginPath(); for (var i = 0; i < 5; i++) { cxt.lineTo(Math.cos((18 + i * 72) / 180 * Math.PI), -Math.sin((18 + i * 72) / 180 * Math.PI)); cxt.lineTo(Math.cos((54 + i * 72) / 180 * Math.PI) * 0.5, -Math.sin((54 + i * 72) / 180 * Math.PI) * 0.5); } cxt.closePath(); } //碰撞检测 function update(width, height) { rot += 1; searchlight.x += searchlight.vx; searchlight.y += searchlight.vy; if (searchlight.x - searchlight.radius <= 0) { searchlight.vx = -searchlight.vx; searchlight.x = searchlight.radius; } if (searchlight.x + searchlight.radius >= width) { searchlight.vx = -searchlight.vx; searchlight.x = width - searchlight.radius; } if (searchlight.y - searchlight.radius <= 0) { searchlight.vy = -searchlight.vy; searchlight.y = searchlight.radius; } if (searchlight.y + searchlight.radius >= height) { searchlight.vy = -searchlight.vy; searchlight.y = height - searchlight.radius; } }
save和restore是用于绘制环境的保存与还原,如果你不写这一对方法,你前面进行的操作(全屏先涂#333)就不会被还原,而是在原来的绘制环境(简单理解就是原图形)上进行新的操作,这样你第二次画的内容都是在原图上画的。
clip与你第一次restore的顺序没有关系,你可以把每一帧的绘画放在一个save和restore之间,最重要的是你需要在clip前调用beginpath方法,如果不调用beginpath你每次的剪切圆不会消失而是一直保持在画面上。
调用一个beginpath,closepath就可以啦。
您好
调试了一下,是因为你的一个小笔误。
在function update(canvasWidth,canvasHeight){}里,有三处把searchlignt.radius错写成了searchligt.radius
弄清楚了,,逻辑没问题,increase变量定义的地方放错了。。