Javascript 缩放HTML5画布图像

Javascript 缩放HTML5画布图像,javascript,html,oop,canvas,scale,Javascript,Html,Oop,Canvas,Scale,构建一个网页,在这个网页上我试图设置一个图像作为主画布的背景。实际图像是1600x805,我正在尝试对应用程序进行编码,以便根据用户屏幕的尺寸向上或向下缩放图像。在Prime.js中,我有一个对象,用于设置位于index.html中的应用程序画布元素的属性。以下是该对象的代码: function Prime(w,h){ if(!(function(){ return Modernizr.canvas; }))

构建一个网页,在这个网页上我试图设置一个图像作为主画布的背景。实际图像是1600x805,我正在尝试对应用程序进行编码,以便根据用户屏幕的尺寸向上或向下缩放图像。在Prime.js中,我有一个对象,用于设置位于index.html中的应用程序画布元素的属性。以下是该对象的代码:

function Prime(w,h){
        if(!(function(){
                    return Modernizr.canvas;
                })){ alert('Error'); return false; };
        this.context = null;
        this.self = this;        
        this.globalCanvasMain.w = w;
        this.globalCanvasMain.h = h;
        this.globalCanvasMain.set(this.self);
        this.background.setBg();
    }

    Prime.prototype = {
        constructor: Prime,
        self: this,
        globalCanvasMain: {
            x: 0,
            y: 0,
            set: function(ref){
                ref.context = document.getElementById('mainCanvas').getContext('2d');
                $("#mainCanvas").parent().css('position', 'relative');
                $("#mainCanvas").css({left: this.x, top: this.y, position: 'absolute'});
                $("#mainCanvas").width(this.w).height(this.h); 
            }
        },
        background: {
            bg: null,
            setBg: function(){
                this.bg = new Image();
                this.bg.src = 'res/background.jpg';
            }
        },
        drawAll: function(){

            this.context.drawImage(this.background.bg, 0,0, this.background.bg.width,this.background.bg.height, 
                                    this.globalCanvasMain.x,this.globalCanvasMain.y, this.globalCanvasMain.w,this.globalCanvasMain.h);
        }
    };
像这样的外部对象与index.html中的元素交互的主要接口是home.js。下面是那里发生的情况:

$(document).ready(function(){
    var prime = new Prime(window.innerWidth,window.innerHeight);
    setInterval(prime.drawAll(), 25);
});

出于某种原因,我对上下文的drawImage函数的调用只剪辑图像的左上角,并将其放大到用户屏幕的大小。为什么我看不到图像的其余部分?

setInterval函数有问题。您没有提供正确的函数引用。代码

setInterval(prime.drawAll(), 25);
仅执行prime.drawAll一次,因此此时加载的图像只有一小部分被渲染

正确的代码应为:

$(document).ready(function(){
    var prime = new Prime(window.innerWidth, window.innerHeight);
    setInterval(function() {
        prime.drawAll();
    }, 25);
});

问题是,在调用setInterval时,映像可能尚未完成加载。如果图像未正确加载和解码,则drawImage将:

如果图像尚未完全解码,则不会绘制任何内容

在尝试绘制图像之前,需要确保图像已加载。使用映像的onload处理程序执行此操作。此操作是异步的,因此意味着您还需要处理回调或承诺:

在背景对象中,需要为图像加载提供回调,例如:

...
background: {
    bg: null,
    setBg: function(callback) {
        this.bg = new Image();
        this.bg.onload = callback;          // supply onload handler before src
        this.bg.src = 'res/background.jpg';
    }
},
...
现在,当设置背景时,请在继续绘制之前等待回调。尽管如此,您似乎从未设置背景,这意味着drawImage尝试绘制空值:

如果要绘制缩放后的完整图像以适合画布,可以简化调用,只需提供新的大小,并且似乎没有定义此.globalCanvasMain.x/y?:

drawAll: function(){
    this.context.drawImage(this.background.bg, 0,0, 
                                                   this.globalCanvasMain.w,
                                                   this.globalCanvasMain.h);
}
我建议您使用来绘制图像,因为这将与监视器更新同步


还记得为映像对象上的onerror/onabort提供回调。

@dfsq-几乎可以肯定这会起作用,但没有改变。
drawAll: function(){
    this.context.drawImage(this.background.bg, 0,0, 
                                                   this.globalCanvasMain.w,
                                                   this.globalCanvasMain.h);
}