Commit 207a7bf0 authored by wangjianfeng.yz's avatar wangjianfeng.yz

2.0.63

parent 8ec760c5
......@@ -18,4 +18,5 @@ test
examples
docs
adapters
testThree
\ No newline at end of file
testThree
README.md
\ No newline at end of file
#
###
```html
<script src="../build/fyge.min.js"></script>
<canvas id="canvas" style="width: 100%;height: 100%"></canvas>
```
```js
npm i fyge
import {} from "fyge"
```
```js
const {Stage,RENDERER_TYPE,Sprite,loadImage} =FYGE
var stage = new Stage(
document.getElementById("canvas"),
750,//designWidth
1624,//designHeight
document.body.clientWidth,//canvas show width
document.body.clientHeight,//canvas show height
RENDERER_TYPE.WEBGL,//render type
false,//stage center
false,//fixed height
window.devicePixelRatio || 1//resolution
);
//mouseEvent
stage.addWebMouseEvent();
//add a imge
let url = "https://img.alicdn.com/imgextra/i4/2275046294/O1CN01avEmL01wMhS5Wxd63_!!2275046294-2-miniprogram.png"
var sprite= stage.addChild(Sprite.fromUrl(url))
sprite.position.set(300, 700);
//
loadImage()
```
### xxxx
xxxx
```shell script
npm run
```
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
{
"name": "fyge",
"version": "2.0.62",
"version": "2.0.63",
"description": "canvas渲染引擎",
"main": "./build/fyge.min.js",
"module": "./build/fyge.esm.js",
......
......@@ -576,6 +576,16 @@
graphics/utils/index.ts删除isPointsClockwise方法
2.0.63 基类Filter的resolution改成了get set方法,为了AdvancedBloomFilter,(待测试)
buildCircle、buildPoly、buildRectangle、buildRoundedRectangle都从改成了export default改成了export方法
添加newLoad文件,并导出里面的load方法,后续考虑删除Loader
createTextureSheet文件里新增导出类型ITextureSheetFrameData,新增方法loadSheet
新增接口Dict,并且很多按照这种方式修改,并且很多interface都导出了
......
......@@ -7,7 +7,7 @@
* @name VERSION
* @type {string}
*/
export const VERSION = "2.0.62";
export const VERSION = "2.0.63";
/**
......
......@@ -54,7 +54,13 @@ export default class Filter {
*
* @member {number}
*/
resolution: number;
protected _resolution: number
get resolution(): number {
return this._resolution
};
set resolution(v: number) {
this._resolution = v;
}
/**
* If enabled is true the filter is applied, if false it will not.
*
......
......@@ -54,7 +54,7 @@ export class AdvancedBloomFilter extends Filter {
private _blurFilter: KawaseBlurFilter
bloomScale: number;
brightness: number;
private _resolution: number;
// private _resolution: number;
constructor(options?: IAdvancedBloomFilterOptions) {
super(defaultVert, fragment);
......
......@@ -4,17 +4,17 @@ import GraphicsData from './GraphicsData';
import RenderTexture from "../texture/RenderTexture";
import { Matrix, Point, Rectangle } from '../math';
import { RoundedRectangle, Ellipse, Polygon, Circle } from "./shapes"
import { sign, string2hex, hex2rgb } from '../utils';
import { sign, string2hex, hex2rgb, Dict } from '../utils';
import { SHAPES, PI_2, SCALE_MODES, WRAP_MODES, BLEND_MODES, LINE_ALIGNMENT, LINE_CAP, LINE_JOIN } from '../const';
import { DisplayObject } from '../display/DisplayObject';
import Texture from '../texture/Texture';
import { CanvasRenderer } from '../renderers/CanvasRenderer';
import { Event } from "../events/Event"
import { WebglRenderer } from '../renderers/WebglRenderer';
import buildPoly from './geomBuild/buildPoly';
import buildCircle from './geomBuild/buildCircle';
import buildRectangle from './geomBuild/buildRectangle';
import buildRoundedRectangle from './geomBuild/buildRoundedRectangle';
import { buildPoly } from './geomBuild/buildPoly';
import { buildCircle } from './geomBuild/buildCircle';
import { buildRectangle } from './geomBuild/buildRectangle';
import { buildRoundedRectangle } from './geomBuild/buildRoundedRectangle';
import buildLine from './geomBuild/buildLine';
import FillStyle from './styles/FillStyle';
import LineStyle from './styles/LineStyle';
......@@ -32,7 +32,10 @@ const temp = new Float32Array(3);
const GEOBATCH_POOL: geoBatchPart[] = [];
//分割三角指令托管
const fillCommands = {};
const fillCommands: Dict<{
build: (graphicsData: GraphicsData) => void,
triangulate: (graphicsData: GraphicsData, graphicsGeometry: Graphics) => void
}> = {};
fillCommands[SHAPES.POLY] = buildPoly;
fillCommands[SHAPES.CIRC] = buildCircle;
fillCommands[SHAPES.ELIP] = buildCircle;
......
......@@ -15,7 +15,7 @@ import Graphics from "../Graphics";
* @param {object} webGLData - an object containing all the WebGL-specific information to create this shape
* @param {object} webGLDataNativeLines - an object containing all the WebGL-specific information to create nativeLines
*/
export default {
export const buildCircle = {
build(graphicsData: GraphicsData) {
// need to convert points to a nice regular data
......@@ -69,7 +69,7 @@ export default {
);
},
triangulate(graphicsData, graphicsGeometry: Graphics) {
triangulate(graphicsData: GraphicsData, graphicsGeometry: Graphics) {
const points = graphicsData.points;
const verts = graphicsGeometry.verts;
const indices = graphicsGeometry.indices;
......
......@@ -13,13 +13,13 @@ import GraphicsData from "../GraphicsData";
* @param {object} webGLData - an object containing all the WebGL-specific information to create this shape
* @param {object} webGLDataNativeLines - an object containing all the WebGL-specific information to create nativeLines
*/
export default {
export const buildPoly = {
build(graphicsData: GraphicsData) {
graphicsData.points = graphicsData.shape.points.slice();
},
triangulate(graphicsData:GraphicsData, graphicsGeometry:Graphics) {
triangulate(graphicsData: GraphicsData, graphicsGeometry: Graphics) {
let points = graphicsData.points;
const holes = graphicsData.holes;
const verts = graphicsGeometry.verts;
......
......@@ -13,10 +13,10 @@ import Graphics from "../Graphics";
* @param {object} webGLData - an object containing all the WebGL-specific information to create this shape
* @param {object} webGLDataNativeLines - an object containing all the WebGL-specific information to create nativeLines
*/
export default {
export const buildRectangle = {
//计算点points
build(graphicsData:GraphicsData) {
build(graphicsData: GraphicsData) {
// --- //
// need to convert points to a nice regular data
//
......@@ -37,7 +37,7 @@ export default {
},
//计算顶点和索引
triangulate(graphicsData:GraphicsData, graphics: Graphics) {
triangulate(graphicsData: GraphicsData, graphics: Graphics) {
const points = graphicsData.points;
//graphics之前可能已经有点
......
......@@ -13,7 +13,7 @@ import Graphics from "../Graphics";
* @param {object} webGLData - an object containing all the WebGL-specific information to create this shape
* @param {object} webGLDataNativeLines - an object containing all the WebGL-specific information to create nativeLines
*/
export default {
export const buildRoundedRectangle = {
build(graphicsData: GraphicsData) {
const rrectData = graphicsData.shape;
......
......@@ -26,6 +26,7 @@ export class Loader extends EventDispatcher {
constructor() {
super();
this._instanceType = "Loader";
console.warn("Instance GlobalLoader with class Loader will be abandoned soon, use each load methods instead(such as loadImage) and change parameters");
}
/**
......@@ -138,7 +139,9 @@ export class Loader extends EventDispatcher {
} else if (window["ActiveXObject"]) {
_req = new window["ActiveXObject"]();
} else {
alert("请升级至最新版本的浏览器")
// alert("请升级至最新版本的浏览器")
callback(false, "your browser doesnt support XMLHttpRequest!");
return
}
if (_req != null) {
_req.open("GET", url, true);
......@@ -275,35 +278,3 @@ export class Loader extends EventDispatcher {
export const GlobalLoader = new Loader();
//https://yun.duiba.com.cn/db_games/activity/yilian0726/1565580040/resource/result/resultAlta1.json
//"https://yun.duiba.com.cn/db_games/activity/etc/optionImages/%E5%8D%8E%E4%B8%BAP30.jpg"
// async function loadTbJson(url) {
// if (url.indexOf("cloud://") == 0) {
// //@ts-ignore
// const { cloud } = getApp();
// //获取临时地址
// var urls = await cloud.file.getTempFileURL({ fileId: [url] });
// url = urls[0].url.replace('-internal', '');
// }
// return new Promise((resolve, reject) => {
// my.downloadFile({
// url,
// success(res) {
// var i = res.apFilePath;//临时地址是否有必要缓存下,如果读不到再考虑下载。
// my.getFileSystemManager().readFile({
// filePath: i,
// encoding: "utf8",//不加表示加载的是ArrayBuffer
// success: function (r) {
// resolve(JSON.parse(r.data))
// },
// fail: function (res) {
// reject(res)
// }
// })
// },
// fail(res) {
// reject(res)
// },
// });
// })
// }
export * from "./Loader"
\ No newline at end of file
export * from "./Loader"
export * from "./newLoad";
\ No newline at end of file
import { createImage, getEnv } from "../utils";
/**
* 加载图片
* @param url 图片路径
* @param onSuccess
* @param onFail
* @param crossOrigin 默认anonymous
*/
export function loadImage(
url: string,
onSuccess: (img: HTMLImageElement) => void,
onFail?: (err?: any) => void,
crossOrigin: string = "anonymous",
) {
let img = createImage();
img.onload = function () {
onSuccess(img);
}
img.onerror = function () {
onFail && onFail();
}
//坑爹中文,decodeURI一次是为了以防链接被encode过一次
url = encodeURI(decodeURI(url))
//除了base64的路径,其他都设置了跨域,其实有部分服务器不允许跨域,不能设置anonymous
if (url.indexOf('data:') !== 0) img.crossOrigin = crossOrigin;
img.src = url;
}
/**
* 加载json
* @param {string} url
* @param onSuccess
* @param onFail
*/
export function loadJson(
url: string,
onSuccess: (res: any) => void,
onFail?: (err?: any) => void,
) {
loadRaw(url, onSuccess, onFail, ResponseDataType.json)
}
/**
* 加载二进制数据
* @param {string} url
* @param onSuccess
* @param onFail
*/
export function loadArrayBuffer(
url: string,
onSuccess: (res: any) => void,
onFail?: (err?: any) => void,
) {
loadRaw(url, onSuccess, onFail, ResponseDataType.arraybuffer)
}
/**
* 加载文本
* @param {string} url
* @param onSuccess
* @param onFail
*/
export function loadText(
url: string,
onSuccess: (res: any) => void,
onFail?: (err?: any) => void,
) {
loadRaw(url, onSuccess, onFail, ResponseDataType.text)
}
/**
* 加载原始数据,需要传type,否则按照文本加载
* @param url
* @param onSuccess
* @param onFail
* @param type 返回数据类型,默认text
*/
export function loadRaw(
url: string,
onSuccess: (res: any) => void,
onFail?: (err?: any) => void,
type: ResponseDataType = ResponseDataType.text,
) {
(getEnv() == "tb" ? tbLoad : loadRawWeb)(
url,
onSuccess,
onFail,
type
)
}
/**
* 返回数据类型
*/
export enum ResponseDataType {
text = "text",
json = "json",
arraybuffer = "arraybuffer",
}
/**
* web环境原生加载方式
* @param callback
* @param url
* @param type
*/
function loadRawWeb(
url: string,
onSuccess: (res: any) => void,
onFail?: (err: any) => void,
type: ResponseDataType = ResponseDataType.text
) {
//每次都要new
let _req;
if (window["XMLHttpRequest"]) {
_req = new XMLHttpRequest();
} else if (window["ActiveXObject"]) {
_req = new window["ActiveXObject"]();
} else {
onFail && onFail("your browser doesnt support XMLHttpRequest!");
return
}
if (_req != null) {
_req.open("GET", url, true);
_req.responseType = type;
_req.send();
_req.onreadystatechange = () => {
// if (_req.readyState == 4 && _req.status == 200) {
// callback(true, _req.response)
// }
if (_req.readyState == 4) {
var status = _req.status;
if ((status >= 200 && status < 300) ||//2XX表示有效响应
status == 304//304意味着是从缓存读取
) {
onSuccess(_req.response)
} else {
onFail && onFail("request.status:" + status);
}
}
};
// _req.onerror = (reason): void => {
// callback(false, reason)
// }
}
}
/////////淘宝小程序相关
/**
* 获取临时路径
* @param url cloud路径
* @param callback
*/
function getTbTempUrl(
url: string,
onSuccess: (src: string) => void,
onFail?: (err: any) => void
) {
//@ts-ignore
const { cloud } = getApp();
//获取临时地址
cloud.file.getTempFileURL({ fileId: [url] }).then((urls) => {
onSuccess(urls[0].url.replace('-internal', ''))
}).catch((err) => {
//淘宝上的问题,直接打印吧
// console.error(err)
onFail && onFail(err);
})
}
function downloadReadFile(
url: string,
onSuccess: (res: any) => void,
onFail?: (err: any) => void,
type: ResponseDataType = ResponseDataType.text//"utf8" | "ArrayBuffer" = "ArrayBuffer"
) {
//@ts-ignore
let tbMy = my;
tbMy.downloadFile({
url: url,
success(res) {
var i = res.apFilePath;//临时地址是否有必要缓存下,如果读不到再考虑下载。
tbMy.getFileSystemManager().readFile({//"utf8" | "ArrayBuffer"是文档给的类型,但是encoding不传才是ArrayBuffer
filePath: i,
encoding: type === ResponseDataType.arraybuffer ? "" : "utf8",//不加表示加载的是ArrayBuffer
success: function (r) {
//是json的需要反序列化一下
onSuccess(type == ResponseDataType.json ? JSON.parse(r.data) : r.data)//注意是r.data
// actions.load_viaProto(r.data, cb, failure);
},
fail: function (res) {
onFail && onFail(res);
}
})
},
fail(res) {
onFail && onFail(res);
},
});
}
function tbLoad(
url: string,
onSuccess: (res?: any) => void,
onFail?: (err: any) => void,
type: ResponseDataType = ResponseDataType.text//"utf8" | "ArrayBuffer" = "ArrayBuffer"
) {
//类似这种地址"cloud://A8673B47AAA58993A24A6718E203B967//dice.svga"
if (url.indexOf("cloud://") == 0) {
getTbTempUrl(
url,
(src) => {
downloadReadFile(src, onSuccess, onFail, type)
},
onFail
)
} else {
downloadReadFile(url, onSuccess, onFail, type)
}
}
\ No newline at end of file
......@@ -57,7 +57,7 @@ export class BatchRenderer extends ObjectRenderer {
* 绘制对象数组
* 包括图片的和矢量图的
*/
elements: batchElementInterface[];
elements: IBatchElement[];
vaos: VertexArrayObject[];
vaoMax: number;
vertexCount: number;
......@@ -197,7 +197,7 @@ export class BatchRenderer extends ObjectRenderer {
*
* the sprite to render when using this spritebatch
*/
render(element: batchElementInterface) {
render(element: IBatchElement) {
if (!element._texture || !element._texture.valid) {
return;
}
......@@ -440,7 +440,7 @@ export class BatchRenderer extends ObjectRenderer {
this.currentIndexSize = 0;
}
packGeometry(element: batchElementInterface, float32View, uint32View, indexBuffer, index, indexCount) {
packGeometry(element: IBatchElement, float32View, uint32View, indexBuffer, index, indexCount) {
const p = index / this.vertSize;// float32View.length / 6 / 2;
const uvs = element._uvs;
const indicies = element._indices;// geometry.getIndex().data;// indicies;
......@@ -524,7 +524,7 @@ export class BatchRenderer extends ObjectRenderer {
// WebglRenderer.registerPlugin('batch', BatchRenderer);
interface batchElementInterface {
export interface IBatchElement {
_blendMode: BLEND_MODES,
_texture: Texture,
_worldAlpha: number,
......
import BaseTexture from "./BaseTexture";
import { Rectangle } from "../math";
import Texture from "./Texture";
import { loadImage, loadJson } from "../loader";
import { Dict } from "../utils";
interface dataTm {
/**
* 纹理在sht图集中的数据格式
*/
export interface ITextureSheetFrameData {
x: number, //x,y,w,h为图集上的切图位置数据
y: number,
w: number,
......@@ -20,23 +25,23 @@ var expData = {
}
/**
*
* 根据基础纹理和图集数据创建纹理图集,会进全局缓存
* @param {BaseTexture} baseTexture
* @param {dataTm} altaData
* @return 返回贴图集。不常用
* @param {Dict<ITextureSheetFrameData>} altaData 图集数据,一般是用pack_textures生成的数据
* @return {Dict<Texture>} 返回贴图集。不常用
*/
export function createTextureSheet(baseTexture: BaseTexture, altaData): { [key: string]: Texture } {
export function createTextureSheet(baseTexture: BaseTexture, altaData: Dict<ITextureSheetFrameData>): Dict<Texture> {
var frames = altaData;
var frameKeys = Object.keys(frames);
let frameIndex = 0;
//要返回的贴图集合
var textures: { [key: string]: Texture } = {};
var textures: Dict<Texture> = {};
while (frameIndex < frameKeys.length) {
//名字
const i = frameKeys[frameIndex];
//数据
const data: dataTm = frames[i];
const data: ITextureSheetFrameData = frames[i];
//切图上的数据
let frame: Rectangle = null;
//裁切的数据
......@@ -91,4 +96,47 @@ export function createTextureSheet(baseTexture: BaseTexture, altaData): { [key:
}
return textures;
}
/**
* 加载sht图集
* @param url
* @param onSuccess
* @param onFail
* @param imgUrl
*/
export function loadSheet(
url: string,
onSuccess?: (textures: Dict<Texture>) => void,
onFail?: (err: any) => void,
imgUrl?: string
) {
//替换后缀改成.png
imgUrl = imgUrl || url.substring(0, url.lastIndexOf('.')) + '.png';
//用promise的写法吧,方便
Promise.all([
//数据
new Promise<Dict<ITextureSheetFrameData>>((r) => {
loadJson(
url,
r,
() => r(null)
)
}),
//图片
new Promise<BaseTexture>((r) => {
loadImage(
imgUrl,
image => r(BaseTexture.fromImage(image)),
() => r(null)
)
})
]).then((results) => {
if (results[0] && results[1]) {
var textures = createTextureSheet(results[1], results[0])
onSuccess && onSuccess(textures)
} else {
onFail && onFail("load failed for sht:" + url)
}
})
}
\ No newline at end of file
......@@ -5,7 +5,7 @@ import { Container, Sprite } from "../display";
import { BaseTexture, Texture } from "../texture";
import { getBezierEasing } from "./forLottie/BezierEaser"
import { buildBezierProp } from "./forLottie/buildBezierProp";
import { createImage, rgb2hex, TextureCache } from "../utils";
import { createImage, Dict, rgb2hex, TextureCache } from "../utils";
import { Shape, Graphics } from "../graphics";
import { AnimationNode } from "./AnimationNode";
import { Matrix } from "../math";
......@@ -21,7 +21,7 @@ export class Lottie extends AnimationNode {
/**
* 原始数据,尽量只获取,不修改
*/
protected rawData: LottieData;
protected rawData: ILottieData;
/**
* 总时间,秒计
*/
......@@ -63,7 +63,7 @@ export class Lottie extends AnimationNode {
}
//lottie图层主容器
private lottieContainer: LottieContainer;
constructor(data: LottieData) {
constructor(data: ILottieData) {
super(data);//里面执行了init
this._instanceType = "Lottie";
}
......@@ -72,7 +72,7 @@ export class Lottie extends AnimationNode {
* @param data
* @returns
*/
public init(data: LottieData) {
public init(data: ILottieData) {
if (!data || data == this.rawData) return;
this.rawData = data;
//名字
......@@ -123,32 +123,37 @@ export class Lottie extends AnimationNode {
}
}
interface LottieData {
export interface ILottieData {
"fr": number,//帧率 30 60等
"ip": number,//开始帧
"op": number,//结束帧
"w": number,//宽度
"h": number,//高度
"nm": string,//名字
"layers": LayerData[],
"layers": ILottieLayerData[],
"assets"?: {
"id": string,//图片id,与layers里的refId对应
"w": number,
"h": number,
"p": string,//base64数据
"layers": LayerData[],//合成嵌套的
"layers": ILottieLayerData[],//合成嵌套的
}[],
"textures"?: { [key: string]: Texture }//缓存的贴图,为了上面的assets里的图片数据,不进全局缓存,
// "components"?: { [key: string]: LottieData }
compositions?: { [key: string]: LayerData[] }
"textures"?: Dict<Texture>//缓存的贴图,为了上面的assets里的图片数据,不进全局缓存,
"compositions"?: Dict<ILottieLayerData[]>
}
interface LayerData {
export interface ILottieLayerData {
"ind": number,//id唯一
"ty": number,//类型,2是图片,0是合成
"nm": string//"owl_sleep.png",//暂时就是图片
"refId": string,
"parent"?: number,//父级id
"ks": KsData;
"ks": {
o: ILottieKeyData //透明度
r: ILottieKeyData //旋转
p: ILottieKeyData //位置
a: ILottieKeyData //锚点
s: ILottieKeyData //缩放
};
"ip": number,//开始帧
"op": number,//结束帧
"st": number,
......@@ -157,21 +162,15 @@ interface LayerData {
hasMask?: boolean,
masksProperties?: ILottieMaskData[],//遮罩数据
}
interface KsData {
o: KeyData //透明度
r: KeyData //旋转
p: KeyData //位置
a: KeyData //锚点
s: KeyData //缩放
}
interface KeyData {
export interface ILottieKeyData {
a: number,//貌似没用,0表示无关键帧,1表示有
"s": boolean,//true表示区分维度,比如p的x和y分开走
k: KeyAniData[] | number[] | number,
k: ILottieKeyAniData[] | number[] | number,
x: string,//可能有表达式
}
interface KeyAniData {
export interface ILottieKeyAniData {
t: number,
s: number[],
......@@ -188,7 +187,7 @@ interface KeyAniData {
fnc?,//贝塞尔函数,可能是数组,
}
interface ILottieMaskData {
export interface ILottieMaskData {
inv: boolean,//true需要处理矩形wh的矩形遮罩
mode: "n" | "a",//遮罩模式,一般是a
pt: {
......@@ -214,14 +213,14 @@ interface ILottieMaskData {
"nm": string
}
enum LoopType {
enum ILottieLoopType {
pingpong = "pingpong",
cycle = "cycle",
}
interface LoopData {
export interface ILottieLoopData {
loopInOrOut: 0 | 1 | 2,//0表示没有,1表示in前面循环,2表示out后续循环
type: LoopType,
type: ILottieLoopType,
duration: number,//为0表示全循环
}
/**
......@@ -232,8 +231,8 @@ class LottieBaseTrack extends HashObject implements IAnimationTrack {
constructor(
protected obj: Sprite,
private type?: "r" | "o" | "s" | "p",
private times?: KeyAniData[],
private loop?: LoopData,
private times?: ILottieKeyAniData[],
private loop?: ILottieLoopData,
private ip: number = 0,//偏移
private xy: "x" | "y" = null
) {
......@@ -426,7 +425,7 @@ class LottieExpressionTrack extends HashObject implements IAnimationTrack {
}
}
function loopOut(type: LoopType, duration: number, keyframes: KeyAniData[], currentFrame: number) {
function loopOut(type: ILottieLoopType, duration: number, keyframes: ILottieKeyAniData[], currentFrame: number) {
var lastKeyFrame = keyframes[keyframes.length - 1].t;
if (currentFrame <= lastKeyFrame) return currentFrame;
......@@ -452,7 +451,7 @@ function loopOut(type: LoopType, duration: number, keyframes: KeyAniData[], curr
//给出时间就行,自行判断是否计算,根据
function loopIn(type: LoopType, duration: number, keyframes: KeyAniData[], currentFrame: number) {
function loopIn(type: ILottieLoopType, duration: number, keyframes: ILottieKeyAniData[], currentFrame: number) {
var firstKeyFrame = keyframes[0].t;
if (currentFrame >= firstKeyFrame) return currentFrame;
//0时取全部
......@@ -463,7 +462,7 @@ function loopIn(type: LoopType, duration: number, keyframes: KeyAniData[], curre
var cycleDuration = lastKeyFrame - firstKeyFrame;
// var i, len, ret;
if (type === LoopType.pingpong) {
if (type === ILottieLoopType.pingpong) {
var iterations = Math.floor((firstKeyFrame - currentFrame) / cycleDuration);
if (iterations % 2 === 0) {
return (firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame;
......@@ -499,7 +498,7 @@ function generateFuncs(outV, inV, len) {
}
}
function getLoopData(x: string): LoopData {
function getLoopData(x: string): ILottieLoopData {
if (!x) return null;
//取数字
var rr = +x.replace(/[^0-9]/ig, "");
......@@ -509,11 +508,11 @@ function getLoopData(x: string): LoopData {
} else if (x.indexOf("loopIn") >= 0) {
loopInOrOut = 1
}
var type: LoopType;
var type: ILottieLoopType;
if (x.indexOf("pingpong") >= 0) {
type = LoopType.pingpong
type = ILottieLoopType.pingpong
} else if (x.indexOf("cycle") >= 0) {
type = LoopType.cycle
type = ILottieLoopType.cycle
}
return { loopInOrOut, type, duration: rr }
}
......@@ -547,7 +546,7 @@ function setValue(obj: Sprite, value: number | number[], type: "r" | "o" | "s" |
/**
*
*/
interface ILottieLater {
export interface ILottieLater {
_mark: boolean;
_isLottieLayer: boolean;
_ind: number
......@@ -623,10 +622,10 @@ class LottieContainer extends Container {
*/
function createLottieTracks(
root: LottieContainer,
layers: LayerData[],
layers: ILottieLayerData[],
offset: number,
textures: { [key: string]: Texture },
compositions?: { [key: string]: LayerData[] },
textures: Dict<Texture>,
compositions?: Dict<ILottieLayerData[]>,
tracks: (LottieVisibleTrack | LottieBaseTrack | LottieExpressionTrack)[] = [],
) {
for (var i = layers.length - 1; i >= 0; i--) {
......@@ -676,7 +675,7 @@ function createLottieTracks(
//加显示隐藏的
tracks.push(new LottieVisibleTrack(c, ip, op, st, offset));
["o", "r", "p", "s"].forEach((type: "o" | "r" | "p" | "s") => {
let k: KeyAniData[] | number[] | number = ks[type].k;
let k: ILottieKeyAniData[] | number[] | number = ks[type].k;
let expression: string = ks[type].x;
//考虑x和y分开的情况,不会有加减
if (!k) {
......@@ -701,7 +700,7 @@ function createLottieTracks(
if (((type == "o" || type == "r") && k.length) ||//透明度和旋转,k有长度就是关键帧,
((type == "s" || type == "p") && typeof k[0] != "number")) {//透明度和旋转,k有长度就是关键帧,位置和缩放得k的元素里不是number
tracks.push(
new LottieBaseTrack(c as Sprite, type, k as KeyAniData[], getLoopData(expression), offset)
new LottieBaseTrack(c as Sprite, type, k as ILottieKeyAniData[], getLoopData(expression), offset)
)
} else {
//没有关键帧的设置下初始值
......
......@@ -4,7 +4,7 @@ import { Shape } from "../graphics";
import { HashObject } from "../HashObject";
import { Matrix } from "../math";
import { BaseTexture, Texture } from "../texture";
import { clamp, createCanvas, createImage, rgb2hex, TextureCache } from "../utils";
import { clamp, createCanvas, createImage, Dict, rgb2hex, TextureCache } from "../utils";
import { AnimationNode } from "./AnimationNode";
/**
......@@ -14,7 +14,7 @@ export class SvgaAni extends AnimationNode {
/**
* 原始数据,接口在解析类上,不搞先,尽量只获取,不修改
*/
protected rawData: VideoEntity;
protected rawData: IVideoEntity;
/**
* 总时间,秒计
*/
......@@ -54,7 +54,7 @@ export class SvgaAni extends AnimationNode {
// * 用于控制动画,这里面的按帧数计,animationClip.totalTime是总帧数,因为文件标记的是帧,而不是时间
// */
// animationClip: AnimationClip;
constructor(data: VideoEntity) {
constructor(data: IVideoEntity) {
super(data);//里面执行了init
this._instanceType = "SvgaAni";
}
......@@ -63,7 +63,7 @@ export class SvgaAni extends AnimationNode {
* @param data
* @returns
*/
init(data: VideoEntity) {
init(data: IVideoEntity) {
if (!data || data == this.rawData) return;
//记录原数据
this.rawData = data;
......@@ -137,7 +137,7 @@ export class SvgaAni extends AnimationNode {
anchorY?: number
): T {
if (!child || !imageKey || !this.rawData || !this.animationClip) return;
var oriFrames: FrameEntity[], sprites = this.rawData.sprites;
var oriFrames: IFrameEntity[], sprites = this.rawData.sprites;
for (var i = 0; i < sprites.length; i++) {
if (sprites[i].imageKey == imageKey) {
oriFrames = sprites[i].frames;
......@@ -252,7 +252,7 @@ export class SvgaAni extends AnimationNode {
* @param anchorY 相对锚点y,默认0
*/
static deepCopyFrames(
frames: FrameEntity[],
frames: IFrameEntity[],
x: number = 0,
y: number = 0,
scaleX: number = 1,
......@@ -260,7 +260,7 @@ export class SvgaAni extends AnimationNode {
rotation: number = 0,
anchorX: number = 0,
anchorY: number = 0
): FrameEntity[] {
): IFrameEntity[] {
var cf = [];
rotation *= Math.PI / 180;
//@ts-ignore
......@@ -293,7 +293,7 @@ export class SvgaAni extends AnimationNode {
/**
* 导出只是当作类型接口用
*/
interface VideoEntity {
export interface IVideoEntity {
/**
* SVGA 文件版本
*/
......@@ -316,15 +316,11 @@ interface VideoEntity {
/**
* base64图片数据记录
*/
images: {
[key: string]: string
};
images: Dict<string>;
/**
* 缓存的纹理
*/
textures: {
[key: string]: Texture
}
textures: Dict<Texture>;
/**
* 图片是否已被缓存,缓存全局,注意名字覆盖
*/
......@@ -332,10 +328,10 @@ interface VideoEntity {
/**
* sprite对象数据
*/
sprites: SpriteEntity[];
sprites: ISpriteEntity[];
}
interface SpriteEntity {
export interface ISpriteEntity {
/**
* 暂时没用
*/
......@@ -347,12 +343,12 @@ interface SpriteEntity {
/**
* 帧数据数组
*/
frames: FrameEntity[];
frames: IFrameEntity[];
}
/**
* 还有很多其他数据,暂不需要,比如矢量路径和遮罩路径暂时都无
*/
interface FrameEntity {
export interface IFrameEntity {
/**
* 透明度
*/
......@@ -377,7 +373,7 @@ interface FrameEntity {
class SvgaTrack extends HashObject implements IAnimationTrack {
constructor(
private obj: Container,
private frames: FrameEntity[],
private frames: IFrameEntity[],
) {
super();
this._instanceType = "SvgaTrack";
......
......@@ -18,6 +18,8 @@ export * from "./tbminiAdapte";
//在mapPremultipliedBlendModes文件内自行导出,以防在引擎外暴露
// export const premultiplyBlendMode = mapPremultipliedBlendModes();
export * from "./types"
let nextUid = 0;
/**
......
//// 这里放一些通用的约束类型和接口
/**
* 所有字段都是统一类型的json接口
*/
export interface Dict<T> { [key: string]: T };
\ No newline at end of file
import ObjectRenderer from "../2d/renderers/webgl/ObjectRenderer";
import { WebglRenderer } from "../2d/renderers/WebglRenderer";
import { Camera } from "./cameras/Camera";
import { LightsConfig, ShadowType } from "./Scene3D";
import { ILightsConfig, ShadowType } from "./Scene3D";
import { GLShader, GLBuffer, VertexArrayObject } from "../glCore";
import { Mesh3D } from "./Mesh3D";
import { BaseShader } from "./shaders/BaseShader";
import { LightShader } from "./shaders/LightShader";
import { hex2rgb, rgb2hex } from "../2d/utils";
import { hex2rgb, rgb2hex, Dict } from "../2d/utils";
import { Matrix4 } from "./math/Matrix4";
import { BLEND_MODES } from "../2d/const";
import { BatchBuffer } from "../2d/renderers/webgl/BatchBuffer";
import { BaseMaterial, RenderSideType } from "./materials/BaseMaterial";
import { getCusShader } from "./shaders/getCusShader";
import { Geometry, VaoBufferInt } from ".";
import { Geometry, IGeoVaoBuffer } from "./Geometry";
import { SkinnedMesh3D } from "./bones/SkinnedMesh3D";
import { nextPow2 } from "../2d/utils"
import { BaseTexture, Texture } from "../2d/texture";
......@@ -36,7 +36,7 @@ export class D3Renderer extends ObjectRenderer {
/**
* 灯光数据,用来初始化着色器和着色器传值
*/
lightsConfig: LightsConfig;
lightsConfig: ILightsConfig;
/**
* 雾化参数
*/
......@@ -487,7 +487,7 @@ var morphInfluences = new Float32Array(8);
function addMorphtargetsAttr(
objectInfluences: number[],
geo: Geometry,
glVaoBuffer: VaoBufferInt,
glVaoBuffer: IGeoVaoBuffer,
vao: VertexArrayObject,
shader: GLShader,
gl: WebGLRenderingContext,
......@@ -623,7 +623,7 @@ WebglRenderer.registerPlugin('d3', D3Renderer);
let shadowMap: RenderTexture;
//暂时只按照渲染器的id来缓存,到时可能还会有顶点或骨骼动画,再修改,TODO
let shadowShaders: { [key: string]: ShadowShader } = {};
let shadowShaders: Dict<ShadowShader> = {};
/**
* 光源相机
*/
......@@ -639,7 +639,7 @@ let shadowShaders: { [key: string]: ShadowShader } = {};
* @param renderer
*/
function getShadowMap(
lights: LightsConfig,
lights: ILightsConfig,
meshes: Mesh3D[],
renderer: WebglRenderer
): { texture: Texture, lightSpaceMatrix: number[], shadowType: ShadowType } {
......
......@@ -6,6 +6,7 @@ import { BatchBuffer } from "../2d/renderers/webgl/BatchBuffer";
import { Box3 } from "./math/Box3";
import { Sphere } from "./math/Sphere";
import { Bone3D } from "./bones/Bone3D";
import { Dict } from "../2d/utils";
......@@ -56,7 +57,7 @@ export class Geometry extends HashObject {
*
*/
// _glVertexArrayObjects: { [key: number]: VertexArrayObject }
_glVaoBuffer: { [key: number]: VaoBufferInt }
_glVaoBuffer: Dict<IGeoVaoBuffer>;
/**
* 记录顶点数据用,包括坐标,颜色,uv,法线
......@@ -160,7 +161,7 @@ export class Geometry extends HashObject {
/**
* 根据webglRendererId存一个,vao还需要根据着色器程序缓存
*/
export interface VaoBufferInt {
export interface IGeoVaoBuffer {
/**
* 索引
*/
......@@ -187,7 +188,7 @@ export interface VaoBufferInt {
* 需要根据着色器程序id作为指向,
* 灯光重置过着色器,基本要重来一次,上面的buffer可以留着,重新addAttr到新的vao
*/
vaos: { [key: string]: VertexArrayObject }
vaos: Dict<VertexArrayObject>
}
......
......@@ -217,7 +217,7 @@ export class Scene3D extends Object3D {
}
getLightConfig(
con: Object3D = this,
arr: LightsConfig = { pointLights: [], directionalLights: [], ambientLightColor: [0, 0, 0] }
arr: ILightsConfig = { pointLights: [], directionalLights: [], ambientLightColor: [0, 0, 0] }
) {
var viewMatrix = this.camera.worldMatrixInverse;
for (var i = 0; i < con.children.length; i++) {
......@@ -572,20 +572,20 @@ export interface IOrbitControlConfig {
export interface LightsConfig {
pointLights: PointLightConfig[],
directionalLights: DirectionalLightConfig[],
export interface ILightsConfig {
pointLights: IPointLightConfig[],
directionalLights: IDirectionalLightConfig[],
ambientLightColor: number[],
}
interface PointLightConfig {
export interface IPointLightConfig {
color: number[],//光源颜色
position: number[],//点光源位置
distance: number,//最大光源距离
decay: number,//衰减系数,默认1,最佳2
}
interface DirectionalLightConfig {
export interface IDirectionalLightConfig {
direction: number[],
color: number[],
castShadow: boolean,
......
import { Dict } from "../../2d/utils";
import { HashObject } from "../../2d/HashObject";
import { WebglRenderer } from "../../2d/renderers/WebglRenderer";
import { GLShader } from "../../glCore";
......@@ -43,7 +44,7 @@ export class ShaderMaterial extends HashObject {
/**
* key就是渲染器唯一id
*/
protected shaders: { [key: string]: GLShader } = {};
protected shaders: Dict<GLShader> = {};
/**
* 标记下。
* 本来想直接用_instanceType判断,但是后续考虑到SpriteMaterial,SkyMaterial都会继承这个,会重写_instanceType
......@@ -54,7 +55,7 @@ export class ShaderMaterial extends HashObject {
constructor(
protected vertexShader = defaultVertexShader3d,
protected fragmentShader = defaultFragmentShader3d,
public uniforms: { [key: string]: { type: UniformType, value: any } } = {}
public uniforms: Dict<{ type: UniformType, value: any }> = {}
) {
super();
this.vertexShader = vertexShader || defaultVertexShader3d;
......
import { GLShader, defaultValue } from "../../glCore";
import { WebglRenderer } from "../../2d/renderers/WebglRenderer";
import { BaseMaterial, EnvBlendType } from "../materials/BaseMaterial";
import { LightsConfig, ShadowType } from "../Scene3D"
import { ILightsConfig, ShadowType } from "../Scene3D"
import { generateUniformAccessObject, mapType } from "../../glCore/shader";
import { Mesh3D } from "..";
import { Mesh3D } from "../Mesh3D";
import { Dict } from "../../2d/utils";
/**
......@@ -15,7 +16,7 @@ import { Mesh3D } from "..";
export function getCusShader(
render: WebglRenderer,
material: BaseMaterial,
lights: LightsConfig,
lights: ILightsConfig,
mesh: Mesh3D,
maxBones?: number,
useVertexTexture?: boolean,
......@@ -23,7 +24,7 @@ export function getCusShader(
shadow?: any
) {
//所有参数
var parameters: ShaderParametersInt = {
var parameters: IShaderParameters = {
glUid: render.CONTEXT_UID,
precision: getMaxPrecision(render),//也可能是材质上传的,再说了TODO
pointLightsNum: lights.pointLights.length,
......@@ -72,7 +73,7 @@ export function getCusShader(
* 根据参数获取shaderKey
* @param parameters
*/
function getShaderKey(parameters: ShaderParametersInt) {
function getShaderKey(parameters: IShaderParameters) {
var array = [];
for (var i = 0; i < parameterNames.length; i++) {
array.push(parameters[parameterNames[i]]);
......@@ -81,7 +82,7 @@ function getShaderKey(parameters: ShaderParametersInt) {
}
//根据渲染器的上下文id缓存的最大精度
const maxPrecisionCache: { [key: number]: string } = {}
const maxPrecisionCache: Dict<string> = {}
/**
* 获取最大精度,暂时不考虑缓存,性能有问题再说TODO
* @param gl
......@@ -121,7 +122,7 @@ class CusShader extends GLShader {
*/
constructor(
gl: WebGLRenderingContext,
parameters: ShaderParametersInt
parameters: IShaderParameters
) {
//预处理参数
var frontVert = [
......@@ -243,7 +244,7 @@ const parameterNames = [
/**
* 着色器编译参数接口
*/
interface ShaderParametersInt {
export interface IShaderParameters {
glUid: number,
precision: string,
pointLightsNum: number,
......
......@@ -5,6 +5,7 @@ import { Attachment } from "./attachment/Attachment";
import { SpineColor } from "./SpineColor";
import { Spine } from "./Spine";
import { Graphics } from "../2d/graphics";
import { Dict } from "../2d/utils";
//作为插槽容器
//外部控制子级的加入及显示隐藏
......@@ -14,9 +15,9 @@ export class Slot extends Container {
currentGraphics: Graphics;
clippingContainer: any;
meshes: { [key: string]: Mesh };
meshes: Dict<Mesh>;
currentMeshName: string;
sprites: { [key: string]: Sprite };
sprites: Dict<Sprite>;
currentSpriteName: string;
//需要显示的附着图片名字。循环时根据
......
......@@ -11,7 +11,7 @@ import { MeshAttachment } from "./attachment/MeshAttachment";
import { Transform } from "../2d/math";
import { Mesh } from "../2d/mesh";
import { rgb2hex } from "../2d/utils";
import { rgb2hex, Dict } from "../2d/utils";
import { IBoneAniData, SpineBoneAniTrack } from "./animation/SpineBoneAniTrack";
import { IColorAniData, SpineColorAniTrack } from "./animation/SpineColorAniTrack";
import { IDeformAniData, SpineDeformAniTrack } from "./animation/SpineDeformAniTrack";
......@@ -33,41 +33,29 @@ export interface ISkeletonData {
spine: number
},
//纹理数据
textures?: { [key: string]: Texture },
textures?: Dict<Texture>,
bones: IBoneData[],
//附着的皮肤
skins: { [key: string]: { [key: string]: { [key: string]: ISkinData } } },
skins: Dict<Dict<Dict<ISkinData>>>,
slots: ISlotData[],
animations: {
[key: string]: {
bones: {
[key: string]: {
rotate: IBoneAniData[],
translate: IBoneAniData[]
scale: IBoneAniData[]
shear: IBoneAniData[]
}
},
//网格变形数据
deform: {
[key: string]: {
[key: string]: {
[key: string]: IDeformAniData[]
}
}
},
slots: {
[key: string]: {
//附着皮肤修改
attachment: IAttachmentAniData[],
//颜色变化
color: IColorAniData[]
}
},
drawOrder: IDrawOrderAniData[]
ik: { [key: string]: { time: number, mix: number, bendPositive: boolean }[] }
}
},
animations: Dict<{
bones: Dict<{
rotate: IBoneAniData[],
translate: IBoneAniData[]
scale: IBoneAniData[]
shear: IBoneAniData[]
}>,
//网格变形数据
deform: Dict<Dict<Dict<IDeformAniData[]>>>,
slots: Dict<{
//附着皮肤修改
attachment: IAttachmentAniData[],
//颜色变化
color: IColorAniData[]
}>,
drawOrder: IDrawOrderAniData[]
ik: Dict<{ time: number, mix: number, bendPositive: boolean }[]>
}>,
transform: {
bones: string[]
name: string
......@@ -94,7 +82,7 @@ export interface ISkeletonData {
}[]
}
interface ISkinData {
export interface ISkinData {
path?: string,//图片路径,没有用name
//类型,没有就是region图片
type?: SkinType,
......
import { GlobalLoader } from "../2d/loader";
import { Texture, BaseTexture } from "../2d/texture";
import { Rectangle } from "../2d/math";
import { Dict } from "../2d/utils";
/**
* 为了不影响原2djson图集的rotate判断,这里单独搞,rotate是6
......@@ -11,8 +12,7 @@ import { Rectangle } from "../2d/math";
*/
export function loadAtlas(
url: string,
// onLoad: (textures: { [key: string]: Texture }) => void,//这种写法,d.ts生成有问题
onLoad: (textures: any) => void,
onLoad: (textures: Dict<Texture>) => void,
onError?: (err: any) => void,
imgUrl?: string
) {
......@@ -44,8 +44,8 @@ export function loadAtlas(
}
//由于旋转角度问题,单开方法
export function createTexturesByAtlas(baseTexture: BaseTexture, altaData: string): { [key: string]: Texture } {
const textures: { [key: string]: Texture } = {}
export function createTexturesByAtlas(baseTexture: BaseTexture, altaData: string): Dict<Texture> {
const textures: Dict<Texture> = {}
//解析数据
var reader = new AtlasReader(altaData)
var tuple = new Array(4);
......
<!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" />
<style>
html,
body {
padding: 0;
margin: 0;
border: 0;
width: 100%;
height: 100%;
overflow: hidden;
position: absolute;
background-color: #eeeeee;
}
</style>
<script src="../build/fyge.min.js"></script>
</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 = 750;
canvas.height = 1624;
//建舞台
var stage = new FYGE.Stage(
canvas,
750,//设计宽度,按设计搞给的就行
1624,//设计高度
document.body.clientWidth,
document.body.clientHeight,
FYGE.RENDERER_TYPE.WEBGL,
false,
);
var mouseEvent = stage.onMouseEvent.bind(stage);
canvas.addEventListener("touchstart", mouseEvent, false);
canvas.addEventListener('touchmove', mouseEvent, false);
canvas.addEventListener('touchend', mouseEvent, false);
//stage初始化
stage.addEventListener(FYGE.Event.INIT_STAGE, async () => {
var img = await new Promise((r) => {
FYGE.loadImage("./res/hor_ele1_0.png", r)
})
let t = FYGE.Texture.from(img);
for (var i = 0; i < 10; i++) {
let s = stage.addChild(new FYGE.Sprite(t));
s.y=500;
// s.addEventListener(FYGE.Event.ENTER_FRAME,)
}
}, this)
//循环
loop();
function loop() {
stage.flush();
FYGE.Tween.flush()
requestAnimationFrame(loop);
}
})
</script>
</html>
\ No newline at end of file
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