如何

改善API文档


需要贡献

许多人要求改进API文档。这是一项主要任务,其中包含许多需要添加注释的文件。注释对于将来的代码开发和维护非常有用,但是现在它们变得更加有用,因为“ TYPEDOC”可以以正确的格式读取注释,并为Babylon.js使用的类,属性和方法生成API文档。 。正如您在新的API文档中所看到的那样,核心团队已经努力做到这一点。需要志愿者来添加评论,因此即使您只有时间来做几个文件,也请做志愿者。

如何贡献

您需要根据以下给出的格式添加适当的注释。检查注释中是否有错误,并在所有内容均经过验证后提交PR。

  1. 从github 分支并克隆Babylon.js ;
  2. 在文件夹Tools / Gulp中安装npm with npm install,然后使用gulp安装npm install -g gulp@4.0.0;
  3. 通过添加注释从src文件夹中编辑文件;
  4. 执行gulp typedoc-check以验证评论;
  5. 不要提交对babylon.d.ts文件的任何更改。使用discard删除变化;
  6. 验证后提交PR

尽管上述步骤将验证注释,但不允许您查看结果。由于您不想影响您在Babylon.js本地克隆中的任何内容,因此需要在Babylon.js文件夹之外创建一个新文件夹。然后,您可以按照以下步骤生成可见的评论结果。

编辑和验证src文件夹中以及PR之前的文件之后:

  1. 在新文件夹中,使用$ npm install typedoc; 安装typedoc 。
  2. 将src文件夹复制到新文件夹中;
  3. tsconfig.json文件从src文件夹复制到新文件夹;
  4. 在新文件夹中创建一个名为documents的文件夹;
  5. 在新文件夹中,用于$ typedoc --out documents src从src创建文档
  6. 在documents文件夹中找到并打开index.html以检查结果。请注意,这些显示的外观与Babylon.js API文档的网页不完全相同,但足够紧密以进行检查。

评论格式

以下是带有示例的各种代码实体的注释格式说明。

注释立即出现在实体前面,并具有纯注释的形式

/**
* comment
* more comments
*/

或评论加关键@words

或评论加关键@words 其次是
@param 参数名称然后参数说明
@returns 函数返回的描述
@see 链接到另一个站点或页面很有用时的URL
@ignore 被忽略的原因

枚举

定义一组命名常量

用简单的注释描述ENUM的用途及其定义的常量

/**
* Defines the list of states available for a task inside an AssetsManager
*/
export enum AssetTaskState {
    /**
     * Initialization
     */
    INIT,
    /**
     * Running
     */
    RUNNING,
    /**
     * Done
     */
    DONE,
    /**
     * Error
     */
    ERROR
}
/**
* Specifies the level of max blur that should be applied when using the depth of field effect
*/
export enum DepthOfFieldEffectBlurLevel {
    /**
     * Subtle blur
     */
    Low,
    /**
     * Medium blur
     */
    Medium,
    /**
     * Large blur
     */
    High
};

模板,其中包含构造函数以及定义对象的公共,私有和受保护的属性以及方法

A定义注释以描述CLASS的目的

/**
 * Defines a HemisphericLight object that simulates the ambient environment light
 * so the passed direction is the light reflection direction, not the incoming direction
 */
export class HemisphericLight extends Light {
    //All the parts defining the class in here
}
/**
 * Define an abstract asset task used with a {BABYLON.AssetsManager} class to load assets into a scene
 */
 export abstract class AbstractAssetTask {
     //All the parts defining the class in here
}

建设者

这将创建该类的实例

没有参数

创建注释以描述构造函数

export class MapperManager {
    //class properties

    /**
     * Creates a new MapperManager object to manage the different implemented mappers
     */
    constructor() {
this._mappers = {
    "html": new HTMLMapper(),
    "json": new JSONMapper(),
    "dom": new DOMMapper()
}
    }
}

带参数

A创建注释以描述CONSTRUCTOR,并为每个参数使用@param。@param之后的第一项必须是参数名称,然后是进一步的注释。此外,如果将构造函数的任何成员声明为public,则应在参数列表中的成员之前重复注释。

没有公共参数

为构造函数创建和@param注释。

/**
 * Create a new Model loader
 * @param _viewer the viewer using this model loader
 */
constructor(private _viewer: AbstractViewer) {
    this._loaders = [];
    this._loadId = 0;
}
/**
 * Creates a Solid Particle object
 * Don't create particles manually, use instead the Solid Particle System internal tools like _addParticle()
 * @param particleIndex is the particle index in the Solid Particle System pool. It's also the particle identifier  
 * @param positionIndex is the starting index of the particle vertices in the SPS "positions" array
 * @param indiceIndex is the starting index of the particle indices in the SPS "indices" array
 * @param model is a reference to the model shape on what the particle is designed.  
 * @param shapeId is the model shape identifier in the SPS
 * @param idxInShape is the index of the particle in the current model (ex: the 10th box of addShape(box, 30))
 * @param modelBoundingInfo is the reference to the model BoundingInfo used for intersection computations
 */
