Commit 9079fb65 authored by rockyl's avatar rockyl

完成栈式视图动效功能

parent 9c1b9a40
This diff is collapsed.
This diff is collapsed.
{"id":"engine","url":"engine.e5b21b3c107402bf145ed205181b96d7c501b51f.js"}
\ No newline at end of file
{"id":"engine","url":"engine.741a07d921ba996527afc8c11ef426f24ada0932.js"}
\ No newline at end of file
......@@ -12,7 +12,7 @@ const fs = require('fs');
const tslibWrapper = 'var tslib = {__extends: __extends,__assign: __assign,__rest: __rest,__decorate: __decorate,__param: __param,__metadata: __metadata,__awaiter: __awaiter,__generator: __generator,__exportStar: __exportStar,__values: __values,__read: __read,__spread: __spread,__spreadArrays: __spreadArrays,__await: __await,__asyncGenerator: __asyncGenerator,__asyncDelegator: __asyncDelegator,__asyncValues: __asyncValues,__makeTemplateObject: __makeTemplateObject,__importStar: __importStar,__importDefault: __importDefault};'
const tslibCode = fs.readFileSync(__dirname + '/scripts/tslib.min.js');
const options = {
export default {
input: 'src/index.ts',
output: [
{
......@@ -23,7 +23,7 @@ const options = {
tslib: 'tslib'
},
banner: tslibCode + '\n' + tslibWrapper,
}
},
],
plugins: [
progress(),
......@@ -32,12 +32,7 @@ const options = {
//useTsconfigDeclarationDir: true,
}),
commonjs(),
process.env.BUILD === 'production' && uglify({})
],
external: ['tslib'],
};
if(process.env.BUILD === 'production'){
options.plugins.push(uglify({}));
}
export default options;
import {SCALE_MODES, TEXT_ALIGN, TEXT_lINETYPE, VERTICAL_ALIGN} from "../const";
import Texture from "../texture/Texture";
import {getRGBA, hex2string} from "../utils/index";
import {Rectangle} from "../math/index";
import {ObservablePoint, Rectangle} from "../math/index";
import Sprite from "../display/Sprite";
import {Event} from "../events/index";
//文本canvas上xy的偏移量
const padding = 10;
const padding = 50;
const styleFields = {
color: 'fillStyle',
......@@ -486,6 +486,86 @@ export class TextField extends Sprite {
private _border: boolean = false;
/**
* 设置或获取阴影颜色
* @property property
* @public
* @since 1.0.6
* @param value
*/
public set shadowColor(value: string) {
if (this._shadowColor != value) {
this._shadowColor = value;
this.dirty = true;
}
}
public get shadowColor(): string {
return this._shadowColor;
}
private _shadowColor: string = '#000';
/**
* 设置或获取阴影模糊度
* @property property
* @public
* @since 1.0.6
* @param value
*/
public set shadowBlur(value: number) {
if (this._shadowBlur != value) {
this._shadowBlur = value;
this.dirty = true;
}
}
public get shadowBlur(): number {
return this._shadowColor;
}
private _shadowBlur: number = 0;
/**
* 设置或获取阴影偏移
* @property property
* @public
* @since 1.0.6
* @param value
*/
public set shadowOffset(value: ObservablePoint) {
if (this._shadowOffset != value) {
this._shadowOffset = value;
this.dirty = true;
}
}
public get shadowOffset(): ObservablePoint {
return this._shadowOffset;
}
get shadowOffsetX(): number {
return this.position.x;
}
set shadowOffsetX(value: number) {
this._shadowOffset.x = value;
}
get shadowOffsetY(): number {
return this.position.y;
}
set shadowOffsetY(value: number) {
this._shadowOffset.y = value;
}
private _shadowOffset: ObservablePoint = new ObservablePoint(this.onShadowOffsetChange, this);
private onShadowOffsetChange() {
this.dirty = true;
}
private _setupFont(font, size, bold, italic) {
let fontStyle: any = size;
fontStyle += "px ";
......@@ -588,7 +668,7 @@ export class TextField extends Sprite {
if (!text) {
s.canvas.width = 0;
s.canvas.height = 0;
if(!this._width && !this._height){
if (!this._width && !this._height) {
s._localBoundsSelf.clear();
}
this.anchorTexture = {x: 0, y: 0};
......@@ -728,6 +808,12 @@ export class TextField extends Sprite {
}
}
ctx.setTransform(1, 0, 0, 1, tx + padding, padding);
if (this._shadowBlur > 0) {
ctx.shadowBlur = this._shadowBlur;
ctx.shadowColor = this._shadowColor;
ctx.shadowOffsetX = this._shadowOffset.x;
ctx.shadowOffsetY = this._shadowOffset.y;
}
s._prepContext(ctx);
let lineH = s._lineSpacing + s.size;
//如果有_textHeight,就需要应用竖直对齐
......
......@@ -18,6 +18,7 @@ import {bind, createStore} from "./mvvm/index";
import {registerCustomModules} from "./custom-module";
import {dealPageRemainTime, dealPxEnv} from "../px-logics";
import Container from "../../2d/display/Container";
import {Event} from "../../2d/events/Event";
/**
* 游戏舞台
......@@ -48,19 +49,17 @@ export class GameStage extends Node {
this.percentHeight = 100;
this.mouseEnabled = false;
let blackLayer = this._blackLayer = new Rect();
let loadingView = this._loadingView = new Container();
this.addChild(this._sceneContainer = new StackContainer());
this.addChild(blackLayer);
this.addChild(this._popupContainer = new StackContainer());
this.addChild(this._popupContainer = new StackContainer(false, 1));
this.addChild(this._toast = new Toast(this));
this.addChild(loadingView);
let blackLayer = this._blackLayer = new Rect();
blackLayer.name = 'blackLayer';
blackLayer.percentWidth = 100;
blackLayer.percentHeight = 100;
blackLayer.visible = false;
blackLayer.width = stage.width;
blackLayer.height = stage.height;
blackLayer.fillColor = 0;
blackLayer.alpha = 0.7;
......@@ -71,7 +70,8 @@ export class GameStage extends Node {
this._sceneContainer.name = 'scene-container';
this._popupContainer.name = 'popup-container';
this._popupContainer.addEventListener('change', this.onPopupContainerChange, this);
this._popupContainer.addEventListener(Event.START, this.onPopupContainerStart, this);
this._popupContainer.addEventListener(Event.COMPLETE, this.onPopupContainerComplete, this);
}
/**
......@@ -272,29 +272,41 @@ export class GameStage extends Node {
return arrayFind(this._config.views, view => view.name === name);
}
/**
* 设置半透明层是否可见
* @param visible
*/
setBlackLayerVisible(visible) {
this._blackLayer.visible = visible;
}
onPopupContainerChange(e) {
const {action, view, options} = e.data;
onPopupContainerStart(e) {
const {action, view, lastView, options, hasView} = e.data;
const target = <StackContainer>e.target;
switch (action) {
case 'push':
case 'replace':
case 'popAll':
if (options && options.center) {
view.horizonCenter = 0;
view.verticalCenter = 0;
view.x = (target.width - view.width) / 2;
view.y = (target.height - view.height) / 2;
}
break;
}
this.setBlackLayerVisible(this._popupContainer.children.length > 0);
let blackLayer = this._blackLayer;
let pParent = blackLayer.parent;
if (hasView) {
target.addChildAt(blackLayer, target.childNum - 1 - (view ? 0 : 1));
if (!pParent) {
blackLayer.alpha = 0;
Tween.get(blackLayer, null, null, true)
.to({alpha: 0.7}, 300);
}
} else if (pParent) {
Tween.get(blackLayer, null, null, true)
.to({alpha: 0}, 300)
.call(() => {
pParent.removeChild(blackLayer);
});
}
}
onPopupContainerComplete(e){
}
lazyLoadAllAssets = async () => {
......
......@@ -4,6 +4,8 @@
import {DisplayObject} from "../../2d/display/index";
import {Node} from "./nodes/Node";
import {Event} from "../../2d/events/Event";
import {playViewEffect} from "./view-effects";
/**
* 栈式视图容器
......@@ -11,77 +13,164 @@ import {Node} from "./nodes/Node";
export class StackContainer extends Node {
private _mutex: boolean;
private _stack = [];
private _inserted = 0;
constructor(mutex = true) {
constructor(mutex = true, inserted = 0) {
super();
this._mutex = mutex;
this._inserted = inserted;
this.percentWidth = 100;
this.percentHeight = 100;
this.mouseEnabled = false;
this.addEventListener(Event.START, () => {
this.mouseChildren = false;
});
this.addEventListener(Event.COMPLETE, () => {
this.mouseChildren = true;
});
}
get childNum() {
let len = this.children.length;
return len > 0 ? len - this._inserted : 0;
}
/**
* 推入视图
* @param view
* @param options
* @param dispatch
* @param playEffect
* @param callback
*/
push(view: DisplayObject, options?, dispatch = true) {
if (this._mutex && this.children.length > 0) {
this._stack.push(this.removeChildAt(0));
push(view: DisplayObject, options?, playEffect = true, callback?) {
const action = 'push';
let lastView;
if (this._mutex && this.childNum > 0) {
lastView = this.getChildAt(0);
this._stack.push(lastView);
}
view.visible = false;
this.addChild(view);
if (dispatch) {
this.dispatchEvent('change', {action: 'push', view, options});
let data = {action, view, lastView, options, hasView: true};
this.dispatchEvent(Event.START, data);
playViewEffect(
playEffect ? options ? options.effect : null : null,
options ? options.effectParams : {},
this._mutex, lastView, view, this,
() => {
this.dispatchEvent(Event.COMPLETE, data);
callback && callback();
}
)
}
/**
* 替换顶层视图
* @param view
* 撤出视图
* @param options
* @param playEffect
* @param callback
*/
replace(view: DisplayObject, options?) {
if (this.pop(false)) {
this.push(view, options, false);
this.dispatchEvent('change', {action: 'replace', view, options});
pop(options?, playEffect = true, callback?) {
const action = 'pop';
let len = this.childNum;
if (len <= 0) {
return false;
}
let lastView = this.getChildAt(this.children.length - 1);
let view;
if (this._mutex) {
view = this._stack.pop();
view.visible = false;
this.addChild(view);
}
let data = {action, view, lastView, options, hasView: len > 1};
this.dispatchEvent(Event.START, data);
playViewEffect(
playEffect ? options ? options.effect : null : null,
options ? options.effectParams : {},
this._mutex, lastView, view, this,
() => {
this.dispatchEvent(Event.COMPLETE, data);
callback && callback();
}
);
return true;
}
/**
* 撤出视图
* 替换顶层视图
* @param view
* @param options
* @param playEffect
* @param callback
*/
pop(dispatch = true) {
let len = this.children.length;
replace(view: DisplayObject, options?, playEffect = true, callback?) {
const action = 'replace';
let len = this.childNum;
if (len <= 0) {
return false;
}
this.removeChildAt(len - 1);
if (this._mutex) {
this.addChild(this._stack.pop());
}
if (dispatch) {
this.dispatchEvent('change', {action: 'pop'});
let lastView = this.getChildAt(len - 1);
view.visible = false;
this.addChild(view);
let data = {action, view, lastView, options, hasView: len > 1};
this.dispatchEvent(Event.START, data);
playViewEffect(
playEffect ? options ? options.effect : null : null,
options ? options.effectParams : {},
this._mutex, lastView, view, this,
() => {
this.dispatchEvent(Event.COMPLETE, data);
callback && callback();
}
return true;
)
}
/**
* 撤出全部视图
* @param view
* @param options
* @param playEffect
* @param callback
*/
popAll(view?: DisplayObject, options?) {
this.removeChildren();
popAll(view?: DisplayObject, options?, playEffect = true, callback?) {
const action = 'popAll';
let lastView = this.getChildAt(0);
let len = this.childNum;
while (this.children.length > 1) {
this.removeChildAt(1);
}
if (this._mutex) {
this._stack.splice(0);
}
if (view) {
this.push(view, options, false);
if(view){
view.visible = false;
this.addChild(view);
}
let data = {action, view, lastView, options, hasView: len > 1};
this.dispatchEvent(Event.START, data);
playViewEffect(
playEffect ? options ? options.effect : null : null,
options ? options.effectParams : {},
this._mutex, lastView, view, this,
() => {
this.dispatchEvent(Event.COMPLETE, data);
callback && callback();
}
this.dispatchEvent('change', {action: 'popAll', view, options});
)
}
}
......@@ -23,12 +23,12 @@ export class Toast extends Node {
this.verticalCenter = 0;
}
show(props: any = {}) {
async show(props: any = {}) {
if (!props.text) {
return;
}
let contentView = this.getContent(props.viewName);
let contentView = await this.getContent(props.viewName);
let lab = contentView.getChildByName('lab');
if (!lab) {
console.warn('[lab] child no exists on toast view');
......@@ -72,12 +72,12 @@ export class Toast extends Node {
this._content = null;
}
private getContent(viewName) {
private async getContent(viewName) {
let view;
if (this.children.length == 0) {
if (viewName) {
view = this._gameStage.instantiateView(viewName);
view = await this._gameStage.instantiateView(viewName);
}
if (!view) {
if (!this._contentSample) {
......
/**
* Created by rockyl on 2020-05-04.
*/
import {Tween} from "../../2d/tween/Tween";
import {gameStage} from "../launcher";
import {injectProp} from "../utils/index";
import {Ease} from "../../2d/tween/Ease";
export function playViewEffect(name, params, mutex, lastView, view, container, callback) {
let effect = name ? effects[name] : effects.simple;
effect = effect || effects.simple;
effect(params || {}, mutex, lastView, view, container, callback);
}
const effects = {
simple(params, mutex, lastView, view, container, callback) {
if (mutex) {
container.removeChild(lastView);
}else{
if (lastView && !view) {
container.removeChild(lastView);
}
}
if(view){
view.visible = true;
}
callback();
},
fade(params, mutex, lastView, view, container, callback) {
const {duration = 300} = params;
if (mutex) {
fadeOut(() => {
fadeIn(callback);
})
} else {
fadeIn(callback);
}
function fadeOut(callback) {
if (lastView) {
Tween.get(lastView, null, null, true)
.to({alpha: 0}, duration)
.call(() => {
container.removeChild(lastView);
lastView.alpha = 1;
callback();
});
} else {
callback();
}
}
function fadeIn(callback) {
if (view) {
view.visible = true;
view.alpha = 0;
Tween.get(view, null, null, true)
.to({alpha: 1}, params.duration || 300)
.call(() => {
callback();
});
} else {
callback();
}
}
},
flew(params, mutex, lastView, view, container, callback) {
const {duration = 300, direction = 'top', ease = 'backOut'} = params;
const {stage: {width, height}} = gameStage;
let outPos: any = {};
switch (direction) {
case 'left':
outPos.x = -width;
break;
case 'right':
outPos.x = width;
break;
case 'top':
outPos.y = -height;
break;
case 'bottom':
outPos.y = height;
break;
}
let inEase = ease;
let outEase = ease.indexOf('Out') ? ease.replace('Out', 'In') : ease.replace('In', 'Out');
if (mutex) {
flewOut(() => {
flewIn(callback);
})
} else {
if (lastView && !view) {
flewOut(callback)
} else {
flewIn(callback);
}
}
function flewOut(callback) {
if (lastView) {
Tween.get(lastView, null, null, true)
.to(outPos, duration, Ease[outEase])
.call(() => {
container.removeChild(lastView);
injectProp(lastView, outPos);
callback();
});
} else {
callback();
}
}
function flewIn(callback) {
if (view) {
let inPos: any = {
x: view.x,
y: view.y,
};
view.visible = true;
injectProp(view, outPos);
Tween.get(view, null, null, true)
.to(inPos, duration, Ease[inEase])
.call(() => {
callback();
});
} else {
callback();
}
}
},
hulu(params, mutex, lastView, view, container, callback) {
const {duration = 300, ease = 'backOut', x = 0, y = 0} = params;
let inEase = ease;
let outEase = ease.indexOf('Out') ? ease.replace('Out', 'In') : ease.replace('In', 'Out');
let outPos = {
x: parseInt(x),
y: parseInt(y),
scaleX: 0, scaleY: 0,
};
if (mutex) {
huluOut(() => {
huluIn(callback);
})
} else {
if (lastView && !view) {
huluOut(callback)
} else {
huluIn(callback);
}
}
function huluOut(callback) {
if (lastView) {
outPos.x -= lastView.width / 2;
outPos.y -= lastView.height / 2;
Tween.get(lastView, null, null, true)
.to(outPos, duration, Ease[outEase])
.call(() => {
container.removeChild(lastView);
injectProp(lastView, outPos);
callback();
});
} else {
callback();
}
}
function huluIn(callback) {
if (view) {
let inPos: any = {
x: view.x,
y: view.y,
scaleX: 1, scaleY: 1
};
view.anchorX = view.width / 2;
view.anchorY = view.height / 2;
outPos.x -= view.width / 2;
outPos.y -= view.height / 2;
view.visible = true;
injectProp(view, outPos);
Tween.get(view, null, null, true)
.to(inPos, duration, Ease[inEase])
.call(() => {
callback();
});
} else {
callback();
}
}
},
zoom(params, mutex, lastView, view, container, callback) {
const {duration = 300, ease = 'backOut'} = params;
let inEase = ease;
let outEase = ease.indexOf('Out') ? ease.replace('Out', 'In') : ease.replace('In', 'Out');
if (mutex) {
zoomOut(() => {
zoomIn(callback);
})
} else {
if (lastView && !view) {
zoomOut(callback)
} else {
zoomIn(callback);
}
}
function zoomOut(callback) {
if (lastView) {
Tween.get(lastView, null, null, true)
.to({scaleX: 0, scaleY: 0}, duration, Ease[outEase])
.call(() => {
container.removeChild(lastView);
injectProp(view, {scaleX: 0, scaleY: 0});
callback();
});
} else {
callback();
}
}
function zoomIn(callback) {
if (view) {
view.anchorX = view.width / 2;
view.anchorY = view.height / 2;
view.visible = true;
injectProp(view, {scaleX: 0, scaleY: 0});
Tween.get(view, null, null, true)
.to({scaleX: 1, scaleY: 1}, duration, Ease[inEase])
.call(() => {
callback();
});
} else {
callback();
}
}
},
};
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