Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用JavaScript编写小型库时遇到的问题_Javascript_Html_Canvas_Html5 Canvas_Drawimage - Fatal编程技术网

用JavaScript编写小型库时遇到的问题

用JavaScript编写小型库时遇到的问题,javascript,html,canvas,html5-canvas,drawimage,Javascript,Html,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

我一直在尝试用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时,我得到了未捕获的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);

如果您想向2d上下文中添加函数,javascript通过原型继承使这变得容易:您可以插入Context2D对象来添加或更改其函数 您可能想看看我在这里制作的一个小画布库中为上下文添加的一些内容:

有些人会说注入是邪恶的,但除非你在一条大船上,否则我只会说:如果你使用一些图形库,尊重现有函数的语义,一切都应该是好的。如果你不使用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,并导致更短的语法

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

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();

您的小型图像库很适合javascript对象。

演示:

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);
  • 图像本身
  • 图像大小(可为您自动计算)
  • 图像中心点(可自动为您计算)
例如:

// 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,
};
// 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对象还可以保存绘制图像的函数(正如您在代码中所做的)

例如:

// 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,
};
// 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);
您可以像这样使用ship对象库:

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);

画图还是画图?顺便说一下。。。为什么使用数组?是..想通过draw_image()覆盖drawImage()…停止每次写入p[0],p[1]:)谢谢..这就是我想要的wt。。但是我的库中有一个小问题..这是到github的链接:在这一行中,this.drawImage(),让我们假设图像是一个像我的演示(double_ship.png)中一样的平铺精灵,那么我认为您不能将第二个精灵与此代码一起使用。。。如果我们改用这个:this.drawImage(图像,Math.floor(中心[0]/srcSize[0])*srcSize[0],Math.floor(中心[1]/srcSize[1])*srcSize[1],srcSize[0],srcSize[1],-halfWidth,-halfhighty,dstSize[0],dstststststsize[1]),会不会很糟糕…我希望这一行将使我们能够为平铺图像设置动画。使用此库似乎会降低游戏动画的性能。。。它在闪烁:(要设置动画,只需移动精灵表中的src坐标,其他什么都不做。性能:对于未旋转的对象,可以跳过save ctx+translate+rotate+restore。是否使用requestAnimationFrame?不…我没有使用raf…我使用的是setInterval()…请给我一些关于raf的有用资源。