constructor(particleIndex: number, positionIndex: number, indiceIndex: number, model: Nullable<ModelShape>, shapeId: number, idxInShape: number, sps: SolidParticleSystem, modelBoundingInfo: Nullable<BoundingInfo> = null) {
    this.idx = particleIndex;
    this._pos = positionIndex;
    this._ind = indiceIndex;
    this._model = <ModelShape>model;
    this.shapeId = shapeId;
    this.idxInShape = idxInShape;
    this._sps = sps;
    if (modelBoundingInfo) {
        this._modelBoundingInfo = modelBoundingInfo;
        this._boundingInfo = new BoundingInfo(modelBoundingInfo.minimum, modelBoundingInfo.maximum);
    }
}

具有公共参数

为构造函数创建和@param注释,并在列表中的任何公共参数之前复制注释

/**
 * Creates a new Action
 * @param triggerOptions the trigger, with or without parameters, for the action
 * @param condition an optional determinant of action 
 */
constructor(

    /**
     * The trigger, with or without parameters, for the action
     */
    public triggerOptions: any, 

    condition?: Condition) {

    if (triggerOptions.parameter) {
                this.trigger = triggerOptions.trigger;
                this._triggerParameter = triggerOptions.parameter;
            } else {
                this.trigger = triggerOptions;
            }

            this._nextActiveAction = this;
            this._condition = condition;
}
/**
 * Creates a new instance ConeParticleEmitter
 * @param radius the radius of the emission cone (1 by default)
 * @param angles the cone base angle (PI by default)
 * @param directionRandomizer defines how much to randomize the particle direction [0-1]
 */
constructor(
    radius = 1, 
    /**
     * The cone base angle (PI by default)
     */
    public angle = Math.PI, 

    /**
     * Defines how much to randomize the particle direction [0-1]
     */
    public directionRandomizer = 0) {

    this.radius = radius;
}

类,构造函数,函数的属性

具有公共变量的公共

用简单的注释来描述属性

/**
 * The groundColor is the light in the opposite direction to the one specified during creation
 * You can think of the diffuse and specular light as coming from the centre of the object in the given direction and the groundColor light in the opposite direction
 */
public groundColor = new Color3(0.0, 0.0, 0.0);

/**
 * The light reflection direction, not the incoming direction
 */
public direction: Vector3

有私有变量的公共

在某些情况下,变量应在使用代码时是公共的,但对用户而言是私有的。此类变量以下划线开头。普通注释对于开发很有用,但是在构建API文档时应忽略该变量。因此使用@ignore

/**
 * Internal only - manager for action
 * @ignore 
 */
public _actionManager: ActionManager;

私人或受保护

在构建API文档时,这些将被自动忽略,并且注释是可选的。

private _worldMatrix: Matrix;

protected _background: string;

类,构造函数或函数的方法

以公开名称公开

没有参数

没有返回值

用简单的注释描述功能

/**
 * Clears the texture
 */
public clear(): void {
    var size = this.getSize();
    this._context.fillRect(0, 0, size.width, size.height);
}
/**
 * Skips to next active action
 */
public skipToNextActiveAction(): void {
    if (this._nextActiveAction._child) {

if (!this._nextActiveAction._child._actionManager) {
    this._nextActiveAction._child._actionManager = this._actionManager;
}

this._nextActiveAction = this._nextActiveAction._child;
    } else {
this._nextActiveAction = this;
    }
}
/**
 * Observable called when all tasks are processed
 */
public onTaskSuccessObservable = new Observable<AbstractAssetTask>();

有回报价值

描述功能并使用@returns的注释

/**
 * Gets the context of the canvas used by the texture
 * @returns the canvas context of the dynamic texture
 */
public getContext(): CanvasRenderingContext2D {
    return this._context;
}
 /**
 * Serializes the current light into a Serialization object 
 * @returns the serialized object
 */
public serialize(): any {
    var serializationObject = SerializationHelper.Serialize(this);

    // Internal working here            

    return serializationObject;
}
/**
 * @returns the current error object (if task is in error)
 */
public get errorObject(): { message?: string; exception?: any; } {
    return this._errorObject;
}

带参数

没有返回值

说明功能的注释,并对每个参数使用@param。@param之后的第一项必须是参数名称,然后是其他注释

/**
 * Execute the current task
 * @param scene defines the scene where you want your assets to be loaded
 * @param onSuccess is a callback called when the task is successfully executed
 * @param onError is a callback called if an error occurs
 */
