【问题标题】:Trouble in writing a small library in JavaScript用 JavaScript 写一个小库的麻烦
【发布时间】:2014-03-28 22:25:16
【问题描述】:

我一直在尝试用 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);

【问题讨论】:

  • draw_image 还是 drawImage ?顺便说一句... 为什么 数组?
  • ya..想要通过 draw_image() 覆盖 drawImage()..
  • 每次都停止写入 p[0],p[1] :)

标签: javascript html canvas html5-canvas drawimage


【解决方案1】:

如果您想将函数添加到 2d 上下文,由于原型继承,javascript 使这变得容易:您可以注入 Context2D 对象以根据需要添加或更改其功能。
您可能想看看我在我在这里制作的一个小画布库中为上下文添加的一些内容:https://github.com/gamealchemist/CanvasLib

有些人会说注入是邪恶的,但除非你在一艘大船上,否则我只会说:如果你使用一些图形库,请尊重现有函数的语义,一切都应该没问题。如果你不使用库:尽一切可能!

所以,为了更具体地回答您的问题,您较短的 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();

【讨论】:

  • thankz..这正是我想要的..但​​我的图书馆有点麻烦..这里是 github 的链接:github.com/d3vas3m/canvasImage
  • 在 this.drawImage() 这一行中,假设图像是像我的演示 (double_ship.png) 中一样的平铺精灵,那么我认为您不能使用带有此代码的第二个精灵...如果我们改用它不会很奇怪: this.drawImage(image, Math.floor(center[0]/srcSize[0])*srcSize[0], Math.floor(center[1]/srcSize[1]) *srcSize[1], srcSize[0], srcSize[1], -halfWidth, -halfHeight, dstSize[0], dstSize[1])...我希望这条线能让我们为平铺图像设置动画。跨度>
  • 使用这个库似乎会降低我游戏动画的性能......它在闪​​烁:(
  • 要制作动画,只需移动精灵表中的 src 坐标即可,无需其他任何操作。对于表演:保存 ctx + translate + rotate + restore 可以跳过非旋转对象。你在使用 requestAnimationFrame 吗?
  • 不...我没有使用 raf...我正在使用 setInterval()...请给我一些有关 raf 的有用资源。
【解决方案2】:

您的小型图像库可以很好地放入 javascript 对象中。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-24
    • 2021-04-28
    • 2012-02-29
    • 1970-01-01
    • 1970-01-01
    • 2015-10-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多