如何在canvas-html5中绘制图像并用现有函数替换

时间:2016-04-24 05:55:01

标签: javascript canvas html5-canvas drawimage

我在绘制图像时出现问题,并在2个函数中替换为填充样式, 这段代码是一个带有画布的简单涂鸦跳线游戏。我想修改此脚本以在fillstyles部分中使用图像。 2功能使用fillstyle:

清除功能:

var clear = function(){
    ctx.fillStyle = '#000000';
    ctx.clearRect(0, 0, width, height);
    ctx.beginPath();
    ctx.rect(0, 0, width, height);
    ctx.closePath();
    ctx.fill();
}

DrawCircles功能:

var howManyCircles = 10, circles = [];

for (var i = 0; i < howManyCircles; i++) 
    circles.push([Math.random() * width, Math.random() * height, Math.random() * 100, Math.random() / 2]);

var DrawCircles = function(){
    for (var i = 0; i < howManyCircles; i++) {
        ctx.fillStyle = 'rgba(255, 255, 255, ' + circles[i][3] + ')';
        ctx.beginPath();
        ctx.arc(circles[i][0], circles[i][1], circles[i][2], 0, Math.PI * 2, true);
        ctx.closePath();
        ctx.fill();
    }
};

完整的脚本:

var width = 320, 
    height = 500,
    gLoop,
    points = 0,
    state = true,
    c = document.getElementById('c'), 
    ctx = c.getContext('2d');

    c.width = width;
    c.height = height;


var clear = function(){
    ctx.fillStyle = '#d0e7f9';
    ctx.clearRect(0, 0, width, height);
    ctx.beginPath();
    ctx.rect(0, 0, width, height);
    ctx.closePath();
    ctx.fill();
}

var howManyCircles = 10, circles = [];

for (var i = 0; i < howManyCircles; i++) 
    circles.push([Math.random() * width, Math.random() * height, Math.random() * 100, Math.random() / 2]);

var DrawCircles = function(){
    for (var i = 0; i < howManyCircles; i++) {
        ctx.fillStyle = 'rgba(255, 255, 255, ' + circles[i][3] + ')';
        ctx.beginPath();
        ctx.arc(circles[i][0], circles[i][1], circles[i][2], 0, Math.PI * 2, true);
        ctx.closePath();
        ctx.fill();
    }
};

var MoveCircles = function(e){
    for (var i = 0; i < howManyCircles; i++) {
        if (circles[i][1] - circles[i][2] > height) {
            circles[i][0] = Math.random() * width;
            circles[i][2] = Math.random() * 100;
            circles[i][1] = 0 - circles[i][2];
            circles[i][3] = Math.random() / 2;
        }
        else {
            circles[i][1] += e;
        }
    }
};

