Commit 058b046d authored by rockyl's avatar rockyl

砖块0的情况

parents
Pipeline #109298 failed with stages
in 0 seconds
# Created by .ignore support plugin (hsz.mobi)
### Node template
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
# parcel-bundler cache (https://parceljs.org/)
.cache
# next.js build output
.next
# nuxt.js build output
.nuxt
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless
/.rpt2_cache/
{
"name": "scilla-components",
"version": "1.0.0",
"main": "./dist/bundle.js",
"types": "./types/index.d.ts",
"license": "MIT",
"scripts": {
"build": "rollup -c"
},
"dependencies": {
"tslib": "^1.9.3"
},
"devDependencies": {
"rollup": "^0.66.6",
"rollup-plugin-commonjs": "^9.2.0",
"rollup-plugin-node-resolve": "^3.4.0",
"rollup-plugin-typescript2": "^0.18.0",
"rollup-plugin-uglify": "^6.0.0",
"tslib": "^1.9.3",
"typescript": "^3.1.6"
}
}
/**
* Created by rockyl on 2018/11/16.
*/
const resolve = require('rollup-plugin-node-resolve');
const commonjs = require('rollup-plugin-commonjs');
const typescript = require('rollup-plugin-typescript2');
const {uglify} = require('rollup-plugin-uglify');
export default {
input: 'src/index.ts',
output: {
file: 'dist/bundle.js',
format: 'umd',
name: 'scilla',
//sourcemap: true,
},
plugins: [
resolve({
browser: true,
}),
typescript({
typescript: require('typescript'),
tslib: require('tslib'),
useTsconfigDeclarationDir: true,
}),
commonjs(),
uglify({}),
]
};
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
/**
* Created by rockyl on 2019-01-04.
*
* 弹动缩放
*/
import {ScillaComponent, createTween, Tween, Vector2D, createVector2D} from "scilla";
const originScale: Vector2D = createVector2D(1, 1);
export default class BounceZoom extends ScillaComponent {
targetScale: Vector2D = createVector2D(1.5, 1.5);
duration:number = 100;
private _tween: Tween;
onAwake() {
super.onAwake();
this._tween = createTween(this.transform, false,
{clazz: Vector2D, fields: ['x', 'y'], autoPlay: false}
)
.to({scale: this.targetScale.clone()}, this.duration * 0.5)
.to({scale: originScale.clone()}, this.duration * 0.5)
}
play(){
this._tween.play(true);
}
}
/**
* Created by rockyl on 2019-01-04.
*
* 渐变组件
*/
import {math, ScillaComponent} from "scilla";
export default class Fade extends ScillaComponent {
fromAlpha: number = 0;
toAlpha: number = 1;
duration: number = 1000;
private _startTime: number;
private _playing: boolean;
onUpdate(t) {
super.onUpdate(t);
if(this._playing){
if(!this._startTime){
this._startTime = t;
}
let ratio = (t - this._startTime) / this.duration;
this.transform.alpha = math.lerp(this.fromAlpha, this.toAlpha, ratio);
if(ratio >= 1){
this.stop();
}
}
}
play(){
this._startTime = 0;
this._playing = true;
}
stop(){
this._playing = false;
}
}
/**
* Created by rockyl on 2018/11/5.
*
* 自转组件
*/
import {createTween, ScillaComponent, ScillaEvent, Tween} from "scilla";
export default class Rotation extends ScillaComponent {
duration: number = 10000;
autoPlay: boolean = false;
loop: number = -1;
onComplete: ScillaEvent = new ScillaEvent();
private _tween: Tween;
onCreate() {
super.onCreate();
}
onAwake() {
super.onAwake();
if(!this._tween){
this._tween = createTween(this.transform, false, {autoPlay: this.autoPlay, loop: this.loop, initFields: ['_rotation']})
.to({rotation: 360}, this.duration)
.call(()=>{
this.onComplete.invoke();
});
}
}
play(){
this._tween.play(true);
}
stop(){
this._tween.stop();
}
}
/**
* Created by rockyl on 2018/11/5.
*/
import {ScillaComponent} from "scilla";
export default class RoundLoop extends ScillaComponent {
transform;
duration: number = 10000;
onUpdate(t) {
super.onUpdate(t);
const {position} = this.transform;
position.setXY(
Math.cos(t * 0.001) * 100,
Math.sin(t * 0.001) * 100,
)
}
}
/**
* Created by rockyl on 2018/11/5.
*
* 摇摆组件
*/
import {ScillaComponent} from "scilla";
export default class Swing extends ScillaComponent {
duration: number = 10000;
onUpdate(t) {
super.onUpdate(t);
this.transform.rotation = Math.sin(t / 100) * 5;
}
}
/**
* Created by rockyl on 2018-11-27.
*
* 触摸缩放交互效果组件
*/
import {createTween, createVector2D, ease, Ease, Tween, Vector2D,} from "scilla";
import {InteractComponent} from "../base";
export default class TouchZoom extends InteractComponent {
scaleOffset: Vector2D = createVector2D(0.1, 0.1);
duration: number = 200;
easeName: Ease = Ease.backOut;
private _zoomIn: Tween;
private _zoomOut: Tween;
private _touchBegin: boolean;
onAwake() {
super.onAwake();
if (!this._zoomIn) {
const {scaleOffset, duration, transform} = this;
const easeFunc = ease[this.easeName];
const scaleFrom = transform.scale.clone();
const scaleTo = transform.scale.clone().add(scaleOffset);
this._zoomIn = createTween(transform, false, {autoPlay: false, clazz: Vector2D, fields: ['x', 'y']})
.to({scale: scaleTo}, duration, easeFunc);
this._zoomOut = createTween(transform, false, {autoPlay: false, clazz: Vector2D, fields: ['x', 'y']})
.to({scale: scaleFrom}, duration, easeFunc);
}
}
onTouchBegin(e) {
super.onTouchOver(e);
if (this.interactable) {
this._touchBegin = true;
this._zoomIn.play(true);
}
}
onGlobalTouchEnd(e) {
super.onGlobalTouchEnd(e);
if (this._touchBegin) {
this._touchBegin = false;
this._zoomOut.play(true);
}
return false;
}
}
/**
* Created by rockyl on 2018/11/5.
*
* 波动组件
*/
import {ScillaComponent, raw} from "scilla";
const PI2 = Math.PI * 2;
export enum WaveMethod {
/**
* 公转
*/
round = 'round',
/**
* 自转
*/
rotate = 'rotate',
/**
* 缩放
*/
zoom = 'zoom',
/**
* 透明渐变
*/
fade = 'fade',
/**
* 横向波动
*/
cosWave = 'cosWave',
/**
* 纵向波动
*/
sinWave = 'sinWave',
/**
* 抖动
*/
shake = 'shake',
/**
* 呼吸
*/
breath = 'breath',
}
export default class Wave extends ScillaComponent {
duration: number = 1000;
waveMethod: WaveMethod;
waveParams: raw;
loop: number = -1;
autoPlay: boolean = true;
private _playing;
private _waveMethod;
private _startTime;
private _oldProps: any = {};
onAwake() {
super.onAwake();
this._waveMethod = waveLibs[this.waveMethod];
this._startTime = 0;
const {transform: {position}} = this;
this._oldProps.x = position.x;
this._oldProps.y = position.y;
if (this.autoPlay) {
this.play();
}
}
onUpdate(t) {
super.onUpdate(t);
if (this._playing) {
if (!this._startTime) {
this._startTime = t;
}
const {duration, waveParams, _waveMethod, transform, transform: {position, scale}, _oldProps} = this;
let loop = (t - this._startTime) % duration;
let r = loop / duration * PI2;
let params = waveParams || [];
let props = _waveMethod(...params, r);
if (props.hasOwnProperty('x')) {
position.x = (props.x || 0) + _oldProps.x;
}
if (props.hasOwnProperty('y')) {
position.y = (props.y || 0) + _oldProps.y;
}
if (props.hasOwnProperty('sx')) {
scale.x = props.sx;
}
if (props.hasOwnProperty('sy')) {
scale.y = props.sy;
}
if (props.hasOwnProperty('r')) {
transform.rotation = props.r;
}
}
}
play() {
this._playing = true;
this._startTime = 0;
}
stop() {
this._playing = false;
}
}
const {cos, sin, PI} = Math;
const waveLibs = {
round: function (h: number, t: number): any {
return {x: cos(t) * h, y: sin(t) * h};
},
cosWave: function (h: number, t: number): any {
return {x: cos(t) * h, y: 0};
},
sinWave: function (h: number, t: number): any {
h = h || 1;
return {x: 0, y: sin(t) * h};
},
rotate: function (t: number): any {
return {r: 360 * t / PI / 2};
},
shake: function (angle: number, count: number, t: number): any {
return {r: sin(t * count) * angle};
},
breath: function (scale: number = 0.1, t: number): any {
return {sx: sin(t) * scale + 1, sy: -sin(t + PI / 4) * scale + 1};
},
zoom: function (scale: number = 0.1, t: number): any {
return {sx: sin(t) * scale + 1, sy: sin(t) * scale + 1};
},
fade: function (base = 1, t: number): any {
return {alpha: (sin(t) + 1) * 0.5 + base};
},
};
/**
* Created by rockyl on 2018/11/5.
*/
import {ScillaComponent} from "scilla";
export default class ZoomLoop extends ScillaComponent{
onUpdate(t) {
super.onUpdate(t);
this.transform.scale.x = this.transform.scale.y = Math.abs(Math.sin(t * 0.001)) * 0.15 + 1;
}
}
/**
* Created by rockyl on 2019-01-10.
*/
export {default as BounceZoom} from './BounceZoom'
export {default as Fade} from './Fade'
export {default as Rotation} from './Rotation'
export {default as RoundLoop} from './RoundLoop'
export {default as Swing} from './Swing'
export {default as TouchZoom} from './TouchZoom'
export {default as Wave} from './Wave'
export {default as ZoomLoop} from './ZoomLoop'
/**
* Created by rockyl on 2018/11/7.
*/
import {Matrix, ScillaComponent, decorators} from "scilla";
import Renderer from "../renderer/Renderer";
const {dirtyFieldTrigger} = decorators;
/**
* 可交互组件
*/
export default class InteractComponent extends ScillaComponent {
/**
* 是否可交互
*/
@dirtyFieldTrigger
interactable = true;
/**
* 触摸中断
*/
touchInterrupt: boolean = false;
protected invertMatrix = Matrix.create();
protected localPos: any = {};
protected isOut = true;
private _touchBeginFlag: boolean;
constructor() {
super();
}
_dealGlobalTouchBegin(e) {
let interrupt = super._dealGlobalTouchBegin(e);
const hitOn = this.hitTest(e);
if (hitOn) {
this._touchBeginFlag = true;
this.onTouchBegin(e);
this._dealTouchOver(e);
}
return hitOn && interrupt;
}
_dealGlobalTouchMove(e) {
let interrupt = super._dealGlobalTouchMove(e);
const hitOn = this.hitTest(e);
if (hitOn) {
this._dealTouchOver(e);
this.onTouchMove(e);
} else {
this._dealTouchOut(e);
}
return hitOn && interrupt;
}
_dealGlobalTouchEnd(e) {
let interrupt = super._dealGlobalTouchEnd(e);
const hitOn = this.hitTest(e);
if (hitOn) {
this.onTouchEnd(e);
if(this._touchBeginFlag){
this.onTouchTap(e);
this._touchBeginFlag = false;
}
}
this.isOut = true;
return hitOn && interrupt;
}
_dealTouchOver(e) {
if (this.isOut) {
this.isOut = false;
this.onTouchOver(e);
}
}
_dealTouchOut(e) {
if (!this.isOut) {
this.isOut = true;
this.onTouchOut(e);
}
}
onTouchBegin(e) {
//console.log('onTouchBegin', e);
}
onTouchMove(e) {
//console.log('onTouchMove', e);
}
onTouchOver(e) {
//console.log('onTouchOver', e);
}
onTouchOut(e) {
//console.log('onTouchOut', e);
}
onTouchEnd(e) {
//console.log('onTouchEnd', e);
}
onTouchTap(e) {
//console.log('onTouchTap', e);
}
/**
* 碰撞检测
* @param e
*/
hitTest(e) {
const matrix = this.transform.getMatrix();
const invertMatrix = this.invertMatrix;
invertMatrix.copyFrom(matrix);
invertMatrix.invert();
invertMatrix.transformPoint(e.x, e.y, this.localPos);
let result = false;
const renderers = this.entity.getComponents(Renderer);
for (let renderer of renderers) {
if (renderer.hitTest(this.localPos.x, this.localPos.y)) {
if (renderer.isUsedToMask) {
continue
} else {
result = true;
break
}
} else if (renderer.isUsedToMask) {
return false
}
}
return result;
}
}
/**
* Created by rockyl on 2018-12-13.
*
* 触摸中断组件
*/
import InteractComponent from "./InteractComponent";
export default class TouchInterrupt extends InteractComponent {
touchInterrupt: boolean = true;
}
/**
* Created by rockyl on 2018/11/5.
*/
import {ScillaComponent, Vector2D, Matrix, decorators} from "scilla";
import Renderer from "../renderer/Renderer";
const {dirtyFieldDetector, dirtyFieldTrigger} = decorators;
/**
* 矩阵处理顺序
* SCALE_ROTATE: 先缩放后旋转
* ROTATE_SCALE: 先旋转后缩放
*/
export enum MATRIX_ORDER {
SCALE_ROTATE,
ROTATE_SCALE,
}
/**
* 矩阵转换组件
* 缩放、旋转、位移
*/
export default class Transform extends ScillaComponent {
onVector2DModify = (value, key, oldValue) => {
this.makeDirty(value, key, oldValue);
};
/**
* 坐标
*/
@dirtyFieldTrigger
position: Vector2D = new Vector2D(0);
/**
* 节点透明度
*/
@dirtyFieldTrigger
alpha: number = 1;
/**
* 节点渲染透明度
*/
private _renderAlpha: number;
get renderAlpha(): number{
return this._renderAlpha;
}
/**
* 尺寸
* 对于不同的子类渲染都有不同的效果
*/
private _width: number = NaN;
private _height: number = NaN;
/**
* 缩放
*/
@dirtyFieldTrigger
scale: Vector2D = new Vector2D(1, 1);
/**
* 轴距
*/
@dirtyFieldTrigger
pivot: Vector2D = new Vector2D(0.5, 0.5);
@dirtyFieldDetector
rotation = 0;
private order: MATRIX_ORDER = MATRIX_ORDER.SCALE_ROTATE;
protected _localMatrix: Matrix = Matrix.create();
protected _globalMatrix: Matrix = Matrix.create();
protected _globalPivotMatrix: Matrix = Matrix.create();
protected dirty: boolean;
get width(): number {
const renderer = this.entity.getComponent(Renderer);
return renderer ? renderer.bounds.width : (isNaN(this._width) ? 0 : this._width);
}
get explicitWidth(): number {
return this._width;
}
set width(value: number) {
if (this._width != value) {
this._width = value;
this.makeDirty(value, 'width');
}
}
get height(): number {
const renderer = this.entity.getComponent(Renderer);
return renderer ? renderer.bounds.height : (isNaN(this._height) ? 0 : this._height);
}
get explicitHeight(): number {
return this._height;
}
set height(value: number) {
if (this._height != value) {
this._height = value;
this.makeDirty(value, 'height');
}
}
makeDirty(value, key, oldValue?) {
this.dirty = true;
switch (key) {
case 'width':
case 'height':
const renderers = this.entity.getComponents(Renderer);
for (let renderer of renderers) {
renderer.makeDirty();
}
break;
}
}
/**
* @inheritDoc
*/
onModify(value, key, oldValue) {
super.onModify(value, key, oldValue);
this.makeDirty(value, key, oldValue);
switch (key) {
case 'position':
case 'scale':
//case 'size':
value.onChange = this.onVector2DModify;
break;
}
}
/**
* 更新本地矩阵
*/
protected updateLocalMatrix() {
const {
position: {x, y},
scale: {x: sx, y: sy}, rotation,
} = this;
const matrix = this._localMatrix;
matrix.identity();
if (this.order = MATRIX_ORDER.ROTATE_SCALE) {
matrix.scale(sx, sy);
matrix.rotate(rotation * Math.PI / 180);
} else {
matrix.rotate(rotation * Math.PI / 180);
matrix.scale(sx, sy);
}
matrix.translate(
x,
y,
);
}
/**
* 更新全局矩阵
*/
protected updateGlobalMatrix() {
const {
entity, _globalMatrix, _localMatrix, _globalPivotMatrix,
pivot: {x: px, y: py},
width, height,
} = this;
_globalMatrix.copyFrom(_localMatrix);
if (entity.parent) {
const parentTransform: Transform = entity.parent.getComponent(Transform);
if (parentTransform) {
this._renderAlpha = parentTransform._renderAlpha * this.alpha;
_globalMatrix.concat(parentTransform.getMatrix());
}
}else{
this._renderAlpha = this.alpha;
}
_globalPivotMatrix.copyFrom(_globalMatrix);
_globalPivotMatrix.translate(
-(px - 0.5) * width,
-(py - 0.5) * height,
);
}
/**
* 获取矩阵
*/
getMatrix(withPivot = false): Matrix {
return withPivot ? this._globalPivotMatrix : this._globalMatrix;
}
onUpdate(t) {
if (this.dirty) {
this.updateLocalMatrix();
this.dirty = false;
}
this.updateGlobalMatrix();
super.onUpdate(t);
}
}
/**
* Created by rockyl on 2019-01-10.
*/
export {default as InteractComponent} from './InteractComponent'
export {default as TouchInterrupt} from './TouchInterrupt'
export {default as Transform} from './Transform'
/**
* Created by rockyl on 2019-01-24.
*/
export * from './animation';
export * from './base';
export * from './other';
export * from './renderer';
export * from './ui';
/**
* Created by rockyl on 2018/11/15.
*
*/
import {Entity, getStageSize, ScillaComponent, createVector2D, Vector2D, math} from "scilla";
import Transform from "../base/Transform";
/**
* 相机控制组件
*/
export default class CameraController extends ScillaComponent {
target: Entity;
viewportAnchor: Vector2D = createVector2D();
targetPosition: Vector2D;
maxScale = 1.2;
private followPosition: Vector2D;
private stageSize;
onCreate() {
super.onCreate();
}
onAwake() {
super.onAwake();
const {target, viewportAnchor} = this;
this.stageSize = getStageSize();
if (target) {
this.targetPosition = target.getComponent(Transform).position;
}
this.followPosition = createVector2D();
if (viewportAnchor) {
const {width, height} = this.stageSize;
const {x, y} = this.viewportAnchor;
this.transform.position.setXY(width * x, height * y);
}
}
onUpdate(t) {
super.onUpdate(t);
if (!this.targetPosition) {
return;
}
const {transform: {scale, position}, stageSize: {width, height}, targetPosition: {x, y, length}, maxScale} = this;
const newScale = maxScale - length * maxScale / 2048;
scale.setXY(newScale, newScale);
this.followPosition.setXY(width / 2, height / 2).subtract(this.targetPosition);
position.copyFrom(math.lerpObj(position, this.followPosition, 0.1, Vector2D, ['x', 'y']));
}
onSleep() {
super.onSleep();
}
onDestroy() {
super.onDestroy();
}
}
/**
* Created by rockyl on 2018-12-17.
*
* 内容组件尺寸自适应组件
*/
import {ScillaComponent, Size} from "scilla";
import Transform from "../base/Transform";
export default class ContentSizeFitter extends ScillaComponent {
private _measureSize: Size = new Size();
afterUpdate() {
super.afterUpdate();
const measureSize = this._measureSize;
measureSize.set(0, 0);
for(let child of this.entity.children){
const transform = child.getComponent(Transform);
if(transform){
const {width, height, pivot} = transform;
measureSize.width += width;
measureSize.height += height;
}
}
this.transform.width = measureSize.width;
this.transform.height = measureSize.height;
}
}
/**
* Created by rockyl on 2018-12-05.
*
*/
import {ScillaComponent} from "scilla";
import Renderer from "../renderer/Renderer";
import Transform from "../base/Transform";
/**
* 相对布局组件
*/
export default class RelativeLayout extends ScillaComponent {
left: number = NaN;
right: number = NaN;
top: number = NaN;
bottom: number = NaN;
horizontalCenter: number = NaN;
verticalCenter: number = NaN;
once: boolean = true;
onCreate() {
super.onCreate();
}
onAwake() {
super.onAwake();
this.adjust();
}
onUpdate(t) {
super.onUpdate(t);
if (!this.once) {
this.adjust();
}
}
onSleep() {
super.onSleep();
}
onDestroy() {
super.onDestroy();
}
adjust = () => {
const {
entity, entity: {parent}, transform, transform: {position, pivot: {x: ax, y: ay},},
left, right, top, bottom, horizontalCenter, verticalCenter
} = this;
const hasLeft = !isNaN(left);
const hasRight = !isNaN(right);
const hasTop = !isNaN(top);
const hasBottom = !isNaN(bottom);
const hasHorizontalCenter = !isNaN(horizontalCenter);
const hasVerticalCenter = !isNaN(verticalCenter);
const parentRenderers = parent.getComponents(Renderer);
for (let parentRenderer of parentRenderers) {
parentRenderer.measureBounds();
}
const parentTransform:Transform = parent.getComponent(Transform);
let pWidth, pHeight;
if(parentRenderers.length > 0){
const parentBounds = parentRenderers[0].bounds;
pWidth = parentBounds.width;
pHeight = parentBounds.height;
}else{
pWidth = parentTransform.explicitWidth;
pHeight = parentTransform.explicitHeight;
}
const {x: pax, y: pay} = parentTransform.pivot;
const renderers = entity.getComponents(Renderer);
for (let renderer of renderers) {
renderer.measureBounds();
}
let {width, height, } = transform;
let {x, y} = position;
let widthModified = false, heightModified = false;
//adjust
{
if (hasHorizontalCenter) {
x = (pWidth - width) / 2 - pWidth * pax + width * ax;
} else if (hasLeft) {
if (hasRight) {
widthModified = true;
width = pWidth - right - left;
x = (left - right) / 2 - (0.5 - ax) * width;
} else {
x = left - pWidth * pax + width * ax;
}
} else if (hasRight) {
x = -right + pWidth * (1 - pax) - width * (1 - ax);
}
if (hasVerticalCenter) {
y = (pHeight - height) / 2 - pHeight * pay + height * ay;
} else if (hasTop) {
if (hasBottom) {
heightModified = true;
height = pHeight - bottom - top;
y = (top - bottom) / 2 - (0.5 - ay) * height;
} else {
y = top - pHeight * pay + height * ay;
}
} else if (hasBottom) {
y = -bottom + pHeight * (1 - pay) - height * (1 - ay);
}
}
position.x = x;
position.y = y;
if(widthModified){
transform.width = width;
}
if(heightModified){
transform.height = height;
}
if(widthModified || heightModified){
for (let renderer of renderers) {
renderer.measureBounds();
}
}
}
}
/**
* Created by rockyl on 2019-01-10.
*/
export {default as CameraController} from './CameraController'
export {default as ContentSizeFitter} from './ContentSizeFitter'
export {default as RelativeLayout} from './RelativeLayout'
/**
* Created by rockyl on 2018/11/6.
*/
import GraphicRenderer from "./GraphicRenderer";
import {decorators} from "scilla";
const {dirtyFieldDetector} = decorators;
/**
* 圆形渲染组件
*/
export default class CircleRenderer extends GraphicRenderer {
/**
* 半径
*/
@dirtyFieldDetector
radius = 50;
/**
* 开始角度
*/
@dirtyFieldDetector
startAngle: number = 0;
/**
* 结束角度
*/
@dirtyFieldDetector
endAngle: number = 360;
/**
* 是否回归到圆心
*/
@dirtyFieldDetector
backToCenter: boolean = true;
protected getRenderSize(): any {
const {radius} = this;
return {width: radius * 2, height: radius * 2};
}
/**
* @inheritDoc
*/
protected draw() {
const {context, bounds: {width, height}, startAngle, endAngle, backToCenter, _margin, _useCacheMode} = this;
let offset = _useCacheMode ? _margin : 0;
const radius = Math.min(width, height) / 2;
const pos = offset + radius;
if(startAngle == 0 && endAngle == 360){
context.arc(pos, pos, radius, 0, 2 * Math.PI);
}else{
if(backToCenter){
context.moveTo(pos, pos);
}
context.arc(pos, pos, radius, startAngle * Math.PI / 180, endAngle * Math.PI / 180);
if(backToCenter){
context.lineTo(pos, pos);
}
}
super.draw();
}
}
/**
* Created by rockyl on 2018-11-30.
*
* 帧动画组件
*
* todo 倒置播放
*/
import Renderer from "./Renderer";
import {FrameAnimation, ScillaEvent} from "scilla";
/**
* 帧动画渲染组件
*/
export default class FrameAnimationRenderer extends Renderer {
/**
* 帧动画资源
*/
public frameAnimation: FrameAnimation;
/**
* 是否自动播放
*/
public autoPlay: boolean = false;
/**
* 帧率
* 不设置就读取动画文件的帧率
*/
public fps: number = NaN;
public onComplete: ScillaEvent = new ScillaEvent();
public onLoopComplete: ScillaEvent = new ScillaEvent();
private _playing;
private _startTime;
private _startFrame;
private _endFrame;
private _currentFrameIndex;
private _startFlag;
private _loop;
private _loopCounting;
private _flag;
/**
* @inheritDoc
*/
onAwake() {
super.onAwake();
if(this.autoPlay){
this.play(0, -1);
}
}
/**
* @inheritDoc
*/
onUpdate(t) {
if (this._playing) {
const {frameAnimation, _startFrame, _endFrame, fps} = this;
if (this._startFlag) {
this._startFlag = false;
this._startTime = t;
this._loopCounting ++;
}
const mFPS = isNaN(fps) ? frameAnimation.fps : fps;
const passTime = t - this._startTime;
const passFrameCount = Math.floor(passTime / (1000 / mFPS));
const passFrameInRegion = passFrameCount % (_endFrame - _startFrame + 1);
this._currentFrameIndex = _startFrame + passFrameInRegion;
if(passFrameInRegion == 0 && passFrameCount > 0){
this._currentFrameIndex = _endFrame;
this.onLoopEnd();
}
}
super.onUpdate(t);
}
/**
* @inheritDoc
*/
onSleep() {
super.onSleep();
}
/**
* 当一遍播放结束时
*/
onLoopEnd(){
if (this._loop < 0) {
this._startFlag = true;
this.onLoopComplete.invoke();
} else if (this._loopCounting < this._loop) {
this._startFlag = true;
this.onLoopComplete.invoke();
} else {
this._playing = false;
this.onComplete.invoke();
}
}
/**
* 播放
* @param frame
* @param loop
* @param force
*/
play(frame: number | string = 0, loop: number = 0, force = true) {
this._loop = loop;
this._loopCounting = 0;
if (!this.frameAnimation) {
return;
}
let startFrame = 0, endFrame = this.frameAnimation.frameCount - 1;
if (typeof frame == 'string') {
const label = this.frameAnimation.getLabel(frame);
if (label) {
startFrame = label.frame - 1;
endFrame = label.end;
}
} else {
startFrame = frame;
}
this._startFrame = startFrame;
this._endFrame = endFrame;
this._currentFrameIndex = this._startFrame;
this._startFlag = true;
this._playing = true;
}
/**
* 停止
*/
stop() {
this._playing = false;
}
/**
* @inheritDoc
*/
protected draw() {
super.draw();
if (!this.frameAnimation) {
return;
}
const {context, frameAnimation, _currentFrameIndex, bounds} = this;
const {texture, data} = frameAnimation.getFrame(_currentFrameIndex);
if (texture) {
const {img, bounds: {x, y, width: textureWidth, height: textureHeight}} = texture;
bounds.setTo(data.x, data.y, textureWidth, textureHeight);
context.drawImage(img, x, y, textureWidth, textureHeight, data.x, data.y, textureWidth, textureHeight);
}
}
}
/**
* Created by rockyl on 2018/11/6.
*
* todo 如果isUsedToMask,就禁用缓存
*/
import Renderer from "./Renderer";
import {color} from 'scilla';
/**
* 图形渲染组件
*/
export default class GraphicRenderer extends Renderer {
fillColor: color = '#42bce4';
borderColor: color = '#0899d0';
borderWidth = 0;
//是否为mask
isUsedToMask = false;
//是否显示mask
maskVisible = false;
protected getUseCacheMode(){
return this._useCacheMode && !this.isUsedToMask;
}
/**
* 获取图形尺寸
*/
protected getRenderSize(): any {
return {width: 0, height: 0};
}
/**
* @inheritDoc
*/
protected beforeDraw() {
super.beforeDraw();
this.applyStyle();
this.context.beginPath();
}
/**
* @inheritDoc
*/
protected draw() {
super.draw();
if (this.isUsedToMask) {
this._context.clip();
this.maskVisible && this.fillAndStoke()
} else {
this.fillAndStoke()
}
}
/**
* 应用渲染样式
*/
protected applyStyle() {
const {context, fillColor, borderColor, borderWidth} = this;
context.fillStyle = fillColor;
if (borderWidth > 0) {
context.strokeStyle = borderColor;
context.lineWidth = borderWidth;
}
}
/**
* 绘制
*/
protected fillAndStoke() {
const {context, borderWidth} = this;
context.fill();
if (borderWidth > 0) {
context.stroke();
}
}
/**
* @inheritDoc
*/
protected drawClip() {
this.isUsedToMask && this.context.save();
}
/**
* @inheritDoc
*/
afterUpdate() {
this.isUsedToMask && this.context.restore();
}
measureBounds() {
if(this.entity.name == 'content'){
console.log();
}
if (!this.dirty) {
return;
}
this._margin = this.borderWidth;
const {bounds, transform: {explicitWidth: tWidth, explicitHeight: tHeight}} = this;
const {width: sWidth, height: sHeight} = this.getRenderSize();
bounds.width = isNaN(tWidth) ? sWidth : tWidth;
bounds.height = isNaN(tHeight) ? sHeight : tHeight;
super.measureBounds();
}
}
/**
* Created by rockyl on 2018/11/6.
*/
import GraphicRenderer from "./GraphicRenderer";
/**
* 线段渲染组件
*/
export default class LineRenderer extends GraphicRenderer {
x0: number = 0;
y0: number = 0;
x1: number = 0;
y1: number = 0;
/**
* @inheritDoc
*/
draw() {
super.draw();
const {context, x0, y0, x1, y1} = this;
context.moveTo(x0, y0);
context.lineTo(x1, y1);
}
/**
* @inheritDoc
*/
measureBounds() {
const {bounds} = this;
bounds.width = 0;
bounds.height = 0;
super.measureBounds();
}
}
/**
* Created by rockyl on 2018/11/6.
*/
import GraphicRenderer from "./GraphicRenderer";
import {decorators} from 'scilla'
const {dirtyFieldDetector} = decorators;
/**
* (圆角)矩形渲染器
*/
export default class RectRenderer extends GraphicRenderer {
@dirtyFieldDetector
width = 100;
@dirtyFieldDetector
height = 100;
@dirtyFieldDetector
cornerRadius = 0;
protected getRenderSize(): any {
const {width, height} = this;
return {width, height};
}
/**
* @inheritDoc
*/
protected draw() {
const {PI} = Math;
const {context, cornerRadius: r, bounds: {width, height}, _margin, _useCacheMode} = this;
let offset = _useCacheMode ? _margin : 0;
if (r) {
context.moveTo(offset + r, offset + 0);
context.lineTo(offset + width - r, offset + 0);
context.arc(offset + width - r, offset + r, r, PI * 3 / 2, PI * 2);
context.lineTo(offset + width, offset + height - r);
context.arc(offset + width - r, offset + height - r, r, 0, PI / 2);
context.lineTo(offset + r, offset + height);
context.arc(offset + r, offset + height - r, r, PI / 2, PI);
context.lineTo(offset + 0, offset + r);
context.arc(offset + r, offset + r, r, PI, PI * 3 / 2);
} else {
context.rect(offset, offset, width, height);
}
super.draw();
}
}
/**
* Created by rockyl on 2018/11/6.
*/
import {createCanvas, getContext, ScillaComponent, Bounds, Vector2D, math, decorators, EngineConfig} from "scilla";
const {dirtyFieldTrigger} = decorators;
/**
* 渲染组件基类
*/
export default class Renderer extends ScillaComponent {
protected onVector2DModify = () => {
this.makeDirty();
};
private _debugDrawColor: string;
protected dirty: boolean = true;
/**
* 是否使用缓存模式
*/
protected _useCacheMode: boolean = false;
/**
* 透明度
*/
alpha: number = 1;
//锚点:在各子render里面加,从绘制上改,将同时更改位置原点,旋转原点,缩放原点,以0到1比例形式(现用此方案)
//在该render上改transform;更改旋转和缩放原点,不改变位置原点,默认中心为位置原点,以真实数值形式
@dirtyFieldTrigger
anchor: Vector2D = new Vector2D(0.5, 0.5);
/**
* 边界
*/
protected bounds = new Bounds();
protected cacheCanvas = null;
/**
* 缓存用的渲染上下文
*/
protected cacheCanvasContext;
/**
* 锚点实际偏移
*/
protected _anchorOffset: Vector2D = new Vector2D();
//渲染上下文
protected _context = getContext();
/**
* 扩展尺寸
*/
protected _margin: number = 0;
get useCacheMode() {
return this.getUseCacheMode();
}
set useCacheMode(value) {
this._useCacheMode = value;
}
constructor(){
super();
this._debugDrawColor = `hsl(${math.makeRandomInt(360)}, ${math.makeRandomInt(100)}%, 60%)`;
}
protected getUseCacheMode() {
return this._useCacheMode;
}
/**
* 获取渲染上下文
* 如果缓存上下文存在,则返回缓存上下文
*/
get context() {
return this.cacheCanvasContext || this._context;
}
makeDirty() {
this.dirty = true;
}
/**
* @inheritDoc
*/
protected onModify(value, key, oldValue) {
super.onModify(value, key, oldValue);
this.makeDirty();
switch (key) {
case 'anchor':
value.onChange = this.onVector2DModify;
break;
}
}
onAwake() {
super.onAwake();
if (!this.transform) {
console.warn('renderer need a transform component');
}
}
/**
* @inheritDoc
*/
onUpdate(t) {
if (this.dirty) {
if(this.entity.name == 'label_status'){
console.log();
}
if (this.useCacheMode) {
this.readyCacheCanvas();
}
this.measureBounds();
if (this.useCacheMode) {
this.updateCacheCanvas();
}
}
this.transformToLocal();
this.render();
if (EngineConfig.drawRenderRect) {
const {_context, _debugDrawColor, bounds: {width, height}, _anchorOffset: {x, y}, transform: {pivot: {x: px, y: py}}} = this;
_context.globalAlpha = 0.9;
_context.strokeStyle = _debugDrawColor;
_context.fillStyle = _debugDrawColor;
_context.beginPath();
_context.rect(0, 0, width, height);
_context.stroke();
_context.beginPath();
_context.arc(width * px, height * py, 3, 0, 2 * Math.PI);
_context.fill();
}
}
/**
* 准备缓存渲染上下文
*/
protected readyCacheCanvas() {
let canvas = this.cacheCanvas;
if (!canvas) {
canvas = this.cacheCanvas = createCanvas();
this.cacheCanvasContext = canvas.getContext('2d');
}
}
/**
* 更新缓存属性
*/
protected updateCacheCanvas() {
let canvas = this.cacheCanvas;
const {width, height} = this.bounds;
canvas.width = width + this._margin * 2;
canvas.height = height + this._margin * 2;
}
/**
* 渲染过程
*/
protected render() {
this.beforeDraw();
this.drawClip();
if (this.dirty) {
if(this.useCacheMode){
this.draw();
}
this.dirty = false;
}
if (this.useCacheMode) {
this.drawCache();
} else {
this.draw();
}
}
/**
* 画之前
*/
protected beforeDraw() {
this.applyAlpha();
}
/**
* 执行矩阵转换
*/
protected transformToLocal() {
const {transform, _anchorOffset: {x: ax, y: ay}} = this;
if (transform && transform.enabled) {
const {a, b, c, d, tx, ty} = transform.getMatrix(true);
const offX = ax * a + ay * c;
const offY = ax * b + ay * d;
this._context.setTransform(a, b, c, d, tx - offX, ty - offY);
} else {
this._context.setTransform(1, 0, 0, 1, -ax, -ay);
}
}
/**
* 应用透明度
*/
protected applyAlpha() {
this._context.globalAlpha = this.alpha * this.transform.renderAlpha;
}
/**
* 绘制缓存
*/
protected drawCache() {
if (this.cacheCanvas.width > 0 && this.cacheCanvas.height > 0) {
this._context.drawImage(this.cacheCanvas, -this._margin, -this._margin);
}
}
/**
* 画遮罩
*/
protected drawClip() {
}
/**
* 画
*/
protected draw() {
}
/**
* 测量边界
*/
protected measureBounds() {
const {anchor: {x, y}, bounds, bounds: {width, height}} = this;
const anchorOffsetX = this._anchorOffset.x = width * x;
const anchorOffsetY = this._anchorOffset.y = height * y;
bounds.x = -anchorOffsetX;
bounds.y = -anchorOffsetY;
}
/**
* 碰撞检测
* @param x
* @param y
*/
hitTest(x, y) {
return this.bounds.contains(x, y);
}
}
This diff is collapsed.
/**
* Created by rockyl on 2018/11/6.
*/
import Renderer from "./Renderer";
import {Texture, decorators} from "scilla";
const {dirtyFieldDetector} = decorators;
export enum FillMode {
/**
* 正常
*/
NORMAL,
/**
* 裁切
*/
SLICED,
/**
* 瓦片
*/
TILED,
}
/**
* 纹理渲染组件
*/
export default class TextureRenderer extends Renderer {
/**
* 纹理资源
*/
@dirtyFieldDetector
texture: Texture;
/**
* 填充模式
*/
@dirtyFieldDetector
fillMode: FillMode = FillMode.NORMAL;
/**
* 滤镜数组
*/
@dirtyFieldDetector
filters = [];
private get hasFilters() {
return this.filters && this.filters.length > 0;
}
/**
* @inheritDoc
*/
draw() {
super.draw();
this.drawImage();
this.applyFilters();
/*const {context, texture, hasFilters} = this;
if (texture && hasFilters) {
const {bounds: {width: textureWidth, height: textureHeight}} = texture;
//筛选阴影滤镜Shadow
let s = this;
let cf = s.filters;
let cfLen = cf.length;
let fId = -1;
if (cfLen) {
for (let i = 0; i < cfLen; i++) {
if (s.filters[i].type == "Shadow") {
fId = i;
break;
}
}
}
if (fId >= 0) {
let ctx: any = context;
ctx.shadowBlur = cf[fId].blur;
ctx.shadowColor = cf[fId].color;
ctx.shadowOffsetX = cf[fId].offsetX;
ctx.shadowOffsetY = cf[fId].offsetY;
ctx.drawImage(this.cacheCanvas, 0, 0, textureWidth, textureHeight);
ctx.shadowBlur = 0;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
} else {
context.drawImage(this.cacheCanvas, 0, 0, textureWidth, textureHeight);
}
// context.drawImage(texture.img, x, y, textureWidth, textureHeight, -width * this.anchor.x, -height * this.anchor.y, width, height);
}*/
}
/**
* 应用滤镜
*/
applyFilters() {
if (!this.hasFilters) return;
const {texture, filters, context} = this;
const {bounds: {width: textureWidth, height: textureHeight}} = texture;
let imageData = context.getImageData(0, 0, textureWidth, textureHeight);
for (const filter of filters) {
filter.drawFilter(imageData);
}
context.putImageData(imageData, 0, 0);
}
/**
* 根据模式绘制图片
*/
drawImage() {
if(!this.texture){
return;
}
const {texture, fillMode, context, bounds: {width, height}} = this;
const {bounds: {x, y, width: textureWidth, height: textureHeight}} = texture;
switch (fillMode) {
case FillMode.NORMAL:
texture.drawToCanvas(context);
break;
case FillMode.SLICED:
break;
case FillMode.TILED:
const textureCanvas = texture.getCacheCanvas();
const pattern = context.createPattern(textureCanvas, 'repeat');
context.rect(0, 0, width, height);
context.fillStyle = pattern;
context.fill();
break;
}
}
/**
* @inheritDoc
*/
measureBounds() {
if (!this.dirty) {
return;
}
const {bounds, transform: {explicitWidth: tWidth, explicitHeight: tHeight}} = this;
if (this.texture) {
const {width: textureWidth, height: textureHeight} = this.texture;
bounds.width = isNaN(tWidth) ? textureWidth : tWidth;
bounds.height = isNaN(tHeight) ? textureHeight : tHeight;
} else {
bounds.width = isNaN(tWidth) ? 0 : tWidth;
bounds.height = isNaN(tHeight) ? 0 : tHeight;
}
super.measureBounds();
}
}
/**
* Created by rockyl on 2019-01-10.
*/
export {default as CircleRenderer} from './CircleRenderer'
export {default as FrameAnimationRenderer} from './FrameAnimationRenderer'
export {default as GraphicRenderer} from './GraphicRenderer'
export {default as LineRenderer} from './LineRenderer'
export {default as RectRenderer} from './RectRenderer'
export {default as Renderer} from './Renderer'
export {default as TextRenderer} from './TextRenderer'
export {default as TextureRenderer} from './TextureRenderer'
/**
* Created by rockyl on 2018/11/23.
*
* 按钮
*/
import {ScillaEvent, Texture,} from "scilla";
import TouchZoom from "../animation/TouchZoom";
import {InteractComponent} from "../base";
import {TextureRenderer} from "../renderer";
export default class Button extends InteractComponent {
upRes: Texture;
downRes: Texture;
disabledRes: Texture;
onClick: ScillaEvent;
private bgRenderer: TextureRenderer;
private currentRes: Texture;
private touchBeginWithSelf: boolean;
private touchOut: boolean;
constructor() {
super();
this.touchInterrupt = true;
}
get touchZoom(): TouchZoom{
return this.entity && this.entity.getComponent(TouchZoom);
}
onModify(value, key, oldValue) {
super.onModify(value, key, oldValue);
if (key === 'interactable') {
if(this.touchZoom){
this.touchZoom.interactable = value;
}
try {
this.changeTexture();
}catch (e) {}
}
}
onCreate() {
super.onCreate();
this.onClick = new ScillaEvent();
}
onAwake() {
super.onAwake();
this.bgRenderer = this.entity.getComponent(TextureRenderer);
this.changeTexture(this.upRes);
}
onTouchBegin(e) {
super.onTouchBegin(e);
this.touchBeginWithSelf = true;
this.changeTexture(this.downRes);
}
onTouchOver(e) {
super.onTouchOver(e);
if (this.touchBeginWithSelf) {
this.touchBeginWithSelf = true;
this.changeTexture(this.downRes);
}
this.touchOut = false;
}
onTouchOut(e) {
super.onTouchOut(e);
if (this.touchBeginWithSelf) {
this.changeTexture(this.upRes);
}
this.touchOut = true;
}
onGlobalTouchEnd(e) {
super.onGlobalTouchEnd(e);
if (this.touchBeginWithSelf && !this.touchOut) {
this.onClick.invoke();
}
this.touchBeginWithSelf = false;
this.changeTexture(this.upRes);
}
changeTexture(res?) {
if(!this.bgRenderer){
return;
}
this.currentRes = res || this.upRes;
if(this.interactable){
this.bgRenderer.texture = this.currentRes;
}else{
this.bgRenderer.texture = this.disabledRes;
}
}
}
/**
* Created by rockyl on 2018-12-26.
*
* 进度条
*/
import {Entity, ScillaComponent, decorators, createTween, ease} from "scilla";
import RectRenderer from "../renderer/RectRenderer";
import Transform from "../base/Transform";
import TextRenderer from "../renderer/TextRenderer";
const {dirtyFieldTrigger} = decorators;
function renderLabelFuncSample(value, maximum, minimum){
return Math.floor(value / (maximum - minimum) * 100) + '%';
}
export default class ProgressBar extends ScillaComponent {
viewport: Entity;
thumb: Entity;
widget: Entity;
label: Entity;
@dirtyFieldTrigger
value: number = 0;
@dirtyFieldTrigger
minimum: number = 0;
@dirtyFieldTrigger
maximum: number = 0;
@dirtyFieldTrigger
snapInterval: number = 1;
@dirtyFieldTrigger
renderLabelFunc: Function;
@dirtyFieldTrigger
fixWithRange: boolean = true;
private _mask: RectRenderer;
private _widgetTransform: Transform;
private _label: TextRenderer;
private _thumbSize: any;
onCreate() {
super.onCreate();
this.renderLabelFunc = renderLabelFuncSample;
}
onAwake() {
super.onAwake();
this._mask = this.viewport.getComponent(RectRenderer);
this._mask.width = 0;
if(this.widget){
this._widgetTransform = this.widget.getComponent(Transform);
}
this._label = this.label.getComponent(TextRenderer);
this.callOnNextTick(this.updateThumbSize);
}
private updateThumbSize=()=>{
const {width, height} = this.thumb.getComponent(Transform);
this._thumbSize = {width, height};
this.update();
};
onModify(value, key, oldValue) {
super.onModify(value, key, oldValue);
if(oldValue === undefined){
return;
}
this.callOnNextTick(this.update);
}
private update(){
const {minimum, maximum, _thumbSize} = this;
if(!_thumbSize){
return ;
}
const range = maximum - minimum;
let value = Math.max(minimum, Math.min(maximum, this.value));
const percentage = (value - minimum) / range;
const width = percentage * _thumbSize.width;
//this._mask.width = width;
createTween(this._mask, true)
.to({width}, 300, ease.cubicOut);
if(this._widgetTransform){
this._widgetTransform.position.x = width;
}
let renderValue = this.fixWithRange ? Math.max(minimum, Math.min(maximum, this.value)) : this.value;
this.value = value;
if(this._label){
let text = this.renderLabelFunc(renderValue, this.maximum, this.minimum);
if(typeof text == 'string'){
this._label.text = text;
this._label.textFlow = null;
}else{
this._label.textFlow = text;
this._label.updateTextFlow();
}
}
}
}
/**
* Created by rockyl on 2018-12-13.
*
* 滚动视图组件
*/
import {Entity, Size, createTween, createVector2D, Vector2D, ease} from "scilla";
import InteractComponent from "../base/InteractComponent";
import Transform from "../base/Transform";
enum LockingType {
NOSET,
HORIZON,
VERTICAL,
}
export default class ScrollView extends InteractComponent {
viewport: Entity;
content: Entity;
lockingType: LockingType = LockingType.NOSET;
private _beginPos: any;
private _lastPos: Vector2D = createVector2D();
private _viewportTransform: Transform;
private _contentTransform: Transform;
private _posOffset: any;
private _posRange: Size;
private _speed: Vector2D = createVector2D();
onAwake() {
super.onAwake();
this._contentTransform = this.content.getComponent(Transform);
this._viewportTransform = this.viewport.getComponent(Transform);
this.callOnNextTick(this.updatePosOffset);
}
updatePosOffset = ()=>{
const {position: {x: x, y: y}} = this._contentTransform;
this._posOffset = {x, y};
//console.log(this._posOffset);
}
updatePosRange = () => {
const {width: pWidth, height: pHeight} = this._viewportTransform;
const {width, height} = this._contentTransform;
this._posRange = new Size(pWidth - width, pHeight - height);
//console.log(this._posRange);
};
onTouchBegin(e) {
super.onTouchBegin(e);
this.updatePosRange();
const {x: tx, y: ty} = e;
const {_contentTransform: {position: {x: cx, y: cy}}} = this;
this._beginPos = {
tx,
ty,
cx,
cy,
};
this._lastPos.setXY(tx, ty);
}
onGlobalTouchMove(e) {
super.onGlobalTouchMove(e);
if (!this._beginPos) {
return;
}
const {
_beginPos: {tx, ty, cx, cy},
_posOffset: {x: offX, y: offY},
_contentTransform: {position},
lockingType,
} = this;
const {x, y} = e;
let px = x - tx + cx;
let py = y - ty + cy;
const {width: rWidth, height: rHeight} = this._posRange;
const halfWidth = Math.abs( rWidth / 2);
const paddingX = halfWidth - Math.abs(offX - halfWidth - px);
if(paddingX < 0){
px += paddingX * 0.8 * (x - tx > 0 ? 1 : -1);
}
const halfHeight = Math.abs( rHeight / 2);
const paddingY = halfHeight - Math.abs(offY - halfHeight - py);
if(paddingY < 0){
py += paddingY * 0.8 * (y - ty > 0 ? 1 : -1);
}
switch (lockingType) {
case LockingType.HORIZON:
position.y = py;
break;
case LockingType.VERTICAL:
position.x = px;
break;
default:
position.setXY(px, py);
}
this._speed.copyFrom(this._lastPos.subtract({x, y}));
this._lastPos.setXY(x, y);
}
onGlobalTouchEnd(e) {
super.onGlobalTouchEnd(e);
if (!this._beginPos) {
return;
}
this._beginPos = null;
const {x: offX, y: offY} = this._posOffset;
const {width: rWidth, height: rHeight} = this._posRange;
const {position, position: {x, y}} = this._contentTransform;
const tx = Math.min(Math.max(offX + rWidth, x), offX);
const ty = Math.min(Math.max(offY + rHeight, y), offY);
const targetPos = createVector2D(tx, ty);
const duration = Math.min(500, Math.max(targetPos.distance(position), 200));
createTween(this._contentTransform, true, {clazz: Vector2D, fields: ['x', 'y']})
.to({position: targetPos}, duration, ease.cubicOut);
}
}
/**
* Created by rockyl on 2019-01-10.
*/
export {default as Button} from './Button'
export {default as ProgressBar} from './ProgressBar'
export {default as ScrollView} from './ScrollView'
{
"compilerOptions": {
"target": "es5",
"experimentalDecorators": true,
"sourceMap": true,
"declarationDir": "./types",
"declaration": true,
"lib": [
"es5",
"es6",
"dom",
"es2015.promise"
],
"baseUrl": "./",
"paths": {
"scilla": ["node_modules/scilla/src"]
}
},
"include": [
"src",
"libs"
]
}
\ No newline at end of file
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment