Commit 6eaccc96 authored by wjf's avatar wjf

2.0.1

parent a1341c41
......@@ -4,3 +4,4 @@ node_modules
debug
.vscode
dist
test
......@@ -11,4 +11,5 @@ webpack.config.js
/dist
rollup.config.js
record.txt
test
\ No newline at end of file
test
examples
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -11,15 +11,9 @@
<meta name="screen-orientation" content="portrait" />
<meta name="x5-fullscreen" content="true" />
<meta name="360-fullscreen" content="true" />
<!-- <script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script> -->
<!-- 小程序分享得用这个 -->
<!-- <script src="https://res.wx.qq.com/open/js/jweixin-1.3.2.js"></script> -->
<!-- 易盾js -->
<!-- <script type="text/javascript" src="//cstaticdun.126.net/load.min.js"></script> -->
<!-- <script src="libs/zepto.min.js"></script> -->
<!-- <script src="libs/p2.js"></script> -->
<!-- 加载svga文件用 -->
<script src="//yun.duiba.com.cn/db_games/libs0924/svgaParser.min.js"></script>
<!-- 加载svga文件用 npm svga-parser-->
<script src="./js/svgaParser.min.js"></script>
<!-- 主引擎 -->
<script src="../build/fyge.min.js"></script>
<style>
html,
......@@ -41,8 +35,6 @@
<div id="cusEngine" style="line-height:0;font-size:0">
<canvas id="canvas" style="width: 100%;height: 100%"></canvas>
</div>
<!-- 帧率检测 -->
<script src="//yun.duiba.com.cn/db_games/libs0924/stats.js"></script>
</body>
<script>
window.addEventListener("load", async function () {
......@@ -72,7 +64,7 @@
//@ts-ignore 存在my就初始化
sysInfo = my.getSystemInfoSync()
}
//建舞台
//建舞台,定宽适配,会根据实际窗口尺寸上下裁切,所以stage实际y坐标会偏移stage.viewRect.y
var stage = new FYGE.Stage(
canvas,
750,//设计宽度,按设计搞给的就行
......@@ -86,6 +78,10 @@
canvas.addEventListener("touchstart", mouseEvent, false);
canvas.addEventListener('touchmove', mouseEvent, false);
canvas.addEventListener('touchend', mouseEvent, false);
//pc
canvas.addEventListener("mousedown", mouseEvent, false);
canvas.addEventListener('mousemove', mouseEvent, false);
canvas.addEventListener('mouseup', mouseEvent, false);
//stage初始化
stage.addEventListener(FYGE.Event.INIT_STAGE, async () => {
......@@ -107,6 +103,12 @@
sp.position.set(200, 500);//位置
sp.scale.set(0.5, 0.5)//缩放
sp.anchorTexture.set(0.5, 0.5)//贴图锚点,改变初始坐标,0到1
//遮罩
var mask = stage.addChild(new FYGE.Graphics())
.beginFill(0x000000)
.drawRect(100, 500, 400, 300)
.endFill()
sp.mask = mask;
//来个动画
FYGE.Tween.get(sp)
.to({ rotation: 360 }, 5000)
......@@ -142,7 +144,7 @@
scroll.position.set(500, 1100)
scroll.view.addChild(new FYGE.Sprite(texture))//在view里面添加
scroll.maxDistance = 1000
setTimeout(()=>{scroll.scrollTo(200,2000)},2000)
setTimeout(() => { scroll.scrollTo(200, 2000) }, 2000)
//滚动列表
var list = new FYGE.ScrollList(class extends FYGE.Sprite {
......@@ -204,7 +206,8 @@
FYGE.Tween.flush()
//舞台每帧刷新
stage.flush();
FYGE.getRequestAnimationFrame()(loop);
// FYGE.getRequestAnimationFrame()(loop);
requestAnimationFrame(loop)
}
})
......
This diff is collapsed.
var Stats = function () {
var startTime = Date.now(), prevTime = startTime;
var ms = 0, msMin = Infinity, msMax = 0;
var fps = 0, fpsMin = Infinity, fpsMax = 0;
var frames = 0, mode = 0;
var container = document.createElement('div');
container.id = 'stats';
container.addEventListener('mousedown', function (event) { event.preventDefault(); setMode(++mode % 2) }, false);
container.style.cssText = 'width:80px;opacity:0.9;cursor:pointer';
var fpsDiv = document.createElement('div');
fpsDiv.id = 'fps';
fpsDiv.style.cssText = 'padding:0 0 3px 3px;text-align:left;background-color:#002';
container.appendChild(fpsDiv);
var fpsText = document.createElement('div');
fpsText.id = 'fpsText';
fpsText.style.cssText = 'color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px';
fpsText.innerHTML = 'FPS';
fpsDiv.appendChild(fpsText);
var fpsGraph = document.createElement('div');
fpsGraph.id = 'fpsGraph';
fpsGraph.style.cssText = 'position:relative;width:74px;height:30px;background-color:#0ff';
fpsDiv.appendChild(fpsGraph);
while (fpsGraph.children.length < 74) {
var bar = document.createElement('span');
bar.style.cssText = 'width:1px;height:30px;float:left;background-color:#113';
fpsGraph.appendChild(bar);
}
var msDiv = document.createElement('div');
msDiv.id = 'ms';
msDiv.style.cssText = 'padding:0 0 3px 3px;text-align:left;background-color:#020;display:none';
container.appendChild(msDiv);
var msText = document.createElement('div');
msText.id = 'msText';
msText.style.cssText = 'color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px';
msText.innerHTML = 'MS';
msDiv.appendChild(msText);
var msGraph = document.createElement('div');
msGraph.id = 'msGraph';
msGraph.style.cssText = 'position:relative;width:74px;height:30px;background-color:#0f0';
msDiv.appendChild(msGraph);
while (msGraph.children.length < 74) {
var bar = document.createElement('span');
bar.style.cssText = 'width:1px;height:30px;float:left;background-color:#131';
msGraph.appendChild(bar);
}
var setMode = function (value) {
mode = value;
switch (mode) {
case 0:
fpsDiv.style.display = 'block';
msDiv.style.display = 'none';
break;
case 1:
fpsDiv.style.display = 'none';
msDiv.style.display = 'block';
break;
}
}
var updateGraph = function (dom, value) {
var child = dom.appendChild(dom.firstChild);
child.style.height = value + 'px';
}
return {
REVISION: 11,
domElement: container,
setMode: setMode,
begin: function () {
startTime = Date.now();
},
end: function () {
var time = Date.now();
ms = time - startTime;
msMin = Math.min(msMin, ms);
msMax = Math.max(msMax, ms);
msText.textContent = ms + ' MS (' + msMin + '-' + msMax + ')';
updateGraph(msGraph, Math.min(30, 30 - (ms / 200) * 30));
frames++;
if (time > prevTime + 1000) {
fps = Math.round((frames * 1000) / (time - prevTime));
fpsMin = Math.min(fpsMin, fps);
fpsMax = Math.max(fpsMax, fps);
fpsText.textContent = fps + ' FPS (' + fpsMin + '-' + fpsMax + ')';
updateGraph(fpsGraph, Math.min(30, 30 - (fps / 100) * 30));
prevTime = time;
frames = 0;
}
return time;
},
update: function () {
startTime = this.end();
}
}
};
//鎵ц
var stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
document.body.appendChild(stats.domElement);
aa();
function aa() {
stats.update();
requestAnimationFrame(aa)
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
{
"name": "fyge",
"version": "2.0.0",
"version": "2.0.1",
"description": "canvas渲染引擎",
"main": "./build/fyge.min.js",
"types": "./build/FYGE.d.ts",
......
......@@ -117,12 +117,17 @@
scrollPage的scrollTo用Tween做缓动
2.0.0 添加3d模块
webglRenderer里的bindVao方法添加第二个参数force,是否强制执行vao.bind(),默认false,D3Renderer里用
webglRenderer里的bindVao方法添加第二个参数force,是否强制执行vao.bind(),默认false,D3Renderer里用(到时考虑根据vao的dirty判断bind)
2.0.1 VertexArrayObject里removeAttribute添加标记this.dirty = true;
generateUniformAccessObject的GLSL_ARRAY_SETTERS里添加setMat4Array方法,传矩阵数组
stage的onMouseEvent添加pc的points,
stage的_mouseEventTypes添加3个pc的鼠标事件映射
scrollPage手动移动时去掉Tween,destroy时去掉Tween
3d添加骨骼动画
//已改,但没build和publish
VertexArrayObject的addAttribute添加个参数name用于移除,添加方法removeAttribute,后续考虑用对象
2.0.0以后的都是3d版本
以后注意提交的时候带版本号,方便搜索修改记录,const里的版本要修改
//TODO
......@@ -156,4 +161,6 @@ Graphics的_canvasRender绘制模式下也要加finishPoly
目前canvas模式下不能用纯纹理的sprite作为遮罩
3D模块分支dev3D,只需要里面的./src/3D文件夹和./test文件夹,暂时不会把dev的修改合并到dev3D
\ No newline at end of file
3D模块分支dev3D,只需要里面的./src/3D文件夹和./test文件夹,暂时不会把dev的修改合并到dev3D
D3Renderer到时要考虑重新addAttr,重新bindVao,重新传数据upload,到时改造下vao,
\ No newline at end of file
......@@ -7,7 +7,7 @@
* @name VERSION
* @type {string}
*/
export const VERSION = "2.0.0";
export const VERSION = "2.0.1";
/**
......
import Container from "./Container";
import { RENDERER_TYPE, VERSION } from "../const"
import { RENDERER_TYPE, VERSION, osType } from "../const"
// import SystemRenderer from "../renderers/SystemRenderer";
import { Rectangle, Point } from "../math";
import { EventDispatcher } from "../events/EventDispatcher";
......@@ -270,14 +270,21 @@ export class Stage extends Container {
/**
* html的鼠标或单点触摸对应的引擎事件类型名
* touchcancel:"onMouseUp"不常用,先不加
* @property _mouseEventTypes
* @type {{mousedown: string, mouseup: string, mousemove: string, touchstart: string, touchmove: string, touchend: string}}
* @private
*/
private _mouseEventTypes: any = {
//pc
mousedown: "onMouseDown",
mousemove: "onMouseMove",
mouseup: "onMouseUp",
//mobile
touchstart: "onMouseDown",
touchmove: "onMouseMove",
touchend: "onMouseUp",
//tbMini
touchStart: "onMouseDown",//小程序返回的时间名是驼峰的
touchMove: "onMouseMove",
touchEnd: "onMouseUp"
......@@ -310,12 +317,14 @@ export class Stage extends Container {
//事件个数
let eLen: number;
let identifier: any;
points = [e.changedTouches[0]];
// points = [e.touches[0]];
// my.alert({
// title: '55729:' + points.length
// });
if (osType == "pc") {
e.identifier = 0;
points = [e];
} else {
points = [e.changedTouches[0]];
}
// points = [e.changedTouches[0]];
// points = [e.touches[0]];//不能用这个
let offSetX = s._canvasOffsetX, offSetY = s._canvasOffsetY;
//@ts-ignore
if (getEnv() == "web") {
......
......@@ -302,7 +302,7 @@ export class WebglRenderer extends SystemRenderer {
bindVao(vao: VertexArrayObject, force: boolean = false): WebglRenderer {
if (this._activeVao === vao) {
//计算是同一个也要bind,因为有可能vao里的attr被修改了,但是vao用的同一个,会导致buff不生效
if (force) vao.bind();
if (force) vao.bind();//TODO,考虑是否用vao.dirty来确定要不要执行bind(讲道理dirty必须重新bind通道)
return this;
}
......
......@@ -306,7 +306,8 @@ export class ScrollPage extends Container {
if (s.autoScroll) {
s.autoScroll = false;
// Tween.kill(s._tweenId);
cancelAnimationFrame(s._tweenId)
// cancelAnimationFrame(s._tweenId)
Tween.removeTweens(s.view)
}
if (s.isVertical) {
s.lastValue = e.stageY//e.localY;//move事件添加到舞台的,需要用stageY
......@@ -439,6 +440,8 @@ export class ScrollPage extends Container {
}
}
public destroy(): void {
//Tween去掉
Tween.removeTweens(this.view);
let s = this;
s.maskObj.destroy();
s.view.destroy();
......
......@@ -13,6 +13,9 @@ import { BatchBuffer } from "../2d/renderers/webgl/BatchBuffer";
import { BaseMaterial, RenderSideType } from "./materials/BaseMaterial";
import { getCusShader } from "./shaders/getCusShader";
import { Geometry, VaoBufferInt } from ".";
import { SkinnedMesh3D } from "./bones/SkinnedMesh3D";
import { nextPow2 } from "../2d/utils"
import { BaseTexture } from "../2d/texture";
//需要管理渲染的状态 resetToDefault resetTo3D
......@@ -26,12 +29,23 @@ export class D3Renderer extends ObjectRenderer {
*/
lightsConfig: LightsConfig;
/**
* 顶点着色器可传的最大uniform通道
*/
maxVertexUniforms: number
floatVertexTextures: boolean;
private curLightkey: string;
constructor(renderer: WebglRenderer) {
super(renderer);
}
onContextChange() {
var gl = this.renderer.gl;
this.maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS );
var maxVertexTextures = gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS);
var vertexTextures = maxVertexTextures > 0;
var floatFragmentTextures = !!gl.getExtension("OES_texture_float");
//传入的数据纹理暂时有问题,是UNPACK_ALIGNMENT还是UNPACK_FLIP_Y_WEBGL的问题未知,所以不管先
this.floatVertexTextures = false//vertexTextures && floatFragmentTextures;
}
start() {
//设置3d状态机属性
......@@ -85,8 +99,9 @@ export class D3Renderer extends ObjectRenderer {
let mesh = this.meshes[i];//怎么判断是否要重新绑定
let mat: BaseMaterial = mesh.material;
let geo = mesh.geometry;
let maxBones = this.getMaxBones(mesh)
let shader = getCusShader(this.renderer, mat, this.lightsConfig, mesh);
let shader = getCusShader(this.renderer, mat, this.lightsConfig, mesh, maxBones, this.floatVertexTextures);
if (curShader !== shader) {//同一着色器只需要传一次相机参数和光照参数(因为都是场景全局)
curShader = shader;
//先绑定着色器,project不设置
......@@ -130,6 +145,46 @@ export class D3Renderer extends ObjectRenderer {
curShader.uniforms["uNormalMatrix"] = normalMatrix.toArray()
// this.setShaderUniform(curShader, "uNormalMatrix", normalMatrix.toArray());
}
//骨骼需要的uniform
if (mat.skinning && maxBones > 0 && mesh.instanceType == "SkinnedMesh3D") {
//@ts-ignore
let sMesh: SkinnedMesh3D = mesh;
curShader.uniforms["uBindMatrix"] = sMesh.bindMatrix.toArray();
curShader.uniforms["uBindMatrixInverse"] = sMesh.bindMatrixInverse.toArray();
// sMesh.skeleton.update()
var skeleton = sMesh.skeleton;
if (skeleton) {
var bones = skeleton.bones;
if (this.floatVertexTextures) {
if (!skeleton.boneTexture) {
// layout (1 matrix = 4 pixels)
// RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)
// with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8)
// 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16)
// 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32)
// 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64)
var size = Math.sqrt(bones.length * 4); // 4 pixels needed for 1 matrix
size = (function (value) {
return Math.pow(2, Math.ceil(Math.log(value) / Math.LN2));
})(size);
size = Math.max(size, 4);
var boneMatrices = new Float32Array(size * size * 4); // 4 floats per RGBA pixel
boneMatrices.set(skeleton.boneMatrices); // copy current values
var boneTexture = new BaseTexture({ data: boneMatrices, width: size, height: size });
boneTexture.mipmap=false;
skeleton.boneMatrices = boneMatrices;
skeleton.boneTexture = boneTexture;
skeleton.boneTextureSize = size;
}
let location: number = this.renderer.textureManager.bindTexture(skeleton.boneTexture, undefined, false);
curShader.uniforms["uBoneTexture"] = location;
curShader.uniforms["uBoneTextureSize"] = skeleton.boneTextureSize;
} else {
curShader.uniforms["uBoneMatrices"] = sMesh.skeleton.boneMatrices;
}
}
}
//几何属性
var glVaoBuffer = geo._glVaoBuffer[this.renderer.CONTEXT_UID];
......@@ -159,6 +214,9 @@ export class D3Renderer extends ObjectRenderer {
// )
// }
}
//骨骼
if (geo._skinWeight) glVaoBuffer.skinWeightBuffer = GLBuffer.createVertexBuffer(gl, null, gl.STATIC_DRAW);
if (geo._skinIndex) glVaoBuffer.skinIndexBuffer = GLBuffer.createVertexBuffer(gl, null, gl.STATIC_DRAW);
//计算一次,打包所有的顶点属性,位置,颜色,uv,法线
packGeometry(geo);
......@@ -181,6 +239,9 @@ export class D3Renderer extends ObjectRenderer {
if (attrs.aNormal) vao.addAttribute(glVaoBuffer.attrBuffer, attrs.aNormal, gl.FLOAT, false, geo._vertByteSize, 8 * 4);
//索引看情况加
if (geo._indices) vao.addIndex(glVaoBuffer.indexBuffer);
//骨骼的
if (attrs.aSkinWeight) vao.addAttribute(glVaoBuffer.skinWeightBuffer, attrs.aSkinWeight, gl.FLOAT, false, 0, 0);
if (attrs.aSkinIndex) vao.addAttribute(glVaoBuffer.skinIndexBuffer, attrs.aSkinIndex, gl.UNSIGNED_BYTE, false, 0, 0);
//变形数据,首次直接addAttribute
var uploadBufferDatas: UploadBufferData[];
if (mesh.morphTargetInfluences && mat.morphTargets) {
......@@ -200,12 +261,15 @@ export class D3Renderer extends ObjectRenderer {
glVaoBuffer.attrBuffer.upload(geo._attrBuffer.vertices, 0, false);//首次还是bind吧,必须bind,否则buffer溢出
//有索引才改
if (geo._indices) glVaoBuffer.indexBuffer.upload(geo._indices, 0, false);//首次还是bind吧
//骨骼的
if (attrs.aSkinWeight) glVaoBuffer.skinWeightBuffer.upload(new Float32Array(geo._skinWeight), 0, false)
if (attrs.aSkinIndex) glVaoBuffer.skinIndexBuffer.upload(new Uint8Array(geo._skinIndex), 0, false)
//还得在这里做数据的变形
if (uploadBufferDatas) uploadBufferDatas.forEach((e) => {
e.buffer.upload(e.data, 0, false);
})
} else {
//变形数据
//变形数据,暂时只有这个要做改变,其他的估计到时也要搞,TODO
var uploadBufferDatas: UploadBufferData[];
if (mesh.morphTargetInfluences && mat.morphTargets) {
uploadBufferDatas = addMorphtargetsAttr(
......@@ -217,9 +281,9 @@ export class D3Renderer extends ObjectRenderer {
gl
)
}
this.renderer.bindVao(vao,!!uploadBufferDatas);
//不修改,估计都不要变,需要修改时候
//进过上面判断,必有uploadBufferDatas,TODO,到时考虑不传force,用vao.dirty判断是否bind
this.renderer.bindVao(vao, !!uploadBufferDatas);
//不修改,估计都不要变,需要修改时候TODO.好多数据,包括vao可能也需要重新bind
// glVaoBuffer.attrBuffer.upload(glVaoBuffer._attrBuffer.vertices, 0, true)
// glVaoBuffer.indexBuffer.upload(glVaoBuffer._indexBuffer, 0, true)
......@@ -242,6 +306,20 @@ export class D3Renderer extends ObjectRenderer {
}
this.meshes.length = 0
}
private getMaxBones(object) {
if (object.instanceType !== "SkinnedMesh3D") return 0;
if (this.floatVertexTextures) return 1024;
var skeleton = object.skeleton;
var bones = skeleton.bones;
var nVertexMatrices = Math.floor((this.maxVertexUniforms - 20) / 4);
var maxBones = Math.min(nVertexMatrices, bones.length);
if (maxBones < bones.length) {
console.warn('Skeleton has ' + bones.length + ' bones. This GPU supports ' + maxBones + '.');
return 0;
}
return maxBones;
}
}
/**
......
......@@ -5,12 +5,15 @@ import { Vector2 } from "./math/Vector2";
import { BatchBuffer } from "../2d/renderers/webgl/BatchBuffer";
import { Box3 } from "./math/Box3";
import { Sphere } from "./math/Sphere";
import { Bone } from "./bones/Bone";
/**
* 考虑需要记录哪些几何数据
* 暂时都在构造中执行一次数据的赋值,如果以后涉及需要动态修改数据的,加标记修改,插件里也需要重新upload数据
* 到时改成对象记录所有attribute。仿three,但是vao还会存在,但是会检查是否更新
* 感觉东西越来越多,迟早得换成three的方式,到时还要考虑数据要修改的情况,否则做游戏蛋疼,现在不改是担心改了后性能出问题,
*/
export class Geometry extends HashObject {
/**
......@@ -23,9 +26,14 @@ export class Geometry extends HashObject {
_uvs: Float32Array | number[];
_normals: Float32Array | number[];
_indices: Uint16Array | number[];
//这两个是为了骨骼动画,都是vec4
_skinWeight: Float32Array | number[];
_skinIndex: Float32Array | number[];
//可自行bind到Mesh,不一定挂在geo上
bones: Bone[]
boundingBox: Box3 = null;
......@@ -131,6 +139,11 @@ export class Geometry extends HashObject {
}
};
// copy(){
// }
// clone(){}
destroy() {
......@@ -157,6 +170,12 @@ export interface VaoBufferInt {
* 变形法线数据,数组,最大长度4
*/
morphNormalBuffers?: GLBuffer[],
/**
* 这两个buffer用于骨骼
*/
skinWeightBuffer?: GLBuffer,
skinIndexBuffer?: GLBuffer,
/**
* 需要根据着色器程序id作为指向,
* 灯光重置过着色器,基本要重来一次,上面的buffer可以留着,重新addAttr到新的vao
......
......@@ -231,6 +231,11 @@ export class Object3D extends EventDispatcher {
this._localMatrix.compose(this.position, this.quaternion, this.scale);
// this.dirty=true
}
/**
* 现在每帧都计算,以后考虑加标记,或手动设置标记更新
* @param updateParents
* @param updateChildren
*/
updateWorldMatrix(updateParents: boolean = false, updateChildren: boolean = true) {
var parent = this.parent;
......
......@@ -63,7 +63,7 @@ export class AnimationTrack3D extends HashObject {
this.node[this.animationType].fromArray(value);
break;
case AnimationType.morphTargetInfluences:
if (this.node.instanceType == "Mesh3D") {
if (this.node.instanceType == "Mesh3D"||this.node.instanceType == "SkinnedMesh3D") {
var arr = this.node["morphTargetInfluences"]
for (var i = 0; i < arr.length; i++) {
arr[i] = value[i] || 0;
......
import { Object3D } from '../Object3D';
/**
* 记录骨骼数据用
*/
export class Bone extends Object3D {
//模型解析注意,不能用parent,用par
par:number
//这三个可能是模型数据上的
pos;
rotq;
scl;
constructor() {
super()
this._instanceType = 'Bone';
}
// __a
// updateWorldMatrix(){
// super.updateWorldMatrix()
// // console.log(this._worldMatrix)
// for(var i=0;i<this._worldMatrix.elements.length;i++){
// if(!this.__a)break
// if(this._worldMatrix.elements!==this.__a[i]){
// // console.log(this.__a[i])
// break
// }
// }
// this.__a = this._worldMatrix.elements.slice()
// }
}
import { Matrix4 } from '../math/Matrix4';
import { Bone } from './Bone';
import { HashObject } from '../../2d/HashObject';
import { BaseTexture } from '../../2d/texture';
const offsetMatrix = new Matrix4();
const identityMatrix = new Matrix4();
export class Skeleton extends HashObject {
bones: Bone[];
boneMatrices: Float32Array;
boneInverses: Matrix4[];
boneTexture: BaseTexture;
boneTextureSize:number
constructor(bones: Bone[] = [], boneInverses?: Matrix4[]) {
super();
this._instanceType = "Skeleton";
this.bones = bones.slice(0);
this.boneMatrices = new Float32Array(this.bones.length * 16);
if (!boneInverses) {
this.calculateInverses();
} else {
if (this.bones.length === boneInverses.length) {
this.boneInverses = boneInverses.slice(0);
} else {
console.warn('boneInverses长度有误');
this.boneInverses = [];
for (var i = 0, il = this.bones.length; i < il; i++) {
this.boneInverses.push(new Matrix4());
}
}
}
}
calculateInverses() {
this.boneInverses = [];
for (var i = 0, il = this.bones.length; i < il; i++) {
var inverse = new Matrix4();
if (this.bones[i]) {
inverse.setInverseOf(this.bones[i]._worldMatrix);
}
this.boneInverses.push(inverse);
}
}
pose() {
var bone: Bone, i, il;
// recover the bind-time world matrices
for (i = 0, il = this.bones.length; i < il; i++) {
bone = this.bones[i];
if (bone) {
bone._worldMatrix.setInverseOf(this.boneInverses[i]);
}
}
// compute the local matrices, positions, rotations and scales
for (i = 0, il = this.bones.length; i < il; i++) {
bone = this.bones[i];
if (bone) {
if (bone.parent && bone.parent.instanceType == "Bone") {
bone._localMatrix.setInverseOf(bone.parent._worldMatrix);
bone._localMatrix.multiply(bone._worldMatrix);
} else {
bone._localMatrix.copy(bone._worldMatrix);
}
bone._localMatrix.decompose(bone.position, bone.quaternion, bone.scale);
}
}
}
/**
* skinnedMesh3D里面调用
*/
update() {
// this.calculateInverses();
var bones = this.bones;
var boneInverses = this.boneInverses;
var boneMatrices = this.boneMatrices;
var boneTexture = this.boneTexture;
// flatten bone matrices to array
for (var i = 0, il = bones.length; i < il; i++) {
// compute the offset between the current and the original transform
var matrix = bones[i] ? bones[i]._worldMatrix : identityMatrix;
offsetMatrix.multiplyMatrices(matrix, boneInverses[i]);
//@ts-ignore
offsetMatrix.toArray(boneMatrices, i * 16);
}
// if(this.instanceId==310)console.log(this.bones[0]._worldMatrix.elements[2])
if (boneTexture) boneTexture.update();
};
clone() {
return new Skeleton(this.bones, this.boneInverses);
}
getBoneByName(name: string) {
for (var i = 0, il = this.bones.length; i < il; i++) {
var bone = this.bones[i];
if (bone.name === name) return bone;
}
return null;
}
destroy() {
//TODO
}
}
import { Mesh3D } from '../Mesh3D';
// import { Vector4 } from '../math/Vector4.js';
import { Skeleton } from './Skeleton';
import { Bone } from './Bone';
import { Matrix4 } from '../math/Matrix4';
import { Geometry } from '../Geometry';
import { BaseMaterial } from '../materials';
export class SkinnedMesh3D extends Mesh3D {
public bindMode: "attached" | "detached" = "attached";
public bindMatrix = new Matrix4();
public bindMatrixInverse = new Matrix4();
public skeleton: Skeleton;
constructor(geometry: Geometry, material: BaseMaterial) {
super(geometry, material)
this._instanceType = "SkinnedMesh3D";
var bones = this.initBones();
var skeleton = new Skeleton(bones);
this.bind(skeleton, this._worldMatrix);
this.normalizeSkinWeights();
}
initBones() {
var bones: Bone[] = [], bone: Bone, gbone: Bone;
var i: number, il: number;
if (this.geometry && this.geometry.bones !== undefined) {
// first, create array of 'Bone' objects from geometry data
for (i = 0, il = this.geometry.bones.length; i < il; i++) {
gbone = this.geometry.bones[i];
// create new 'Bone' object
bone = new Bone();
bones.push(bone);
// apply values
bone.name = gbone.name;
bone.position.fromArray(gbone.pos);
bone.quaternion.fromArray(gbone.rotq);
if (gbone.scl !== undefined) bone.scale.fromArray(gbone.scl);
}
// second, create bone hierarchy
for (i = 0, il = this.geometry.bones.length; i < il; i++) {
gbone = this.geometry.bones[i];
if ((gbone.par !== - 1) && (gbone.par !== null) && (bones[gbone.par] !== undefined)) {
// subsequent bones in the hierarchy
bones[gbone.par].addChild(bones[i]);
} else {
// topmost bone, immediate child of the skinned mesh
this.addChild(bones[i]);
}
}
}
// now the bones are part of the scene graph and children of the skinned mesh.
// let's update the corresponding matrices
this.updateWorldMatrix();
return bones;
}
bind(skeleton: Skeleton, bindMatrix: Matrix4) {
this.skeleton = skeleton;
if (bindMatrix === undefined) {
this.updateWorldMatrix();
this.skeleton.calculateInverses();
bindMatrix = this._worldMatrix;
}
this.bindMatrix.copy(bindMatrix);
this.bindMatrixInverse.setInverseOf(bindMatrix);
}
pose() {
this.skeleton.pose();
}
normalizeSkinWeights() {
var scale, i;
if (this.geometry) {
var vec = new Vector4();
var skinWeight = this.geometry._skinWeight;
var len = skinWeight.length / 4 || 0;
for (i = 0; i < len; i++) {
vec.x = skinWeight[i * 4];
vec.y = skinWeight[i * 4 + 1];
vec.z = skinWeight[i * 4 + 2];
vec.w = skinWeight[i * 4 + 3];
scale = 1.0 / vec.manhattanLength();
if (scale !== Infinity) {
vec.multiplyScalar(scale);
} else {
vec.set(1, 0, 0, 0); // do something reasonable
}
// skinWeight.setXYZW(i, vec.x, vec.y, vec.z, vec.w);
skinWeight[i * 4] = vec.x;
skinWeight[i * 4 + 1] = vec.y;
skinWeight[i * 4 + 2] = vec.z;
skinWeight[i * 4 + 3] = vec.w;
}
}
}
updateWorldMatrix() {
super.updateWorldMatrix()
if (this.bindMode === 'attached') {
this.bindMatrixInverse.setInverseOf(this._worldMatrix);
} else if (this.bindMode === 'detached') {
this.bindMatrixInverse.setInverseOf(this.bindMatrix);
} else {
}
}
update() {
if (!this.visible) return;
this.skeleton.update();
super.update();
}
clone() {
return new SkinnedMesh3D(this.geometry, this.material).copy(this);
}
}
//暂时只有这里用到,就几个方法,简单写
class Vector4 {
constructor(
public x: number = 0,
public y: number = 0,
public z: number = 0,
public w = 1
) { }
set(x: number, y: number, z: number, w: number) {
this.x = x;
this.y = y;
this.z = z;
this.w = w;
return this;
}
multiplyScalar(scalar: number) {
this.x *= scalar;
this.y *= scalar;
this.z *= scalar;
this.w *= scalar;
return this;
}
manhattanLength() {
return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z) + Math.abs(this.w);
}
}
This diff is collapsed.
......@@ -60,6 +60,7 @@ export class BaseMaterial extends HashObject {
}
morphTargets: boolean = false;
morphNormals: boolean = false;
skinning: boolean = false;
/**
* 是否用线框形式绘制
*/
......@@ -81,6 +82,21 @@ export class BaseMaterial extends HashObject {
}
}
}
copy(material: BaseMaterial) {
this.color = material.color;
this.map = material.map;
this.alpha = material.alpha;
this.morphTargets = material.morphTargets;
this.morphNormals = material.morphNormals;
this.skinning = material.skinning;
this.wireframe = material.wireframe;
this.side = material.side;
this._lightAffect = material._lightAffect;
return this;
}
clone() {
return new BaseMaterial().copy( this );
}
destroy() {
this._color = null;
}
......@@ -91,5 +107,5 @@ export interface BaseMaterialParamsInt {
alpha?: number,
map?: Texture,
wireframe?: boolean,
side?:RenderSideType
side?: RenderSideType
}
\ No newline at end of file
......@@ -7,4 +7,7 @@ export class LightMaterial extends BaseMaterial {
this._instanceType = "LightMaterial";
this._lightAffect = true;
}
clone() {
return new LightMaterial().copy(this);
}
}
\ No newline at end of file
......@@ -12,13 +12,25 @@ import { Mesh3D } from "..";
* @param material
* @param lights
*/
export function getCusShader(render: WebglRenderer, material: BaseMaterial, lights: LightsConfig, mesh: Mesh3D) {
export function getCusShader(
render: WebglRenderer,
material: BaseMaterial,
lights: LightsConfig,
mesh: Mesh3D,
maxBones?: number,
useVertexTexture?: boolean
) {
//所有参数
var parameters: ShaderParametersInt = {
pointLightsNum: lights.pointLights.length,
dirLightsNum: lights.directionalLights.length,
morphTargets: mesh.morphTargetInfluences && material.morphTargets,
morphNormals: mesh.morphTargetInfluences && material.morphTargets && material.morphNormals,
skinning: material.skinning && maxBones > 0,
maxBones: maxBones || 0,
useVertexTexture: useVertexTexture,
lightAffect: material._lightAffect,
}
//计算code,
......@@ -78,6 +90,9 @@ class CusShader extends GLShader {
parameters.lightAffect ? '#define USE_LIGHT' : '',
parameters.morphTargets ? '#define USE_MORPHTARGETS' : '',
parameters.morphNormals ? '#define USE_MORPHNORMALS' : '',
parameters.skinning ? '#define USE_SKINNING' : '',
parameters.useVertexTexture ? '#define BONE_TEXTURE' : '',
'#define MAX_BONES ' + parameters.maxBones,
].filter(e => e !== '').join('\n');
//不为空加个换行
if (frontVert) frontVert += "\n";
......@@ -103,6 +118,10 @@ class CusShader extends GLShader {
this.usedTimes = 0;
}
}
//部分属性不清除中括号(比如光照数据,链式结构赋值),
//有些清掉中括号,传纯数字数组(比如纹理通道数量uSamplers,变形权重morphTargetInfluences)
//复制一个不清除中括号的
function extractUniforms(gl: WebGLRenderingContext, program: WebGLProgram) {
var uniforms = {};
......@@ -113,10 +132,11 @@ function extractUniforms(gl: WebGLRenderingContext, program: WebGLProgram) {
var uniformData: WebGLActiveInfo = gl.getActiveUniform(program, i);
//morphTargetInfluences直接传一个数组吧,还是说不区分,也直接按morphTargetInfluences[0]传
var name = uniformData.name.indexOf("morphTargetInfluences") == 0 ?
var name = (uniformData.name.indexOf("morphTargetInfluences") == 0 || uniformData.name.indexOf("uBoneMatrices") == 0) ?
uniformData.name.replace(/\[.*?\]/, "") : uniformData.name;
var type = mapType(gl, uniformData.type);
// console.log(name)
uniforms[name] = {
type: type,
size: uniformData.size,
......@@ -147,6 +167,9 @@ const parameterNames = [
"dirLightsNum",
"morphTargets",
"morphNormals",
"skinning",
"maxBones",
"useVertexTexture",
"lightAffect",
]
......@@ -158,7 +181,10 @@ interface ShaderParametersInt {
dirLightsNum: number,
morphTargets: boolean,
morphNormals: boolean,
lightAffect: boolean
skinning: boolean,
maxBones: number,
useVertexTexture: boolean,
lightAffect: boolean,
}
/**
......@@ -192,6 +218,38 @@ const VERT = [
" varying vec3 vViewPosition;", //传入计算镜面光
'#endif',
//使用骨骼蒙皮
"#ifdef USE_SKINNING",
" uniform mat4 uBindMatrix;",
" uniform mat4 uBindMatrixInverse;",
" #ifdef BONE_TEXTURE",
" uniform sampler2D uBoneTexture;",
" uniform int uBoneTextureSize;",
" mat4 getBoneMatrix( const in float i ) {",
" float j = i * 4.0;",
" float x = mod( j, float( uBoneTextureSize ) );",
" float y = floor( j / float( uBoneTextureSize ) );",
" float dx = 1.0 / float( uBoneTextureSize );",
" float dy = 1.0 / float( uBoneTextureSize );",
" y = dy * ( y + 0.5 );",
" vec4 v1 = texture2D( uBoneTexture, vec2( dx * ( x + 0.5 ), y ) );",
" vec4 v2 = texture2D( uBoneTexture, vec2( dx * ( x + 1.5 ), y ) );",
" vec4 v3 = texture2D( uBoneTexture, vec2( dx * ( x + 2.5 ), y ) );",
" vec4 v4 = texture2D( uBoneTexture, vec2( dx * ( x + 3.5 ), y ) );",
" mat4 bone = mat4( v1, v2, v3, v4 );",
" return bone;",
" }",
" #else",
" uniform mat4 uBoneMatrices[ MAX_BONES ];",
" mat4 getBoneMatrix( const in float i ) {",
" mat4 bone = uBoneMatrices[ int(i) ];",
" return bone;",
" }",
" #endif",
' attribute vec4 aSkinIndex;',
' attribute vec4 aSkinWeight;',
"#endif",
//变形顶点数据,单独建数组传,还是放入vao
'#ifdef USE_MORPHTARGETS',
' attribute vec3 morphTarget0;',
......@@ -229,6 +287,23 @@ const VERT = [
" transformed += ( morphTarget7 - aPosition ) * morphTargetInfluences[ 7 ];",
" #endif",
"#endif",
//使用蒙皮骨骼
"#ifdef USE_SKINNING",
" mat4 boneMatX = getBoneMatrix( aSkinIndex.x );",
" mat4 boneMatY = getBoneMatrix( aSkinIndex.y );",
" mat4 boneMatZ = getBoneMatrix( aSkinIndex.z );",
" mat4 boneMatW = getBoneMatrix( aSkinIndex.w );",
" vec4 skinVertex = uBindMatrix * vec4( transformed, 1.0 );",
" vec4 skinned = vec4( 0.0 );",
" skinned += boneMatX * skinVertex * aSkinWeight.x;",
" skinned += boneMatY * skinVertex * aSkinWeight.y;",
" skinned += boneMatZ * skinVertex * aSkinWeight.z;",
" skinned += boneMatW * skinVertex * aSkinWeight.w;",
" transformed = ( uBindMatrixInverse * skinned ).xyz;",
"#endif",
//常规的
"vec4 mvPosition = uViewMatrix * uModelMatrix * vec4( transformed, 1.0 );",
......@@ -238,14 +313,25 @@ const VERT = [
//光照的
'#ifdef USE_LIGHT',
//考虑变形,法线
" vec3 objectNormal = vec3( aNormal );",
//考虑变形,法线
" #ifdef USE_MORPHNORMALS",
" objectNormal += ( morphNormal0 - aNormal ) * morphTargetInfluences[ 0 ];",
" objectNormal += ( morphNormal1 - aNormal ) * morphTargetInfluences[ 1 ];",
" objectNormal += ( morphNormal2 - aNormal ) * morphTargetInfluences[ 2 ];",
" objectNormal += ( morphNormal3 - aNormal ) * morphTargetInfluences[ 3 ];",
" objectNormal += ( morphNormal0 - aNormal ) * morphTargetInfluences[ 0 ];",
" objectNormal += ( morphNormal1 - aNormal ) * morphTargetInfluences[ 1 ];",
" objectNormal += ( morphNormal2 - aNormal ) * morphTargetInfluences[ 2 ];",
" objectNormal += ( morphNormal3 - aNormal ) * morphTargetInfluences[ 3 ];",
" #endif",
//骨骼蒙皮
" #ifdef USE_SKINNING",
" mat4 skinMatrix = mat4( 0.0 );",
" skinMatrix += aSkinWeight.x * boneMatX;",
" skinMatrix += aSkinWeight.y * boneMatY;",
" skinMatrix += aSkinWeight.z * boneMatZ;",
" skinMatrix += aSkinWeight.w * boneMatW;",
" skinMatrix = uBindMatrixInverse * skinMatrix * uBindMatrix;",
" objectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;",
" #endif",
" vViewPosition = -mvPosition.xyz;",
" vPosition = vec3(uModelMatrix * vec4(transformed,1.0));",
" vNormal = normalize(vec3(uNormalMatrix * vec4(objectNormal,1.0)));",
......
......@@ -181,6 +181,8 @@ export class VertexArrayObject {
let attr = this.attributes[i]
if (attr.name === name) {//同名移除
this.attributes.splice(i, 1);//从数组移除
//有改动,标记下
this.dirty = true;
//只需要移除一个就break
if (onlyOne) break;
}
......
......@@ -81,6 +81,8 @@ var GLSL_ARRAY_SETTERS = {
bvec3: function setBvec3Array(gl, location, value) { gl.uniform3iv(location, value); },
bvec4: function setBvec4Array(gl, location, value) { gl.uniform4iv(location, value); },
sampler2D: function setSampler2DArray(gl, location, value) { gl.uniform1iv(location, value); },
//添加矩阵数组
mat4: function setMat4Array(gl, location, value) { gl.uniformMatrix4fv(location, false, value); },
};
function generateSetter(name, uniform) {
......
const cloud_back = {
"v": "5.6.10",
"fr": 30,
"ip": 0,
"op": 120,
"w": 750,
"h": 1624,
"nm": "cloud_back",
"layers": [
{
"ind": 1,
"ty": 2,
"nm": "control",
"refId": "cloud_7",
"ks": {
"o": {
"a": 0,
"k": 1
},
"r": {
"a": 0,
"k": 0
},
"p": {
"a": 1,
"k": [
{
"t": 0,
"s": [
997,
652,
0
]
},
{
"t": 59,
"s": [
997,
675,
0
]
},
{
"t": 120,
"s": [
997,
652,
0
]
}
]
},
"a": {
"a": 0,
"k": [
249,
110,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
}
},
"ip": 0,
"op": 450
},
{
"ind": 2,
"ty": 2,
"nm": "cloud_3.png",
"parent": 1,
"refId": "cloud_3",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 0,
"k": 0
},
"p": {
"a": 1,
"k": [
{
"t": -12,
"s": [
434,
-20,
0
]
},
{
"t": 33,
"s": [
-1190,
454,
0
]
}
]
},
"a": {
"a": 0,
"k": [
446.5,
151.5,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
}
},
"ip": -12,
"op": 438
},
{
"ind": 3,
"ty": 2,
"nm": "cloud_2.png",
"parent": 1,
"refId": "cloud_2",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 0,
"k": 0
},
"p": {
"a": 1,
"k": [
{
"t": -17,
"s": [
308,
140,
0
]
},
{
"t": 48,
"s": [
-1060,
550,
0
]
}
]
},
"a": {
"a": 0,
"k": [
317,
102,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
}
},
"ip": -17,
"op": 423
},
{
"ind": 4,
"ty": 2,
"nm": "cloud_1.png",
"parent": 1,
"refId": "cloud_1",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 1,
"k": [
{
"t": -35,
"s": [
-5
]
},
{
"t": 60,
"s": [
2
]
}
]
},
"p": {
"a": 1,
"k": [
{
"t": -35,
"s": [
537.999,
164.3,
0
]
},
{
"t": 13,
"s": [
-385.998,
477.299,
0
]
},
{
"t": 61,
"s": [
-1318.001,
786.3,
0
]
}
]
},
"a": {
"a": 0,
"k": [
535,
153,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
}
},
"ip": -35,
"op": 407
},
{
"ind": 5,
"ty": 2,
"nm": "cloud_3.png",
"parent": 1,
"refId": "cloud_3",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 0,
"k": 0
},
"p": {
"a": 1,
"k": [
{
"t": 108,
"s": [
434,
-20,
0
]
},
{
"t": 153,
"s": [
-1190,
454,
0
]
}
]
},
"a": {
"a": 0,
"k": [
446.5,
151.5,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
}
},
"ip": 108,
"op": 558
},
{
"ind": 6,
"ty": 2,
"nm": "cloud_2.png",
"parent": 1,
"refId": "cloud_2",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 0,
"k": 0
},
"p": {
"a": 1,
"k": [
{
"t": 103,
"s": [
308,
140,
0
]
},
{
"t": 168,
"s": [
-1060,
550,
0
]
}
]
},
"a": {
"a": 0,
"k": [
317,
102,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
}
},
"ip": 103,
"op": 543
},
{
"ind": 7,
"ty": 2,
"nm": "cloud_1.png",
"parent": 1,
"refId": "cloud_1",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 1,
"k": [
{
"t": 84,
"s": [
-5
]
},
{
"t": 179,
"s": [
2
]
}
]
},
"p": {
"a": 1,
"k": [
{
"t": 84,
"s": [
537.999,
164.3,
0
]
},
{
"t": 132,
"s": [
-385.998,
477.299,
0
]
},
{
"t": 180,
"s": [
-1318.001,
786.3,
0
]
}
]
},
"a": {
"a": 0,
"k": [
535,
153,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
}
},
"ip": 84,
"op": 526
},
{
"ind": 8,
"ty": 2,
"nm": "cloud_3.png",
"parent": 1,
"refId": "cloud_3",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 0,
"k": 0
},
"p": {
"a": 1,
"k": [
{
"t": 48,
"s": [
434,
-20,
0
]
},
{
"t": 93,
"s": [
-1190,
454,
0
]
}
]
},
"a": {
"a": 0,
"k": [
446.5,
151.5,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
}
},
"ip": 48,
"op": 498
},
{
"ind": 9,
"ty": 2,
"nm": "cloud_2.png",
"parent": 1,
"refId": "cloud_2",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 0,
"k": 0
},
"p": {
"a": 1,
"k": [
{
"t": 43,
"s": [
308,
140,
0
]
},
{
"t": 108,
"s": [
-1060,
550,
0
]
}
]
},
"a": {
"a": 0,
"k": [
317,
102,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
}
},
"ip": 43,
"op": 483
},
{
"ind": 10,
"ty": 2,
"nm": "cloud_1.png",
"parent": 1,
"refId": "cloud_1",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 1,
"k": [
{
"t": 24,
"s": [
-5
]
},
{
"t": 119,
"s": [
2
]
}
]
},
"p": {
"a": 1,
"k": [
{
"t": 24,
"s": [
537.999,
164.3,
0
]
},
{
"t": 72,
"s": [
-385.998,
477.299,
0
]
},
{
"t": 120,
"s": [
-1318.001,
786.3,
0
]
}
]
},
"a": {
"a": 0,
"k": [
535,
153,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
}
},
"ip": 24,
"op": 466
}
],
"markers": []
}
\ No newline at end of file
const cloud_front = {
"v": "5.6.10",
"fr": 30,
"ip": 0,
"op": 120,
"w": 750,
"h": 1624,
"nm": "cloud_front",
"layers": [
{
"ind": 1,
"ty": 2,
"nm": "control",
"refId": "cloud_7",
"ks": {
"o": {
"a": 0,
"k": 1
},
"r": {
"a": 0,
"k": 0
},
"p": {
"a": 1,
"k": [
{
"t": 0,
"s": [
997,
652,
0
]
},
{
"t": 59,
"s": [
997,
675,
0
]
},
{
"t": 120,
"s": [
997,
652,
0
]
}
]
},
"a": {
"a": 0,
"k": [
249,
110,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
}
},
"ip": 0,
"op": 450
},
{
"ind": 2,
"ty": 2,
"nm": "cloud_7.png",
"parent": 1,
"refId": "a5bbb59e-f2cb-4599-a952-76f361200a24",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 0,
"k": 0
},
"p": {
"a": 1,
"k": [
{
"t": -35,
"s": [
249,
110,
0
]
},
{
"t": 40,
"s": [
-1009,
442,
0
]
}
]
},
"a": {
"a": 0,
"k": [
249,
110,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
}
},
"ip": -35,
"op": 415
},
{
"ind": 3,
"ty": 2,
"nm": "cloud_6.png",
"parent": 1,
"refId": "cloud_6",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 0,
"k": 0
},
"p": {
"a": 1,
"k": [
{
"t": -60,
"s": [
306,
-264,
0
]
},
{
"t": 20,
"s": [
-1040,
146,
0
]
}
]
},
"a": {
"a": 0,
"k": [
298.5,
130,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
}
},
"ip": -60,
"op": 390
},
{
"ind": 4,
"ty": 2,
"nm": "cloud_5.png",
"parent": 1,
"refId": "cloud_5",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 0,
"k": 0
},
"p": {
"a": 1,
"k": [
{
"t": -29,
"s": [
558,
-288,
0
]
},
{
"t": 46,
"s": [
-1300,
382,
0
]
}
]
},
"a": {
"a": 0,
"k": [
537.5,
191.5,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
}
},
"ip": -29,
"op": 421
},
{
"ind": 5,
"ty": 2,
"nm": "cloud_4.png",
"parent": 1,
"refId": "cloud_4",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 0,
"k": 0
},
"p": {
"a": 1,
"k": [
{
"t": -51,
"s": [
154,
-64,
0
]
},
{
"t": 9,
"s": [
-894,
270,
0
]
}
]
},
"a": {
"a": 0,
"k": [
144.5,
74,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
}
},
"ip": -51,
"op": 399
},
{
"ind": 6,
"ty": 2,
"nm": "cloud_7.png",
"parent": 1,
"refId": "a5bbb59e-f2cb-4599-a952-76f361200a24",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 0,
"k": 0
},
"p": {
"a": 1,
"k": [
{
"t": 85,
"s": [
249,
110,
0
]
},
{
"t": 160,
"s": [
-1009,
442,
0
]
}
]
},
"a": {
"a": 0,
"k": [
249,
110,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
}
},
"ip": 85,
"op": 535
},
{
"ind": 7,
"ty": 2,
"nm": "cloud_6.png",
"parent": 1,
"refId": "cloud_6",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 0,
"k": 0
},
"p": {
"a": 1,
"k": [
{
"t": 60,
"s": [
306,
-264,
0
]
},
{
"t": 140,
"s": [
-1040,
146,
0
]
}
]
},
"a": {
"a": 0,
"k": [
298.5,
130,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
}
},
"ip": 60,
"op": 510
},
{
"ind": 8,
"ty": 2,
"nm": "cloud_5.png",
"parent": 1,
"refId": "cloud_5",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 0,
"k": 0
},
"p": {
"a": 1,
"k": [
{
"t": 91,
"s": [
558,
-288,
0
]
},
{
"t": 166,
"s": [
-1300,
382,
0
]
}
]
},
"a": {
"a": 0,
"k": [
537.5,
191.5,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
}
},
"ip": 91,
"op": 541
},
{
"ind": 9,
"ty": 2,
"nm": "cloud_4.png",
"parent": 1,
"refId": "cloud_4",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 0,
"k": 0
},
"p": {
"a": 1,
"k": [
{
"t": 69,
"s": [
154,
-64,
0
]
},
{
"t": 129,
"s": [
-894,
270,
0
]
}
]
},
"a": {
"a": 0,
"k": [
144.5,
74,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
}
},
"ip": 69,
"op": 519
},
{
"ind": 10,
"ty": 2,
"nm": "cloud_7.png",
"parent": 1,
"refId": "a5bbb59e-f2cb-4599-a952-76f361200a24",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 0,
"k": 0
},
"p": {
"a": 1,
"k": [
{
"t": 25,
"s": [
249,
110,
0
]
},
{
"t": 100,
"s": [
-1009,
442,
0
]
}
]
},
"a": {
"a": 0,
"k": [
249,
110,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
}
},
"ip": 25,
"op": 475
},
{
"ind": 11,
"ty": 2,
"nm": "cloud_6.png",
"parent": 1,
"refId": "cloud_6",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 0,
"k": 0
},
"p": {
"a": 1,
"k": [
{
"t": 0,
"s": [
306,
-264,
0
]
},
{
"t": 80,
"s": [
-1040,
146,
0
]
}
]
},
"a": {
"a": 0,
"k": [
298.5,
130,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
}
},
"ip": 0,
"op": 450
},
{
"ind": 12,
"ty": 2,
"nm": "cloud_5.png",
"parent": 1,
"refId": "cloud_5",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 0,
"k": 0
},
"p": {
"a": 1,
"k": [
{
"t": 31,
"s": [
558,
-288,
0
]
},
{
"t": 106,
"s": [
-1300,
382,
0
]
}
]
},
"a": {
"a": 0,
"k": [
537.5,
191.5,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
}
},
"ip": 31,
"op": 481
},
{
"ind": 13,
"ty": 2,
"nm": "cloud_4.png",
"parent": 1,
"refId": "cloud_4",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 0,
"k": 0
},
"p": {
"a": 1,
"k": [
{
"t": 9,
"s": [
154,
-64,
0
]
},
{
"t": 69,
"s": [
-894,
270,
0
]
}
]
},
"a": {
"a": 0,
"k": [
144.5,
74,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
}
},
"ip": 9,
"op": 459
}
],
"markers": []
}
\ No newline at end of file
const egg_break = {
"v": "5.6.10",
"fr": 30,
"ip": 0,
"op": 45,
"w": 750,
"h": 1624,
"nm": "egg_break",
"layers": [
{
"ind": 1,
"ty": 2,
"nm": "egg_1.png",
"refId": "egg_1",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 0,
"k": 0
},
"p": {
"a": 0,
"k": [
375,
822,
0
]
},
"a": {
"a": 0,
"k": [
300.5,
238.5,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
}
},
"ip": 20,
"op": 469
},
{
"ind": 2,
"ty": 2,
"nm": "light_1.png",
"refId": "light_1",
"ks": {
"o": {
"a": 1,
"k": [
{
"t": 27,
"s": [
0
]
},
{
"t": 42,
"s": [
80
]
}
]
},
"r": {
"a": 0,
"k": 0
},
"p": {
"a": 0,
"k": [
374,
816,
0
]
},
"a": {
"a": 0,
"k": [
557.5,
493,
0
]
},
"s": {
"a": 1,
"k": [
{
"t": 27,
"s": [
64,
64,
100
]
},
{
"t": 42,
"s": [
100,
100,
100
]
}
]
}
},
"ip": 27,
"op": 457
},
{
"ind": 3,
"ty": 2,
"nm": "light.png",
"refId": "light",
"ks": {
"o": {
"a": 1,
"k": [
{
"t": 14,
"s": [
0
]
},
{
"t": 20,
"s": [
90
]
}
]
},
"r": {
"a": 0,
"k": -7
},
"p": {
"a": 0,
"k": [
342,
717,
0
]
},
"a": {
"a": 0,
"k": [
89.5,
517,
0
]
},
"s": {
"a": 0,
"k": [
100,
120,
100
]
}
},
"ip": 14,
"op": 464
},
{
"ind": 4,
"ty": 2,
"nm": "light.png",
"refId": "light",
"ks": {
"o": {
"a": 1,
"k": [
{
"t": 10,
"s": [
0
]
},
{
"t": 16,
"s": [
90
]
}
]
},
"r": {
"a": 0,
"k": 15
},
"p": {
"a": 0,
"k": [
420,
698,
0
]
},
"a": {
"a": 0,
"k": [
89.5,
517,
0
]
},
"s": {
"a": 1,
"k": [
{
"t": 10,
"s": [
100,
40,
100
]
},
{
"t": 16,
"s": [
100,
100,
100
]
}
]
}
},
"ip": 10,
"op": 460
},
{
"ind": 5,
"ty": 2,
"nm": "light.png",
"refId": "light",
"ks": {
"o": {
"a": 1,
"k": [
{
"t": 6,
"s": [
0
]
},
{
"t": 12,
"s": [
70
]
}
]
},
"r": {
"a": 0,
"k": 28
},
"p": {
"a": 0,
"k": [
493,
690,
0
]
},
"a": {
"a": 0,
"k": [
89.5,
517,
0
]
},
"s": {
"a": 1,
"k": [
{
"t": 6,
"s": [
100,
30,
100
]
},
{
"t": 12,
"s": [
100,
90,
100
]
}
]
}
},
"ip": 6,
"op": 456
},
{
"ind": 6,
"ty": 2,
"nm": "light_s.png",
"refId": "light_s",
"ks": {
"o": {
"a": 1,
"k": [
{
"t": 2,
"s": [
0
]
},
{
"t": 8,
"s": [
70
]
}
]
},
"r": {
"a": 0,
"k": 52
},
"p": {
"a": 0,
"k": [
578,
640,
0
]
},
"a": {
"a": 0,
"k": [
89.5,
429.17,
0
]
},
"s": {
"a": 1,
"k": [
{
"t": 2,
"s": [
100,
40,
100
]
},
{
"t": 8,
"s": [
100,
80,
100
]
}
]
}
},
"ip": 2,
"op": 452
},
{
"ind": 7,
"ty": 2,
"nm": "light_s.png",
"refId": "light_s",
"ks": {
"o": {
"a": 1,
"k": [
{
"t": 0,
"s": [
0
]
},
{
"t": 6,
"s": [
70
]
}
]
},
"r": {
"a": 0,
"k": -47
},
"p": {
"a": 0,
"k": [
143,
727,
0
]
},
"a": {
"a": 0,
"k": [
89.5,
429.17,
0
]
},
"s": {
"a": 1,
"k": [
{
"t": 0,
"s": [
100,
40,
100
]
},
{
"t": 6,
"s": [
100,
90,
100
]
}
]
}
},
"ip": 0,
"op": 450
},
{
"ind": 8,
"ty": 2,
"nm": "egg_2.png",
"refId": "egg_2",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 1,
"k": [
{
"t": 42,
"s": [
0
]
},
{
"t": 45,
"s": [
-7
]
}
]
},
"p": {
"a": 1,
"k": [
{
"t": 42,
"s": [
128,
717,
0
]
},
{
"t": 45,
"s": [
124,
692,
0
]
}
]
},
"a": {
"a": 0,
"k": [
50,
264,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
}
},
"ip": 20,
"op": 446
},
{
"ind": 9,
"ty": 2,
"nm": "crevice_5.png",
"refId": "crevice_5",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 0,
"k": -20
},
"p": {
"a": 0,
"k": [
121.5,
738,
0
]
},
"a": {
"a": 0,
"k": [
1.578,
5.132,
0
]
},
"s": {
"a": 1,
"k": [
{
"t": 0,
"s": [
0,
100,
100
]
},
{
"t": 3,
"s": [
100,
100,
100
]
}
]
}
},
"ip": 0,
"op": 444
},
{
"ind": 10,
"ty": 2,
"nm": "crevice_4.png",
"refId": "crevice_4",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 0,
"k": 0
},
"p": {
"a": 0,
"k": [
340,
718,
0
]
},
"a": {
"a": 0,
"k": [
32,
35,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
}
},
"ip": 14,
"op": 453
},
{
"ind": 11,
"ty": 2,
"nm": "crevice_3.png",
"refId": "crevice_3",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 0,
"k": 15
},
"p": {
"a": 0,
"k": [
469.5,
709.75,
0
]
},
"a": {
"a": 0,
"k": [
101.811,
4.103,
0
]
},
"s": {
"a": 1,
"k": [
{
"t": 10,
"s": [
0,
100,
100
]
},
{
"t": 12,
"s": [
100,
100,
100
]
}
]
}
},
"ip": 10,
"op": 450
},
{
"ind": 12,
"ty": 2,
"nm": "crevice_2.png",
"refId": "crevice_2",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 0,
"k": -40
},
"p": {
"a": 0,
"k": [
550.25,
643,
0
]
},
"a": {
"a": 0,
"k": [
107.324,
6.513,
0
]
},
"s": {
"a": 1,
"k": [
{
"t": 6,
"s": [
0,
100,
100
]
},
{
"t": 8,
"s": [
100,
100,
100
]
}
]
}
},
"ip": 6,
"op": 448
},
{
"ind": 13,
"ty": 2,
"nm": "crevice_1.png",
"refId": "crevice_1",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 0,
"k": -24
},
"p": {
"a": 0,
"k": [
589,
628.25,
0
]
},
"a": {
"a": 0,
"k": [
46,
8.5,
0
]
},
"s": {
"a": 1,
"k": [
{
"t": 2,
"s": [
0,
100,
100
]
},
{
"t": 4,
"s": [
100,
100,
100
]
}
]
}
},
"ip": 2,
"op": 446
},
{
"ind": 14,
"ty": 2,
"nm": "egg_0.png",
"refId": "egg_0",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 0,
"k": 0
},
"p": {
"a": 0,
"k": [
375,
760,
0
]
},
"a": {
"a": 0,
"k": [
300.5,
300.5,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
}
},
"ip": 0,
"op": 20
}
],
"markers": [
{
"tm": 30,
"cm": "1",
"dr": 0
}
]
}
\ No newline at end of file
const egg_loop = {
"v": "5.6.10",
"fr": 30,
"ip": 0,
"op": 90,
"w": 750,
"h": 1624,
"nm": "egg_loop",
"layers": [
{
"ind": 2,
"ty": 2,
"nm": "egg_0.png",
"refId": "egg_0",
"ks": {
"o": {
"a": 0,
"k": 100
},
"r": {
"a": 0,
"k": 0
},
"p": {
"a": 1,
"k": [
{
"t": 0,
"s": [
375,
760,
0
]
},
{
"t": 45,
"s": [
375,
782,
0
]
},
{
"t": 90,
"s": [
375,
760,
0
]
}
],
"x": "var $bm_rt;\n$bm_rt = loopOut('cycle', 0);"
},
"a": {
"a": 0,
"k": [
300.5,
300.5,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
}
},
"ip": 0,
"op": 450
}
],
"markers": []
}
\ No newline at end of file
const res = {
"cloud_5.png": {
"x": 2,
"y": 2,
"w": 1075,
"h": 383,
"ox": 0,
"oy": 0,
"sw": 1075,
"sh": 383,
"ro": false
},
"cloud_1.png": {
"x": 2,
"y": 387,
"w": 1070,
"h": 306,
"ox": 0,
"oy": 0,
"sw": 1070,
"sh": 306,
"ro": false
},
"light_1.png": {
"x": 2,
"y": 695,
"w": 1015,
"h": 481,
"ox": 0,
"oy": 29,
"sw": 1119,
"sh": 510,
"ro": false
},
"cloud_3.png": {
"x": 1079,
"y": 2,
"w": 893,
"h": 303,
"ox": 0,
"oy": 0,
"sw": 893,
"sh": 303,
"ro": true
},
"cloud_2.png": {
"x": 2,
"y": 1178,
"w": 634,
"h": 204,
"ox": 0,
"oy": 0,
"sw": 634,
"sh": 204,
"ro": false
},
"egg_0.png": {
"x": 1384,
"y": 2,
"w": 601,
"h": 601,
"ox": 0,
"oy": 0,
"sw": 601,
"sh": 601,
"ro": false
},
"egg_1.png": {
"x": 1384,
"y": 605,
"w": 601,
"h": 477,
"ox": 0,
"oy": 0,
"sw": 601,
"sh": 477,
"ro": false
},
"cloud_6.png": {
"x": 1019,
"y": 1084,
"w": 597,
"h": 260,
"ox": 0,
"oy": 0,
"sw": 597,
"sh": 260,
"ro": false
},
"egg_2.png": {
"x": 638,
"y": 1178,
"w": 550,
"h": 344,
"ox": 0,
"oy": 0,
"sw": 550,
"sh": 344,
"ro": true
},
"light.png": {
"x": 2,
"y": 1384,
"w": 143,
"h": 518,
"ox": 0,
"oy": 0,
"sw": 143,
"sh": 518,
"ro": true
},
"cloud_7.png": {
"x": 1618,
"y": 1084,
"w": 498,
"h": 220,
"ox": 0,
"oy": 0,
"sw": 498,
"sh": 220,
"ro": true
},
"light_s.png": {
"x": 984,
"y": 1584,
"w": 143,
"h": 430,
"ox": 0,
"oy": 0,
"sw": 143,
"sh": 430,
"ro": true
},
"cloud_4.png": {
"x": 1019,
"y": 897,
"w": 289,
"h": 148,
"ox": 0,
"oy": 0,
"sw": 289,
"sh": 148,
"ro": false
},
"crevice_2.png": {
"x": 522,
"y": 1384,
"w": 108,
"h": 11,
"ox": 0,
"oy": 0,
"sw": 108,
"sh": 11,
"ro": false
},
"crevice_3.png": {
"x": 522,
"y": 1397,
"w": 106,
"h": 9,
"ox": 0,
"oy": 0,
"sw": 106,
"sh": 9,
"ro": false
},
"crevice_4.png": {
"x": 1310,
"y": 897,
"w": 64,
"h": 70,
"ox": 0,
"oy": 0,
"sw": 64,
"sh": 70,
"ro": true
},
"crevice_5.png": {
"x": 1019,
"y": 695,
"w": 55,
"h": 10,
"ox": 0,
"oy": 0,
"sw": 55,
"sh": 10,
"ro": false
},
"crevice_1.png": {
"x": 1019,
"y": 707,
"w": 48,
"h": 16,
"ox": 0,
"oy": 0,
"sw": 48,
"sh": 16,
"ro": false
}
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<meta name="viewport"
content="width=device-width,initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="full-screen" content="true"/>
<meta name="screen-orientation" content="portrait"/>
<meta name="x5-fullscreen" content="true"/>
<meta name="360-fullscreen" content="true"/>
<!-- <script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script> -->
<!-- 小程序分享得用这个 -->
<!-- <script src="https://res.wx.qq.com/open/js/jweixin-1.3.2.js"></script> -->
<!-- 易盾js -->
<!-- <script type="text/javascript" src="//cstaticdun.126.net/load.min.js"></script> -->
<!-- <script src="libs/zepto.min.js"></script> -->
<!-- <script src="libs/p2.js"></script> -->
<script src="../build/fyge.min.js"></script>
<!-- <script src="../debug/FYGE.js"></script>-->
<script src="./js/res.js"></script>
<script src="./js/egg_break.js"></script>
<script src="./js/egg_loop.js"></script>
<script src="./js/cloud_back.js"></script>
<script src="./js/cloud_front.js"></script>
<style>
html,
body {
padding: 0;
margin: 0;
border: 0;
width: 100%;
height: 100%;
overflow: hidden;
position: absolute;
background-color: #eeeeee;
}
</style>
</head>
<body>
<div id="cusEngine" style="line-height:0;font-size:0">
<canvas id="canvas" style="width: 100%;height: 100%"></canvas>
</div>
</body>
<script>
window.addEventListener("load", async function () {
//获取canvas
var canvas = document.getElementById("canvas");
canvas.width = document.body.clientWidth * (window.devicePixelRatio || 1)
canvas.height = document.body.clientHeight * (window.devicePixelRatio || 1)
//小程序上canvas用自己的方式建
// var canvas = await new Promise((r) => {
// my.createCanvas({
// id: 'canvas',
// success: (ccc) => {
// const dpr = my.getSystemInfoSync().pixelRatio
// const windowWidth = my.getSystemInfoSync().windowWidth;
// const windowHeight = my.getSystemInfoSync().windowHeight;
// ccc.width = windowWidth * dpr + dpr;//重新修改会有误差
// ccc.height = windowHeight * dpr + dpr;
// r(ccc);
// }
// })
// })
var sysInfo;
//@ts-ignore 存在my就初始化
if (my) {
FYGE.initedByCanvas(canvas)
//@ts-ignore 存在my就初始化
sysInfo = my.getSystemInfoSync()
}
//建舞台
var stage = new FYGE.Stage(
canvas,
750,//设计宽度,按设计搞给的就行
1624,//设计高度
sysInfo && sysInfo.windowWidth || document.body.clientWidth,
sysInfo && sysInfo.windowHeight || document.body.clientHeight,
FYGE.RENDERER_TYPE.WEBGL
);
//stage初始化
stage.addEventListener(FYGE.Event.INIT_STAGE, () => {
//添加个背景
// var a = stage.addChild(new FYGE.Graphics())
// .beginFill(0x000000, 0.7)
// .drawRect(0, 0, 750, 1624)
// .endFill()
//资源
const a = {x: 0};
const t = FYGE.Tween.get(a)
.to({x: 100}, 100)
.call(() => {
console.log(a.x);
})
.to({x: 200}, 100)
.call(() => {
console.log(a.x);
})
.by({x: 200}, 100)
.call(() => {
console.log(a.x);
})
.by({x: 200}, 100)
.call(() => {
console.log(a.x);
});
FYGE.GlobalLoader.loadImage((s, image) => {
if (s) {
//会进TextureCache
FYGE.createTextureSheet(new FYGE.BaseTexture(image), res)
var a = stage.addChild(new FYGE.Lottie(cloud_back))
a.play();
//加个lottie
var b = stage.addChild(new FYGE.Lottie(egg_break))
b.play();
// var b = stage.addChild(new FYGE.Lottie(egg_loop))
// b.play();
var mask =new FYGE.Shape();
mask.beginFill(0xff0000);
// mask.drawRect(0,0,500,500);
// mask.moveTo(0,0)
// mask.lineTo(500,0)
// mask.lineTo(500,500)
// mask.lineTo(0,500)
// mask.lineTo(0,0)
mask.drawRoundedRect(0, 0, 333, 32, 50)
mask.endFill();
stage.addChild(mask)
mask.y+=800
b.mask =mask
var a=1
FYGE.Tween.get(mask,{onChange:function(){
a++
mask.clear()
mask.beginFill(0xff0000)
mask.drawRoundedRect(0, 0, a, 32, 50)
mask.endFill()
// mask._boundsID++;
// console.log(111)
}})
.wait(9000)
var b = stage.addChild(new FYGE.Lottie(cloud_front))
b.play()
} else {
}
}, "./res/res.png")
}, this);
//循环
loop();
function loop() {
FYGE.Tween.flush()
stage.flush();
FYGE.getRequestAnimationFrame()(loop);
}
})
</script>
</html>
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment