创建纹理

那么,问题来了,如何加载并转换一张图片为一个可用的纹理?

使用 fromImage

创建纹理的姿势有很多,最通用的就是通过 Texture 的静态方法 fromImage 传递一个图片链接来创建:

var texture = Tiny.Texture.fromImage('images/ant.png');

接着,你可以直接使用 texture,也可以在其他地方从 TextureCache 里拿到:

console.log(Tiny.TextureCache['images/ant.png']);

注意

如果用不到加载器,且使用 Sprite 的静态方法 fromImage 创建精灵后要获取到它的宽高,那你得到一定是 {1, 1},因为没有预加载,图片要通过实例化 Image 对象来加载, new Image() 是异步的,无论在线图片还是本地的,所以此时你需要创建纹理,并监听纹理的 update

var texture = Tiny.Texture.fromImage('https://gw.alipayobjects.com/as/g/tiny/resources/1.0.0/images/logo.png');
var sprite = new Tiny.Sprite(texture);
// 如果纹理没有销毁,那么此监听回调只调用一次(慎用)
texture.on('update',function () {
  console.log('w:',sprite.width, ', h:', sprite.height);
  // w: 300, h: 300
});

使用加载器

使用加载器 Tiny.Loader 也可以缓存纹理来使用:

var loader = new Tiny.loaders.Loader();
loader
  .add('https://gw.alipayobjects.com/as/g/tiny/resources/1.0.0/images/ants/ant.png')
  .load(function(){
    var texture = Tiny.TextureCache['https://gw.alipayobjects.com/as/g/tiny/resources/1.0.0/images/ants/ant.png'];
    console.log(texture);
  });

你也可以从 loader 的 resources 对象中获取到纹理,像这样:

var texture = loader.resources['images/ant.png'].texture;
console.log(texture);

纹理创建出来了,就可以用它来创建精灵了:

var sprite = new Tiny.Sprite(texture);

实际上,最优雅的姿势是使用 Tiny.Loader.run({..}) 把所有或当前场景所需的资源都加载了,再直接通过静态方法 Tiny.Sprite.fromImage('..') 来创建精灵。

Tips

如果场景特殊,不需要提前加载资源,也可以直接使用 Tiny.Sprite.fromImage('..') 来创建精灵,Tiny.js 会 new Image() 来实时加载图片。当然,强烈建议不要这样,网络环境很差时,体验很糟糕。

使用 Image 对象或 Canvas

使用加载器并缓存到纹理缓存里来创建精灵是最优且效率最高的方式,特殊场景可以通过 Image 对象来制作纹理,这时你就需要用到 BaseTextureTexture 类:

var image = new Image();
image.crossOrigin = 'Anonymous';
image.src = 'https://gw.alipayobjects.com/as/g/tiny/resources/1.0.0/images/logo.png';
var base = new Tiny.BaseTexture(image);
var texture = new Tiny.Texture(base);

可以通过 BaseTexture.fromCanvas 静态方法来通过存在的 Canvas 对象来制作纹理:

var base = Tiny.BaseTexture.fromCanvas(anyCanvasElement);
var texture = new Tiny.Texture(base);

不使用静态方法就是这样的:

var base = new Tiny.BaseTexture(anyCanvasElement);
var texture = new Tiny.Texture(base);

使用视频

视频资源的加载往往就是用到此姿势,我们先来看看如果使用视频资源创建纹理:

var texture = Tiny.Texture.fromVideo('https://os.alipayobjects.com/rmsportal/QSOJoFHAtLqVHppcEKHj.mp4');

使用 from

这是 Texture 类的万能静态方法,它会自己判定资源类型,不信我们看看:

图片链接:

var texture = Tiny.Texture.from('https://gw.alipayobjects.com/as/g/tiny/resources/1.0.0/images/logo.png');

视频链接:

var texture = Tiny.Texture.from('https://os.alipayobjects.com/rmsportal/QSOJoFHAtLqVHppcEKHj.mp4');

HTMLImageElement:

var image = new Image();
image.crossOrigin = 'Anonymous';
image.src = 'https://gw.alipayobjects.com/as/g/tiny/resources/1.0.0/images/logo.png';
var texture = Tiny.Texture.from(image);

HTMLCanvasElement:

var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'green';
ctx.fillRect(10, 10, 100, 100);
var texture = Tiny.Texture.from(canvas);

HTMLVideoElement:

var video = document.createElement('video');
video.crossOrigin = 'Anonymous';
video.src = 'https://os.alipayobjects.com/rmsportal/QSOJoFHAtLqVHppcEKHj.mp4';
var texture = Tiny.Texture.from(video);

Tips

无论通过什么方式创建纹理,Tiny 都会把它添加到“纹理缓存”里,并且创建之前都会去“纹理缓存”中查找,所以,你可以通过任何方式重复创建,不要担心性能问题。