uniapp微信小程序加载spine动画

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
}

### 回答1: 微信小程序是一个具有高度可扩展性和交互性的平台,可以支持各种类型的应用。其中,Spine作为一种专业的2D动画引擎,可以广泛应用于游戏开发等领域。在微信小程序中使用Spine,可以为开发者提供更好的动画效果和用户体验。 使用Spine微信小程序中创建动画需要进行以下步骤: 1.将Spine动画导出为JSON格式,并将JSON文件上传到微信小程序的资源库中。 2.在微信小程序加载这个JSON文件。 3.通过代码来对这个动画进行控制、播放以及其它相应的操作。 参考Spine提供的API,开发者可以轻松地实现Spine动画微信小程序中的使用。例如,可以使用如下代码来加载一个Spine动画: let spine = wx.createAnimation({ duration: 1000, timingFunction: 'linear' }) spine.addSpriteFrame('resource/animation/spine.json') 然后,可以使用如下代码来对这个动画进行控制: let spineAnimation = spine.getSpineAnimation() // 播放Spine动画 spineAnimation.play() // 暂停Spine动画 spineAnimation.pause() // 设置Spine动画循环播放 spineAnimation.setLoop(true) // 设置Spine动画位置 spineAnimation.setPosition(0, 0) 通过以上步骤,开发者可以很容易地在微信小程序中使用Spine动画,并为用户带来更好的视觉效果和动画体验。 ### 回答2: 微信小程序现在支持使用Spine技术制作动画Spine是一种基于骨骼动画的技术,它可以让开发者更快速、灵活地创建动画效果。如果你想在小程序中使用Spine技术,你需要按照以下步骤进行: 1. 下载并安装Spine编辑器 在Spine网站中下载并安装Spine编辑器,这是创建和编辑Spine动画的必要工具。 2. 导出Spine动画文件 将Spine编辑器中的动画保存为.json文件。小程序中支持使用的Spine版本为3.5。 3. 导入小程序项目 将Spine动画文件导入到小程序项目中,并在需要使用的页面中引入文件。 4. 创建Spine对象 在页面中创建一个Spine对象,并设置动画相关的属性,如文件路径、动画名称、循环模式等。可以通过Spine对象的方法控制动画的播放和暂停。 5. 显示Spine动画Spine对象添加到页面中,并设置动画的位置和大小。则可以在小程序中展示Spine动画。 在Spine动画中,骨骼、图片和动画效果是分离的。这意味着通过更改骨骼的位置和旋转,可以轻松地创建复杂的动画效果。使用Spine技术,在小程序中展示富有表现力的动画将变得更加容易和高效。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值