我通过使用for循环生成六边形网格,我有一些问题
for (var i=0; i <= rows; i++) {
for (var j=0; j <= cols; j++) {
ctx.save();
ctx.translate(0+i*distX, 0+j*distY);
drawHexagon(ctx);
ctx.fill();
ctx.restore();
}
}
我的最终目标是创建一个六边形网格,当它在页面上移动时会移动远离鼠标光标的影响区域。我无法弄清楚如何在每个六边形之间绘制一条路径,而且我在尝试为六边形设置动画时遇到了问题。
我还是画布新手,我浏览了Mozilla开发者网络上的教程,所有动画都是在单个对象上,而不是在网格中生成的对象。
我在想我应该尝试存储网格并稍后影响它,但我不确定如何去做,我也不认为画布是这样的。
我发现这几乎是我想做的事情,但我无法理解它是如何工作的: http://codepen.io/soulwire/pen/Ffvlo
我现在很好地梳理它,如果有人能指引我通过它会很棒:)
编辑:我已经在点后面画了一个网格,我也想操纵它。我仍然不理解上面链接的编码器,它有点过头了。
答案 0 :(得分:4)
您的链接适用2种力量:
鼠标附近的粒子被击退。更具体地说,如果粒子中心点靠近鼠标中心点,那么粒子就会沿着两个中心点之间的线排斥。
不靠近鼠标的粒子被吸引回到原来的位置。更具体地说,粒子沿其当前中心点与其原始中心点之间的线移向其原始中心点。
数学运算如下:
// Given the mouse centerpoint (mx,my) & particle's centerpoint (px,py)
// calculate the difference between x's & y's
var dx=px-mx;
var dy=py-my;
// You can repel the particle by increasing the
// particle's position by a fraction of dx & dy
px+=dx/100;
py+=dy/100;
// And you can attract the particle by decreasing the
// particle's position by a fraction of dx & dy
px-=dx/100;
py-=dy/100;
这里带注释的代码和演示(为了便于理解而删除了缓动):
// canvas related variables
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
function reOffset(){
var BB=canvas.getBoundingClientRect();
offsetX=BB.left;
offsetY=BB.top;
}
var offsetX,offsetY;
reOffset();
window.onscroll=function(e){ reOffset(); }
window.onresize=function(e){ reOffset(); }
ctx.fillStyle='skyblue';
// mouse related variables
var PI2=Math.PI*2;
var mouseRadius=75; // this is the mouse's radius of influence
var mouseRadiusSquared=mouseRadius*mouseRadius;
var mouseIsDown=false;
var mx,my;
// define a bunch of hex objects stored in an array
var hexRadius=5;
var hexPadding=5;
var hexes=[];
for(var y=hexRadius;y<ch;y+=hexRadius*2+hexPadding){
for(var x=hexRadius;x<cw;x+=hexRadius*2+hexPadding){
hexes.push({startingX:x,startingY:y,x:x,y:y});
}}
// start a continuously running ticker loop
requestAnimationFrame(tick);
// listen for mouse events
$("#canvas").mousedown(function(e){handleMouseDown(e);});
$("#canvas").mouseup(function(e){handleMouseUp(e);});
// draw every hex in its current position
function draw(){
ctx.clearRect(0,0,cw,ch);
ctx.beginPath();
for(var i=0;i<hexes.length;i++){
var h=hexes[i];
ctx.moveTo(h.x,h.y);
ctx.arc(h.x,h.y,hexRadius,0,PI2);
ctx.closePath();
}
ctx.fill();
}
// create a continuously running ticker
function tick(time){
// update each hex position based on its
// position relative to the mouse
for(var i=0;i<hexes.length;i++){
var h=hexes[i];
// calculate if this hex is inside the mouse radius
var dx=h.x-mx;
var dy=h.y-my;
if(mouseIsDown && dx*dx+dy*dy<mouseRadiusSquared){
// hex is inside mouseRadius
// so mouseDown repels hex
h.x+=dx/120;
h.y+=dy/120;
}else if(h.x==h.startingX && h.y==h.startingY){
// hex is at startingX/Y & is not being repelled
// so do nothing
}else{
// hex has moved off startingX/Y
// but is no longer being repelled
// so gravity attracts hex back to its startingX/Y
dx=h.x-h.startingX;
dy=h.y-h.startingY;
h.x-=dx/60;
h.y-=dy/60;
}
}
// redraw the hexes in their new positions
draw();
// request another tick
requestAnimationFrame(tick);
}
// listen for mousedown events
function handleMouseDown(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
// calculate the mouse position
mx=parseInt(e.clientX-offsetX);
my=parseInt(e.clientY-offsetY);
// set the mousedown flag
mouseIsDown=true;
}
// listen for mouseup events
function handleMouseUp(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
// clear the mousedown flag
mouseIsDown=false;
}
&#13;
body{ background-color: ivory; padding:10px; }
#canvas{border:1px solid red;}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Press the mouse down to repel the particles.<br>Release to return particles to starting point.</h4>
<canvas id="canvas" width=300 height=300></canvas>
&#13;