aframe 不渲染 lottie json 纹理映射到 canvas 但在 three.js 中工作
aframe not rendering lottie json texture mapped to canvas but works in three.js
所以我基本上是在尝试通过 aframe 将 json 渲染到 canvas 上,你确实成功地将它映射到 three.js 中的 canvas 上,但是当我尝试在框架中复制它时,它只显示一个白色框架,它表明它在那里,但没有显示动画。
无法在框架中呈现 (https://glitch.com/edit/#!/sun-innate-cupboard)
能够在 three.js (https://jsfiddle.net/crays/15cgbvsp)
中呈现
function init() {
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10 );
camera.position.z = 5;
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xffffff );
const canvas = document.createElement( 'canvas' );
canvas.width = 1024;
canvas.height = 1024;
const context = canvas.getContext( '2d' );
const animation = bodymovin.loadAnimation( {
container: document.getElementById( 'bm' ),
renderer: 'canvas',
rendererSettings: {
context: context
},
loop: true,
autplay: true,
path: 'https://assets5.lottiefiles.com/packages/lf20_mb9ka7yz.json'
//animationData: json
} );
const texture = new THREE.CanvasTexture( canvas );
const geometry = new THREE.PlaneGeometry();
const material = new THREE.MeshBasicMaterial( { map: texture } );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
}
function animate() {
requestAnimationFrame( animate );
mesh.material.map.needsUpdate = true;
renderer.render( scene, camera );
}
会不会是我遗漏了什么?
两件事,不仅关于 lottie 动画,而且关于一般纹理:
1. canvas 包含透明元素
您需要告诉 material 您希望它是透明的,否则您会看到这样的伪像:
这样做相当straight-forward:
<!-- in threejs: material.transparent = true -->
<!-- in a-frame: -->
<a-entity material="transparent: true">
2。 canvas 动画
您需要告诉纹理在每个渲染循环中更新。否则只有动画的第一帧是可见的(或一个空的 cavas)。
您可以使用 custom component 轻松完成,简而言之:
// grab the mesh upon initialization
const mesh = element.getObject3D("mesh");
// cache it for later use
texture = mesh.material.map;
// on each renderloop
texture.needsUpdate = true;
3。将理论付诸实践
// load the lottie animation
const canvas = document.getElementById('animation')
const context = canvas.getContext("2d");
const animation = bodymovin.loadAnimation({
renderer: "canvas",
rendererSettings: {
context: context
},
loop: true,
autplay: true,
path: "https://assets5.lottiefiles.com/packages/lf20_mb9ka7yz.json"
});
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.7.3/lottie.min.js"></script>
<script>
AFRAME.registerComponent("update-texture", {
init: function() {
this.el.addEventListener("loaded", e => {
const mesh = this.el.getObject3D("mesh");
this.texture = mesh.material.map
})
},
tick: function() {
if (this.texture) {
this.texture.needsUpdate = true;
}
}
})
</script>
<canvas id="animation" width="1024" height="1024"></canvas>
<a-scene background="color: #ECECEC">
<a-plane position="0 1.5 -1" material="shading: flat; transparent: true; src: #animation" update-texture></a-plane>
</a-scene>
所以我基本上是在尝试通过 aframe 将 json 渲染到 canvas 上,你确实成功地将它映射到 three.js 中的 canvas 上,但是当我尝试在框架中复制它时,它只显示一个白色框架,它表明它在那里,但没有显示动画。
无法在框架中呈现 (https://glitch.com/edit/#!/sun-innate-cupboard)
能够在 three.js (https://jsfiddle.net/crays/15cgbvsp)
中呈现function init() {
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10 );
camera.position.z = 5;
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xffffff );
const canvas = document.createElement( 'canvas' );
canvas.width = 1024;
canvas.height = 1024;
const context = canvas.getContext( '2d' );
const animation = bodymovin.loadAnimation( {
container: document.getElementById( 'bm' ),
renderer: 'canvas',
rendererSettings: {
context: context
},
loop: true,
autplay: true,
path: 'https://assets5.lottiefiles.com/packages/lf20_mb9ka7yz.json'
//animationData: json
} );
const texture = new THREE.CanvasTexture( canvas );
const geometry = new THREE.PlaneGeometry();
const material = new THREE.MeshBasicMaterial( { map: texture } );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
}
function animate() {
requestAnimationFrame( animate );
mesh.material.map.needsUpdate = true;
renderer.render( scene, camera );
}
会不会是我遗漏了什么?
两件事,不仅关于 lottie 动画,而且关于一般纹理:
1. canvas 包含透明元素
您需要告诉 material 您希望它是透明的,否则您会看到这样的伪像:
这样做相当straight-forward:
<!-- in threejs: material.transparent = true -->
<!-- in a-frame: -->
<a-entity material="transparent: true">
2。 canvas 动画
您需要告诉纹理在每个渲染循环中更新。否则只有动画的第一帧是可见的(或一个空的 cavas)。 您可以使用 custom component 轻松完成,简而言之:
// grab the mesh upon initialization
const mesh = element.getObject3D("mesh");
// cache it for later use
texture = mesh.material.map;
// on each renderloop
texture.needsUpdate = true;
3。将理论付诸实践
// load the lottie animation
const canvas = document.getElementById('animation')
const context = canvas.getContext("2d");
const animation = bodymovin.loadAnimation({
renderer: "canvas",
rendererSettings: {
context: context
},
loop: true,
autplay: true,
path: "https://assets5.lottiefiles.com/packages/lf20_mb9ka7yz.json"
});
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.7.3/lottie.min.js"></script>
<script>
AFRAME.registerComponent("update-texture", {
init: function() {
this.el.addEventListener("loaded", e => {
const mesh = this.el.getObject3D("mesh");
this.texture = mesh.material.map
})
},
tick: function() {
if (this.texture) {
this.texture.needsUpdate = true;
}
}
})
</script>
<canvas id="animation" width="1024" height="1024"></canvas>
<a-scene background="color: #ECECEC">
<a-plane position="0 1.5 -1" material="shading: flat; transparent: true; src: #animation" update-texture></a-plane>
</a-scene>