var player = new (function(){
    var that = this;
    that.image = new Image();

    that.image.src = "angel.png"
    that.width = 65;
    that.height = 95;
    that.frames = 1;
    that.actualFrame = 0;
    that.X = 0;
    that.Y = 0; 

    that.isJumping = false;
    that.isFalling = false;
    that.jumpSpeed = 0;
    that.fallSpeed = 0;

    that.jump = function() {
        if (!that.isJumping && !that.isFalling) {
            that.fallSpeed = 0;
            that.isJumping = true;
            that.jumpSpeed = 17;
        }
    }

    that.checkJump = function() {
        //a lot of changes here

        if (that.Y > height*0.4) {
            that.setPosition(that.X, that.Y - that.jumpSpeed);      
        }
        else {
            if (that.jumpSpeed > 10) 
                points++;
            // if player is in mid of the gamescreen
            // dont move player up, move obstacles down instead
            MoveCircles(that.jumpSpeed * 0.5);

            platforms.forEach(function(platform, ind){
                platform.y += that.jumpSpeed;

                if (platform.y > height) {
                    var type = ~~(Math.random() * 5);
                    if (type == 0) 
                        type = 1;
                    else 
                        type = 0;

                    platforms[ind] = new Platform(Math.random() * (width - platformWidth), platform.y - height, type);
                }
            });
        }


        that.jumpSpeed--;
        if (that.jumpSpeed == 0) {
            that.isJumping = false;
            that.isFalling = true;
            that.fallSpeed = 1;
        }

    }

    that.fallStop = function(){
        that.isFalling = false;
        that.fallSpeed = 0;
        that.jump();    
    }

    that.checkFall = function(){
        if (that.Y < height - that.height) {
            that.setPosition(that.X, that.Y + that.fallSpeed);
            that.fallSpeed++;
        } else {
            if (points == 0) 
                that.fallStop();
            else 
                GameOver();
        }
    }

    that.moveLeft = function(){
        if (that.X > 0) {
            that.setPosition(that.X - 5, that.Y);
        }
    }

    that.moveRight = function(){
        if (that.X + that.width < width) {
            that.setPosition(that.X + 5, that.Y);
        }
    }


    that.setPosition = function(x, y){
        that.X = x;
        that.Y = y;
    }

    that.interval = 0;
    that.draw = function(){
        try {
            ctx.drawImage(that.image, 0, that.height * that.actualFrame, that.width, that.height, that.X, that.Y, that.width, that.height);
        } 
        catch (e) {
        };

        if (that.interval == 4 ) {
            if (that.actualFrame == that.frames) {
                that.actualFrame = 0;
            }
            else {
                that.actualFrame++;
            }
            that.interval = 0;
        }
        that.interval++;        
    }
})();


player.setPosition(~~((width-player.width)/2), height - player.height);
player.jump();

document.onmousemove = function(e){
    if (player.X + c.offsetLeft > e.pageX) {
        player.moveLeft();
    } else if (player.X + c.offsetLeft < e.pageX) {
        player.moveRight();
    }

}
    var nrOfPlatforms = 7, 
        platforms = [],
        platformWidth = 70,
        platformHeight = 20;

    var Platform = function(x, y, type){
        var that=this;

        that.firstColor = '#FF8C00';
        that.secondColor = '#EEEE00';
        that.onCollide = function(){
            player.fallStop();
        };

        if (type === 1) {
            that.firstColor = '#AADD00';
            that.secondColor = '#698B22';
            that.onCollide = function(){
                player.fallStop();
                player.jumpSpeed = 50;
            };
        }



        that.x = ~~ x;
        that.y = y;
        that.type = type;

        //NEW IN PART 5
        that.isMoving = ~~(Math.random() * 2);
        that.direction= ~~(Math.random() * 2) ? -1 : 1;

        that.draw = function(){
            ctx.fillStyle = 'rgba(255, 255, 255, 1)';
            var gradient = ctx.createRadialGradient(that.x + (platformWidth/2), that.y + (platformHeight/2), 5, that.x + (platformWidth/2), that.y + (platformHeight/2), 45);
            gradient.addColorStop(0, that.firstColor);
            gradient.addColorStop(1, that.secondColor);
            ctx.fillStyle = gradient;
            ctx.fillRect(that.x, that.y, platformWidth, platformHeight);
        };

        return that;
    };

    var generatePlatforms = function(){
        var position = 0, type;
        for (var i = 0; i < nrOfPlatforms; i++) {
            type = ~~(Math.random()*5);
            if (type == 0) 
                type = 1;
            else 
                type = 0;
            platforms[i] = new Platform(Math.random() * (width - platformWidth), position, type);
            if (position < height - platformHeight) 
                position += ~~(height / nrOfPlatforms);
        }
    }();

    var checkCollision = function(){
    platforms.forEach(function(e, ind){
        if (
        (player.isFalling) && 
        (player.X < e.x + platformWidth) && 
        (player.X + player.width > e.x) && 
        (player.Y + player.height > e.y) && 
        (player.Y + player.height < e.y + platformHeight)
        ) {
            e.onCollide();
        }
    })
    }

