uniapp微信小程序加载spine动画

目录

  • 1.XMLHttpRequest封装
  • spine-webgl小程序适配修改
  • 加载动画

1.XMLHttpRequest封装

function XMLHttpRequest() {
	this.config = {};
}

XMLHttpRequest.prototype = {
	overrideMimeType(mimeType) {
		this.mimeType = mimeType;
	},
	open(method, url, isAsync) {
		this.config.method = method;
		this.config.url = url;
		this.isAsync = isAsync;
	},
	send(data) {
		let reqParam = {
			url: this.config.url,
			header: {
				'Content-Type': this.mimeType || 'application/x-www-form-urlencoded'
			},
			method: this.config.method || 'post',
			dataType: 'text',
			responseType: this.responseType || 'text',
			data: data || "",
			success: (resp) => {
				this.status = resp.statusCode;
				this.readystate = 4;
				this.responseText = resp.data;
				this.onload && this.onload();
			},
			fail: (err) => {
				this.status = 9001;
				this.readystate = 4;
				this.responseText = err.message;
				this.onerror && this.onerror();
			}
		}

		uni.request(reqParam);
	}
}

module.exports = XMLHttpRequest;

spine-webgl小程序适配修改

由于js代码太大,点击下载js文件

加载动画

const spine = require('../../common/spine/spine-webgl.js');

var canvas;
var gl;
var shader;
var batcher;
var mvp = new spine.webgl.Matrix4();
var skeletonRenderer;
var assetManager;

var debugRenderer;
var shapes;

var lastFrameTime;
var skeletons = {};
var activeSkeleton = "";
var animation = "";
var swirlEffect = new spine.SwirlEffect(0);
var jitterEffect = new spine.JitterEffect(20, 20);
var swirlTime = 0;

const assetsPath = "你的资源路径";
let currentCanvas;

const dpr = uni.getSystemInfoSync().pixelRatio;

function init(initCanvas, intGl, as, am) {
	activeSkeleton = as;
	animation = am;
	
	// 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.
	currentCanvas = canvas = initCanvas;
	gl = intGl;
	if (!gl) {
		alert('WebGL is unavailable.');
		return;
	}
	
	canvas._width = canvas._width * dpr;
	canvas._height = canvas._height * dpr;
	gl.canvas.width = canvas._width * dpr;
	gl.canvas.height = canvas._height * dpr;

	shader = spine.webgl.Shader.newTwoColoredTextured(gl);
	batcher = new spine.webgl.PolygonBatcher(gl);
	mvp.ortho2d(0, 0, canvas._width, canvas._width);
	skeletonRenderer = new spine.webgl.SkeletonRenderer(gl);
	shapes = new spine.webgl.ShapeRenderer(gl);
	assetManager = new spine.webgl.AssetManager(gl);

	// Tell AssetManager to load the resources for each skeleton, including the exported .skel file, the .atlas file and the .png
	// file for the atlas. We then wait until all resources are loaded in the load() method.
	uni._canvasContexts = {
		currentCanvas,
	};

	uni._canvasContexts[assetsPath + activeSkeleton + "-pma.png"] = {
		canvas: canvas,
		gl: gl,
	}
	assetManager.loadText(assetsPath + activeSkeleton + "-pro.json");
	assetManager.loadText(assetsPath + activeSkeleton + "-pma.atlas");
	assetManager.loadTexture(assetsPath + activeSkeleton + "-pma.png");

	currentCanvas.requestAnimationFrame(load);
}

function animationChange(animationName) {
	var state = skeletons[activeSkeleton].state;
	var skeleton = skeletons[activeSkeleton].skeleton;
	skeleton.setToSetupPose();
	state.setAnimation(0, animationName, true);
}

function load() {
	// Wait until the AssetManager has loaded all resources, then load the skeletons.
	if (assetManager.isLoadingComplete()) {
		skeletons[activeSkeleton] = loadSkeleton(activeSkeleton + "-pro", animation, false);
		lastFrameTime = Date.now() / 1000;
		currentCanvas.requestAnimationFrame(render); // Loading is done, call render every frame.
	} else {
		currentCanvas.requestAnimationFrame(load);
	}
}

var atlas;
var atlasLoader;
var animationStateData;

