Commit 2afda240 authored by wjf's avatar wjf

l

parent f49611da
# project ignores
node_modules
\ No newline at end of file
jsconfig111111.json
\ No newline at end of file
......@@ -2,6 +2,7 @@
node_modules
/scripts
/src
/build/fyge.min.js.map
tsConfig.json
package-lock.json
webpack.config.js
\ No newline at end of file
jsconfig111111.json
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"allowSyntheticDefaultImports": true
},
"exclude": [
"node_modules",
"bower_components",
"jspm_packages",
"tmp",
"temp"
]
}
\ No newline at end of file
......@@ -1429,12 +1429,14 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
......@@ -1449,17 +1451,20 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"core-util-is": {
"version": "1.0.2",
......@@ -1576,7 +1581,8 @@
"inherits": {
"version": "2.0.4",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"ini": {
"version": "1.3.5",
......@@ -1588,6 +1594,7 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
......@@ -1602,6 +1609,7 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
......@@ -1609,12 +1617,14 @@
"minimist": {
"version": "1.2.5",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"minipass": {
"version": "2.9.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
......@@ -1633,6 +1643,7 @@
"version": "0.5.3",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"minimist": "^1.2.5"
}
......@@ -1694,7 +1705,8 @@
"npm-normalize-package-bin": {
"version": "1.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"npm-packlist": {
"version": "1.4.8",
......@@ -1722,7 +1734,8 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"object-assign": {
"version": "4.1.1",
......@@ -1734,6 +1747,7 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"wrappy": "1"
}
......@@ -1847,6 +1861,7 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
......
{
"name": "fyge",
"version": "1.0.3",
"name": "fyge-tbmini",
"version": "1.0.8",
"description": "淘宝小程序canvas渲染引擎",
"main": "./dist/fyge.min.js",
"types": "./types/FYGE.d.ts",
"main": "./build/fyge.min.js",
"types": "./build/FYGE.d.ts",
"dependencies": {},
"scripts": {
"declare": "node scripts/declare.js src/index.ts",
......
......@@ -42,7 +42,7 @@ function compile(fileNames, options) {
// const content = `declare module FYGE{${allExports}}`;
const content = `declare namespace FYGE{${allExports}}\ndeclare module "fyge" {export = FYGE;}`;
fs.writeFileSync('types/FYGE.d.ts', content);
fs.writeFileSync('build/FYGE.d.ts', content);
}
compile(process.argv.slice(2), {
......
// /**
// * 相关配置信息,外部可修改,注意修改
// * 主要为了一些方法适配,以及
// */
// export const Setting = {
// createCanvas: function () {
// //@ts-ignore
// return document && document.createElement("canvas") || my._createOffscreenCanvas()
// },
// /**
// * 手动赋值,这个必须要
// */
// createImage: function (): HTMLImageElement {
// return new Image()
// },
// // createImage: function () {
// // return canvas.createImage(),
// // },
// /**
// * 手动赋值,尽量在外面自行处理
// */
// requestAnimationFrame: function (loop): any {
// return window.requestAnimationFrame(loop)
// },
// // requestAnimationFrame: function (loop) {
// // canvas.requestAnimationFrame(loop)
// // },
// /**
// * 手动赋值,尽量在外面自行处理
// */
// cancelAnimationFrame: function (loopId) {
// window.cancelAnimationFrame(loopId)
// },
// // cancelAnimationFrame: function (loop) {
// // canvas.cancelAnimationFrame(loop)
// // }
// }
......@@ -54,6 +54,14 @@ export default class Container extends DisplayObject {
this.addChildAt(child, this.children.length);
return child;
}
/**
* 批量添加child
* @param children
*/
addChildren<T extends DisplayObject>(...children: T[]): T[] {
children.forEach((child: T) => { this.addChild(child); })
return children
}
/**
* 在相应index处添加child
......@@ -252,21 +260,45 @@ export default class Container extends DisplayObject {
return child;
}
/**
* 批量移除child,
* @param children 不传参数,表示全部移除
*/
removeChildren<T extends DisplayObject>(...children: T[]): T[] {
if (!children.length) return this.spliceChildren(0);
children.forEach((child: T) => { this.removeChild(child); })
return children
}
/**
* 通过索引批量移除child
* @param {number} [beginIndex=0]
* @param {number} [endIndex=this.children.length]
* @returns {DisplayObject[]} List of removed children
*/
removeChildren(beginIndex: number = 0, endIndex: number = this.children.length): DisplayObject[] {
removeChildrenAt(beginIndex: number = 0, endIndex: number = this.children.length): DisplayObject[] {
const begin = beginIndex;
const end = typeof endIndex === 'number' ? endIndex : this.children.length;
const range = end - begin;
let removed;
if (range > 0 && range <= end) {
removed = this.children.splice(begin, range);
return this.spliceChildren(begin, range)
}
else if (range === 0 && this.children.length === 0) {
return [];
}
throw new RangeError('removeChildren: numeric values are outside the acceptable range.');
}
/**
* 类比splice方法
* @param beginIndex
* @param count
*/
spliceChildren<T extends DisplayObject>(beginIndex?: number, count?: number): T[] {
let removed = this.children.splice(beginIndex, count);
if (!removed.length) return [];
for (let i = 0; i < removed.length; ++i) {
removed[i].parent = null;
......@@ -282,15 +314,8 @@ export default class Container extends DisplayObject {
for (let i = 0; i < removed.length; ++i) {
removed[i]._onDispatchBubbledEvent(Event.REMOVED_FROM_STAGE);
}
return removed;
}
else if (range === 0 && this.children.length === 0) {
return [];
}
throw new RangeError('removeChildren: numeric values are outside the acceptable range.');
}
/**
* 更新矩阵
......
......@@ -246,7 +246,7 @@ export class DisplayObject extends EventDispatcher {
}
/**
* 以父级为世界坐标系的本地包围盒
* 以自身为世界坐标系的本地包围盒
* @param {Rectangle} [rect] - Optional rectangle to store the result of the bounds calculation
* @return {Rectangle} the rectangular bounding area
*/
......@@ -395,7 +395,8 @@ export class DisplayObject extends EventDispatcher {
*/
destroy() {
//移除所有监听
this.removeAllEventListener();
// this.removeAllEventListener();
super.destroy();
//如果有父级,从中移除自己
if (this.parent) {
this.parent.removeChild(this);
......
......@@ -162,12 +162,7 @@ export default class Sprite extends Container {
}
//修改_localBoundsSelf
const width = this._texture.orig.width;
const height = this._texture.orig.height;
this._localBoundsSelf.x = -width * this.anchorTexture.x;
this._localBoundsSelf.y = -height * this.anchorTexture.y;
this._localBoundsSelf.width = width;
this._localBoundsSelf.height = height;
this.updateLocalBoundsSelf();
}
/**
......@@ -175,9 +170,25 @@ export default class Sprite extends Container {
*
* @private
*/
_onAnchorUpdate() {
private _onAnchorUpdate() {
this._transformID = -1;
this._transformTrimmedID = -1;
//贴图锚点修改,也要修改自身盒子,因为鼠标点击有用到
this.updateLocalBoundsSelf();
}
/**
* 通过自身贴图修改自身盒子
* 子类可修改,比如文本不需要padding的话,暂时还没做
*/
protected updateLocalBoundsSelf() {
//修改_localBoundsSelf
const width = this._texture.orig.width;
const height = this._texture.orig.height;
this._localBoundsSelf.x = -width * this.anchorTexture.x;
this._localBoundsSelf.y = -height * this.anchorTexture.y;
this._localBoundsSelf.width = width;
this._localBoundsSelf.height = height;
}
/**
......
......@@ -9,9 +9,9 @@ import { DisplayObject } from "./DisplayObject";
import { MouseEvent } from "../events/MouseEvent";
import { WebglRenderer } from "../renderers/WebglRenderer";
import { getRequestAnimationFrame, getCancelAnimationFrame } from "../utils";
import { Stats } from "../../Stats";
import { CanvasRenderer } from "../renderers/CanvasRenderer";
import { SystemRenderer } from "../renderers/SystemRenderer";
export class Stage extends Container {
......@@ -24,7 +24,7 @@ export class Stage extends Container {
* @type {IRender}
* @default null
*/
public renderObj: WebglRenderer = null;
public renderObj: SystemRenderer = null;
/**
......@@ -45,36 +45,7 @@ export class Stage extends Container {
* @private
*/
private static _stageList: any = {};
/**
* 是否暂停
* @property pause
* @static
* @type {boolean}
* @public
* @since 1.0.0
* @default false
*/
static get pause(): boolean {
return this._pause;
}
static set pause(value: boolean) {
this._pause = value;
if (value != this._pause) {
//触发事件
// GDispatcher.dispatchEvent("onStagePause", { pause: value });
}
}
/**
* @property _pause
* @type {boolean}
* @private
* @static
*/
private static _pause: boolean = false;
private static _flushId = -1;
/**
* 舞台在设备里截取后的可见区域,有些时候知道可见区域是非常重要的,因为这样你就可以根据舞台的可见区域做自适应了。
* @property viewRect
......@@ -166,16 +137,12 @@ export class Stage extends Container {
* @param {*} data desWidth,desHeight,divWidth,divHeight,canWidth,canHeight
*/
public constructor(
context: WebGLRenderingContext | CanvasRenderingContext2D,
data: {
type: RENDERER_TYPE
desWidth: number,
desHeight: number,
canvas: HTMLCanvasElement,
desWidth: number = 750,
desHeight: number = 1624,
divWidth: number,
divHeight: number,
canWidth: number,
canHeight: number
}
renderType: RENDERER_TYPE = RENDERER_TYPE.CANVAS,
) {
super();
let s: Stage = this;
......@@ -183,48 +150,49 @@ export class Stage extends Container {
Stage._stageList["canvas"] = s;
s.stage = this;
s.name = "stageInstance_" + s.instanceId;
s.desWidth = data.desWidth || 750;
s.desHeight = data.desHeight || 1206;
s.divWidth = data.divWidth;
s.divHeight = data.divHeight;
s.desWidth = desWidth || 750;
s.desHeight = desHeight || 1206;
s.divWidth = divWidth;
s.divHeight = divHeight;
s.dpi = data.canWidth / data.divWidth
// my.alert({
// title: '55729:'+data.canWidth+","+data.canHeight
// });
// s.renderObj = new CanvasRenderer(context, data.canWidth, data.canHeight);
if (data.type == RENDERER_TYPE.CANVAS) {
//@ts-ignore
s.renderObj = new CanvasRenderer(context, data.canWidth, data.canHeight);
if (renderType == RENDERER_TYPE.CANVAS) {
let context = canvas.getContext("2d");
s.renderObj = new CanvasRenderer(context, canvas.width, canvas.height);
} else {
//@ts-ignore
s.renderObj = new WebglRenderer(context, data.canWidth, data.canHeight);
let context = canvas.getContext("webgl");
s.renderObj = new WebglRenderer(context, canvas.width, canvas.height);
}
s.dpi = canvas.width / divWidth
//不加刚好置顶
s.anchorX = data.desWidth >> 1;
s.anchorY = data.desHeight >> 1;
s.x = (data.canWidth - data.desWidth) >> 1;
s.y = (data.canHeight - data.desHeight) >> 1;
s.anchorX = desWidth >> 1;
s.anchorY = desHeight >> 1;
s.x = (canvas.width - desWidth) >> 1;
s.y = (canvas.height - desHeight) >> 1;
//定宽
var scale = data.canWidth / data.desWidth;
var scale = canvas.width / desWidth;
s.scaleX = scale;
s.scaleY = scale;
s.viewRect = new Rectangle();
s.viewRect.x = (data.desWidth - data.canWidth / scale) >> 1;
s.viewRect.y = (data.desHeight - data.canHeight / scale) >> 1;
s.viewRect.width = data.desWidth - s.viewRect.x * 2;
s.viewRect.height = data.desHeight - s.viewRect.y * 2;
s.viewRect.x = (desWidth - canvas.width / scale) >> 1;
s.viewRect.y = (desHeight - canvas.height / scale) >> 1;
s.viewRect.width = desWidth - s.viewRect.x * 2;
s.viewRect.height = desHeight - s.viewRect.y * 2;
// my.alert({
// title: StageManager.ins.width
// });
setTimeout(function () {
//同时添加到主更新循环中
Stage.addUpdateObj(s);
//派发事件
s.dispatchEvent(Event.INIT_STAGE);
// }
}, 100);
}
......@@ -276,16 +244,6 @@ export class Stage extends Container {
this.renderObj.render(this);
}
/**
* 当一个stage不再需要使用,或者要从浏览器移除之前,请先停止它,避免内存泄漏
* @method kill
* @since 1.0.0
* @public
*/
public kill(): void {
Stage.removeUpdateObj(this);
}
/**
* html的鼠标或单点触摸对应的引擎事件类型名
* @property _mouseEventTypes
......@@ -527,110 +485,8 @@ export class Stage extends Container {
return this.viewRect;
}
/**
* 要循环调用 flush 函数对象列表
* @method allUpdateObjList
* @static
* @since 1.0.0
* @type {Array}
*/
private static allUpdateObjList: Array<any> = [];
static requestAnimationFrame;
static cancelAnimationFrame;
private static _stats: any
/**
* 刷新所有定时器
* @static
* @private
* @since 1.0.0
* @method flushAll
*/
static flushAll(): void {
if (!Stage.requestAnimationFrame) {
Stage.requestAnimationFrame = getRequestAnimationFrame();
Stage.cancelAnimationFrame = getCancelAnimationFrame();
}
if (!Stage.requestAnimationFrame) return;
if (!Stage._pause) {
if (Stage._stats) Stage._stats.begin();
let len = Stage.allUpdateObjList.length;
for (let i = 0; i < len; i++) {
Stage.allUpdateObjList[i] && Stage.allUpdateObjList[i].flush();
}
if (Stage._stats) Stage._stats.end();
}
Stage._flushId = Stage.requestAnimationFrame(Stage.flushAll);
}
//页面关闭时要执行,隐藏或显示只修改pause,
public static stop() {
//取消帧循环
Stage.cancelAnimationFrame(Stage._flushId);
//去掉帧率检测
Stage._stats = null;
//去掉循环函数,因为时跟着canvas的
Stage.requestAnimationFrame = null;
Stage.cancelAnimationFrame = null
}
/**
* 添加stats帧率显示
* @param canvasId
*/
public static addFPS(canvasId: string) {
//@ts-ignore
if (my) Stage._stats = new Stats(canvasId);
}
/**
* 添加一个刷新对象,这个对象里一定要有一个 flush 函数。
* 因为一但添加,这个对象的 flush 函数会以stage的fps间隔调用
* 如,你的stage是30fps 那么你这个对象的 flush 函数1秒会调用30次。
* @method addUpdateObj
* @param target 要循化调用 flush 函数的对象
* @public
* @static
* @since
*/
public static addUpdateObj(target: any): void {
let isHave: boolean = false;
let len = Stage.allUpdateObjList.length;
for (let i = 0; i < len; i++) {
if (Stage.allUpdateObjList[i] === target) {
isHave = true;
break;
}
}
if (!isHave) {
Stage.allUpdateObjList.unshift(target);
}
}
/**
* 移除掉已经添加的循环刷新对象
* @method removeUpdateObj
* @param target
* @public
* @static
* @since 1.0.0
*/
public static removeUpdateObj(target: any): void {
let len = Stage.allUpdateObjList.length;
for (let i = 0; i < len; i++) {
if (Stage.allUpdateObjList[i] === target) {
Stage.allUpdateObjList.splice(i, 1);
break;
}
}
}
public destroy(): void {
let s = this;
Stage.removeUpdateObj(s);
// s.rootDiv = null;
// s._floatDisplayList = null;
s.renderObj.destroy();
s.renderObj = null;
s.viewRect = null;
......
import { createCanvas } from "../../utils";
/**
* Creates a Canvas element of the given size.
* 其实就是一个离屏canvas,webgl模式不需要建canvas,因为可以用帧缓存
......@@ -20,11 +22,11 @@ export default class CanvasRenderTarget {
*/
constructor(width: number, height: number) {
this.canvas =createCanvas() //document.createElement('canvas');
this.canvas = createCanvas() //document.createElement('canvas');
// console.log("rd1",this.canvas)
this.resize(width, height);//要先设置尺寸?
this.context = this.canvas.getContext('2d');
// console.log("rd",this.context)
// console.log("rd",this.context)
this.resize(width, height);
}
......
import { SCALE_MODES, TEXT_ALIGN, TEXT_lINETYPE, VERTICAL_ALIGN, osType } from "../const";
import Texture from "../texture/Texture";
import { getRGBA, getBackupCanvasContext, createCanvas } from "../utils";
import { getRGBA, createCanvas } from "../utils";
import { Rectangle } from "../math";
import Sprite from "../display/Sprite";
import { BaseTexture } from "../texture";
//文本canvas上xy的偏移量
const padding = 10;
/**
......
......@@ -141,9 +141,10 @@ export default class BaseTexture extends EventDispatcher {
this._sourceChange(source);
this.dispatchEvent("loaded");
} else {
var self = this
source.onload = function () {
this._sourceChange(source);
this.dispatchEvent("loaded");
self._sourceChange(source);
self.dispatchEvent("loaded");
}
}
}
......
......@@ -142,7 +142,7 @@ export default class Texture extends EventDispatcher {
this._rotate = Number(rotate || 0);
if (baseTexture.hasLoaded) {//对于canvas形式的判断hasLoaded有问题,导致不能监听update,到时改
if (baseTexture.hasLoaded || (baseTexture.source && baseTexture.source.getContext)) {//对于canvas形式的判断hasLoaded有问题,导致不能监听update,到时改
if (this.noFrame) {
frame = new Rectangle(0, 0, baseTexture.width, baseTexture.height);
// if there is no frame we should monitor for any base texture changes..
......
import Texture from "../texture/Texture";
import { Event } from "../events/Event";
import Sprite from "../display/Sprite";
import { Container } from "../display";
/**
* 直接通过替换texture替换图片的动画帧
......@@ -8,36 +9,43 @@ import Sprite from "../display/Sprite";
* 默认按时间间隔播放
* 图片都以素材为中心为原点
*/
export class FrameAni extends Sprite {
export class FrameAni extends Container {
private showImage: Sprite
/**
* 所有的纹理
*/
texturesAll: Texture[];
private texturesAll: Texture[];
/**
* 从0开始 锁步会跳帧
* 每一帧就是一张图片,从0开始
*/
currentFrame: number;
private currentFrame: number;
/**
* 所有帧数
*/
totalFrames: number;
get totalFrames(): number {
return this.texturesAll.length
};
/**
* 是否运行中
*/
isPlay: boolean;
private isPlay: boolean;
/**
* 循环次数
*/
private loop: number = 1;
/**
* 开始时间
*/
startTime: number
private startTime: number
/**
* 所有时间,播完所用时间
*/
allTime: number
private allTime: number
/**
* 播放完的回调
*/
callback: Function;
private callback: Function;
/**
* 每秒的帧数,默认30帧
*/
......@@ -56,10 +64,12 @@ export class FrameAni extends Sprite {
*/
constructor(texturesAll: Texture[]) {
super()
this.showImage = new Sprite();
this.showImage.anchorTexture.set(0.5, 0.5);
this.addChild(this.showImage);
this.texturesAll = texturesAll;
this.changeTexture(0);
this.currentFrame = 0;
this.totalFrames = texturesAll.length;
this.addEventListener(Event.ENTER_FRAME, this.onEnterFrame, this)
this.frameRate = 30;
}
......@@ -86,36 +96,38 @@ export class FrameAni extends Sprite {
var deltaTime = dataNow - this.startTime;
var scale = deltaTime / this.allTime;
if (scale >= 1) {
this.loop--;
if (this.loop == 0) {
this.isPlay = false
this.callback && this.callback();
//要循环时加
// this.startTime = Date.now()
// this.currentFrame = 0;
// this.changeTexture(this.currentFrame);
} else {
this.startTime = Date.now()
this.currentFrame = 0;
this.changeTexture(this.currentFrame);
}
} else {
this.currentFrame = (scale * this.texturesAll.length) >> 0;
this.changeTexture(this.currentFrame);
}
}
/**
* 从0开始播
* 回调是播放完后做回收用的
* 从0开始播放
*/
play(callback) {
play(loop: number = 1, callback?: Function) {
this.startTime = Date.now();
this.isPlay = true;
this.currentFrame = 0;
this.changeTexture(0);
this.loop = loop;
this.callback = callback;
}
/**
* 重置为0
* 重置为frame,不播放
*/
reset() {
reset(frame: number = 0) {
this.isPlay = false;
this.currentFrame = 0;
this.changeTexture(0);
this.currentFrame = frame;
this.changeTexture(frame);
}
/**
* 改texture和居中
......@@ -124,11 +136,11 @@ export class FrameAni extends Sprite {
private changeTexture(index: number) {
//考虑空帧的情况
if (this.texturesAll[index]) {
this.texture = this.texturesAll[index];
this.x = -this.texture.width / 2;
this.y = -this.texture.height / 2;
this.showImage.texture = this.texturesAll[index];
// this.showImage.x = -this.texturesAll[index].width / 2;
// this.showImage.y = -this.texturesAll[index].height / 2;
} else {
this.texture = null;
this.showImage.texture = null;
}
}
......
import Container from "../display/Container";
import Texture from "../texture/Texture";
import Sprite from "../display/Sprite";
import { Event } from "../events/Event";
import { TextureCache, getCreateImage } from "../utils";
import { RAD_TO_DEG } from "../const";
import { Matrix } from "../math";
/**
* 用于播放动画
* 帧数监听,已ued给的文件为主,不做补间增加帧数,
* 暂无setImage,setText再加
* 暂时无矢量图和遮罩解析
* 暂不支持加快播放,
* 暂不支持loops循环次数
* 考虑是否支持加快播放,如果能加速,中间帧数监听会出问题
* 考虑是否帧率锁步,同上问题,锁步后会可能失效currentFrame判断
* s.addEventListener(Event.ENTER_FRAME, func = (e) => {
* //这个判断如果只希望执行一次得多加一个条件isInTimeFrame为true,或者及时移除
* if (e.target.currentFrame == 66&&e.target.isInTimeFrame) {
* e.target.removeEventListener(Event.ENTER_FRAME, func);
* }
* });
* 锁步时的每帧监听,用>或<判断,及时移除
* @class MovieClip
* @since 1.0.0
* @public
* @extends Container
*/
export class MovieClip extends Container {
/**
* 锁步将按时间间隔来执行动画
*/
public lockStep: boolean = false;
/**
* mc的当前帧,从1开始
* @property currentFrame
* @public
* @since 1.0.0
* @type {number}
* @default 1
* @readonly
*/
public get currentFrame(): number {
return this._curFrame;
}
/**
* @property _curFrame
* @type {number}
* @private
* @since 2.0.0
* @default 1
*/
private _curFrame: number = 1;
/**
* 当前动画是否处于播放状态
* @property isPlaying
* @readOnly
* @public
* @since 1.0.0
* @type {boolean}
* @default true
* @readonly
*/
public get isPlaying(): boolean {
return this._isPlaying;
}
/**
* @property _isPlaying
* @type {boolean}
* @private
* @since 2.0.0
* @default true
*/
private _isPlaying: boolean = true;
/**
* 动画的播放方向,是顺着播还是在倒着播
* @property isFront
* @public
* @since 1.0.0
* @type {boolean}
* @default true
* @readonly
*/
get isFront(): boolean {
return this._isFront;
}
/**
* @property _isFront
* @type {boolean}
* @private
* @default true
*/
private _isFront: boolean = true;
/**
* 当前动画的总帧数
* @property totalFrames
* @public
* @since 1.0.0
* @type {number}
* @default 1
* @readonly
*/
public totalFrames: number;
public videoWidth: number;
public videoHeight: number;
/**
* 所有textures缓存
*/
private textures = {};
/**
* 锁步的时间间隔,按fps定,毫秒
*/
private timeInterval;
/**
* 前提引擎按60设置
*/
private deltaFrame: number;
/**
* 中间帧计时
*/
private frameCount: number = 0;
/**
* 构造函数
* @method MovieClip
* @public
* @param mv VideoEntity格式,这里不给了
*/
public constructor(mv?) {
super();
let s: any = this;
s._instanceType = "MovieClip";
//初始化
if (mv) {
s.init(mv);
} else {
s.totalFrames = 0;
}
}
/**
* 可以手动用init,
* @param mv
*/
init(mv) {
//记录基本信息,fps,每秒输出帧数,frames,总帧数,videoSize暂时不管
//如果fps小于60怎么处理。update时怎么处理
this.timeInterval = 1000 / mv.FPS;
this.startTime = Date.now();
this.startFrame = 1;
this.totalFrames = mv.frames
//间隔帧数,
this.deltaFrame = 60 / mv.FPS;
this.frameCount = this.deltaFrame;
this._curFrame = 1;
this.videoWidth = mv.videoSize.width;
this.videoHeight = mv.videoSize.height;
//考虑是否要加遮罩,用videoSize,暂时不用,为了性能
// var mask = new Graphics();
// mask.beginFill(0xffffff, 1);
// mask.drawRect(0, 0, mv.videoSize.width, mv.videoSize.height);
// mask.endFill();
// this.mask = mask;
//缓存所有图片
const images = mv.images;
if (mv.hasBeenCached) {
//如已被缓存,则直接取了赋值
for (var keyName in images) {
this.textures[keyName] = TextureCache[keyName];
}
this.initChildren(mv.sprites)
} else {
//合图有bug,先不合了
// if (GlobalPro.stageRenderType == RENDERER_TYPE.WEBGL) {
// //缓存成一张canvas,考虑要不要把所有资源搞成图集
// DrawAllToCanvas(images, (t) => {
// this.textures = t;
// this.initChildren(mv.sprites)
// //缓存
// for (var key in this.textures) {
// Texture.addToCache(this.textures[key], key)
// }
// mv.hasBeenCached = true;
// })
// } else {
//canvas直接缓存
for (var key in images) {
var bitmap = images[key];
// let imgTag = document.createElement('img');
let imgTag = getCreateImage()();
let backCanvas;
if (bitmap.indexOf("iVBO") === 0 || bitmap.indexOf("/9j/2w") === 0) {
imgTag.src = 'data:image/png;base64,' + bitmap;
}
else {
imgTag.src = bitmap;
//这里有问题,再说
// if (frames[0] && frames[0].layout) {
// backCanvas = document.createElement('canvas');
// backCanvas.width = frames[0].layout.width
// backCanvas.height = frames[0].layout.height
// imgTag.onload = function () {
// backCanvas.getContext('2d').drawImage(imgTag, 0, 0, frames[0].layout.width, frames[0].layout.height)
// }
// }
}
this.textures[key] = Texture.from(backCanvas || imgTag);
// this.textures[key].once("loaded",()=>{
// 是否监听加载完成?
// })
//考虑到key和已有缓存冲突,svga的都单独自己缓存,外部不可用,以后有时间搞
Texture.addToCache(this.textures[key], key)
}
mv.hasBeenCached = true;
this.initChildren(mv.sprites)
// }
}
}
private initChildren(sprites) {
for (var i = 0, len = sprites.length; i < len; i++) {
var ele = sprites[i];
if (ele.imageKey) {
var child = new Sprite(this.textures[ele.imageKey]);
//直接赋值矩阵
child["frames"] = ele.frames;
child.transform.localMatrix.copy(ele.frames[0].transform);
child.transform._parentID = -1;
this.addChild(child);
//透明度处理
if (ele.frames[0].alpha < 0.05) {
child.visible = false;
} else {
child.alpha = ele.frames[0].alpha;
}
//记录一个源数据
child["framesOri"] = ele.frames;
//记录一个源imageKey
child["imageKey"] = ele.imageKey;
//记录一个标识
child["matteKey"] = ele.matteKey;
}
}
}
/**
* 用基础属性重置
* @param display
* @param transform
*/
private resetTransform(display, transform) {
display.x = transform.tx;
display.y = transform.ty;
display.scaleX = transform.a;
display.scaleY = transform.d;
display.rotation = Math.round(Math.atan2(transform.b, transform.a) * RAD_TO_DEG);
}
/**
* 用基础属性重置所有的待frame的children
* @param frameIndex 帧 1到total
*/
public resetTransformAll(frameIndex: number) {
if (frameIndex > this.totalFrames) frameIndex = this.totalFrames;
if (frameIndex <= 0) frameIndex = 1;
for (var i = 0; i < this.children.length; i++) {
let child = this.children[i];
if (child["frames"] && child["frames"][frameIndex - 1]) {
this.resetTransform(child, child["frames"][frameIndex - 1].transform)
}
}
}
/**
*
* @param imagekey 对应的imagekey
* @param imageUrl 图片路径,以后考虑支持多种形式
*/
setImage(imagekey, imageUrl: string) {
if (!this.textures[imagekey]) return
let texture = this.textures[imagekey]
var width = texture.width;
var height = texture.height;
let image = getCreateImage()();
var self = this;
image.onload = function () {
let newTexture: Texture
if (image.width == width && image.height == height) {
newTexture = Texture.from(image);
} else {
var canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext("2d")
//适配绘制,为了全部显示在canvas中
var scaleCan = width / height;
var scale = image.width / image.height;
if (scaleCan > scale) {
//定高
ctx.drawImage(image, 0, 0, image.width, image.height
, (width - scale * height) / 2, 0, scale * height, height)
} else {
//定宽
ctx.drawImage(image, 0, 0, image.width, image.height
, 0, (height - width / scale) / 2, width, width / scale)
}
newTexture = Texture.fromCanvas(canvas)
}
//修改textures指向
// self.textures[imagekey]=Texture.fromCanvas(canvas)
//修改相应sprite
for (var i = 0; i < self.children.length; i++) {
let child = self.children[i]
//texture相等
if (child["imageKey"] == imagekey) {
child.texture = newTexture
}
}
}
image.src = imageUrl;
}
/**
* 调用止方法将停止当前帧
* @method stop
* @public
* @since 1.0.0
*/
public stop(): void {
let s = this;
s._isPlaying = false;
}
/**
* 将播放头向后移一帧并停在下一帧,如果本身在最后一帧则不做任何反应
* @method nextFrame
* @since 1.0.0
* @public
*/
public nextFrame(): void {
let s = this;
if (s._curFrame < s.totalFrames) {
s._curFrame++;
}
s._isPlaying = false;
}
/**
* 将播放头向前移一帧并停在下一帧,如果本身在第一帧则不做任何反应
* @method prevFrame
* @since 1.0.0
* @public
*/
public prevFrame(): void {
let s = this;
if (s._curFrame > 1) {
s._curFrame--;
}
s._isPlaying = false;
}
/**
* 将播放头跳转到指定帧并停在那一帧,如果本身在第一帧则不做任何反应
* @method gotoAndStop
* @public
* @since 1.0.0
* @param {number} frameIndex 批定帧的帧数或指定帧的标签名
*/
public gotoAndStop(frameIndex: number): void {
let s: any = this;
s._isPlaying = false;
if (frameIndex > s.totalFrames) {
frameIndex = s.totalFrames;
}
if (frameIndex < 1) {
frameIndex = 1;
}
s._curFrame = <number>frameIndex;
}
/**
* 如果当前时间轴停在某一帧,调用此方法将继续播放.
* @method play
* @public
* @since 1.0.0
*/
public play(isFront: boolean = true): void {
let s = this;
s.frameCount = s.deltaFrame;
s.startTime = Date.now();
s.startFrame = s._curFrame;
s._isPlaying = true;
s._isFront = isFront;
}
/**
* @property _lastFrame
* @type {number}
* @private
* @default 0
*/
private _lastFrame: number = 0;
/**
* 刚执行到的帧数,用于帧监听时判断用,刚好执行到当前帧,而不是之前保留的状态
* 不是60fps的videoItem的中间有几帧curFrame会不变,判断只执行一次监听时会出错,刚好动画满帧60fps时就无所谓
*/
public get isInTimeFrame(): boolean {
//相等时就是刚开始的curFrame
return this.frameCount == this.deltaFrame;
}
/**
* 将播放头跳转到指定帧并从那一帧开始继续播放
* @method gotoAndPlay
* @public
* @since 1.0.0
* @param {number} frameIndex 批定帧的帧数或指定帧的标签名
* @param {boolean} isFront 跳到指定帧后是向前播放, 还是向后播放.不设置些参数将默认向前播放
*/
public gotoAndPlay(frameIndex: number, isFront: boolean = true): void {
let s: any = this;
s._isFront = isFront;
s._isPlaying = true;
if (frameIndex > s.totalFrames) {
frameIndex = s.totalFrames;
}
if (frameIndex < 1) {
frameIndex = 1;
}
s.frameCount = s.deltaFrame;
s.startTime = Date.now();
s._curFrame = <number>frameIndex;
s.startFrame = s._curFrame;
}
/**
* 记录的startAniRange对应的fun
*/
private startAniRangeFun: Function
/**
* 优先级最高,会覆盖
* @param beginFrame 默认1
* @param endFrame 默认 this.totalFrames
* @param loops 默认1 0
*/
public startAniRange(
beginFrame: number = 1,
endFrame: number = this.totalFrames,
loops: number = 1,
callback?: Function
) {
if (beginFrame < 1) {
beginFrame = 1;
}
if (beginFrame > this.totalFrames) {
beginFrame = this.totalFrames;
}
if (endFrame < 1) {
endFrame = 1;
}
if (endFrame > this.totalFrames) {
endFrame = this.totalFrames;
}
if (beginFrame === endFrame) {
this.gotoAndStop(beginFrame)
//如果相等
return
} else if (beginFrame < endFrame) {
this._isFront = true;
} else {
this._isFront = false;
var temp = beginFrame;
beginFrame = endFrame;
endFrame = temp;
}
//移除原先的绑定吧
if (this.startAniRangeFun) this.removeEventListener(Event.ENTER_FRAME, this.startAniRangeFun, this)
this._curFrame = beginFrame;
//赋值count最大
this.frameCount = this.deltaFrame;
this.startTime = Date.now();
this.startFrame = this._curFrame;
this._isPlaying = true;
let loopCount = loops ? (loops + 0.5 >> 0) : Infinity;
this.addEventListener(Event.ENTER_FRAME, this.startAniRangeFun = (e) => {
if (e.target._isFront) {
//用大于等于可以避免锁步时出现的问题
if (e.target.currentFrame >= endFrame || e.target._endMark) {
loopCount--;
if (loopCount <= 0) {
e.target.gotoAndStop(endFrame);
e.target.removeEventListener(Event.ENTER_FRAME, this.startAniRangeFun, this);
this.startAniRangeFun = null;
callback && callback();
} else {
e.target.gotoAndPlay(beginFrame);
}
}
} else {
if (e.target.currentFrame <= beginFrame || e.target._endMark) {
loopCount--
if (loopCount <= 0) {
e.target.gotoAndStop(beginFrame);
e.target.removeEventListener(Event.ENTER_FRAME, this.startAniRangeFun, this);
this.startAniRangeFun = null;
callback && callback();
} else {
e.target.gotoAndPlay(endFrame, false);
}
}
}
}, this)
}
/**
* 开始时间,每次有play的时候就需要重置now
* 锁步思想,设置开始时间,后面每帧实际时间与开始时间相减,得到当前帧数
*
*/
private startTime: number;
/**
* 开始时的frame
*/
private startFrame: number;
/**
* 与startFrame相间隔的帧数量,绝对值
*/
private lastDeltaFrame: number
/**
* 锁步时的每次end的标识
*/
private _endMark: boolean
commonDeltaTime = 1000 / 60;
updateFrame() {
var s = this;
//1帧的时候也有相应的frameCount,无用,return
if (s.totalFrames == 0 || s.totalFrames == 1) return;
let isNeedUpdate = false;
if (s._lastFrame != s._curFrame) {
//帧不相等
isNeedUpdate = true;
s._lastFrame = s._curFrame;
//锁步的时候
s.startTime = Date.now();
s.startFrame = s._curFrame;
s._endMark = false;
} else {
if (s._isPlaying) {
if (s.lockStep) {
isNeedUpdate = s.getCurFrameWhenLockStep();
} else {
if (--s.frameCount == 0) {
s.frameCount = s.deltaFrame;
isNeedUpdate = true;
if (s._isFront) {
s._curFrame++;
if (s._curFrame > s.totalFrames) {
s._curFrame = 1;
}
} else {
s._curFrame--;
if (s._curFrame < 1) {
s._curFrame = s.totalFrames;
}
}
s._lastFrame = s._curFrame;
}
}
}
}
//如果需要更新
if (isNeedUpdate) {
//对每个child还原对应的transform,alpha为0的默认visible设为false,避免计算
for (var i = 0, len = s.children.length; i < len; i++) {
var child = s.children[i]
//只修改动画加入的child,不修改手动加入的,,所以想要修改动画中的元素属性,直接去掉frames属性,将不会执行动画
if (child["frames"] && child["frames"][s._curFrame - 1]) {
var frame = child["frames"][s._curFrame - 1];
//layout不晓得干嘛用,暂不管
if (frame.alpha < 0.05) {
child.visible = false;
} else {
child.visible = true;
child.alpha = frame.alpha;
//先判断transform是否相等
if (!Matrix.isEqual(child.transform.localMatrix, frame.transform)) {
child.transform.localMatrix.copy(frame.transform)
child.transform._parentID = -1;
}
}
}
}
//事件播放结束监听
if (!s.lockStep) {
if (((s._curFrame == 1 && !s._isFront) || (s._curFrame == s.totalFrames && s._isFront)) && s.hasEventListener(Event.END_FRAME)) {
s.dispatchEvent(Event.END_FRAME, {
frameIndex: s._curFrame,
frameName: "endFrame"
});
}
} else {
//锁步的时候另外判断
if (s._endMark && s.hasEventListener(Event.END_FRAME)) {
s.dispatchEvent(Event.END_FRAME, {
frameIndex: s._curFrame,
frameName: "endFrame"
});
}
}
}
}
private getCurFrameWhenLockStep() {
var dateNow = Date.now()
//相差
var deltaFrame = ((dateNow - this.startTime) / this.timeInterval) >> 0;
//间隔帧数与上一帧一致,就不执行
if (deltaFrame == this.lastDeltaFrame) {
//设置不等
this.frameCount = 0;
return false
}
this._endMark = false;
//相等,刚好执行切换
this.frameCount = this.deltaFrame;
this.lastDeltaFrame = deltaFrame
if (this._isFront) {
//取余数
this._curFrame = (this.startFrame + deltaFrame) % this.totalFrames;
if (this._curFrame == 0) {
this._curFrame = this.totalFrames;
this._endMark = true;
}
//当上一帧大于_curFrame,并且上一帧不是totalFrames时,说明跳过了最后一帧
else if (this._lastFrame > this._curFrame &&
this._lastFrame != this.totalFrames) {
this._endMark = true;
}
} else {
this._curFrame = (this.startFrame - deltaFrame) % this.totalFrames;
if (this._curFrame == 0) {
this._curFrame = this.totalFrames;
} else if (this._curFrame < 0) {
this._curFrame += this.totalFrames;
}
if (this._curFrame == 1) {
this._endMark = true;
}
//当上一帧小于_curFrame,并且上一帧不是1时,说明跳过了第一帧
else if (this._lastFrame < this._curFrame &&
this._lastFrame != 1) {
this._endMark = true;
}
}
this._lastFrame = this._curFrame;
return true
}
/**
* 重写刷新
* @method update
* @public
* @since 1.0.0
*/
public update(): void {
let s: any = this;
//更新帧数据
this.updateFrame();
super.update();
}
public destroy(): void {
//todo-清除相应的数据引用
super.destroy();
}
}
......@@ -257,6 +257,8 @@ export class ScrollPage extends Container {
if (view[s.paramXY] > 0 || view[s.paramXY] < s.distance - s.maxDistance) {
s.isStop = false;
s.stopTimes = -1;
//加一个
s.isMouseDownState = 0;
}
}
}
......
export * from "./Button";
export * from "./FrameAni";
export * from "./ScrollPage"
export * from "./ScrollList"
export * from "./ShowWord"
export * from "./ScrollPage";
export * from "./ScrollList";
export * from "./ShowWord";
export * from "./MovieClip";
\ No newline at end of file
......@@ -4,6 +4,7 @@ import { nextPow2 } from "./twiddle";
import BaseTexture from "../texture/BaseTexture";
import { createCanvas } from "./tbminiAdapte";
const pool = [];
let padding = 2;
let maxSize = 4096;
......
import { createCanvas } from "./tbminiAdapte";
let result: boolean = null;
/**
* 创建带颜色的canvas
......
......@@ -2,7 +2,6 @@ import { canUseNewCanvasBlendModes } from "./canUseNewCanvasBlendModes";
import Texture from "../texture/Texture";
import { createCanvas } from "./tbminiAdapte";
/**
* Number of steps which will be used as a cap when rounding colors.
*
......
......@@ -6,7 +6,6 @@ import { RENDERER_TYPE } from "../const";
import { mapPremultipliedBlendModes } from "./mapPremultipliedBlendModes";
import { createCanvas } from "./tbminiAdapte";
export * from './twiddle';
export { default as toDisplayDataURL } from "./toDisplayDataURL";
export { default as determineCrossOrigin } from './determineCrossOrigin';
......
......@@ -3,17 +3,6 @@ export function createCanvas(): HTMLCanvasElement {
//@ts-ignore
return document && document.createElement("canvas") || my._createOffscreenCanvas() || document.createElement("canvas")
}
//每次都要重置
let backupCanvasContext: CanvasRenderingContext2D
export function setBackupCanvasContext(bc) {
backupCanvasContext = bc;
}
export function getBackupCanvasContext() {
return backupCanvasContext
}
export function destroyBackupCanvasContext() {
backupCanvasContext = null;
}
/**
* 备用的canvas上下文,用于绘制文本,图片等等
* 外面赋值
......
......@@ -4,6 +4,7 @@ import { Matrix, Rectangle } from "../math";
import { DisplayObject } from "../display/DisplayObject";
import { createCanvas } from "./tbminiAdapte";
// 作为将显示对象导出成图片的render渲染器
let _dRender: CanvasRenderer = null;
let _dCanvas
......
import { createContext } from './createContext';
import { createCanvas } from '../2d/utils';
const fragTemplate = [
'precision mediump float;',
'void main(void){',
......
import { Tween } from './tween';
import { Stage } from './2d/display';
//tween循环加入
Stage.addUpdateObj(Tween)
export * from './2d/const';
// export * from './2d/Setting';
export * from "./2d/display";
......@@ -37,8 +34,9 @@ export * from "./sound"
export * from "./tween";
if(window)window["my"]=null
// export * from "./Stats";
//如果是浏览器环境,声明个my为null,为了无声明不报错
if (window) window["my"] = null
export * from "./Stats";
/**
* ios端canvas现在是永远根据设置的width和height(不是style里的)乘以dpi返回的尺寸
......
......@@ -10,7 +10,7 @@ module.exports = {
},
output: {
path: __dirname,
filename: "dist/[name].js",
filename: "build/[name].js",
libraryTarget: 'umd',
library: 'FYGE',
},
......
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