使用JavaScript编写小型库时遇到麻烦

时间:2014-03-27 15:04:53

标签: javascript html5 canvas html5-canvas drawimage

我一直在尝试用Javascript编写一个小型库,主要用于Canvas drawImage()方法。 该库的主要用途是传递数组值,而不是传递单个值,例如:

// srcPos=[0,0] , size=[90,90], dstPos=[50,50] 

function draw_image(context, image, srcPos, size, dstPos, size) {
    context.drawImage(image, srcPos[0], srcPos[1], size[0], size[1], dstPos[0], dstPos[1], size[0], size[1]);
}

但是当我像这样调用这个函数jzz时,我得到了Uncaught ReferenceError:

var canvas = document.getElementById("display"),
    frame = canvas.getContext("2d");
var shipInfo = { center:[45, 45], size:[90, 90], radius: 35, angle:45 },
            shipImage = new Image(),
            pos = [40, 70];
shipImage.src = "ship.png";

function draw() {
    draw_image(frame, shipImage, shipInfo.size, pos, shipInfo.size);
}

window.onload = function() {
    draw();
}

是否可以实现覆盖默认drawImage()的方法,如下所示:

frame.draw_image(shipImage, srcPos, shipInfo.size, dstPos, shipInfo.size);

2 个答案:

答案 0 :(得分:1)

如果你想在2d上下文中添加一个函数,javascript使得原型继承变得简单:你可以注入Context2D对象来添加或改变它的功能。
您可能想看一下我在这里制作的小画布库中对上下文做的一些添加:https://github.com/gamealchemist/CanvasLib

有些人会说注射是邪恶的,但除非你在一艘巨大的船上我会说:如果你使用一些图形库,尊重现有功能的语义,一切都应该没问题。如果你不使用libs:做任何事情!

所以,为了更具体地回答你的问题,你的较短的drawImage会给出:

CanvasRenderingContext2D.prototype.draw_image = function ( image, 
                                                            srcPos, size, 
                                                            dstPos, size) {
      this.drawImage(image, srcPos[0], srcPos[1], size[0], size[1], 
                               dstPos[0], dstPos[1], size[0], size[1]);
}; 

然后您可以在所有上下文中使用新功能:

var canvas = document.getElementById("display"),
     frame  = canvas.getContext("2d");
frame.draw_image( ... ) ;

请注意,您可以使用'rect'对象,这些对象将是包含4个元素x,y,w,h的数组,并导致语法更短。

编辑:我在你的lib中看到你要旋转你的矩形 首先,您不想重置转换。只需保存然后恢复它 我会尝试更接近这个:

var x = dstPos[0],
    y = dstPos[1],
    halfWidth = dstSize[0]*0.5, // !! not src use >>1 if you know it's an int.
    halfHeight = dstSize[1]*0.5, // !! not src  ...
    angleInRads = angle * Math.PI / 180;
this.save();
this.translate(x+halfWidth,y+halfHeight);
this.rotate(angleInRads);
this.drawImage(image
                , center[0], center[1], srcSize[0], srcSize[1]
                 , -halfWidth, -halfHeight, dstSize[0],dstSize[1]);
this.restore();

答案 1 :(得分:1)

您的小图片库非常适合javascript对象。

演示:http://jsfiddle.net/m1erickson/7pZJw/

enter image description here

javascript对象可以保存有关您图片的信息:

  • 图像本身
  • 图像尺寸(可自动为您计算)
  • 图像中心点(可自动为您计算)

示例:

// create a new object
// fill it with the info about the image

var object={
    image:shipImage,
    width:shipImage.width,
    height:shipImage.height,
    centerOffsetX:shipImage.width/2,
    centerOffsetY:shipImage.height/2,
    radius:35,
    angle:45,
};

javascript对象还可以保存绘制图像的功能(正如您在代码中所做的那样)

示例:

// when you call object.draw the image will be drawn by this function
// which is added to the object itself

draw:function(context,atX,atY,newWidth,newHeight){
    context.drawImage(
        this.image,
        0,0,this.width,this.height,
        atX,atY,newWidth,newHeight);
},

在javascript对象中创建小图像库的功能可能如下所示:

function createImageObject(image,radius,angle){

    // create a new object
    // fill it with the info about the image
    var object={
        image:image,
        width:image.width,
        height:image.height,
        centerOffsetX:image.width/2,
        centerOffsetY:image.height/2,
        radius:radius,
        angle:angle,
        draw:function(context,atX,atY,newWidth,newHeight){
            context.drawImage(
                this.image,
                0,0,this.width,this.height,
                atX,atY,newWidth,newHeight);
        },
    };
    return(object);
}

您可以像这样使用您的船舶对象库:

// create a new ship object

var shipObject=createImageObject(img,35,45);

// draw the ship image using the ship object
// draw at 20,20 with size 75,75

shipObject.draw(frame,20,20,75,75);

顺便说一句,我看到你正在使用缩放/剪辑源图像的drawImage版本。

如果您只想以原始尺寸绘制完整图像,可以使用以下快捷方式:

// draw the image full-sized at x,y

context.drawImage(image,x,y);