3.7版本
代码如下
`
SpinePlayer.prototype.init = function () {
// Setup canvas and WebGL context. We pass alpha: false to canvas.getContext() so we don't use premultiplied alpha when
// loading textures. That is handled separately by PolygonBatcher.
let _this = this;
var config = {
alpha: this.alpha,
...this.otherGlOptions
};
this.gl = this.dom.getContext("webgl", config) || this.dom.getContext("experimental-webgl", config);
if (!this.gl) {
// alert('WebGL is unavailable.');
this.on.loadFail && this.on.loadFail();
return;
}
// Create a simple shader, mesh, model-view-projection matrix and SkeletonRenderer.
this.shader = spine.webgl.Shader.newTwoColoredTextured(this.gl);
this.batcher = new spine.webgl.PolygonBatcher(this.gl);
this.skeletonRenderer = new spine.webgl.SkeletonRenderer(this.gl);
// debugRenderer = new spine.webgl.SkeletonDebugRenderer(gl);
// debugRenderer.drawRegionAttachments = true;
// debugRenderer.drawBoundingBoxes = true;
// debugRenderer.drawMeshHull = true;
// debugRenderer.drawMeshTriangles = true;
// debugRenderer.drawPaths = true;
// debugShader = spine.webgl.Shader.newColored(gl);
// shapes = new spine.webgl.ShapeRenderer(gl);
this.assetManager = new spine.webgl.AssetManager(this.gl);
// Tell AssetManager to load the resources for each model, including the exported .json file, the .atlas file and the .png
// file for the atlas. We then wait until all resources are loaded in the load() method.
this.assetManager.loadText(this.jsonUrl);
this.assetManager.loadTextureAtlas(this.atlasUrl);
requestAnimationFrame(function () {
_this.load();
});
};
SpinePlayer.prototype.load = function () {
let _this = this;
let calculateBounds = (skeleton: any) => {
skeleton.setToSetupPose();
skeleton.updateWorldTransform();
var offset = new spine.Vector2();
var size = new spine.Vector2();
skeleton.getBounds(offset, size, []);
return { offset: offset, size: size };
}
let loadSkeleton = (initialAnimation: string, premultipliedAlpha: boolean, skin = "default") => {
// Load the texture atlas using name.atlas from the AssetManager.
let atlas = _this.assetManager.get(_this.atlasUrl);
// Create a AtlasAttachmentLoader that resolves region, mesh, boundingbox and path attachments
let atlasLoader = new spine.AtlasAttachmentLoader(atlas);
// Create a SkeletonJson instance for parsing the .json file.
var skeletonJson = new spine.SkeletonJson(atlasLoader);
// Set the scale to apply during parsing, parse the file, and create a new skeleton.
var skeletonData = skeletonJson.readSkeletonData(_this.assetManager.get(_this.jsonUrl));
var skeleton = new spine.Skeleton(skeletonData);
skeleton.setSkinByName(skin);
var bounds = calculateBounds(skeleton);
// Create an AnimationState, and set the initial animation in looping mode.
let animationStateData = new spine.AnimationStateData(skeleton.data);
var animationState = new spine.AnimationState(animationStateData);
animationState.addListener({
start: function (track: any) {
// console.log("Animation on track " + track.trackIndex + " started");
_this.on.start && _this.on.start(track);
},
interrupt: function (track: any) {
// console.log("Animation on track " + track.trackIndex + " interrupted");
_this.on.interrupt && _this.on.interrupt(track);
},
end: function (track: any) {
// console.log("Animation on track " + track.trackIndex + " ended");
_this.on.end && _this.on.end(track);
},
disposed: function (track: any) {
// console.log("Animation on track " + track.trackIndex + " disposed");
_this.on.disposed && _this.on.disposed(track);
},
complete: function (track: any) {
// console.log("Animation on track " + track.trackIndex + " completed");
_this.on.complete && _this.on.complete(track);
},
event: function (track: any, event: any) {
// console.log("Event on track " + track.trackIndex + ": " + JSON.stringify(event));
_this.on.event && _this.on.event(track, event);
}
});
animationState.setAnimation(0, initialAnimation, _this.isLoop);
// Pack everything up and return to caller.
return { skeleton: skeleton, state: animationState, bounds: bounds, premultipliedAlpha: premultipliedAlpha };
}
// Wait until the AssetManager has loaded all resources, then load the skeletons.
if (this.assetManager.isLoadingComplete()) {
this.skeletons = loadSkeleton(this.animName, false);
this.skeletons.bounds.size.x = Math.round(this.skeletons.bounds.size.x);
this.skeletons.bounds.size.y = Math.round(this.skeletons.bounds.size.y);
this.dom.width = this.skeletons.bounds.size.x;
this.dom.height = this.skeletons.bounds.size.y;
this.mvp.ortho2d(0, 0, this.dom.width - 1, this.dom.height - 1);
_this.autoPlay && requestAnimationFrame(function () {
_this.render();
});
} else {
requestAnimationFrame(function () {
_this.load();
});
}
};
SpinePlayer.prototype.render = function () {
let _this = this;
var now = Date.now() / 1000;
var delta = now - this.lastFrameTime;
this.lastFrameTime = now;
// Update the MVP matrix to adjust for canvas size changes
this.resize();
if (this.bgColor[0]) {
this.gl.clearColor(this.bgColor[0], this.bgColor[1], this.bgColor[2], this.bgColor[3]);
}
this.gl.clear(this.gl.COLOR_BUFFER_BIT);
// Apply the animation state based on the delta time.
var state = this.skeletons.state;
var skeleton = this.skeletons.skeleton;
var bounds = this.skeletons.bounds;
var premultipliedAlpha = this.skeletons.premultipliedAlpha;
state.update(delta);
state.apply(skeleton);
skeleton.updateWorldTransform();
// Bind the shader and set the texture and model-view-projection matrix.
this.shader.bind();
this.shader.setUniformi(spine.webgl.Shader.SAMPLER, 0);
this.shader.setUniform4x4f(spine.webgl.Shader.MVP_MATRIX, this.mvp.values);
// Start the batch and tell the SkeletonRenderer to render the active skeleton.
this.batcher.begin(this.shader);
this.skeletonRenderer.premultipliedAlpha = premultipliedAlpha;
this.skeletonRenderer.draw(this.batcher, skeleton);
this.batcher.end();
this.shader.unbind();
requestAnimationFrame(function () {
console.log('-----------,spinePlayer.init-----requestAnimationFrame')
_this.render();
});
};
`
两个spine对象同时播放时部分手机会卡死,也会出现某一动画消失的问题