当它明确地

时间:2015-07-31 17:10:13

标签: javascript

任何帮助表示赞赏,所以请我喜欢评论和答案,绑定也会有所帮助

xx: function (a) {
  return(this.x+this.r*Math.cos(a));
},
yy: function (a) {
  return(this.y+this.r*Math.sin(a));
},
lerp: function (a,b,x){
 return(a+x*(b-a));
}

描述形状的尺寸

draw: function () { 
    // snip

    drawSides(this.percent);

    // snip

    function drawSides(pct,color){
        // snip

            ctx.beginPath();
            ctx.moveTo(sides[0].x0,sides[0].y0);
            for(var i=0;i<sideCount;i++){
                var side=sides[i];
                var cpx=this.lerp(side.midX,side.cpX,pct/100); //Error here
                var cpy=this.lerp(side.midY,side.cpY,pct/100);        
                ctx.quadraticCurveTo(cpx,cpy,side.x2,side.y2);
            }
            ctx.fill();

        // snip
    }

这是错误的位置(第115行是错误是var cpx的地方)

以下是完整的代码:

var canvas, ctx, fps, radius, width, height;

var ball = [1];

function randomLocation() {

return 600*Math.random();

}

function randomVelocity(){

var ran = 2*Math.random();

if(ran < 1) { return 10*Math.random()}
else { return -10*Math.random()}
}   

function addBall() {
ball.push(createBall());
}

function toCircle() {
for(i=0; i < ball.length; i++) {
    ball[i].toCircle();
}
}

function toShape() {
for(i=0; i < ball.length; i++) {
    ball[i].toShape();
}
}

function createBall() {

return {x:randomLocation(),
    y:randomLocation(),
    r:radius,
    vx:randomVelocity(),
    vy:randomVelocity(),
    c:getRandomColor(),
    percent: 0,
    percentDirection: 0.50,
    move: function () {
        if(  this.y > height   ){
            this.vy = -this.vy;
        } else if ( this.y < 0 ){
            this.vy = -this.vy;
        }
        if ( this.x > width ){
            this.vx = -this.vx;
        } else if ( this.x < 0 ){
            this.vx = -this.vx;
        }
        this.x += this.vx;
        this.y += this.vy;
    },
    toShape: function () {
        this.percentDirection = -0.50;
    },
    toCircle: function () {
        this.percentDirection = 0.50;
    },
    xx: function (a) {
        return(this.x+this.r*Math.cos(a));
    },
    yy: function (a) {
        return(this.y+this.r*Math.sin(a));
    },
    lerp: function (a,b,x){
        return(a+x*(b-a));
    },          
    draw: function () { 

        var sideCount = 3;

        var sides=[];
        for(var i=0;i<sideCount;i++){
            sides.push(makeSide(i,sideCount));
        }

        drawSides(this.percent);
        this.percent+=this.percentDirection;
        if(this.percent>100){this.percent=100;}
        if(this.percent<0){this.percent=0;}


        var PI2=Math.PI*2;

        // functions

        function drawSides(pct,color){
            ctx.clearRect(0,0,canvas.width,canvas.height);
            if(pct==100){
                ctx.beginPath();
                ctx.arc(this.x,this.y,this.r,0,PI2);
                ctx.closePath();
                ctx.fill();
            }else{
                ctx.beginPath();
                ctx.moveTo(sides[0].x0,sides[0].y0);
                for(var i=0;i<sideCount;i++){
                    var side=sides[i];
                    var cpx=this.lerp(side.midX,side.cpX,pct/100);
                    var cpy=this.lerp(side.midY,side.cpY,pct/100);        
                    ctx.quadraticCurveTo(cpx,cpy,side.x2,side.y2);
                }
                ctx.fill();
            }
        }

        function makeSide(n,sideCount){
            var sweep=PI2/sideCount;
            var sAngle=sweep*(n-1);
            var eAngle=sweep*n;

            var x0=this.xx(sAngle);
            var y0=this.yy(sAngle);
            var x1=this.xx((eAngle+sAngle)/2);
            var y1=this.yy((eAngle+sAngle)/2);
            var x2=this.xx(eAngle);
            var y2=this.yy(eAngle);

            var dx=x2-x1;
            var dy=y2-y1;
            var a=Math.atan2(dy,dx);
            var midX=this.lerp(x0,x2,0.50);
            var midY=this.lerp(y0,y2,0.50);
            var cpX=2*x1-x0/2-x2/2;
            var cpY=2*y1-y0/2-y2/2;

            return({
                x0:x0, y0:y0,
                x2:x2, y2:y2,
                midX:midX, midY:midY,
                cpX:cpX, cpY:cpY,
                color:randomColor()
            });
        }
    }
    };

}

// this is where we can draw our shapes!

function clearCanvas(){
ctx.fillStyle = "white";
ctx.fillRect(0,0,width,height);
}

function draw() {
clearCanvas();

for( i=0; i < ball.length; i++) {
    ball[i].move();
    ball[i].draw();
}
}

// this function initializes our variables when the
// page loads

function init(){
canvas = document.getElementById('canvas');
ctx = canvas.getContext('2d');

ball[0] = createBall();

radius = 20;
width = 1000;
height = 600;
}

 // This function starts the animation loop
// when the window loads

window.onload = function () {
init();
animloop();                                   
}

// This is the looping animation function
// the variable fps sets hows many frames are shown
// per second
function animloop() {

requestAnimFrame(animloop);
draw();

}

// The function below sends a request to reload the canvas
// 60 times every second

window.requestAnimFrame = (
function(){ return window.requestAnimationFrame|| 
window.webkitRequestAnimationFrame         || 
window.mozRequestAnimationFrame            || 
window.oRequestAnimationFrame              || 
window.msRequestAnimationFrame             || 
function( callback ){ 
    return window.setTimeout(callback, 1000 / 60);
}; 
}
)();

 //this function returns a string
// that represents a random hexadecimal color

function getRandomColor() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++ ) {
    color += letters[Math.floor(Math.random() * 16)];
}
return color;

}

可能存在其他一些错误,因此任何帮助都会受到赞赏,尤其是答案

2 个答案:

答案 0 :(得分:0)

在运行代码时,我在makeSide函数中获得了异常(xx未定义this)。就我而言,this绑定到全局对象(window)而不是调用对象。

您可能想查看this在您的案例中绑定的内容,我猜它也是window

如果你想手动设置this,你可以调用这样的函数:

myFunction.call(objectThatShouldBeThis, arguments);

而不是:

myFunction(arguments);

一般来说,我建议您不要使用this这么多,因为它通常不是您所期望的,并且使您的功能更不可重复使用。

答案 1 :(得分:0)

drawSides方法中的draw函数在新上下文中运行,因此this引用其他内容(全局)。

一种解决方案是使用内部函数之外的变量来保持对所需this对象的引用。例如:

draw: function(){
  ...
  var that = this;
  function drawSides() {
    ...
    var ctx = that.lerp( ... );
    ...
  }
  ...
}

或者,当您调用drawSlides时,如果仅在现代环境中运行,则可以使用.bind方法:

drawSlides( this.percent ).bind(this);