Commit d5c1a94f authored by wangjianfeng.yz's avatar wangjianfeng.yz

2.0.66

parent 14ed7b3c
......@@ -20,4 +20,5 @@ docs
adapters
testThree
README.md
abandoned
\ No newline at end of file
abandoned
beta
\ No newline at end of file
export interface IContainer {
children: IContainer[]
name: string
}
function _getElementsByName(name: RegExp | string, root: IContainer, isRecursive?: boolean): IContainer[] {
if (!name || !root || !root.children || !root.children.length) return [];
let list: IContainer[] = [];
let rex: RegExp;
if (typeof (name) == "string") {
rex = new RegExp("^" + name + "$");
} else {
rex = name;
}
let child: IContainer;
for (let i = 0; i < root.children.length; i++) {
child = root.children[i];
if (rex.test(child.name)) {
list.push(child);
}
if (isRecursive) {
list.push(..._getElementsByName(rex, child, isRecursive));
}
}
return list;
}
\ No newline at end of file
declare namespace FYGE{export const VERSION = "2.0.65";
declare namespace FYGE{export const VERSION = "2.0.66";
export function cos(angle: number): number;
......@@ -8775,6 +8775,7 @@ export class ScrollView extends Container {
hasMomentum: boolean;
/**
* 惯性的阻尼
* 默认0.002
*/
damping: number;
/**
......@@ -9462,6 +9463,7 @@ export interface ILottieKeyData {
export interface ILottieKeyAniData {
t: number;
s: number[];
e: number[];
i: {
x: number | number[];
y: number | number[];
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
export const VERSION = "2.0.65";
export const VERSION = "2.0.66";
export function cos(angle: number): number;
......@@ -8775,6 +8775,7 @@ export class ScrollView extends Container {
hasMomentum: boolean;
/**
* 惯性的阻尼
* 默认0.002
*/
damping: number;
/**
......@@ -9462,6 +9463,7 @@ export interface ILottieKeyData {
export interface ILottieKeyAniData {
t: number;
s: number[];
e: number[];
i: {
x: number | number[];
y: number | number[];
......
{
"name": "fyge",
"version": "2.0.65",
"version": "2.0.66",
"description": "canvas渲染引擎",
"main": "./build/fyge.min.js",
"module": "./build/fyge.esm.js",
......
......@@ -592,12 +592,26 @@
Object3D的lookAt方法新增一个重载,可传xyz对象
Object3D的update方法去掉自身的visible判断
2.0.66 FpsPanel的maxValue改成120
Button的构造函数添加提示,不希望被使用的类
Lottie添加e属性,当前关键帧的s不存在时取前一帧的e
ScrollView的damping默认值改成0.002
ScrollView的up时判断累计的速度绝对值是否大于0.02,大于时才缓冲
ScrollView修改了toMomentum的计算方式
ScrollView的_scrollTo缓动方法默认值改成Ease.quadOut
Object3D的destroy方法吧removeAllEventListener的操作放到removeChild之后,否则从scene移除的事件触发不了
getElementsByName到时要处理下
stage的鼠标事件,changedTouches考虑放开
three的wireframe会修改index,以后考虑
批处理着色器最后参考pixi的改
destroyed啥时候要处理下
......
......@@ -16,7 +16,7 @@ export class FpsPanel extends Sprite {
private GRAPH_WIDTH = 74 * this.PR;
private GRAPH_HEIGHT = 30 * this.PR;
private GRAPH_SIZE = 74;
private maxValue = 100;
private maxValue = 120;
private min = Infinity;
private max = 0;
private items = [];
......
......@@ -7,7 +7,7 @@
* @name VERSION
* @type {string}
*/
export const VERSION = "2.0.65";
export const VERSION = "2.0.66";
/**
......
......@@ -5,12 +5,35 @@ import { MouseEvent } from "../events/MouseEvent";
import Texture from "../texture/Texture";
import Tween from "../../tween/Tween";
let hasWarned: boolean;
export class Button extends Sprite {
private textureUp: Texture;
private textureDown: Texture;
private textureDisable: Texture;
constructor(tUp: Texture, tDown?: Texture, tDisable?: Texture) {
super(tUp);
if (!hasWarned) console.warn(`Class Button will be abandoned later,maybe you can:
function addClickZoom(dis: DisplayObject, zoomCenter: boolean = true) {
if (zoomCenter) {
dis.anchorX = dis.width / 2;
dis.anchorY = dis.height / 2;
}
dis.addEventListener("onMouseDown", _mouseEvent, dis)
.addEventListener("onMouseUp", _mouseEvent, dis)
.addEventListener("onMouseOut", _mouseEvent, dis);
let s = dis;
function _mouseEvent(e: MouseEvent) {
if (e.type == MouseEvent.MOUSE_DOWN) {
Tween.removeTweens(s);
Tween.get(s).to({ scaleX: 0.9, scaleY: 0.9 }, 50);
} else {
Tween.removeTweens(s);
Tween.get(s).to({ scaleX: 1, scaleY: 1 }, 50);
}
}
}`)
hasWarned = true;
this._instanceType = "Button";
this.textureUp = tUp;
......
......@@ -173,6 +173,7 @@ export interface ILottieKeyData {
export interface ILottieKeyAniData {
t: number,
s: number[],
e: number[],//s不存在时取前一帧数据的e
i: { x: number | number[], y: number | number[] },
o: { x: number | number[], y: number | number[] },
......@@ -274,13 +275,13 @@ class LottieBaseTrack extends HashObject implements IAnimationTrack {
time = (this.loop.loopInOrOut == 1 ? loopIn : loopOut)(this.loop.type, this.loop.duration, this.times, time)
}
if (time <= this.times[0].t) return this.times[0].s;
if (time >= this.times[this.times.length - 1].t) return this.times[this.times.length - 1].s;
if (time >= this.times[this.times.length - 1].t) return this.times[this.times.length - 1].s || this.times[this.times.length - 2].e;
//其他的计算补间了要,找前后两个索引
var after = this.findIndex(time);
var before = after - 1;
var da = this.times[after];
var db = this.times[before];
var beforeValue = db.s, afterValue = da.s;
var beforeValue = db.s, afterValue = da.s || db.e;
var value: number[]
//有路径的
if (db.to) {
......
......@@ -126,8 +126,9 @@ export class ScrollView extends Container {
public hasMomentum: boolean = true;
/**
* 惯性的阻尼
* 默认0.002
*/
public damping: number = 0.0006
public damping: number = 0.002
/**
* 0无交互状态
* 1点击状态
......@@ -328,11 +329,14 @@ export class ScrollView extends Container {
totalW += w;
}
s.velocitys.length = 0;
let momentumX = s.scrollWidth ? toMomentum(newX, sum.x / totalW, s.maxScrollX, s.damping) : {
let sx = sum.x / totalW,
sy = sum.y / totalW;
let momentumX = (s.scrollWidth && Math.abs(sx) > 0.02) ? toMomentum(newX, sx, s.maxScrollX, s.damping) : {
destination: newX,
duration: 0
};
let momentumY = s.scrollHeight ? toMomentum(newY, sum.y / totalW, s.maxScrollY, s.damping) : {
let momentumY = (s.scrollHeight && Math.abs(sy) > 0.02) ? toMomentum(newY, sy, s.maxScrollY, s.damping) : {
destination: newY,
duration: 0
};
......@@ -356,8 +360,8 @@ export class ScrollView extends Container {
private onEnterFrame(e: Event) {
let s = this;
let now = Date.now();
//不清楚有啥用
if (s.lastTouchTime && now - s.lastTouchTime > 100 && now - s.lastTouchTime < 300) {
//用户点击交互时需要加
if (s.mouseStatus && s.lastTouchTime && now - s.lastTouchTime > 100 && now - s.lastTouchTime < 300) {
s.pushVelocitys(0, 0);
}
if (!s.isRunning) return;
......@@ -457,7 +461,7 @@ export class ScrollView extends Container {
s.destX = x;
s.destY = y;
s.duration = time;
s.easeFn = easeFn || Ease.circOut;
s.easeFn = easeFn || Ease.quadOut;
s.isRunning = true;
}
}
......@@ -559,6 +563,30 @@ function toMomentum(
speed: number,
lowerMargin: number,
deceleration: number = 0.0006
) {
//衰减到0的时间
let duration = Math.abs(speed) / deceleration;
let destination = current + duration * (speed / 2)
// console.log(current, speed)
if (destination < lowerMargin) {
destination = lowerMargin;
duration = Math.abs((destination - current) / (speed / 2));
}
else if (destination > 0) {
destination = 0;
duration = Math.abs(current / (speed / 2));
}
return {
destination,
duration
};
};
function toMomentum1(
current: number,
speed: number,
lowerMargin: number,
deceleration: number = 0.0006
) {
let destination = current + (speed * speed) / (2 * deceleration) * (speed < 0 ? -1 : 1);
let duration = Math.abs(speed) / deceleration;
......@@ -577,6 +605,38 @@ function toMomentum(
};
};
function toMomentum2(
curPos: number,
pixelsPerMS: number,
maxPos: number,
damping: number
): { destination: number; duration: number } {
let absPixelsPerMS: number = Math.abs(pixelsPerMS);
let extraFricition: number = 0.95;
let duration: number = 0;
let friction: number = 0.998;
let minVelocity: number = 0.02;
let posTo: number = curPos + pixelsPerMS * 500;
if (posTo < maxPos) {
posTo = maxPos;
duration = Math.abs((posTo - curPos) / pixelsPerMS);
}
else if (posTo > 0) {
posTo = 0;
duration = Math.abs(curPos / pixelsPerMS);
}
else {
duration = -Math.log(minVelocity / absPixelsPerMS) * 500;
}
let result = {
destination: posTo,
duration
};
return result;
}
export interface IScrollData {
/**
* 横向滚动位置,通常为正
......
This diff is collapsed.
......@@ -425,11 +425,11 @@ export class Object3D extends EventDispatcher {
destroy() {
//子级的destroy
for (let i = this.children.length - 1; i >= 0; i--) this.children[i].destroy();
//移除事件
this.removeAllEventListener();
// super.destroy();//不适用继承的,里面的eventTypes置空很麻烦
//从父级移除自己
if (this.parent) this.parent.removeChild(this);
//移除事件
this.removeAllEventListener();
//还有很多自己的属性,再说了
}
......
( function () {
/**
* Description: A THREE loader for STL ASCII files, as created by Solidworks and other CAD programs.
*
* Supports both binary and ASCII encoded files, with automatic detection of type.
*
* The loader returns a non-indexed buffer geometry.
*
* Limitations:
* Binary decoding supports "Magics" color format (http://en.wikipedia.org/wiki/STL_(file_format)#Color_in_binary_STL).
* There is perhaps some question as to how valid it is to always assume little-endian-ness.
* ASCII decoding assumes file is UTF-8.
*
* Usage:
* const loader = new STLLoader();
* loader.load( './models/stl/slotted_disk.stl', function ( geometry ) {
* scene.add( new THREE.Mesh( geometry ) );
* });
*
* For binary STLs geometry might contain colors for vertices. To use it:
* // use the same code to load STL as above
* if (geometry.hasColors) {
* material = new THREE.MeshPhongMaterial({ opacity: geometry.alpha, vertexColors: true });
* } else { .... }
* const mesh = new THREE.Mesh( geometry, material );
*
* For ASCII STLs containing multiple solids, each solid is assigned to a different group.
* Groups can be used to assign a different color by defining an array of materials with the same length of
* geometry.groups and passing it to the Mesh constructor:
*
* const mesh = new THREE.Mesh( geometry, material );
*
* For example:
*
* const materials = [];
* const nGeometryGroups = geometry.groups.length;
*
* const colorMap = ...; // Some logic to index colors.
*
* for (let i = 0; i < nGeometryGroups; i++) {
*
* const material = new THREE.MeshPhongMaterial({
* color: colorMap[i],
* wireframe: false
* });
*
* }
*
* materials.push(material);
* const mesh = new THREE.Mesh(geometry, materials);
*/
class STLLoader extends THREE.Loader {
constructor( manager ) {
super( manager );
}
load( url, onLoad, onProgress, onError ) {
const scope = this;
const loader = new THREE.FileLoader( this.manager );
loader.setPath( this.path );
loader.setResponseType( 'arraybuffer' );
loader.setRequestHeader( this.requestHeader );
loader.setWithCredentials( this.withCredentials );
loader.load( url, function ( text ) {
try {
onLoad( scope.parse( text ) );
} catch ( e ) {
if ( onError ) {
onError( e );
} else {
console.error( e );
}
scope.manager.itemError( url );
}
}, onProgress, onError );
}
parse( data ) {
function isBinary( data ) {
const reader = new DataView( data );
const face_size = 32 / 8 * 3 + 32 / 8 * 3 * 3 + 16 / 8;
const n_faces = reader.getUint32( 80, true );
const expect = 80 + 32 / 8 + n_faces * face_size;
if ( expect === reader.byteLength ) {
return true;
} // An ASCII STL data must begin with 'solid ' as the first six bytes.
// However, ASCII STLs lacking the SPACE after the 'd' are known to be
// plentiful. So, check the first 5 bytes for 'solid'.
// Several encodings, such as UTF-8, precede the text with up to 5 bytes:
// https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding
// Search for "solid" to start anywhere after those prefixes.
// US-ASCII ordinal values for 's', 'o', 'l', 'i', 'd'
const solid = [ 115, 111, 108, 105, 100 ];
for ( let off = 0; off < 5; off ++ ) {
// If "solid" text is matched to the current offset, declare it to be an ASCII STL.
if ( matchDataViewAt( solid, reader, off ) ) return false;
} // Couldn't find "solid" text at the beginning; it is binary STL.
return true;
}
function matchDataViewAt( query, reader, offset ) {
// Check if each byte in query matches the corresponding byte from the current offset
for ( let i = 0, il = query.length; i < il; i ++ ) {
if ( query[ i ] !== reader.getUint8( offset + i, false ) ) return false;
}
return true;
}
function parseBinary( data ) {
const reader = new DataView( data );
const faces = reader.getUint32( 80, true );
let r,
g,
b,
hasColors = false,
colors;
let defaultR, defaultG, defaultB, alpha; // process STL header
// check for default color in header ("COLOR=rgba" sequence).
for ( let index = 0; index < 80 - 10; index ++ ) {
if ( reader.getUint32( index, false ) == 0x434F4C4F
/*COLO*/
&& reader.getUint8( index + 4 ) == 0x52
/*'R'*/
&& reader.getUint8( index + 5 ) == 0x3D
/*'='*/
) {
hasColors = true;
colors = new Float32Array( faces * 3 * 3 );
defaultR = reader.getUint8( index + 6 ) / 255;
defaultG = reader.getUint8( index + 7 ) / 255;
defaultB = reader.getUint8( index + 8 ) / 255;
alpha = reader.getUint8( index + 9 ) / 255;
}
}
const dataOffset = 84;
const faceLength = 12 * 4 + 2;
const geometry = new THREE.BufferGeometry();
const vertices = new Float32Array( faces * 3 * 3 );
const normals = new Float32Array( faces * 3 * 3 );
for ( let face = 0; face < faces; face ++ ) {
const start = dataOffset + face * faceLength;
const normalX = reader.getFloat32( start, true );
const normalY = reader.getFloat32( start + 4, true );
const normalZ = reader.getFloat32( start + 8, true );
if ( hasColors ) {
const packedColor = reader.getUint16( start + 48, true );
if ( ( packedColor & 0x8000 ) === 0 ) {
// facet has its own unique color
r = ( packedColor & 0x1F ) / 31;
g = ( packedColor >> 5 & 0x1F ) / 31;
b = ( packedColor >> 10 & 0x1F ) / 31;
} else {
r = defaultR;
g = defaultG;
b = defaultB;
}
}
for ( let i = 1; i <= 3; i ++ ) {
const vertexstart = start + i * 12;
const componentIdx = face * 3 * 3 + ( i - 1 ) * 3;
vertices[ componentIdx ] = reader.getFloat32( vertexstart, true );
vertices[ componentIdx + 1 ] = reader.getFloat32( vertexstart + 4, true );
vertices[ componentIdx + 2 ] = reader.getFloat32( vertexstart + 8, true );
normals[ componentIdx ] = normalX;
normals[ componentIdx + 1 ] = normalY;
normals[ componentIdx + 2 ] = normalZ;
if ( hasColors ) {
colors[ componentIdx ] = r;
colors[ componentIdx + 1 ] = g;
colors[ componentIdx + 2 ] = b;
}
}
}
geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
geometry.setAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
if ( hasColors ) {
geometry.setAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) );
geometry.hasColors = true;
geometry.alpha = alpha;
}
return geometry;
}
function parseASCII( data ) {
const geometry = new THREE.BufferGeometry();
const patternSolid = /solid([\s\S]*?)endsolid/g;
const patternFace = /facet([\s\S]*?)endfacet/g;
let faceCounter = 0;
const patternFloat = /[\s]+([+-]?(?:\d*)(?:\.\d*)?(?:[eE][+-]?\d+)?)/.source;
const patternVertex = new RegExp( 'vertex' + patternFloat + patternFloat + patternFloat, 'g' );
const patternNormal = new RegExp( 'normal' + patternFloat + patternFloat + patternFloat, 'g' );
const vertices = [];
const normals = [];
const normal = new THREE.Vector3();
let result;
let groupCount = 0;
let startVertex = 0;
let endVertex = 0;
while ( ( result = patternSolid.exec( data ) ) !== null ) {
startVertex = endVertex;
const solid = result[ 0 ];
while ( ( result = patternFace.exec( solid ) ) !== null ) {
let vertexCountPerFace = 0;
let normalCountPerFace = 0;
const text = result[ 0 ];
while ( ( result = patternNormal.exec( text ) ) !== null ) {
normal.x = parseFloat( result[ 1 ] );
normal.y = parseFloat( result[ 2 ] );
normal.z = parseFloat( result[ 3 ] );
normalCountPerFace ++;
}
while ( ( result = patternVertex.exec( text ) ) !== null ) {
vertices.push( parseFloat( result[ 1 ] ), parseFloat( result[ 2 ] ), parseFloat( result[ 3 ] ) );
normals.push( normal.x, normal.y, normal.z );
vertexCountPerFace ++;
endVertex ++;
} // every face have to own ONE valid normal
if ( normalCountPerFace !== 1 ) {
console.error( 'THREE.STLLoader: Something isn\'t right with the normal of face number ' + faceCounter );
} // each face have to own THREE valid vertices
if ( vertexCountPerFace !== 3 ) {
console.error( 'THREE.STLLoader: Something isn\'t right with the vertices of face number ' + faceCounter );
}
faceCounter ++;
}
const start = startVertex;
const count = endVertex - startVertex;
geometry.addGroup( start, count, groupCount );
groupCount ++;
}
geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );
geometry.setAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) );
return geometry;
}
function ensureString( buffer ) {
if ( typeof buffer !== 'string' ) {
return THREE.LoaderUtils.decodeText( new Uint8Array( buffer ) );
}
return buffer;
}
function ensureBinary( buffer ) {
if ( typeof buffer === 'string' ) {
const array_buffer = new Uint8Array( buffer.length );
for ( let i = 0; i < buffer.length; i ++ ) {
array_buffer[ i ] = buffer.charCodeAt( i ) & 0xff; // implicitly assumes little-endian
}
return array_buffer.buffer || array_buffer;
} else {
return buffer;
}
} // start
const binData = ensureBinary( data );
return isBinary( binData ) ? parseBinary( binData ) : parseASCII( ensureString( data ) );
}
}
THREE.STLLoader = STLLoader;
} )();
<!DOCTYPE html>
<html lang="en">
<head>
<title>test</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
color: #cccccc;
font-family: Monospace;
font-size: 13px;
text-align: center;
background-color: #999999;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="./js/three.js"></script>
<script src="./js/OrbitControls.js"></script>
<script src="./js/STLLoader.js"></script>
<script>
// if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container, stats;
var camera, scene, renderer;
var mesh, parent_node;
var testObjs = [];
init();
render();
function init() {
container = document.getElementById('container');
camera = new THREE.PerspectiveCamera(27, window.innerWidth / window.innerHeight, 1, 10000);
// camera.position.set(10, 10, 10);
camera.position.set(0, 0, 130);
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.gammaInput = true;
renderer.gammaOutput = true;
//相机控件,方便调整角度
var orbit = new THREE.OrbitControls(camera, renderer.domElement);
// orbit.enableZoom = false;
container.appendChild(renderer.domElement);
// 直线光
var dl = new THREE.DirectionalLight()
dl.position.set(1, -2, 3)
scene.add(dl);
scene.add(new THREE.AmbientLight(0xffffff, 0.2));
//网格
scene.add(new THREE.GridHelper(100, 100, 100, 0x888888, 0x888888))
//加坐标轴
scene.add(new THREE.AxesHelper(1000))
//加载模型
const loader = new THREE.STLLoader();
const material = new THREE.MeshPhongMaterial({ color: 0xAAAAAA, specular: 0x111111, shininess: 200, wireframe: true });
loader.load('./assets/glass.stl', function (geometry) {
const mesh = new THREE.Mesh(geometry, material);
console.log(geometry)
geometry.computeBoundingBox()
// mesh.position.set(0, - 0.37, - 0.6);
mesh.rotation.set(- Math.PI / 2, 0, 0);
mesh.scale.set(0.2, 0.2, 0.2);
mesh.castShadow = true;
mesh.receiveShadow = true;
scene.add(mesh);
//测试下拉伸
//只处理右边x轴的先
//变形基准点,左边区间往左,右边区间往右
let mark = 0,
//拉伸区间,绝对坐标?后续再考虑
range = [20, 50],
//拉伸宽度
width = 23;
//取顶点数据
let attrP = geometry.attributes["position"];
//拷贝一份初始数据
let orignArray = new Float32Array(attrP.array);
for (let i = 0; i < orignArray.length; i += 3) {
let x = orignArray[i];
let [start, end] = range;
//在拉伸区间内的
if (x > start && x < end) {
//均匀偏移,如果失真,考虑修改权重,靠近边界的权重小,远离的权重大
attrP.array[i] = x + Math.abs(x - start) / (end - start) * width;
}
//大于end的所有点便宜固定的量
else if (x >= end) {
attrP.array[i] = x + width
}
}
//更新一下顶点
attrP.needsUpdate = true;
});
}
function render() {
var time = Date.now() * 0.001;
// parent_node.rotation.z = time * 0.5;
renderer.render(scene, camera);
requestAnimationFrame(render);
}
</script>
</body>
</html>
\ No newline at end of file
......@@ -13,6 +13,7 @@
"lib": [
"es5",
"dom",
"es6",
"es2015.promise"
]
},
......
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