public run(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {
    this._taskState = AssetTaskState.RUNNING;
    this.runTask(scene, () => {
this.onDoneCallback(onSuccess, onError);
    }, (msg, exception) => {
this.onErrorCallback(onError, msg, exception);
    });
}
/**
 * Draws text onto the texture
 * @param text defines the text to be drawn
 * @param x defines the placement of the text from the left
 * @param y defines the placement of the text from the top when invertY is true and from the bottom when false
 * @param font defines the font to be used with font-style, font-size, font-name 
 * @param color defines the color used for the text
 * @param clearColor defines the color for the canvas, use null to not overwrite canvas 
 * @param invertY defines the direction for the Y axis (default is true - y increases downwards)
 * @param update defines whether texture is immediately update (default is true)  
 */
public drawText(text: string, x: number, y: number, font: string, color: string, clearColor: string, invertY?: boolean, update = true) {
    var size = this.getSize();
    if (clearColor) {
this._context.fillStyle = clearColor;
this._context.fillRect(0, 0, size.width, size.height);
    }

    this._context.font = font;
    if (x === null || x === undefined) {
var textSize = this._context.measureText(text);
x = (size.width - textSize.width) / 2;
    }
    if (y === null || y === undefined) {
var fontSize = parseInt((font.replace(/\D/g, '')));;
y = (size.height / 2) + (fontSize / 3.65);
    }

    this._context.fillStyle = color;
    this._context.fillText(text, x, y);

    if (update) {
this.update(invertY);
    }
}

有回报价值

使用注释描述功能,并使用@param表示每个参数,使用@returns表示函数返回的内容。@param之后的第一项必须是参数名称,然后是进一步的注释。

/**
 * Add a TextFileAssetTask to the list of active tasks
 * @param taskName defines the name of the new task
 * @param url defines the url of the file to load
 * @returns a new TextFileAssetTask object
 */
public addTextFileTask(taskName: string, url: string): TextFileAssetTask {
var task = new TextFileAssetTask(taskName, url);
    this._tasks.push(task);

    return task;
}
 /**
 * Sets the passed Effect object with the HemisphericLight normalized direction and color and the passed name (string).  
 * @param effect The effect to update
 * @param lightIndex The index of the light in the effect to update
 * @returns The hemispheric light
 */
public transferToEffect(effect: Effect, lightIndex: string): HemisphericLight {
    var normalizeDirection = Vector3.Normalize(this.direction);
    this._uniformBuffer.updateFloat4("vLightData",
normalizeDirection.x,
normalizeDirection.y,
normalizeDirection.z,
0.0,
lightIndex);
    this._uniformBuffer.updateColor3("vLightGround", this.groundColor.scale(this.intensity), lightIndex);
    return this;
}

以私人名称公开

在某些情况下,某个功能应为使用代码而公开,但对用户不公开。这些名称以下划线开头。普通注释对于开发很有用,但是在构建API文档时应忽略该变量。因此使用@ignore

/**
 * @ignore internal use only
 */
public _getWorldMatrix(): Matrix {
    if (!this._worldMatrix) {
this._worldMatrix = Matrix.Identity();
    }
    return this._worldMatrix;
}
/**
 * @ignore internal use only
 */
public _onPointerEnter(target: Control): boolean {
    if (!super._onPointerEnter(target)) {
return false;
    }

    if (this.pointerEnterAnimation) {
this.pointerEnterAnimation();
    }

    return true;
}

私人或受保护

在构建API文档时,这些将被自动忽略,并且注释是可选的。

protected _buildUniformLayout(): void {
    this._uniformBuffer.addUniform("vLightData", 4);
    this._uniformBuffer.addUniform("vLightDiffuse", 4);
    this._uniformBuffer.addUniform("vLightSpecular", 3);
    this._uniformBuffer.addUniform("vLightGround", 3);
    this._uniformBuffer.addUniform("shadowsInfo", 3);
    this._uniformBuffer.addUniform("depthValues", 2);
    this._uniformBuffer.create();
}
private follow(): void {
    if (!this.target) {
        return;
    }
    this._cartesianCoordinates.x = this.radius * Math.cos(this.alpha) * Math.cos(this.beta);
    this._cartesianCoordinates.y = this.radius * Math.sin(this.beta);
    this._cartesianCoordinates.z = this.radius * Math.sin(this.alpha) * Math.cos(this.beta);

    var targetPosition = this.target.getAbsolutePosition();
    this.position = targetPosition.add(this._cartesianCoordinates);
    this.setTarget(targetPosition);
}
private _drawRoundedRect(context: CanvasRenderingContext2D, offset: number = 0): void {
    var x = this._currentMeasure.left + offset;
    var y = this._currentMeasure.top + offset;
    var width = this._currentMeasure.width - offset * 2;
    var height = this._currentMeasure.height - offset * 2;

    var radius = Math.min(height / 2 - 2, Math.min(width / 2 - 2, this._cornerRadius));

    context.beginPath();
    context.moveTo(x + radius, y);
    context.lineTo(x + width - radius, y);
    context.quadraticCurveTo(x + width, y, x + width, y + radius);
    context.lineTo(x + width, y + height - radius);
    context.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
    context.lineTo(x + radius, y + height);
    context.quadraticCurveTo(x, y + height, x, y + height - radius);
    context.lineTo(x, y + radius);
    context.quadraticCurveTo(x, y, x + radius, y);
    context.closePath();
}