createPattern(this.image,' repeat')在本地保存图像时返回null

时间:2017-09-26 15:45:30

标签: javascript image canvas

当我在本地保存图像http://www.tigrisgames.com/crate.png并使用它运行程序时,我没有获得重复模式,因为我得到了下面的代码。只有1个箱子被拉伸。我认为这与图像没有加载有关,但我无法修复它。对于任何反馈,我们都表示感谢。



var Context = {
    canvas: null,
    context: null,
    create: function(canvas_tag_id){
        this.canvas = document.getElementById(canvas_tag_id);
        this.context = this.canvas.getContext('2d');
        return this.context;
    }
}

var Sprite = function(filename, is_pattern){
    this.image = null;
    this.pattern = null;
    this.TO_RADIANS = Math.PI/180;
    if(filename != null && filename != "" && filename !=undefined ){
        this.image=  new Image();
        this.image.src = filename;
        if(is_pattern){
            
            this.pattern = Context.context.createPattern(this.image, 'repeat');
            console.log(this.pattern);

        }
    }else{
        console.log('Unable to load sprite');
    }

    this.draw = function(x,y,w,h){
        if(this.pattern != null){
            Context.context.fillStyle = this.pattern;
            Context.context.fillRect(x,y,w,h);
            
        }else{
            if(w == undefined || h == undefined){
                Context.context.drawImage(this.image, x,y, 
                                            this.image.width, 
                                            this.image.height);
            }else{
                //stretched
                Context.context.drawImage(this.image, x,y, w, h);
            }
        }
    }
}


$(document).ready(function(){
    
    Context.create('canvas');
    

    var wall = "http://www.tigrisgames.com/wall.png";
    var crate = 'http://www.tigrisgames.com/crate.png'; // 'crate.png' after saving locally in same folder


    var image = new Sprite(wall, false);
    var image2 = new Sprite(crate, false);
    var pattern = new Sprite(crate, true);
    var angle = 0;

    setInterval(function(){
        Context.context.fillStyle = "#000";
        Context.context.fillRect(0,0 , canvas.width, canvas.height);
        image.draw(0,0, undefined, 64);
        image.draw(0, 74, 256, 32);
        pattern.draw(160,160, 256, 180);

    }, 25);


});

<canvas id = "canvas" width = "640" height = "480" style="border:1px solid gray"></canvas>


<script   src="https://code.jquery.com/jquery-3.2.1.js"   integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE="   crossorigin="anonymous"></script>
<script  src="commands.js"></script>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:0)

有几个问题需要解决:

  • 使用带有canvas-context的图片时使用onload,因为如果createPattern在不使用onload的情况下不知道图片的尺寸,window.requestAnimationFrame将无法正常工作。
  • 我已插入代码来处理strech / unstrech图像显示,因此请查看注释代码。
  • 使用prototype,因为切换到另一个标签时动画停止,更多信息here
  • 将此绘制定义为instance - 函数,然后您将获得的优势是,在创建新实例时,绘制仅创建一次而不是多次
  • 使用类似this的变量来明确调用属性/方法的上下文,与var Context = { canvas: null, context: null, create: function(canvas_tag_id){ this.canvas = document.getElementById(canvas_tag_id); this.context = this.canvas.getContext('2d'); return this.context; } } var Sprite = function(filename, is_pattern, streched){ var instance = this; instance.image = null; instance.pattern = null; instance.streched = streched; // do you want to streche a image or not instance.TO_RADIANS = Math.PI/180; if(filename != null && filename != "" && filename !=undefined ){ instance.image = new Image(); // always use onload before using the image with the canvas-context instance.image.onload = function(){ // remember w/h ration for unstreched display instance.ration = instance.image.width/instance.image.height; if(is_pattern){ // createPattern did not know the dimensions of the image without onload instance.pattern = Context.context.createPattern(instance.image, 'repeat'); } }; instance.image.src = filename; }else{ console.log('Unable to load sprite'); } } // this draw function is only created once not several times when a new instance is created Sprite.prototype.draw = function(x,y,w,h){ var instance = this; if(instance.pattern != null){ Context.context.fillStyle = instance.pattern; Context.context.fillRect(x,y,w,h); }else{ if(w == undefined || h == undefined){ Context.context.drawImage(instance.image,x,y, instance.image.width, instance.image.height); }else{ //stretched // you can now control whether to strech or not by using the thir constructor-param Context.context.drawImage(instance.image, x,y, w, instance.streched ? h : w*instance.ration); } } } $(document).ready(function(){ Context.create('canvas'); var wall = "http://www.tigrisgames.com/wall.png"; var crate = 'http://www.tigrisgames.com/crate.png'; // 'crate.png' after saving locally in same folder var image = new Sprite(wall, false, true); var image2 = new Sprite(wall, false, false); // image 2 is displayed unstreched because of third param var pattern = new Sprite(crate, true); var angle = 0; // better use this instead of setInterval var drawEverything = function(){ Context.context.fillStyle = "#000"; Context.context.fillRect(0,0 , canvas.width, canvas.height); image.draw(0,0, undefined, 64); // did you not want to use image2 instead? then the wall in the middle is displayed unstreched //image2.draw(0, 74, 256, 32); image.draw(0, 74, 256, 32); pattern.draw(160,160, 256, 180); setTimeout(function(){ window.requestAnimationFrame(drawEverything); },25); }; window.requestAnimationFrame(drawEverything); }); // better use this instead of setInterval window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || function(f){return setTimeout(f, 1000/60)}
  • 相比,它的故障安全性更高
  • 我在代码中也发表了一些评论

&#13;
&#13;
<canvas id = "canvas" width = "640" height = "480" style="border:1px solid gray"></canvas>


<script   src="https://code.jquery.com/jquery-3.2.1.js"   integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE="   crossorigin="anonymous"></script>
<script  src="commands.js"></script>
&#13;
<div class="row hidden_one" (clickOutside)="onClickOutside($event)">
&#13;
&#13;
&#13;