function loadSkeleton(name, initialAnimation, premultipliedAlpha, skin) {
	if (skin === undefined) skin = "default";

	// Load the texture atlas using name.atlas from the AssetManager.
	atlas = new spine.TextureAtlas(assetManager.get(assetsPath + name.replace("-pro", "") + "-pma.atlas"), function(path) {
		return assetManager.get(assetsPath + path);
	});

	// Create a AtlasAttachmentLoader that resolves region, mesh, boundingbox and path attachments
	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(assetManager.get(assetsPath + name + ".json"));
	var skeleton = new spine.Skeleton(skeletonData);
	skeleton.setSkinByName(skin);
	var bounds = calculateSetupPoseBounds(skeleton);

	// Create an AnimationState, and set the initial animation in looping mode.
	animationStateData = new spine.AnimationStateData(skeleton.data);
	var animationState = new spine.AnimationState(animationStateData);
	animationState.setAnimation(0, initialAnimation, true);
	animationState.addListener({
		start: function(track) {
			// console.log("Animation on track " + track.trackIndex + " started");
		},
		interrupt: function(track) {
			// console.log("Animation on track " + track.trackIndex + " interrupted");
		},
		end: function(track) {
			// console.log("Animation on track " + track.trackIndex + " ended");
		},
		disposed: function(track) {
			// console.log("Animation on track " + track.trackIndex + " disposed");
		},
		complete: function(track) {
			// console.log("Animation on track " + track.trackIndex + " completed");
		},
		event: function(track, event) {
			// console.log("Event on track " + track.trackIndex + ": " + JSON.stringify(event));
		}
	})

	// Pack everything up and return to caller.
	return {
		skeleton: skeleton,
		state: animationState,
		bounds: bounds,
		premultipliedAlpha: premultipliedAlpha
	};
}

function calculateSetupPoseBounds(skeleton) {
	skeleton.setToSetupPose();
	skeleton.updateWorldTransform();
	var offset = new spine.Vector2();
	var size = new spine.Vector2();
	skeleton.getBounds(offset, size, []);
	return {
		offset: offset,
		size: size
	};
}

function render() {
	var now = Date.now() / 1000;
	var delta = now - lastFrameTime;
	lastFrameTime = now;

	// Update the MVP matrix to adjust for canvas size changes
	resize();

	gl.clearColor(0.0, 0.0, 0.0, 0);
	gl.clear(gl.COLOR_BUFFER_BIT);

	// Apply the animation state based on the delta time.
	var skeleton = skeletons[activeSkeleton].skeleton;
	var state = skeletons[activeSkeleton].state;
	var bounds = skeletons[activeSkeleton].bounds;
	var premultipliedAlpha = skeletons[activeSkeleton].premultipliedAlpha;
	state.update(delta);
	state.apply(skeleton);
	skeleton.updateWorldTransform();

	// Bind the shader and set the texture and model-view-projection matrix.
	shader.bind();
	shader.setUniformi(spine.webgl.Shader.SAMPLER, 0);
	shader.setUniform4x4f(spine.webgl.Shader.MVP_MATRIX, mvp.values);

	// Start the batch and tell the SkeletonRenderer to render the active skeleton.
	batcher.begin(shader);
	skeletonRenderer.premultipliedAlpha = premultipliedAlpha;
	skeletonRenderer.draw(batcher, skeleton);
	batcher.end();

	shader.unbind();

	currentCanvas.requestAnimationFrame(render);
}

function resize() {
	// Calculations to center the skeleton in the canvas.
	var bounds = skeletons[activeSkeleton].bounds;

	var centerX = bounds.offset.x + bounds.size.x / dpr;
	var centerY = bounds.offset.y + bounds.size.y / dpr;
	var scaleX = bounds.size.x / canvas._width;
	var scaleY = bounds.size.y / canvas._height;
	var scale = Math.max(scaleX, scaleY) * 1.2;
	// if (scale < 1) scale = 1;

	var width = canvas._width * scale;
	var height = canvas._height * scale;

	mvp.ortho2d(Math.floor(centerX - width / dpr), Math.floor(centerY - height / dpr), Math.floor(width), Math.floor(height));
	// mvp.ortho2d(centerX - width / 2, centerY - height / 2, width, height);
	gl.viewport(0, 0, canvas._width * dpr, canvas._height * dpr);
}

module.exports = {
	init,
	animationChange
}

你可能感兴趣的:(joker的开发日记,微信小程序,spine,动画)