var GameLoop = function(){
    clear();
    //MoveCircles(5);
    DrawCircles();

    if (player.isJumping) player.checkJump();
    if (player.isFalling) player.checkFall();

    player.draw();

    platforms.forEach(function(platform, index){
        if (platform.isMoving) {
            if (platform.x < 0) {
                platform.direction = 1;
            } else if (platform.x > width - platformWidth) {
                platform.direction = -1;
            }
                platform.x += platform.direction * (index / 2) * ~~(points / 100);
            }
        platform.draw();
    });

    checkCollision();

    ctx.fillStyle = "Black";
    ctx.fillText("POINTS:" + points, 10, height-10);

    if (state)
        gLoop = setTimeout(GameLoop, 1000 / 50);
}

    var GameOver = function(){
        state = false;
        clearTimeout(gLoop);
        setTimeout(function(){
            clear();

            ctx.fillStyle = "Black";
            ctx.font = "10pt Arial";
            ctx.fillText("GAME OVER", width / 2 - 60, height / 2 - 50);
            ctx.fillText("YOUR RESULT:" + points, width / 2 - 60, height / 2 - 30);
        }, 100);

    };

GameLoop();

任何人都可以帮助我吗?

感谢

1 个答案:

答案 0 :(得分:0)

您可以使用缩放版context.drawImage将背景图像完全填充画布。下面的clear版本会向上或向下缩放图像以完全填充可用的画布区域。

function clear(img){
    var scale=(Math.min((img.width/canvas.width),(img.height/canvas.height)));
    ctx.drawImage(bk,0,0,img.width*scale,img.height*scale);
}

您可以使用合成将图像剪切到圆圈内。下面的代码创建一个新画布,其中包含在具有指定半径的圆内绘制的指定图像。它通过两个步骤完成此任务:

  • 创建新画布并绘制具有指定半径的实心圆
  • 使用source-atop合成drawImage该圈内的图片。由于合成,图像不会在现有圆圈之外绘制。

创建一个在圆圈内剪裁的图像。

function makeCircledImage(r,img){
    var c=document.createElement('canvas');
    var cctx=c.getContext('2d');
    c.width=c.height=r*2;
    cctx.beginPath();
    cctx.arc(r,r,r,0,Math.PI*2);
    cctx.fill();
    cctx.globalCompositeOperation='source-atop';
    cctx.drawImage(img,r/2-img.width/2,r/2-img.height/2);
    return(c);
}

以下是示例代码和演示:

enter image description here

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");

var bk=new Image();
bk.onload=start;
bk.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/water.jpg";
var marble=new Image();
marble.onload=start;
marble.src='https://dl.dropboxusercontent.com/u/139992952/stack1/marble.jpg';
var imgCount=2;
function start(){
  if(--imgCount>0){return;}
  clear(bk);
  var marbleCircle=makeCircledImage(20,marble);
  for(var i=0;i<5;i++){
    ctx.drawImage(marbleCircle,i*50+25,100)
  }
}

function clear(img){
  var scale=(Math.min((img.width/canvas.width),(img.height/canvas.height)));
  ctx.drawImage(bk,0,0,img.width*scale,img.height*scale);
}

function makeCircledImage(r,img){
  var c=document.createElement('canvas');
  var cctx=c.getContext('2d');
  c.width=c.height=r*2;
  cctx.beginPath();
  cctx.arc(r,r,r,0,Math.PI*2);
  cctx.fill();
  cctx.globalCompositeOperation='source-atop';
  cctx.drawImage(img,r/2-img.width/2,r/2-img.height/2);
  return(c);
}
body{ background-color: ivory; padding:10px; }
#canvas{border:1px solid red;}
<h4>Water background with circular marble canvas-images.</h4>
<canvas id="canvas" width=300 height=300></canvas>