前端

Bootstrap

介绍 #

在jquery基础上的组件框架

移动 #

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

css #

全局
        container
                # div, 唯一包裹容器
        container-fluid
                # 占全部视口
栅格
        # 必须放在row内
        col-xs-1
                # 适用于大于等于分界点的屏幕
                ## 大于12的最后那个col另起一行排列
                # xs < 768px 宽度, container 最大宽度: 自动
                # sm >= 768px, 750px
                # md >= 992px, 970px
                # lg >= 1200px, 1170px
        
        col-md-offset-4
                # 向右偏移4
        col-md-pull-9
                # 向后推9, 改变元素的顺序
        col-md-push-3
        
        o-> mixin
        make-row
                如 .wrapper {.make-row();}
        make-xs-column
        make-sm-column-offset
        make-sm-column-push
        make-sm-column-pull

样式 #

muted
        # 文本颜色
        text-warning
        text-error
        text-info
        text-success
text-left
        # 文本左对齐
        text-center
        text-right
        text-justify
        text-nowrap
        text-lowercase
        text-uppercase
        text-capitalize

bg-primary
        # p
        bg-success
        bg-info
        bg-warning
        bg-danger

success
        # 状态类
        # table行颜色, control-group div
        error
        danger
        warning
        info
        active
has-warning
        # div元素
        # 适用class: control-label, form-control, help-block
        has-error
        has-success
has-feedback
        # div, 

pull-right
        # 任意元素向右浮动
        pull-left
navbar-right
        # 导航条中向右浮动
        navbar-left
clearfix
        # 清除浮动

initialism
        # 缩略语样式, abbr标签
small
        # small标签的样式
lead
        # p标签,突出显示
blockquote-reverse
        # blockquote标签使用, 内容右对齐

disabled
        # btn, input, 只disable样式
        o-> 适用的class
        radio
        radio-inline
        checkbox
        checkbox-inline
        o-> 适用的标签
        fieldset

inline
        # 行内ul, checkbox

center-block
        # 任意元素, 水平居中

show
        # 任意元素显示
        hidden

.sr-only
        # 任意元素, 辅助技术支持的文本, 隐藏当前元素
        sr-only-focusable
                # 元素有焦点时显示出来

visible-xs-block
        # 只对xs屏幕可见
        visible-xs-inline
        visible-xs-inline-block
hidden-xs
        # 对xs屏隐藏
visible-print-block
        # 对打印机可见
        visible-print-inline
        visible-print-inline-block
hidden-print

table #

table
        # table样式
table-responsive
        # div元素,包裹table样式后,创建响应式表格,带有滚动条
table-striped
        # 斑马纹样式
table-bordered
        # 边框圆角
table-hover
        # 行悬停样式
table-condensed
        # 内补减半使更紧凑

form #

form-search
        # form标签中添加,其中有input
        search-query
                # search中的input的样式
form-actions
        # div元素, 内部按钮自动缩进
form-inline
        # 行内表单
form-actions
        # div元素,按钮列表,和表单其它元素对齐
form-horizontal
        # 元素右对齐左浮动的表单
form-group
        # form中的div元素
        form-control
                # input, textarea, select
                o-> 支持的input类型
                text
                password
                datetime
                datetime-local
                date
                month
                time
                week
                number
                email
                url        
                search
                tel        
                color    
        form-control-static
                # p标签,用来代input显示文本  
        control-group
                control-label
                controls
        input-group
                input-group-addon
                        # span
                form-control
                        # 同外
        glyphicon-ok
                # input元素或input-group的div元素后的span, 添加input内的图标
                # 联合使用 class: glyphicon, form-control-feedback; 
                ## 属性 aria-hidden="true"
                glyphicon-warning-sign
                glyphicon-remove
                
checkbox
        # div, label
radio
        # div, label
checkbox-inline
        # div
radio-inline
        # div

controls
        # div元素,为input增加合适的间距, 浮动它们缩减空白,再清除浮动
        controls-row
                # 排一行,增加合适间距

input-mini
        input-small
        input-medium
        input-large
        input-xlarge
        input-xxlarge
input-sm
        # input, select, 高度
        input-lg
form-group-sm
        # class为form-group的div, 高度
        form-group-lg
        
input-prepend
        # 前缀input, 可与input-append组合
        add-on
                # span标签
        btn
        span2
                # input标签
input-append

input-block-level
        # 块级input
uneditable-input
        # span元素模拟不可编辑input

小件 #

btn
        # a, button, input
btn-group
        # div标签 按钮下拉菜单
        dropdown-toggle
                # 要赋加自定义属性data-toggle="dropdown"来关联执行js
        dropdown-menu
                # ul标签
btn-primary
        # 按钮样式
        btn-info
        btn-success
        btn-warning
        btn-danger
        btn-inverse
        btn-link
        btn-default
btn-lg
        btn-sm
        btn-xs
btn-block
        # 块级按钮

span1
        # input元素, select元素
        span2
        span3
        span4
        span5
help-inline
        # span元素,帮助文本
help-block
        # span元素, 块显示帮助

img-rounded
        # img, 图片样式
        img-circle
        img-polaroid
img-responsive
        # img, 图片响应式

caret
        # span标签, 下箭头
close
        # button, 关闭图


list-unstyled
        # 无样式列表
dl-horizontal
        # dl列表水平描述
pre-scrollable
        # pre标签内容滚动
text-overflow
        # 截断改写数据, 可能会垂直显示
text-hide
        # h1, 将元素的文本内容替换为背景图

导航 #

<div role="navigation"
        # 如果作为导航条, 父元素加属性,或者用nav标签
        <ul class="nav nav-tabs"
                # nav-pills 改成胶囊样式
                # nav-stacked 改成垂直
                # nav-justified 自适应宽度
                <li role="presentation" class="active"
                        # disabled
                <li role="presentation" class="dropdown"
                        <a class="dropdown-toggle" role="button" 
                                data-toggle="dropdown"
                                aria-haspopup="true" aria-expanded="false" 
                        <ul class="dropdown-menu"

<nav class="navbar navbar-default"
        # 添加navbar-fixed-top可以冻结到顶部
        ## 设置body{padding-top: 70px;}来使内容不被遮盖
        ## navbar-fixed-bottom, 同样要设置padding-bottom
        ## navbar-static-top 向下滚动就消失
        # navbar-inverse 反色
        <div class="container-fluid"
                <div class="navbar-header"
                        <a class="navbar-brand"
                                <img alt="Brand"
                                        # 图标
                        <button type="button" class="navbar-toggle collapsed"
                                data-toggle="collapse" 
                                data-target="#bs"
                                aria-expanded="false"
                                <span class="icon-bar"
                                        # 放隐藏菜单的
                                <span class="icon-bar"
                                <span class="icon-bar"
                        <a class="navbar-brand"
                <button type="button" class="btn btn-default navbar-btn"
                        # navbar-btn可以上按钮垂直居中
                <p class="navbar-text"
                <div class="collapse navbar-collapse" id="bs"
                        <ul class="nav navbar-nav"
                                <li><a
                        <form class="navbar-form navbar-left" role="search"
                                # navbar-form自动垂直对齐,折叠
                                # navbar-left 让正确对齐,由pull-left mixin而来
                                <div class="form-group"
                                        <input class="form-control"
                                <button class="btn btn-default"
                        <ul class="nav navbar-nav navbar-right"
                        <p class="navbar-text navbar-right"
                                # 不支持多个navbar-right
                                <a class="navbar-link"

<ol class="breadcrumb"
        # 面包屑
        <li
        <li class="active"

图标 #

icon-white
        # 反色为白色
fa-dashboard
        # 配合fa使用                
        fa-fw
                # 小左箭头
fa-lg

默认渲染 #

<h1> ... <h6>
<small>
<p>
<mark>
<del>
<s>
<ins>
<u>
<small>
<strong>
<em>
<abbr>
<address>
<blockquote>
        <p>
        <footer>
                <cite>
<ul>
        <li>
<ol>
        <li>
<dl>
        <dt>
        <dd>
<code>
<kbd>
<pre>
<var>
<samp>
        # 程序输出
属性
        aria-label
                # input元素, 替代label
        aria-labelledby
        title
                # 辅助功能阅读
        aria-describedby
                # input 辅助阅读
        disabled
        readonly

less #

@baseFontSize
        @font-size-base
        # 全局font-size基准,计算出所有页面元素的margin, padding, line-height, 改变bootstrap默认样式
@baseLineHeight
        @line-height-base
        # 同上, line-height基准

案例 #

<div class="table-responsive">
        <table class="table table-striped table-bordered table-hover">
                # table table-condensed 紧凑型表格
                <thead>
                        <tr>
                                <th>标题
                <tbody>
                        <tr class="active">
                                # success info warning danger
</div>

插件 #

scrollspy
    介绍
            监测滚动到目前页面锚点

工具 #

bootInit
    介绍
            检测bootstrap标签语法,不支持扩展插件

Threejs

介绍 #

协调程序加载项的类库

使用 #

var preload = new createjs.LoadQueue(false, "assets/");
var plugin= {
        getPreloadHandlers: function(){
                return{
                        types: ["image"],
                        callback: function(src){
                                var id = src.toLowerCase().split("/").pop().split(".")[0];
                                var img = document.getElementById(id);
                                return {tag: img};
                        }
                }
        }
}
preload.installPlugin(plugin);
preload.loadManifest([
        "Autumn.png",
        "BlueBird.png",
        "Nepal.jpg",
        "Texas.jpg"
]);

api #

涉及dom #

属性
        window.innerWidth
        window.innerHeight
事件
        window.addEventListener('resize', onWindowResize, false);
                function onWindowResize(){
                        camera.aspect = window.innerWidth / window.innerHeight;
                        camera.updateProjectionMatrix();
                        renderer.setSize(window.innerWidth, window.innerHeight);
                        controls.handleResize();
                }
三大组件
    场景(scene)
            var scene = new THREE.Scene();
    相机(camera)
            var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);                                        # 透视相机
    渲染器(renderer)
            var renderer = new THREE.WebGLRenderer();
            renderer.setSize(window.innerWidth, window.innerHeight);
            document.body.appendChild(renderer.domElement);                        # domElement 是画布
            render( scene, camera, renderTarget, forceClear )                        # renderTarget默认是前面设置的renderer  size, forceClear自动清除(设置为false也会清除)
版本
    THREE.VERSION

renderer #

使用
    THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);                # 透视摄像机
    camera.position.x = 0;
    camera.position.y = 0;
    camera.position.z = 600;                                                                # 相机位置
    camera.up.x = 0;
    camera.up.y = 1;
    camera.up.z = 0;                                                                        # 相机"上"的方向
    camera.lookAt({x:0, y:0, z:0});                                                                # 视野中心坐标
    camera.setViewOffset(fullWidth, fullHeight, viewX, viewY, viewWidth, viewHeight)
            # 相机的有效显示部分

WebGLRenderer 
    renderer = new THREE.WebGLRenderer({ antialias: false});
                    # 抗锯齿为false。true时显示更清晰,更耗cpu
            renderer.setClearColorHex( 0x000000, 1);
            renderer.setSize(window.innerWidth, window.innerHeight);
                    # 设置渲染器的宽度和高度
            renderer.autoClear = false;
            renderer.sortObjects = false;
            
            renderTarget = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight);
                    # 设置一个渲染目标
            renderTarget.minFilter = THREE.LinearFilter;
            renderTarget.magFilter = THREE.NearestFilter;
            postBloom = new BloomEffect(renderer, renderTarget, window.innerWidth, window.innerHeight, 4);

            renderer.shadowMapEnabled = true;
                    # 开启显示阴影
                    ## 要显示阴影,还要设置物体castShadow = true; receiveShadow = true;
                    ## shadowMap是一张记录每个像素用于比较遮挡关系的texture
            renderer.shadowMapSoft = true;
                    # 可以使阴影更加平滑,产生更少的锯齿
            renderer.shadowCameraNear = 3;
            renderer.shadowCameraFar = camera.far;
            renderer.shadowCameraFov = 50;
                    # 表示摄像机近平面、远平面、角度的值。在摄像机范围内的物体产生阴影
            renderer.shadowMapBias = 0.0039;
            renderer.shadowMapDarkness = 0.5;
                    # 表示阴影的透明度, 0是完全透明
            renderer.shadowMapWidth = 512;
            renderer.shadowMapHeight = 512;
                    # 指定阴影渲染面的大小
                    ## 根据shadermap原理,阴影需要先绘制在一个缓冲区中,再根据缓冲区计算阴影。这就是缓冲区的大小。

            container = document.createElement('div');
            document.body.appendChild(container);
            container.appendChild(renderer.domElement);

camera #

使用
    camera = new THREE.Camera(60, 1, 1, 6500);
    camera.position.z = -85;
    camera.position.y = 40;
    camera.aspect = window.innerWidth / window.innerHeight;

    cameraTarget = new THREE.Object3D();
            # 相机目标
    cameraTarget.position.y = 10;
    cameraTarget.position.z = 6000;
    camera.target = cameraTarget;

    camera.updateProjectionMatrix();
PerspectiveCamera
    THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);                # 透视摄像机
    camera.position.x = 0;
    camera.position.y = 0;
    camera.position.z = 600;                                                                # 相机位置
    camera.up.x = 0;
    camera.up.y = 1;
    camera.up.z = 0;                                                                        # 相机"上"的方向
    camera.lookAt({x:0, y:0, z:0});                                                                # 视野中心坐标
    camera.setViewOffset(fullWidth, fullHeight, viewX, viewY, viewWidth, viewHeight)
            # 相机的有效显示部分
OrthographicCamera
    OrthographicCamera(left, right, top, bottom, near, far)
            # 左右上下远近
controls
    contorls = new THREE.FirstPersonControls(camera);
    contorls.movementSpeed = 20;                                        # 移动速度
    controls.lookSpeed = 0.05;                                                # 转头速度
    controls.lookVertical = true;                                                # 是否允许抬头或低头
PathControls        # 路径相机
    controls = new THREE.PathControls(camera);
    controls.createDebugPath = true;
            # 是否显示轨道
            ## scene.add(controls.debugPath)来添加显示
    controls.waypoints = [[-500, 0, 0], [0, 200, 0], [500, 0, 0]];
            # 路径的转折点,非转折点用插值来计算
    controls.duration = 28;
            # 轨道的一头到另一头的运动时间(ms), 默认是10 * 1000
    controls.useConstantSpeed =true;
            # 设置为匀速运行
    controls.lookSpeed = 0.06;
            # 转头速度, 默认是0.005。数越大,转头越快
            ##页面显示帧数越快, 转头越快
    controls.lookVertical = true;
            # 是否可以上下转头
    controls.lookHorizontal = true;
            # 是否可以左右转头
    controls.verticalAngleMap = {srcRange: [0, 2 * Math.PI], dstRange:[1.1, 3.8]};
    controls.horizontalAngleMap = {srcRange: [0, 2 * Math.PI], dstRange: [0.3, Math.PI - 0.3]};
    controls.lon = 180;

    controls.init();
    scene.add( controls.animationParent );
            # 用THREE.js提供的Animation类来插值改变相机位置和方向
            ## pathControls类中有initAnimationPath函数将动作转换为关键帧,存到了parentAnimation属性中
            ### THREE.AnimationHandler中的add函数,把scene中的parentAnimation中的关键帧动作键入THREE.JS的动画引擎中。动画引擎会自动在关键帧之间插值,来决定关键帧中物体(如相机)的位置、大小、缩放等。

    function  render(){
            controls.update(delta);
            THREE.AnimationHandler.update(delta);
                    ### 让动画引擎动起来
    }
TrackballControls   # 轨迹球相机
    介绍
            追踪相机, 轨迹球相机
    作用
            控制相机,左键旋转,右键平移,滚轮缩放
    api
            THREE.TrackballControls = function (object, domElement)
                    # object一般是传入相机这个变量
                    # domElement为在哪个div中监听鼠标事件, 默认为document

    controls = new THREE.TrackballControls(camera);
            # 传入相机作为参数来控制相机
    controls.rotateSpeed = 5.0;
            # 旋转的速度
    controls.zoomSpeed = 5;
            # 缩放的速度
    controls.panSpeed = 2;
            # 平移的速度
    controls.noZoom = false;
            # 不允许放大
    controls.noPan = false;
            # 不允许右键摇镜头
    controls.staticMoving = false;
            #  是否静态移动, false时移动镜头会有弹性
    controls.dynamicDampingFactor = 0.3;
            # 阻力系数
            ## 旋转时慢慢停下来是这个系数起作用

    function animate(){
            requestAnimationFrame(animate);
            controls.update();
                    # 完成更新相机属性的工作
            rederer.render(scene, camera);
            stats.update();
    }
FlyControls     # 飞行相机
FirstPersonControls     # 第一人称相机

scene #

使用
    scene = new THREE.Scene();  # 场景
            scene.add(meshCube);
            scene.add(light);

light #

使用
    // light.position.x = x;
    light.position.set(0, 0, 300).normalize();;        
            # 坐标, 向量化为1

    scene.add(light);                        
PointLight  # 点光源
    var light = new THREE.PointLight(0x00FF00);
DirectionalLight    # 方向光
    var dirLight = new THREE.DirectionalLight( 0xffffff, 0.125);
            # 0.125是颜色的密度, 和透明度差不多, 这里表示很淡很淡的白色
    scene.add(dirLight)
AmbientLight    # 环境光
    scene.add(new THREE.AmbientLight(0x111111));
SpotLight   # 聚光灯
    light = new THREE.SpotLight(0xffffff, 1.25);
        light.target.position.set(0, 0, 0);
        light.castShadow = true;
                # 显现阴影,默认不显现
                ## 显现阴影还要对renderer进行设置

object #

mesh #

使用
    var mesh = THREE.Mesh(geometry, material);                                                                # mesh模型
            mesh.position.x= x;
            mesh.rotation.x = rx;
            scene.add(meshCube);
    方法
            mesh1.addChild(mesh2)
                    # mesh2加入mesh1, 组成一个Mesh
            
    api
            mesh.scale.multiplyScalar(0.35)
                    # 让x y z方向缩放系数到原模型的0.35倍
line
    THREE.Line( geometry, material, THREE.LinePieces );                                                # 线
            scene.add(line);
    例子
            var line_material = new THREE.LineBasicMaterial({color: 0x303030}),
            geometry = new THREE.Geometry(),
            floor = -75, step = 25;
            for( var i = 0; i <= 40; i++){
                    geometry.vertices.push(new THREE.Vector3(-500, floor, i * step - 500));
                    geometry.vertices.push(new THREE.Vector3(500, floor, i * step - 500));

                    geometry.vertices.push(new THREE.Vector3(i * step - 500, floor,- 500));
                    geometry.vertices.push(new THREE.Vector3(i * step - 500, floor, 500));
            }
            var line = new THREE.Line(geometry, line_material, THREE.LinePieces);
            scene.add(line);
MorphAnimMesh
    介绍
            动画网格模型
            包含几个动画帧(一极动画模型),通过播放帧来看动画。
            可以设置帧数,播放到哪一帧,顺播还是倒播。
    THREE.MorphAnimMesh = function (geometry, material){
            THREE.Mesh.call(this, geometry, material);
                    # 调用基类构造函数
            this.duration = 1000;
                    # 完成所有帧的时间(milliseconds)
            this.mirroredLoop = false;
                    # 表示镜像循环(是否循环播放)
            this.time = 0;
                    # 当前播放时间
            this.lastKeyframe = 0;
                    # 上一帧
            this.currentKeyframe = 0;
                    # 当前播放的帧
            this.direction = 1;
                    # 表示从前向后播放, -1是从后向前
            this.directionBackwards = false;
                    # 是否倒播
            this.setFrameRange(0, this.geometry.morphTargets.length - 1);
                    # 设置最小帧和最大帧
                    ## 这里开始帧是0, 结束帧是 总帧数 - 1
    }
    方法
            THREE.MorphAnimMesh.prototype.setDirectionForward = function(){
                    this.direction = 1;
                            # 1是前进, -1是后退
                    this.directionBackwords = false;
                            # false表示前进
            }
                    # 计算下一帧是哪一帧时,根据上面两个变量计算
            THREE.MorphAnimMesh.prototype.setDirectionBackward
            THREE.MorphAnimMesh.prototype.setAnimationLabel = function(label, start, end){
                    if( !this.geometry.animations) this.geometry.animation = {};
                    this.geometry.animations[label] = {start: start, end: end};
            }
                    # 设置帧分组标签(为了给每组设置不同的播放速度)
            THREE.MorphAnimMesh.playAnimation('A', 33)
                    # 播放标签为'A'的组动画,帧数(fps)为33帧/秒
            THREE.MorphAnimMesh.prototype.updateAnimation = function(delta
                    # delta表示实际浏览器每次刷新的间隔时间
                    # 作用: 主要更新lastKeyframe

mesh组件 #

geometry #

介绍
        geometry表示形状
THREE.Geometry();
        # 空几何体
        geometry.vertices.push(p1);
        # p1是一个点
        geometry.vertices.push(p2);
        geometry.colors.push( color1, color2 );

属性
        vertices
                # 顶点数组
        colors
        morphColors
                # 加载json模型后存储颜色的地方
        faces        
                # 面数组
                color
        faceVertexUvs
                # 面法线数组
                方法
                        set                # 设置纹理坐标
                                faceVertexUvs[0][2][0].set(0, 0)
                                faceVertexUvs[0][2][1].set(0, 0)
                                faceVertexUvs[0][2][2].set(0, 0)
                                faceVertexUvs[0][2][3].set(0, 0)
                                        # 设置第2个面(顶面)的纹理坐标全部为0,这样就去掉了这个面的纹理坐标
                                        # 第一维表示第几种纹理,第二维表示第几个面,第三维表示第几个顶点的纹理坐标
BufferGeometry
    一般编程中
            物体的形状可以用一个类Geometry来表示
            物体顶点内容如果放到缓冲区中,可以new分配连续的内存
            物体和内存是分离的
    Tree.js中
            物体和内存统一起来,形成了THREE.BufferGeometry
            THREE.BufferGeometry = Buffer + THREE.Geometry
            BufferGeometry是自由度最高的geometry类型
                    自由指定每个顶点的位置、颜色、法线(影响光照)
                    Buffer就是将顶点位置数组、顶点颜色数组等放在一个缓冲区中,加快加载与运行速度。
                            Buffer的这些缓冲区存储在BufferGeometry的属性attributes集合对象里面
                                    # attributes初始化时为空 this.attributes = {};
    api
            var geometry = new THREE.BufferGeometry();
                    # THREE.BufferGeometry = function()
IcosahedronGeometry
    二十面体

    radius = 200
    geometry = new THREE.IcosahedronGeometry(radius, 1);
    faceIndices = ['a', 'b', 'c', 'd'];
    for(var i = 0; i < geometry.faces.length; i++){
            f = geometry.faces[i];
                    # 得到第i个面
            n = (f instanceof THREE.Face3) ? 3 : 4;
                    # 判断每个面由几个点组成
                    # 每个点可以由f.a, f.b, f.c, f.d得到
            for(var j = 0; j < n; j++){
                    vertexIndex = f[faceIndices[j]];
                            # 得到点在geometry中的索引
                    p = geometry.vertices[vertexIndex];
                            # 得到点
                    f.vertexColors[j] = color;
                            # 给面的顶点赋值
                            ## 顶点默认颜色为白色
            }
    }
SphereGeometry
    var geometry = new THREE.SphereGeometry(70, 32, 16);
            # 70是半径, 32和16表示横向和纵向球体由多少线分割
BoxGeometry
    介绍
            原来的CubeGeometry
    长立方体
            THREE.CubeGeometry = function(width, height, depth, widthSegments, heightSegments, depthSegments)
                    # 参数分别表示x y z轴长度和分别在x y z轴上被分成了几份
CylinderGeometry
    圆柱体
            THREE.CylinderGeometry(100, 150, 400);
PlaneGeometry   # 平面
TextGeometry
    介绍
            可以从字体文件中生成字体几何体

    THREE.TextGeometry = function(text, parameters)
            # text是要显示的文字
            # parameters包括
            ## size: <float> 字体大小, 如80号是小字体
            ## height: <float> 厚度
            ## curveSegments: <int> 一条曲线上点的数目, 越多越精细
            ## font: <string> 使用字体的名称
            ## weight: <string> `取值normal或bold, 如果字体中没有bold, 整个程序会崩溃
            ## style: <string> 取值normal或italics(斜体), 没有italics也会崩溃

    使用
            在typeface上转换自己的字体
                    http://typeface.neocracy.org/fonts.html
                    # 要求字体的签名是TrueType或OpenType
                    # 在Convert Font页面选择要转换的字,可以加快转换,也减少生成js文件的大小
            var text3d = new THREE.TextGeometry('要显示的字', {
                    size: 120,
                    height: 30,
                    curveSegments: 3,
                    font: 'simhei',
                    face: 'simhei',
                    weight: 'normal'

    });

material #

使用
    THREE.LineBasicMaterial( parameters );                                                        # 线材质
        参数
                Color:线条的颜色,用16进制来表示,默认的颜色是白色。
                Linewidth:线条的宽度,默认时候1个单位宽度。
                Linecap:线条两端的外观,默认是圆角端点,当线条较粗的时候才看得出效果,如果线条很细,那么你几乎看不出效果了。
                Linejoin:两个线条的连接点处的外观,默认是“round”,表示圆角。
                VertexColors:定义线条材质是否使用顶点颜色,这是一个boolean值。意思是,线条各部分的颜色会根据顶点的颜色来进行插值。(如果关于插值不是很明白,可以QQ问我,QQ在前言中你一定能够找到,嘿嘿,虽然没有明确写出)。
                Fog:定义材质的颜色是否受全局雾效的影响。
                    uniforms: 传入着色器中的固定变量, 如
                            {
                                    scale: {type: 'v2', value: new THREE.Vector2()}
                            }
    THREE.MeshBasicMaterial({color: 0x00ff00});                                                        # mesh材质
MeshBasicMaterial
    介绍
            是three.js中最基本的材质
    功能
            将mesh渲染成线框模式或平面模式
                    # 平面模式指表面渲染比较平整
    api
            new THREE.MeshBasicMaterial({
                    color: 0xffaa00, 
                    transparent: true, 
                            # 标志为true时颜色A分量(alpha)才起作用
                    blending: THREE.AdditiveBlending
                            # 混合方式, 对应OpenGL ES中不同混合方式。表示怎么与背景结合
                            ## OpenGL中有一个颜色缓冲区,存放每次渲染的颜色(目标颜色),新颜色(源颜色)可以与它混合,形成最新的颜色。
                            ## 可以是THREE.NoBlending = 0
                            ### 不混合。直接用新颜色覆盖以前的颜色
                            ## THREE.NormalBlending = 1
                            ### 将源颜色与目标颜色通过透明度正常混合
                            ## THREE.AdditiveBlending = 2
                            ### 加法混合
                            ## THREE.SubtractiveBlending = 3
                            ### 减法混合
                            ## THREE.MultiplyBlending = 4
                            ### 乘法混合
                            ## THREE.CustomBlending = 5
                            ### 自定义混合
            });
            new THREE.MeshBasicMaterial({
                    color: 0xffaa00, 
                    wireframe: true
            });
            new THREE.MeshBasicMaterial({
                    map: texture, 
                    transparent: true
            });

MeshNormalMaterial
    只支持以THREE.FlatShading模式来渲染Mesh, 不支持将Mesh渲染为线框模式

MeshLambertMaterial
    在灰暗或不光滑的表面产生的均匀散射而形成的材质类型。向各个方向均反射光线。如白纸

    new THREE.MeshLambertMaterial({
            color: 0xff6600,                                # 材质的颜色
            ambient: 0xff2200,                                # 受环境光情况
            envMap: textureCube,                                # 环境纹理,会将环境纹理映射到材质身上
            combine: THREE.MixOperation,                # 与环境材质之间的混合方式
            reflectivity: 0.3                                        # 对反射光的反射系数
    })
    new THREE.MeshLambertMaterial({map:texture, transparent: true})
            # 带透明的兰伯特材质, 可以看到球体另一边的颜色
    new THREE.MeshLambertMaterial({color: 0xdddddd, shading: THREE.FlatShading})
            # 灰色,非平滑
    new THREE.MeshLambertMaterial({color: 0xdddddd, shading: THREE.SmoothShading})
            # 灰色,平滑
    new THREE.MeshLambertMaterial({color: 0x666666, emissive: 0xff0000, ambient: 0x000000, shading: THREE.SmoothShading})
            # emissive表示自发光

MeshPhongMaterial
    有明显高光区,适用于湿滑的,表面具有光泽的物体。如: 玻璃,水滴等
    特点
            会产生高光(球某一点在光线下特别亮)
    THREE.MeshPhongMaterial({ambient: 0x030303, color: 0xdddddd, specular: 0x009900, shininess: 30, shading: THREE.FloatShading})

    THREE.MeshPhongMaterial({ambient:0x030303, color:0xdddddd, specular: 0x009900, shininess: 30, shading: THREE.SmoothShading, map: texture, transparent: true})

    THREE.MeshPhongMaterial({color: 0x000000, specular: 0x666666, emissive: 0xff0000, ambient: 0x000000, shininess: 10, shading: THREE.SmoothShading, opacity: 0.9, transparent: true})
MeshDepthMaterial
    支持一些尝试测试的效果
MeshFaceMaterial
    面材质,它是一个材质数组。
    有且仅有一个成员数组materials, 用来存放一组材质。
            这组材质会被geometry的不同面所使用,来做到同一个物体不同面使用不同材质的效果。
            每一个面使用什么材质由geometry中的索引决定
ShaderMaterial
    使用
            material = new THREE.ShaderMaterial({
                    uniforms: uniforms,
                            # 一致变量数组,传递到两个着色器中使用
                    vertexShader: document.getElementById('vertexShader').textContent,
                            # 顶点着色器的代码
                    fragmentShader: document.getElementById('fragmentShader').textContent
                            # 片元着色器代码
            });
            uniforms = {
                    time: {type: 'f', value: 1.0},
                            # 表示时间, f 代表浮点型
                    resolution: {type: 'v2', value: new THREE.Vector2() }
                            # 表示浏览器窗口的宽度和高度,v2代表二维向量
            }                # 该一致变量在绘制过程中不会改变,在顶点shader与片元shader之间用相同名字来共享
                            ## 一致变量在不同图元中会改变
            uniforms.resolution.value.x = window.innerWidth
            uniforms.time.value += 0.005
                            # 通过value改变uniforms中变量的值

texture #

例子
        var geometry = new THREE.PlaneGeometry( 500, 300, 1, 1 );
        geometry.vertices[0].uv = new THREE.Vector2(0,0);
        geometry.vertices[1].uv = new THREE.Vector2(2,0);
        geometry.vertices[2].uv = new THREE.Vector2(2,2);
        geometry.vertices[3].uv = new THREE.Vector2(0,2);
                                        # 平面有4个纹理坐标。由顶点的成员nv表示,nv是一个二维向量,对应到纹理坐标

        var texture = THREE.ImageUtils.loadTexture("textures/a.jpg",null,function(t){});
        var material = new THREE.MeshBasicMaterial({map:texture});

        var mesh = new THREE.Mesh( geometry,material );
        scene.add( mesh );

例子2(canvas)
        var geometry = new THREE.CubeGeometry(150, 150, 150);
        texture = new THREE.Texture(canvas);
                                        # 默认情况下,纹理被均匀地分配到四边形的各个顶点上。
        var material = new THREE.MeshBasicMaterial({map: texture});
        texture.needsUpdate = true;
                                        # 如果canvas中有动画的话,要设置纹理更新。而且每requestAnimationFrame渲染一帧动画,都要对texture.needsUpdate设置一遍true。如果不更新,显示黑色正方体。
                                        ## 黑色正方体原因: js异步运行,canvas绘制时钟需要时间, three.js已经开始渲染图形了,这时候canvas没有绘制完成,就显示材质本身的颜色。
        mesh = new THREE.Mesh(geometry, material);
        scene.add(mesh);
Mapping
    UVMapping
Filter
    LinearFilter
Wrapping
    RepeatWrapping

Color #

THREE.Color()
THREE.Color( 0x444444 );       

Vector3 #

THREE.Vecotor3(4,8,9);                                                                        
THREE.Vector3();
point1.set(4,8,9);

Quaternion #

介绍 
        四元组
api
        THREE.Quaternion = function(x, y, z, w){
                this._x = x || 0;
                this._y = y || 0;
                this._z = z || 0;
                this._w = (w !== undefined) ? w : 1;
        }
        setFromAxisAngle: function(axis, angle)
                # Quaternion的静态方法
                ## axis是向量,表示轴, angle表示弧度
                ## 返回一个四元组
        setFromEuler: function(euler, update)
                # 欧拉角转为四元组
        setFromRotationMatrix: function(m)
                # 把矩阵转为欧拉角

fog #

scene.fog = new THREE.Fog(0x999999, 0.1, 8000);
THREE.Fog = function(hex, near, far)
    # hex为颜色, near是雾开始的地方, far是雾结束的地方

Object3D #

new THREE.Object3D();

Ray #

介绍
        一条射线

ray = new THREE.Ray(camera.position);
        # 传入起点

particle #

particleSystem = new THREE.ParticleSystem(particles, material);

工具 #

utils #

ImageUtils
    loadTextureCube(["", ""]);
ShaderUtils
    var shader = lib["cube"]
UniformsUtils
    clone(shader.uniforms)
GeometryUtils
    merge = function(geometry1, object2/* mesh | geometry */){ ... }
        # geometry1是合成后的对象,第二个是要合并的对象,如果是mesh,就取mesh中的geometry对象

filter #

LinearFilter
NearestFilter

effect #

BloomEffect
    postBloom = new BloomEffect(renderer, renderTarget, window.innerWidth, window.innerHeight, 4);

helper #

o-> 辅助对象一键打开或关闭
        # 将所有辅助对象放到helps数组中
    var help = [];
    helps.push(helper);
    helps.push(faceNormalsHelper);
    helps.push(vertexNormalsHelper);

    window.addEventListener('keydown', onKeyDown, false);

    function setVisible(visible){
            for(var i = 0; i < helps.length; i++){
                    helps[i].visible = visible;
            }
    }

    function onKeyDown(event){
            switch(event.keyCode){
                    case 65: /*A*/
                            setVisible(false);
                            break;
                    case 83: /*S*/
                            setVisible(true);
                            break;
            }
    }
GridHelper
    介绍
            网格辅助类, 绘制网格和网格线颜色

    api
            THREE.GridHelper = function(size, step)
                    # size定义网格正方形边长, step是间隔距离
    使用
            var helper = new THREE.GridHelper(200, 10);
            helper.setColors(0x0000ff, 0x808080);
                    # 第一个是x y z轴颜色, 第二个是其它线条颜色
            helper.position.y = -150;
            scene.add(helper);
BoxHelper
    介绍
            长方体包围盒, 椭圆包围盒, 包围物体用于检查碰撞或辅助设计中表示选中

    使用
            var boxHelper = new THREE.BoxHelper(mesh);
            scene.add(boxHelper);
FaceNormalsHelper
    介绍
            辅助画法线

    api
            FaceNormalsHelper(object, size, hex, linewidth)

    使用
            var faceNormalsHelper = new THREE.FaceNormalsHelper(mesh, 10)
VertexNormalsHelper
    介绍
            辅助画顶点法线
WireframeHelper
    介绍
            将模型转换为线框图

物件 #

Mirror
    介绍
            模拟一个镜子, 放在那, 就反射它前面的景物
            原理是一个平面, 上面的材质不断变化

    o-> api
    THREE.Mirror = function(renderer, camera options)
            renderer是渲染器
            camera最好是透视相机
            options
                    textureWidth
                    textureHeight
                    clipBias
                    color
                    debugMode
    o-> 使用
    var planeGeo = new THREE.PlanneGeometry(100.1, 100.1);
            # 定义平面
    groundMirror = new THREE.Mirror(
            # 定义镜面
            renderer,
            camera,
            {clipBias: 0.003,
            textureWidth: WIDTH,
            textureHeight: HEIGHT,
                    # 表示内存中生成纹理的大小, 最好和屏幕一样大, 否则有mosaic
            debugMode: true}
                    # 开启调试模式会有辅助线
    );

AnimationHandler #

介绍
        主要负责动画的插值和播放

shader #

EffectComposer
    介绍
            用于渲染复杂效果, 例如将一个场景作为纹理传入, 例如用着色器将场景某部分模糊或发光处理
            原理是将画面在一个临时缓冲区先画出来,再将大量效果组合. 一般是用着色器来实现

    使用
            composer = new THREE.EffectComposer(render);
                    # 可以是WEBGLRenderer或CanvasRenderer
                    ## 第二个参数是renderTarget(渲染目标), 没有时默认生成一个
                    ### renderTarget是gpu的内部对象,用来暂存绘制结果
            composer.addPass(new THREE.RenderPass(scene, camera));
                    # 第一个效果通常是RenderPass, 它将渲染结果放入效果链中
                    ## 将结果渲染到gpu的一个帧缓冲区(临时内存)
                    ## pass中有enable成员变量, 只有为true时该pass才起作用
            var effect = new THREE.ShaderPass(THREE.DotScreenShader);
                    # DotScreenShader是examples/js/shaders中的一个
                    ## 它定义了一些一致变量, 每个帧循环操作它们来控制渲染效果
            effect.uniforms['scale'].value = 4;
            composer.addPass(effect);
            var effect = new THREE.ShaderPass(THREE.RGBShiftShader);
            effect.uniforms['amount'].value = 0.0015;
            effect.renderToScreen = true;
            composer.addPass(effect);
                    # 通过addPass加效果到效果链passes中
                    ## 添加顺序重要,后一个效果会作用于前一个效果
            composer.render()
                    # 用它替换render.render(scene, camera)
                    ## 遍历所有通道, 可以传入参数delta, 表示帧与帧之间渡过的时间
    api
        方法
                insertPass(pass, index)
                        # 将某一个通道插入指定的位置
                
        对象
                WebGLRenderTarget(width, height, options)
                        # width是缓冲区的宽度, height是缓冲区的高度, options是参数
                RenderPass(scene, camera, overrideMaterial, clearColor, clearAlpha)
                        # overrideMaterial表示一种材质, 它会覆盖先前设置的材质
                        # clearColor表示每一次帧缓冲绘制前的底色. 用于清除上一次绘制结果
                        # clearAlpha是0或1, 表示清除透明色
                        ## this.enabled属性表示是否启用该pass
                        方法
                                render(renderer, writeBuffer, readBuffer, delta)
                DotScreenShader
                        # 点阵屏效果, 就是报纸中点阵的印刷效果
                RGBShiftShader
                        # 变化颜色分量RGBA, 如A点的R值不显示, 而取B点的R值
                        ## angle表示偏移角度
                        ## amount表示AB的长度. 由于纹理坐标为0到1, 所以0.005会有很多像素
                BloomPass(n)
                        # 像素点膨胀模糊, 像墨水渗出
                        # n 是模糊的程度
                FilmPass(noiseIntensity, scanlinesIntensity, scanlinesCount, grayscale)
                        # 依赖FilmShader.js. 整个场景灰白, 或像lcd荧光屏在屏幕上看到线条等屏幕效果
                        ## noiseIntensity 表示杂点的密度, 值越大杂点越多
                        ## scanlinesIntensity 是扫描线的密度, 值越大扫描线透明度越小
                        ## scanlinesCount 扫描线的数量
                        ## grayscale 如果true表示黑白显示
                        var effectFilm = new THREE.FilmPass(0.35, 0.75, 2048, false);
                        effectFilm.renderToScreen = true;
                        composer.addPass(effectFilm);

projector #

介绍
        包含各种矩阵
        提供重要且简单的函数,进行二维和三维之间的转换

函数
        this.unprojectVector = function(vector, camera)
                # 归一化空间中的点
                ## 归一化是将(-1, -1, -1)到(1, 1, 1)中的某个点还原成三维中的某个点
                # vector是需要归一化的那个点,要归一化成(-1, -1)到(1, 1)空间的点
                ## z 是没有意义的,通常设置为1
                # camera是当前相机,有了相机才能计算当前投影。

扩展 #

性能 #

stats.js #

官网
        https://github.com/mrdoob/stats.js 
视图                        # 点击切换
        fps                # 上一秒的帧数
        ms                # 一帧的毫秒数
使用
        引入stats.js文件
        init中
                var stats = new Stats();
                stats.setMode(1); // 0: fps, 1: ms
                // 将stats的界面对应左上角
                stats.domElement.style.position = 'absolute';
                stats.domElement.style.left = '0px';
                stats.domElement.style.top = '0px';
                document.body.appendChild( stats.domElement );
        treeStart中
                setInterval( function () {
                    stats.begin();
                    // 你的每一帧的代码
                    stats.end();
                }, 1000 / 60 );
        
        或
        init中
                stats = new Stats();
                stats.domElement.style.position = 'absolute';
                stats.domElement.style.left = '0px';
                stats.domElement.style.top = '0px';
        animation中
                stats.update();

动画引擎 #

tween.js #

官网
        https://github.com/sole
介绍
        开源的缓动类
使用
        引入tween.js
        
        initObject之后调用
                function initTween()
                {
                    new TWEEN.Tween( mesh.position)
                            .to( { x: -400 }, 3000 ).repeat( Infinity ).start();
                }
        animation中
                requestAnimationFrame(animation);
                    TWEEN.update();
使用2(雾的far的缓动)
        scene.tween = new TWEEN.Tween(scene.fog, false)
                # 对scene.fog的属性进行操作
                .to({far: 1500}, 6000)
                        # 在6秒种内将scene.fog.far变为1500
                .easing(TWEEN.Easing.Sinusoidal.EaseOut)
                .delay(6000)
                        # 缓动在调用start()后,等待6秒执行
                .onComplete(function(){
                        # 缓动执行完成后(far= 1500后)的回调函数
                }).start();
        
        scene.tweenBack = new TWEEN.Tween(scene.fog, false)
                .delay(2000)
                .to({far: 15000}, 10000)
                .easing(TWEEN.Easing.Sinusoidal.EaseOut);

        scene.tween.chain(scene.tweenBack);

使用3(相机的左右[-500, 500]摇动)
                # 缓动链
        camera.tween = new TWEEN.Tween(camera.position, false)
                .to({x: 500}, 6000)
                .easing(TWEEN.Easing.Sinusoidal.EaseInOut)
                .start();

        camera.tweenBack = new TWEEN.Tween(camera.position, false)
                .easing(TWEEN.Easing.Sinusoidal.EaseInOut)
                .to({x: -500}, 6000)

        camera.tween.chain(camera.tweenBack);
        camera.tweenBack.chain(camera.tween);
                # 两个动画彼此加入了自己的缓动链中,两个动画可以交替执行
TWEEN.Easing
    TWEEN.Easing.Sinusoidal.EaseOut
            # Sinusoidal是正弦曲线的缓动

Loader #

VTKLoader
    var loader = new THREE.VTKLoader();
    loader.addEventListener('load', function(event){
            var geometry = event.content;
            var mesh = new THREE.Mesh(geometry, material);
            mesh.position.setY( - 0.09);
            scene.add(mesh);
    });
    loader.load("models/vtk/bunny.vtk");
JSONLoader
    THREE.JSONLoader.prototype.load = functiono(url, callback, texturePath)
        # url是json文件的地址
        # callback在异步加载完后执行
        # texturePath 纹理路径,没有这个参数时,在当前路径下寻找默认纹理。
BinaryLoader
    使用
            var loader = new THREE.BinaryLoader(true);
            document.body.appendChild(loader.statusDomElement);
                    # 实时显示加载进度

    THREE.BinaryLoader = function(showStatus){
            THREE.Loader.call(this, showStatus);
                    # showStatus表示是否显示进度条
    }
    THREE.BinaryLoader.prototype.load = function(url, callback, texturePath, binaryPath)
            # url是js文件的路径
            # callback 当url中数据加载完成后调用。callback中接收geometry作为参数
            # texturePath 纹理路径,不指定默认放在url同文件夹下,或无纹理。
            # binaryPath 二进制文件的路径,不指定时,根据url地址中的文件来加载。

ColladaLoader
UTF8Loader
    介绍
            导入 google WebGL-Loader格式的高压缩文件
SceneLoader
    介绍
            导入各物体、变换层级、材质、纹理、相机、光源的统一js文件,其中有其它js的url引用

Controls #

见Camara

Detector #

if(! Detector.webgl) Detector.addGetWebGLMessage();

命令 #

convert_obj_three.py
    介绍
            转换obj文件为three.js二进制文件

    python convert_boj_three.py -i alien2.obj -o alien2_bin.js -t binary

着色器 #

介绍
        一种二进制码,在绘制场景之前做一些事。操作在显卡中进行
        对每一个顶点或者片元执行一次着色器,这个操作并行执行
        浏览器底层只支持着色器
        three.js底层是着色器实现的,所以着色器能实现一些three.js无法实现的功能,并能提高three.js的性能
优势与性能
        1. 处理大量数据能力。顶点着色器为每一个顶点确定位置,片元着色器为每个片元确定颜色,数据量非常庞大
                # 一个3d游戏中,一帧几十万个三角形。显示器分辨率1280x1024, 有1310720个像素,每一帧由片元着色器处理。
                ## 每个顶点位置与每个片元颜色几乎同时计算完成
webgl着色器分类
        # 无论在opengl, openes, dx中,都分为顶点着色器和片元着色器
        顶点着色器
                对顶点进行操作,如
                                改变顶点的位置和大小
        片元着色器
                定义屏幕中各点的颜色
                顶点之间的颜色也被一起处理了(插值)

顶点着色器 #

介绍
        接收三维点坐标,处理为二维坐标并输出
        THREE.ShaderMaterial用来定义着色器,着色器材质用着色器程序去控制几何体的顶点和颜色
内置变量
        gl_Position
three.js注入变量
        postion
                # gl_Position = vec4(position, 1.0);
        uv
使用
        <script id="vertexShader" type="x-shader/x-vertex">
                # type只是通用标记为顶点着色器, 不起作用
                void main(){
                        # 类似c语言, 着色器有一个main函数
                        ## 每个顶点在计算时,都会执行main函数
                        gl_Position = vec4(position, 1.0);
                                # 将计算顶点最终位置的结果放在gl_Position中
                                ## 这个位置被称为设备归一化坐标
                                ## gl_Position是默认变量,不必声明就可用,gl_Position一定要赋值
                                ## 顶点着色器最主要作用就是给gl_Position赋值
                                # 作用:
                                ## gl_Position 是相机投影之后的坐标
                                ## 顶点的位置传给position, 通过我们变换, 再赋值给gl_Position
                                ## position中的值来源如mesh.vertices.push(new THREE.Vector3(x, -y, 0))
                }
        </script>
例子
    void main(){
            gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }                # projectionMatrix是投影矩阵,modelViewMatrix是模型视图矩阵

片元着色器 #

介绍
        一个片元对应一个像素,对其输出一个颜色值。
                # 将顶点着色器输出的二维点坐标转化为待处理的像素并传递给片元着色器的过程,称为图元光栅化
        颜色会受到光照, 阴影等影响, 所以片元着色器大多处理这些物理效果

内置变量
        gl_FragColor
                #  输出的一个像素的颜色, vec4类型, 红 绿 蓝 透明
        gl_FragCoord
                #只读变量,保存了片元相对窗口的坐标位置
                ## x, y, z, 1/w   其中z表示片元深度, z越大越深

输入
        varying0, varying1, .... , varyingn
                #用户自定义的易变变量
        uniforms
                # 一致变量. 在js, 顶点着色器, 片元着色器中传递数据, 一次渲染中数据不变
        临时变量

        gl_Position
                # 当前片段(像素)的位置
        gl_FrontFacing
                # 表示每个顶点的大小
        gl_PointSize
                # 当前片段来自三角形的正面还是背面. 该变量只是为了节省性能
        采样器

使用
        <script id="fragmentShader" type="x-shader/x-fragment">
                void main(){
                        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
                                # 表示片元颜色,是RGBA
                }
        </script>
例子
    uniform vec2 resolution;
    uniform float time;
    float a = 1.0, b = 1.0, c = 1.0;
    float t;
    void main (){
            t = time;
            a = abs(sin(t));
            b = abs(cos(t));
            c = abs(sin(t) * cos(t));
            gl_FragColor = vec4(vec3(a, b, c), 1.0);
    }

变量 #

变量分类
        attributes(属性变量)                        # 保存顶点独有数据,如顶点的位置
                attributes vec3 pos;
        uniform(一致变量)                                # 一帧渲染过程中保持不变,如光照方向
                uniform vec3 a;
        varying(易变变量)                                # 比较容易变化的变量,用来在顶点着色器与片元着色器之间传递数据
                varying vec3 a;
类型
        vec2
                # 二维变量
        vec3
                # 三维变量
        vec4
        mat4
        sampler2D
        float
传递关系
        attribute        ->        顶点着色器        ->        varying        ->        图元光栅化        ->        varying        ->        片元着色器        ->        gl_FragColor
        uniform        ->        顶点着色器        ->        gl_Position        ->        图元光栅化        ->        gl_Position        ->        片元着色器        ->        gl_FragColor

思路 #

animate动画 #

window.requestAnimationFrame(callback)
        # 返回id, 传给window.cancelAnimationFrame()取消该次动画
        ## 原理
        ### 传递浏览器回调函数,浏览器调用它更新画面。
        #### 与setInterval()不同之处在于自动控制了时间。对方法调用进行了优化。页面失去选中时动画自动暂停。
        ### 回调函数中 调用了requestAnimation(callback)来循环调用
        ### 通常执行callback函数来开始动画
        # 最原始的是window.setTimout()或者window.setInterval()来更新元素的位置
        ## 更新频率要达到每秒60次
animation
    function threeStart() {
                initThree();
                initCamera();
                initScene();
                initLight();
                initObject();
                animation();

            }
    function animation() {
                //rend+                                                                                                                                                                                                                erer.clear();
                camera.position.x = camera.position.x + 1;
                renderer.render(scene, camera);
                requestAnimationFrame(animation);
            }
    或
    function animation()
                {
                    mesh.position.x-=1;
                    renderer.render(scene, camera);
                    requestAnimationFrame(animation);
                }
render
    function animate(){
            for(var i = 0; i < apps.length; ++i){
                    apps[i].animate();
            }
            requestAnimationFrame(animate);
    }
    function App(...){
            this.animate = function(){
                    render();
                    stats.update();
            }
            function render(){
                    camera.position.x += (mouseX - camera.position.x) * 0.05;
                    camera.position.y += (-mouseY - camera.position.y) * 0.05;
                            # 相机位置随鼠标移动
                            ## mouseX, mouseY为自定义的全局变量
                    camera.lookAt(scene.postion);
                    renderer.render(scene, camera);
            }
    }
render计算
    var mouseX = 0, mouseY = 0;
    document.addEventListener('mousemove', onDocumentMouseMove, false);
    function onDocumentMouseMove(event){
            mouseX = (event.clientX - windowHalfX);
            mouseY = (event.clientY - windowHalfY);
    }
相机旋转
    围绕y轴, 半径1000的圆作圆周运动。
            var timer = 0.0001 * Date.now();
                    # 用当前时间作弧度
            camera.position.x = Math.cos(timer) * 1000;
            camera.position.z = Math.sin(timer) * 1000;
            camera.lookAt(scene.position);
自发光变化
    material.emissive.setHSV(0.54, 1, 0.7 * (0.5 + 0.5 * Math.sin(35 * timer)));
引擎
    组成
            定义与初始化相机
            定义与初始化场景
            定义与初始化光
            定义与初始化渲染器
            定义与初始化性能监视器
            定义鼠标事件, 窗口缩放事件
                    ele.addEventListener('mousedown', ...)
                    ele.addEventListener('mouseup', ...)
                    ele.addEventListener('mousemove', ...)
                    window.addEventListener('resize', ...)
            播放音乐

结构 #

定义App类
    App类将相机,视图,灯光等场景代码封装,为了场景的代码的重用
            # 场景重新new
    例子1, 视口app
            function App( containerId, fullWidth, fullHeight, viewX, viewY, viewWidth, viewHeight )
对象池
    介绍
            用过的对象保存起来,下次需要时重复使用。
            减少频繁创建对象所造成的内存开销和cpu开销
    自定义ObjectPool.js
            function ObjectPool(){
                    this.pool = new Array();
                    this.avail = new Array();
                            # 可用在pool中的索引,pool中对象不在使用,待再利用时放入avail中
            }
            ObjectPool.prototype.createObject = function(){
                    return new Object();
            }
                    #  创建一个多态的对象(如一个豆径),需要重载,
            ObjectPool.prototype.returnObject = function(poolId){
                    this.avail.push(poolId);
            }
                    # 标记为可再利用
            ObjectPool.prototype.getObject = function(){
                    if(this.avail.length ==0){
                            var o = this.createObject();
                            o.poolId = this.pool.length;
                            this.pool.push(o);
                            this.avail.push(o.poolId);
                    }
                    var poolId = this.avail.pop();
                    return this.pool[poolId];
            }

控制 #

resize
    window.addEventListener( 'resize', onWindowResize, false );

    function onWindowResize( event ) {
            SCREEN_WIDTH = window.innerWidth;
            SCREEN_HEIGHT = window.innerHeight;

            renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
            camera.aspect = 0.5 * SCREEN_WIDTH / SCREEN_HEIGHT;
            camera.updateProjectionMatrix();
                    # 产生透视投影矩阵
    }
鼠标射线
    mouse = new THREE.Vector3(0, 0, 1);
    projector = new THREE.Projector();
    ray = new THREE.Ray(camera.position);

    function onDocumentMouseMove(event){
            mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
            mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
                    # 取得鼠标的位置,并将其转换为-1到1之间(归一化)
            ray.direction = projector.unprojectVector(mouse.clone(), camera);
                    # 得到当前鼠标指向二维的点在程序三维中的位置
            ray.direction.subSelf(camera.position).normalize();
                    # 鼠标所在的点送去相机所在的点,得到相机指向鼠标所在点的向量并规范化
            intersects = ray.intersectObject(plane);
                    # 计算射线与模型的相交点数组
    }

场景 #

天空盒
    两种实现
            立方体内部贴纹理
            椭球内部贴纹理
    立方体天空盒
            var r = 'textures/cube/Bridge2';
            var urls = [r + 'posx.jpg', r + 'negx.jpg', r + 'posy.jpg', r + 'negy.jpg', r + 'posz.jpg', r + 'negz.jpg'];
            var textureCube = THREE.ImageUtils.loadTextureCube(urls);
            textureCube.format = THREE.RGBFormat;
                    # 设置图片格式,此格式不需要透明度。节约内存又加快渲染速度
            var shader = THREE.ShaderLib['cube'];
                    # ShaderLib与three.js引擎的一个数组, 其中的cube存放的是立方体贴图的shader
            shader.uniforms['tCube'].value = textureCube;
                    # 纹理给shader着色器
            var material = new THREE.ShaderMaterial({
                    fragmentShader: shader.fragmentShader,
                    vertexShader: shader.vertexShader,
                    uniforms: shader.uniforms,
                    depthWrite: false,
                    side: THREE.BackSide
            });        # 用ShaderMaterial材质包装shader
            mesh = new THREE.Mesh(new THREE.CubeGeometry(100, 100, 100), 22, material);
            sceneCube.add(mesh);

性能 #

概要
        3d设计的精髓在于性能优化
        使用连续内存(如数组)将加速程序运行,不连续内存将增加读取时寻址的时间。
使用
    $(document).ready(
            function(){
                    var container = document.getElementById("container");
                    var app = new MineCraftApp();
                    app.init({container: container});
                            # container属性 表示最后渲染结果外层的div
                    app.run();
            }
    );
App
    介绍
            封装了three.js的一些基本操作, 如
                    创建渲染场景
                    创建相机
                    控制画布缩放
                    鼠标输入
            对three.js进行了面向对象的封装,可以面向对象编程
    函数
            prototype.init(param)
                    # 初始化
                    ## 参数是一个键值对对象
                    ## 一个WebGLRenderer渲染器
                    ## 一个场景 THREE.Scene()
                    ## 一个透视投影 THREE.PerspectiveCamera
                    ## 一个投影器 THREE.Projector()
                    ## 一些鼠标键盘的操作
            prototype.run = function(){
                    # 是渲染循环,会不断被调用
                    ## 调用每一个Sim.Object的update
                    this.update();
                    this.renderer.render(this.scene, this.camera);
                    var that = this;
                    requestAnimationFrame(function(){that.run(); });
                            # run的帧循环
            }
                    
            prototype.addObject
                    # 将Sim.Object对象加入场景中
            prototype.removeObject
                    # 将Sim.Object对象从场景移出

    属性
            renderer
            scene
            camera
            objects
                    # 场景中的所有可视对象
Publisher
    介绍
            一个事件驱动模型
            Sim.Publisher用于
                    记录事件
                    发送事件
                    处理事件
            当事件发生时,它遍历注册的回调列表,调用每一个注册的函数
    函数
            prototype.subscribe = function(message, subscriber, callback)
                    # 发起订阅
                    ## message表示事件名
                    ## 放callback函数的类
                    ## 事件发生时的执行回调函数
            prototype.unsubscribe = function(message, subscriber, callback)
                    # 取消订阅, 删除MessageTypes数组中事件名对就的链表中的一节点
                    ## message值为null, false, undefined时表示删除整个链表(不删除事件)
            prototype.publish = function(message)
                    # 触发事件
    属性
            MessageTypes
                    # 事件与其处理函数的集合
                    ## 形如 messageType['remove'] = [subscriber, callback] -> [subscriber, callback]
                    ### 'remove'是事件名, subscriber是订阅者, callback是订阅者该事件的回调方法
                    ### -> 是链表的意思
Object
    介绍
            sim.js所有封装类的基类, 派生于Sim.Publisher
            可以表示大多数对象(自定义的对象派生于它)
    方法
            prototype.setPosition
                    # 设置object3D对象的位置
            prototype.setScale
            prototype.setVisible
            prototype.update
                    # 更新该对象和它的children
                    ## 在每一次渲染循环时调用,用来产生自己的动画
            prototype.addChild
                    # 添加子对象, 如汽车添加轮子
            prototype.removeChild
    属性
            object3D
                    # 用于保存three.js中的Object3D对象
            children

框架 #

sim #

介绍
    封装three.js大量重复工作
            如设置渲染器,循环重绘,向场景添加Mesh等

physi.js #

介绍
        基于three.js上构建的物理引擎

voxel.js #

介绍
        像素方块游戏开发(minecraft)

例子(来自webgl中文网) #

16万个三角形 #

定义
        o-> triangles = 160000
        o-> 每个三角形有3个顶点, 一个顶点三个float表示,共triangles * 3 * 3个float
                # 用数组存放
        o-> 每个顶点一个法向量,一个三角形3个法向量

赋值
        o-> 所有三角形顶点应该在一个以原点为中心的正方体内
        o-> 三角形的位置在正方体内随机分布
实现
        var geometry = new THREE.BufferGeometry();
        geometry.attributes = {
                        index:{
                                itemSize: 1,
                                array: new Uint16Array(triangles * 3),
                                numItems: triangles * 3
                        },
                                # 索引
                                ## 每一个数组元素的聚会范围是[0, 65535],如果顶点数超过65535,必须通过geometry的offset成员来进一步设置偏移量。
                                ### 65535是16位整型
                        position: {
                                itemSize: 3,
                                array: new Float32Array(triangles * 3 * 3),
                                numItems: triangles * 3 * 3
                        },
                                # 位置
                        normal:{
                                itemSize: 3,
                                array: new Float32Array(triangle * 3 * 3),
                                numItems: triangles * 3 * 3
                        },
                                # 法线
                        color: {
                                itemSize: 3,
                                        # 一项目(元)由几个字节组成
                                array: new Float32Array(triangles * 3 * 3),
                                        # 实际存项目的内存数组
                                numItems: triangles * 3 * 3
                                        # 有多少个项目
                        }
                                # 颜色
                }
                        # Uint16Array分配指定个数的16位无符号整数,寝值为0
                        ##  如果内存紧张,无法分配时则引发异常
                        ## api uint16Array = new Uint16Array(length);
                        ### uint16Array = new Uint16Array(array);
                        # 位置,用Vector3来表示,共有triangles * 3个Vector3
                        ## 每个Vector3有x, y, z三个分量组成, 所以顶点需要triangles * 3 * 3个浮点数表示。
                        # 法线, 一个点对应一个法线, 由x, y, z三个float组成,所以需要triangles    * 3 * 3个float
                        # 颜色, 每个顶点一种颜色,颜色由R, G, B组成,所以需要triangles * 3 * 3个float
                var n = 800, n2 = n/2;
                        # n是正方体的边长
                # 为三角形顶点赋随机值,后计算每个顶点的法向量
                ## positions数组每隔9个是一个三角形
                ## normals数组每隔9个是一个三角形
                # 随机生成颜色,赋给顶点
                ## colors数组每隔9个是一个三角形

                # 给geometry设置索引和偏移量
                ## 索引对应到点,所以有triangles * 3个
                ### 索引从0开始

                # 将BufferGeometry和材质组成mesh

人物粒子 #

生成粒子
        var vertices = geometry.vertices;
        var mesh = new THREE.ParticleSystem(geometry, new THREE.ParticleBasicMaterial({size: 3, color: c}));
        mesh.scale.x = mesh.scale.y = mesh.scale.z = scale;
        mesh.position.x = mesh.position.y = mesh.position.z = position;
渲染
        render()
        mesh.geometry.verticesNeedUpdate = true;
                # 如果不刷新,渲染出来的顶点位置不会改变
        renderer.clear();
        composer.render(0.01);
                # composer为THREE.EffectComposer, 效果组合器

多视口 #

viewport
注意
        视口的坐标为归一化的坐标。左上角是(0, 0), 右下角是(1, 1)
阴影贴图
    canvas画阴影
    阴影纹理
            var shadowTexture= new THREE.Texture(canvas);
            shadowTexture.needsUpdate = true;
                    # 表示纹理是新纹理,在绘制的时候,需要更新到材质上
            var shadowMaterial = new THREE.MeshBasicMaterial({map:shadowTexture});
平面和线框同时显示
    材质wireframe属性只有true和false,所以要创建2个不同材质的相同物体

    THREE.SceneUtils.createMultiMaterialObject(geometry, materials)
            # 传递一个几何体和材质数组,几何体每一个材质组合成一个Mesh, 将Mesh加入组group对象中,返回组对象。

杰克与豆径 #

主要内容
        天空盒
        生长效果
                树叶的生长
                树干变形
                音乐渲染控制生长
        对象池
设计
        鼠标操作
        植物模型
                plant
                        豆干,豆径(leaf3.js),豆叶(leaf5.js)
                        豆径豆叶的材质
        植物生长
        阴天、晴天
                天空材质

        相机动画
音乐
    <audio id="audio" preload="auto" loop>
                    # 预加载音乐并循环播放
            <source src="a.mp3" type="audio/mpeg">
    </audio>

    <script>
            audio = document.getElementById('audio');
            audio.play();
    </script>

流动立方体 #

设计
        从相机到鼠标发射射线, 与射线相交的点,就是选中物体的某个点

我的世界 #

MineCraftApp = function(){
        Sim.App.call(this);
}
MineCraftApp.prototype = new Sim.App();

MineCraftApp.prototype.init = function(param){
        Sim.App.prototype.init.call(this, param);
                # 调用父类的init函数,在父类中初始化相机, 场景等类
        # 性能监视器
        # 天空盒
        # 相机控制类
        # 场景中的一个个小物体
}
$(document).ready(
        function(){
                var container = document.getElementById("container");
                var app = new MineCraftApp();
                app.init({container: container});
                        # container属性 表示最后渲染结果外层的div
                app.run();
        }
);

汽车换装 #

设计
        汽车类
                更换s汽车模型
                更换汽车各部分颜色
        两个相机
        两个场景
        三种光源
        天空盒
        渲染器
        效率监听器
        初始化各种材质
汽车类
        veyron: {
                name: '布加迪威龙',
                url: 'obj/veyron/VeyronNoUv_bin.js',
                author: '布加迪威龙',
                init_rotation: [0, 0, 0],
                scale: 5.5,
                init_materials: 4,
                body_materials: [2],
                object: null,
                buttons: null,
                materials: null
        }

分形 #

uniforms = {
        scale: {type: 'v2', value: new THREE.Vector2()},
        c: {type: 'v2', value: new THREE.Vector2()}
}
material = new THREE.ShaderMaterial({
        uniforms: uniforms,
        vertexShader: document.getElementById('vertexShader').textContent,
        fragmentShader: document.getElementById('fragmentShader').textContent
});
mesh = new THREE.Mesh(new THREE.PlaneGeometry(2.0, 2.0), material);
        # 用 2 * 2 的平面来覆盖浏览器窗口
function onWidowResize(event){
        renderer.setSize(window.innerWidth, window.innerHeight);
        uniforms.scale.value.x = window.innerWidth / 2;
        uniforms.scale.value.y = window.innerHeight;
}

o-> 片元着色器中代码 
uniform vec2 c;
uniform vec2 scale;
void main(void){
        float R = (gl_FragCoord.x - scale.x) / scale.y;
        float I = (gl_FragCoord.y - scale.x) / scale.y;
        float R2 = R * R, I2 = I * I;
        int mm;
        for(int m =0; m < 255; m++){
                I = (R + R) * I + c.y; R = R2 - I2 + c.x; R2 = R * R; I2 = I * I; mm = m;
                if(abs((I2) / (I + R)) > 10.) break;
        }
        if(mm == 254) gl_FragColor = vec4(0., 0., 0., 1.);
        else{
                float a = float(mm);
                a = mod(a, 15.) / 5.;
                gl_FragColor = vec4(max(0., abs(a - 1.5) - .5)),
                        max(0., 1. - abs(a - 1.)),
                        max(0., 1. - abs(a - 2.)),
                        1.);
        }
}

镜像分形 #

介绍
        镜面反射场景

var mirrorMesh = new THREE.Mesh(planeGeo, groundMirror.material);
        # groundMirror.material是THREE.Mirror中定义的材质. 会在每次update(或者render)过程中变化
        ## groundMirror.updateTextureMatrix()
        ## groundMirror.render() 要在update或render前重新渲染镜子的纹理.
        ### 多面镜子时, 如上一个个更新会有干扰, 要用下面代码更新
        ### groundMirror.renderWithMirror(verticalMirror);
        ### verticalMirror.renderWithMirror(groundMirror);
mirrorMesh.add(groundMirror);
mirrorMesh.rotateX(-Math.PI / 2);
scene.add(mirrorMesh);

THREE.ShaderLib['mirror'] = {
        uniforms: {
                mirrorColor: {
                        type: 'c',
                        value: new THREE.Color(0x7F7F7F)
                },
                mirrorSampler: {type: 't', value: null},
                textureMatrix: {type: 'm4', value: new THREE.Matrix4()}
        },
        vertexShader: [
                'uniform mat4 textureMatrix;',
                'varying vec4 mirrorCoord;',
                'void main() {',
                        'vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);',
                        'vec4 worldPosition = modelMatrix * vec4(position, 1.0);',
                        'mirrorCoord = textureMatrix * worldPosition;',
                        'gl_Position = projectionMatrix * mvPosition;',
                '}'
        ].join(''\n),
        fragmentShader: [
                'uniform vec3 mirrorColor;',
                'uniform sampler2D mirrorSampler;',
                'varying vec4 mirrorCoord;',
                'float blendOverlay(float base, float blend){',
                        'return (base < 0.5 ? (2.0 * base * blend) : (1.0 - 2.0 * (1.0 - base) * (1.0 - blend)));',
                '}',
                'void main(){',
                        'vec4 color = texture2DProj(mirrorSampler, mirrorCoord);',
                        'color = vec4(blendOverlay(mirrorColor.r, color.r), blendOverlay(mirrorColor.g, color.g), blendOverlay(mirrorColor.b, mirrorColor.b), 1.0);',
                        'gl_FragColor = color;',
                '}'
        ].join('\n')
};

文字 #

介绍
    原理: 每个要显示的文字生成mesh

小地图 #

介绍
        实现方式1, 在天空直接用正投影相机
                # 实现简单,但渲染效果差,占很多cpu时间(重新绘制一次整个场景)
        实现方式2, 用正投影相机, 但用画大地图的数据来绘制
                # 小地图渲染用很少时间, 因为复杂模型都用小方块或图片代替了

o-> 实现
        camera.lookAt(scene.position);
        camera2.lookA(scene.position);

        renderer2 = new THREE.CanvasRenderer();
                # 两个WebGLRenderer位置重叠时,会渲染不正常(其中一个全黑)
        renderer2.setSize(200, 150);

        renderer.render(scene, camera);
        renderer2.render(scene, camera2);

Angular

介绍 #

google发布
提倡SPA(Single Page Apps), 运行快,一次加载
mvvm

特点 #

前端mvc
双向数据绑定
指令和语义化标签
模块化工具
依赖注入
html模板
常用工具封装,如$http $cookies $location

directive #

内置
    ng-app                      # 声明app名, 在最外层
    ng-submit                   # <form ng-submit="submit()">
    ng-controller
    ng-repeat                   # $index返回当前引用的元素序号,$first, $middle, $last 返回布尔值
    ng-model                    # 绑定当前元素的值
    ng-click
        ng-eventhandler="expression"类的指令可以在所有浏览器中有相同的行为,angular将会屏蔽差异性
        不会在全局命名空间中进行操作,指定的表达式只能访问元素控制器作用域范围内的函数和数据
    ng-bind
    ng-change
    <form ng-submit="aaFunc()"> # 会阻止浏览器默认的提交操作
    ng-dblclick
    ng-show
    ng-hide
    ng-class                    # 可以是类名字符串,空格分隔,可以是类名数组,可以是类名到布尔值的映射
        ng-class="{true: 'active', false: 'inactive'}[isActive]"
        ng-class="{'selected': isSelected, 'car': isCar}"
    ng-style                    # templete中写css不好维护
    ng-src="/images/cats/{{favoriteCat}}"       # src,href属性中简单使用templete,由于浏览器优先并行加载图片和其它内容,angular没有机会拦截到数据绑定请求,所以无法运行
    ng-href
    ng-options
        <select ng-model="x" ng-options="(m.a + ' - ' + m.b) group by m.c for (key, m) in opts">
自定义
    angular.module('CAT.TryDrt', [])
    .directive('hello', function(){
        return {
            restrict: 'E',                          # E: element, A:attribute, C:class, M: comment
            template: '<div>Hello world</div>',     # 标签内容
            replace: true                           # 表示替换原标签
        }
    });

    <hello></hello>

controller #

使用
    通过ng-controller
    router中绑定到动态加载的dom模板片段上
作用
    初始化页面状态
    通过$scope对象暴露数据模型给视图
    监视模型变化,并采取相应动作
嵌套
    原理是$scope的继承

templete #

使用范围
    页面中
    value、class、style属性
表达式                      # 自定义的解释器而非eval执行
    + - * / %
    == != > < >= <=
    && || !
    \^ & |
    $scope中暴露的函数
            # 但不是视图的职责,也不利于测试
    {} []
filter
    使用
        expression | filterName : parameter1 : parameter2 : ...
        可以多次过滤, 11.2 | currency | number:0 会显示$11

    currency                # 数字过滤成美元
    date
    number
    uppercase

    自定义
        homeModule.filter('titleCase', function(){
            var titleCaseFilter = function (input){
                var words = input.split(' ');
                for(var i = 0; i < words.length; i++){
                    words[i] = words[i].charAt(0).toUpperCase() + words[i].slice(1);
                }
                return words.join(' ');
            };
            return titleCaseFilter;
        })

        {{pageHeading | titleCase}}

module #

api
    angular
        module('todoApp', [])       # 数组中传入依赖的外部模块名
        controller('TodoListController', function(){
            var todoList = this;
            todoList.todos = [{a:'a1'},{a:'a2'}];
            todoList.addTode = function(){}
        });
        value()
        service()
        config()
        factory('globalInterceptor', GlobalInterceptor)
        run()
        angular.ent($('.container')).scope().fetchDept()    # 得到element的scope

    o-> 例子
    angular.module('project', ['ngRoute', 'firebase'])
    .value('fbURL', 'https://ng-projects-list.firebaseio.com/')
    .service('fbRef', function(fbURL){return new Firebase(fbURL)
    })
    .service('fbAuth', function...)
    .config(function($routeProvider){
        var resolveProjects = {
            projects: function(Projects){
                return ...
            }
        };
    })

    o->
    xxxModule.config(function ($routeProvider) {
        $routeProvider
        .when('url', {controller: aController, templateUrl: '/path/to/template'})
        .when(..)
        .otherwise(..);
    })

    o->
    someModule.config(function($routeProvider){
        $routeProvider.
            when('url', {controller: aController, templateUrl: '/path/to/template'}).
            when(...) ...
            otherwise(...)
    })

第三方module
    ngCookies
    ngAnimate
    'ngWebSocket'
    angularJwt
    ngclipboard
    react.name
    'flow'
        # 文件上传
    'flowchart'
        # 流程图
    ngTouch
    'angular-carousel'
        # 图片轮换, 可移动端

    FBAngular.name
        # 全屏
    ngMaterial
        # 响应式布局
    ngMdIcons
        # 图标
    angularSocialshare
        # 社交分享
    'pascalprecht.translate'
        # 国际化
    'mdColorPicker'
        # 颜色选择器
    'ngMaterialDateRangePicker'
        # 日期选择器
    mdPickers
        # 日期选择器
    ngSanitize
        # html过滤
    vAccordion
        # 折叠菜单
    'dndLists'
        # 拖拽
    mdDataTable
        # 表格
    fixedTableHeader
        # 表头固定
    'material.components.expansionPanels'
        # 可扩展panel
    'mdSteppers'
        # 步骤图

对象 #

内置
    $rootScope          # 全局作用域
    $scope
    $scope.$watch
        监控属性或函数
        $watch(watchFn, watchAction, deepWatch)
            # angular的表达式(如$scope.xxx)或字符串,函数或表达式,布尔。返回一个函数,用来注销watcher
            # watch中的函数会翻倍执行,来检测模型中的变更已经被完整地进行了传播。会把所有被监控的属性都复制一份,再与当前值比较,看是否发生了变化。
            ## 最多运行10次,如果10次中watchFn的值都发生变化,则可能有循环依赖。
            ## Object.observe()会优化这一点,在支持此函数的地方自动使用它。
        $watch($scope.totalCart, calculate)
            # totalCart是函数
        $watch('items', calculate)
            # items是$scope.items数组
        $watch(function(){
            for($scope.items)
            $scope.bill.totalCartNum = total;
        })
        # 如果监控多个属性可以
        ## 监控这些属性连接起来的表达式
        ## deepWatch这些属性的数组
    $scope.$apply
        # 在所有绑定关系都获得刷新,所有变化都反映到了视图上时懒惰调用,angular定时提醒这个服务
        # 自主修改dom后,只是在$apply中注册并不调用,如果想马上得到angular双向绑定后的结果,要手动调用$apply
        # 触发完digest循环后执行回调
        $scope.$apply(function () {})
    $scope.$digest
        # 只是触发digest循环
        $scope.$digest()

服务 #

内置
    $location
    $log
    $http
    $route
    $routeProvider
    $urlRouterProvider
    $stateProvider
    $locationProvider
    $timeout
    $parse
        var submitHandler = $parse(attrs.ngSubmit)(scope);
        submitHandler();
    $q                  # node q, 并发控制
    $injector           # get注入的模块
创建服务
    provider
        # 创建可配置的服务
    factory
        # 创建不可配置的服务
    service
        # 创建不可配置的服务,比较简单

浏览器插件 #

Batarang
    # 调试

Jquery

对象命名方式 #

var $a = $("#inputID");        

选择器(选择多个时形成数组) #

基本选择器
    $("#inputID");                # id选择
    $("input"); // 标签名,默认获取第一个                # 标签名选择
        $(".className"); // 按样式名定位                # 样式名选择
        $("#div1ID,.myClass,p");                # 选择多个
        $("*");                        # 所有元素
层级选择器
    $("form input")                        # form所有后代元素中input元素的个数
    $("form>input")                        # form子元素中input元素个数,不包括下层元素
    $("form+input")                        # form同级并且下面的第一个input元素
    $("form~input")                        # form同级并且下面的所有input元素
子元素选择器                # 只选择一个
    $("ul li:first")                # ul中第一个子元素li
    $("ul li:last")                        # ul中最后一个子元素li
    $("input:not(:checked)")                        # input标签中所有未选中的元素
    $("table tr:even")                # 表格的奇数行(索引号为偶数)
    $("table tr:odd")                # 表格的偶数行(索引号为奇数)
    $("table tr:eq(1)")                # table中索引号等于1的行
    $("table tr:gt(0)")                # table中索引号大于0的行(不包括0)
    $("table tr:lt(2)")                # table中索引号小于2的行(不包括2)
    $(":header")                        # 匹配如 h1, h2, h3之类的标题元素
内容选择器
    $("div:contains('Join')")                # div 标签的html()中包含'Join'字符串的元素
    $("p:empty")                        # p 标签的html()的内容为空的元素
    $("div:has(p)")                        # div标签中包含p标签的该div标签
    $("p:parent");                        # 非空的p标签元素,即p为父元素
可见性选择器
    $("tr:hidden")                        # 查找隐藏的tr元素,如<tr style="display:none">
                                                                                                    <td>Value 1</td>
                                                                                            </tr>
    $("tr:visible")                        # 查找可见的tr元素
属性选择器
    $("div[id]")                        # 含有id属性的div元素
    $("input[name='newsletter']")                        # 所有name属性是newsletter的input元素
    $("input[name!='newsletter']")                        # 所有name属性不是newsletter的input元素
    $("input[name^='news']")                                # name以'news'开始的input元素
    $("input[name$='leter']")                                # name 以'letter'结尾的input元素
    $("input[name*='news']")                                # name包含'news'的input元素
    $("input[id][name$='leter']")                        # 含有id属性,并且它的name属性是以"letter"结尾的input 元素
子元素选择器
    $("ul li:first-child");                        # 匹配多个ul中的第一个子li元素的li元素集合
    $("ul li:last-child");                                # 匹配多个ul中的最后一个子li元素的li元素集合
    $("ul li:nth-child(1)");                        # 匹配多个ul中的第一个子li元素的li元素集合,注意:标记从1开始(eq 从0开始)
    $("ul li:only-child");                                # 匹配多个ul中的只有一个li元素的li元素集合
表单选择器
    $(":input");        # 所有input元素,包括select textarea button等
    $(":text");        # 所有文本框
    $(":password");    # 密码框
    $(":radio");        # 单选框
    $(":checkbox");    # 复选框
    $(":submit");      # 提交按钮
    $(":image");        # 有提交功能的图片
    $(":reset");        # 重置按钮
    $(":button");      # 按钮,包括<button></button>
    $(":file");        # 文件域
    $(":input:hidden");    # 隐藏域
表单对象属性
    $(":input:enabled");        # 所有可用的input元素
    $(":input:disabled")        # 所有不可用的input元素
    $(":checkbox:checked");    # 所有已选中的checkbox(有checked属性的)元素    $(":checkbox:not(:checked)");  未选中的checkbox
    $(":select option:selected");      # 所有已选中的option元素

基础函数 #

对象访问
    size()          # 同length,返回元素个数
    length          # 同size(),返回元素个数
    get(index)      # 取得一个匹配的元素,从0开始
    each(function(){});                        # 遍历调用该方法的元素数组中的元素,其中的this代表循环中的每一个元素
    
属性
    val()                              # value属性的值,或option元素之间的值
    val("")                        # 设置value的值
    var(["Multiple2", "Multiple3"]);        # 设置select 下option的值
    html()                                # 相当于innerHTML ,同样不支持xml
    attr("")                        # 查找属性
    attr("checked","checked")                # 设置checked属性的值为"checked"
    removeAttr("align");                # 删除属性
    样式类(css)
        addClass("myClass");          # 添加 css 样式
        removeClass("myClass");        # 删除样式
        toggleClass("myClass");        # 切换样式,有变无,无变有
        hasClass("myClass")            # 返回是否有样式

筛选 #

过滤
        eq(index)                                                # 从0开始的第index元素
        is(expr)                                                # 判断元素中是否有符合expr的元素(如"form"),有则返回true,无则返回false
        first()                                                        # 第一个元素
        last()                                                        # 最后一个元素
        filter(expr)                                        # 筛选出符合表达式的集合
        has(expr)                                                # 保留符合expr的元素,去掉不符合的
        not(expr)                                                # 删除符合expr的元素,与has相反
查找
    find("");                      # 搜索所有与指定表达式匹配的后代元素
    children()                      # 取得所有直接子元素,不包含后代
    next()                          # 下一个同级兄弟
    prev();                        # 上一个同级兄弟
    parent("")                      # 含着所有匹配元素的唯一父元素 ,可以用选择器筛选
    parents("p")                    # $("span").parents("p") 每个span的所有是p元素的祖先元素
    nextAll()                      # 之后所有同级兄弟
    prevAll()                      # 之前所有同级兄弟
    siblings()                      # 上下的所有同级兄弟
对象处理
    replaceWith()                  # $("p").replaceWith("<b>Paragraph. </b>"); 替换p节点为自制的粗体节点
    remove()                        # 自己删除自己
    clone()                        # 复制自己  clone(true) 会复制行为
    内部插入
        append(content)            # 元素内部之后添加元素,相当于appendChild()
        prepend(content)            # 元素内部之前添加元素
    外部插入
        after(content)              # 元素同级之后插入
        before(content)            # 元素同级之前插入

事件函数 #

change(fn)              # $("select").change(function(){})  dom 中的onchange事件,元素内容变化时触发
submit(fn)              # $("form").submit(function(){})  选中表单提交时触发,多用于简单检测输入
                # 该事件函数中写return false;代表不提交表单
focus(fn)              # $(":text").focus();      将光标定位到input text表单中
select(fn)              # 选中  如 $(function(){  $(":text").select(); $(":text").focus(); })  页面加载时定位光标到input text文本域,并选中其中的文字        
mouseover(fn)           
mouseout(fn)
mousemove(function(e){})          # 鼠标移动时执行 ie 中已经定义参数,不用传递,直接用event,event.clientX,event.clientY分别得到鼠标的x,y坐标
keyup(fn)                  # ie 中 event.keyCode得到按键编码(firefox 中传递参数e,e.which得到按键编码)
ready(fn)              # $(document).ready(fn) 相当于window.load()事件,但可以写多个

css函数 #

    css("background-color","red");                # 设置style属性
    addClass("myClass")                                # 添加css样式
removeClass("myClass")              # 删除样式
toggleClass("myClass")              # 切换样式,有则删除,无则添加
hasClass("myClass")                # 是否有样式,返回true或false

效果函数 #

slideUp(speed,fn)      # 向上滑动,如$("div").slideUp(200);
slideToggle(speed,fn)  # 滑上滑下切换,如$("div").slideToggle(200);

show(speed,fn)          # 元素从无到有动画显示出来
hide(speed,fn)          # 元素从有到无隐藏起来
toggle(speed,fn)        # 有则无,无则有隐藏、显示元素
fadeIn(speed,fn)        # 淡入显示图片
fadeOut(speed,fn)      # 淡出隐藏图片
animate(styles,speed,easing,callback)                # 自定义动画。只有数字值可创建动画(比如 "margin:30px")

工具函数 #

$.trim(str)            # 去除str字符串开头和结尾的空白

其它函数 #

serialize()            # 序列表单内容为字符串  ajax提交表单时可以        var sendData = $("form").serialize();  给sendData赋值传递表单信息

特殊使用 #

$(document)    # 得到document区  ,可以定义事件,如$(document).mousemove(fn);
                $(document).ready(fn); 相当于$(fn)
$(fn)          # 相当于window.load ,在页面加载时执行,可以写多个,(而window.load只能一个生效,后面的会覆盖前面的)
$("<div id='2013'>ss</idv>");      # 创建一个元素

与dom之间的转换 #

    var $input = $(inputElemenet); // 注意,没有双引号
    var inputElement = $input.get(0); // jquery相当于存储了dom对象的数组 
      var inputElement = $input[0];

ajax #

load(url)                      # $("span").css("color","red").load(url)        无参以get方式提交,返回的值直接作为<span>标签内的文本节点值
load(url,sendData);            # 有参以post的方式提交
                                ## var sendData = {"username":"user","password":"psw"};  sendData的内容用json的语法写
load(url,sendData,function(backData,textStatus,ajax){});          # 加上处理返回值的函数,服务器返回数据时调用此函数
                                                                  ##  其中backData是返回的字符串,textStatus是响应头状态码的值对应的信息(success代表200),ajax是ajax引擎对象
                                                                  ##  <span>标签的文本节点的值仍会被改变
                                                                  ##  可以只写一个参数:backData,参数的名字可以任意更改
$.get(url,sendData,function(backData,textStatus,ajax){});          # 用get方式提交ajax模拟的表单
$.post(url,sendData,function(backData,textStatus,ajax){});          # 用post方式提交ajax模拟的表单 响应头 content-type = "application/x-www-form-urlencoded" 会自动设置好

插件 #

jquery提供
    fixedtableheader
    tablesort
    tools
    ui
    hashchange
        控制浏览器的前进后退到一个页面中(不必刷新)
    easing
        jquery的动画扩展, 比如动画执行的速度曲线
代码
    icanhaz
    mustache
功能
    fileupload
    treeview
        文件
                jquery.treeview.js                        # treeview插件简化板
                jquery.treeview.edit.js                # 可编辑的菜单
                jquery.treeview.css                        # treeview可选使用的样式
                
        使用
                $("#root").treeview({                        # $("#root")是顶层ul元素
                        /* 展开还是收起, 默认为false 展开*/
                        collapsed: true,
                        /* 唯一的, 当前菜单打开的时候其他菜单收缩*/
                        unique: true,
                        /*动态加载菜单(接收json数据)*/
                        url: "source.do"
                });
                        # 动态加载菜单时接收的数据格式为
                                [
                                {
                                "text": "1. Pre Lunch (120 min)",
                                "expanded": true,
                                "classes": "important",
                                "children":
                                [
                                {
                                        "text": "1.1 The State of the Powerdome (30 min)"
                                },
                                        {
                                        "text": "1.2 The Future of jQuery (30 min)"
                                },
                                        {
                                        "text": "1.2 jQuery UI - A step to richnessy (60 min)"
                                }
                                ]
                                },
                                {
                                "text": "2. Lunch  (60 min)"
                                },
                                {
                                "text": "3. After Lunch  (120+ min)",
                                "children":
                                [
                                {
                                        "text": "3.1 jQuery Calendar Success Story (20 min)"
                                },
                                        {
                                        "text": "3.2 jQuery and Ruby Web Frameworks (20 min)"
                                },
                                        {
                                        "text": "3.3 Hey, I Can Do That! (20 min)"
                                },
                                        {
                                        "text": "3.4 Taconite and Form (20 min)"
                                },
                                        {
                                        "text": "3.5 Server-side JavaScript with jQuery and AOLserver (20 min)"
                                },
                                        {
                                        "text": "3.6 The Onion: How to add features without adding features (20 min)",
                                        "id": "36",
                                        "hasChildren": true
                                },
                                        {
                                        "text": "3.7 Visualizations with JavaScript and Canvas (20 min)"
                                },
                                        {
                                        "text": "3.8 ActiveDOM (20 min)"
                                },
                                        {
                                        "text": "3.8 Growing jQuery (20 min)"
                                }
                                ]
                                }
                                ]
                                        # "expanded": true 代表这个结点下的child是展开的。
                                        # 返回的json字符串中的双引号必须是双引号。
                                        ## 初次请求时传递数据 root=source,点击节点申请数据时传递id值,如3.6中有id为36,且hasChildren:true,点击后传递36,我们再据此返回相应json数据。
                        
                
                引入css文件,根据其中的样式对页面进行设置
    validate
        使用
                验证写在<head>中时,要写在页面加载中($(function{}))                # 否则读取<head>时,页面还没有加载,没有表单
                验证完成触发事件
                        失败事件:errorPlacement:function(error,element){}                        # error是错误消息,element是求救消息的js对象 
                        成功事件:success:function(label){}                        # label是显示消息的js对象
                远程验证:发送ajax请求到指定url                # 自动传递验证名与验证值,ie中get请求调用浏览器缓存,所以用户回退字符时不提交。所以用post方式发送请求
                                                                        ## 返回"true"表示成功,"false"表示失败
                        remote:{
                                url:"/outrun/servlet/JqueryValidateServlet",
                                type:"post"
                        }
                简单例子:
                        $("form").validate({
                                debug:true,
                                rules:{
                                        name:{
                                                required:true,
                                                rangelength:[6,12]
                                        },
                                },
                                messages:{
                                        name:{
                                                required:"用户名必填",
                                                rangelength:$.format("用户名长度必须在{0}-{1}之间")
                                        },
                                }
                        });

        兼容:
                不同validate验证框架要求不同的jquery版本
                validate1.5.2配jquery1.3
                
        经验
                默认情况是丢失焦点验证,如果验证失败则 在失败的文本框每次输入数据都会触发onkeyup
                        设置        onkeyup:false
                        
        样式
                默认是class="error"的样式,可以在页面中自定义.error{}样式取代,但是这样除了出错信息的样式修改外,用户输入信息的样式也会修改
                错误信息是以添加<label>标签的形式显示的,所以可以添加<label>标签的样式,如form label{}
    acccordion  下拉菜单
    autocomplete    自动补全(用索引库)
    password Vlidation 密码强度
    prettdate 日期插件
    message 消息框
报表
    highcharts
    jscharts
    am charts
        对象与属性
            对象                # 静态创建
                AmCharts.AmSerialChart()                 序列图
                        属性
                                dataProvider        数据
                                        # 接收json数据
                                categoryAxis        横坐标
                                        属性
                                                labelRotation          横坐标显示名角度
                                                gridPosition                网格的起始位置,"start"表示开始处
                                                dashLength                值为数字,网格中垂直线虚线程度 ,0代表实线
                                categoryField        横坐标显示名(dataProvider数据中的字段名)
                                depth3D        3D图形深度
                                angle                3D图形角度(左上俯角)
                                creditsPosition        未购买之前的商标位置,如"top-right"表示右上。
                        方法
                                write("chartdiv")                # 要绘图div的id属性值
                AmCharts.AmPieChart()                饼图
                AmCharts.AmSerialChart()         雷达图
                AmCharts.AmXYChart()                离散图
                AmCharts.AmLegend()                图例
                AmCharts.ValueAxis()                纵坐标
                        # 通过 AmCharts对象中图对象的addValueAxis()方法给图添加本属性
                        属性
                                title                        纵坐标标题
                                dashLength                值为数字,网格中水平线虚线程度 ,0代表实线
                AmCharts.AmGraph()                图形
                        # 通过 AmCharts对象中图对象的addGraph()方法给图添加本属性
                        属性
                                colorField                值为dataProvider提供数据中的字段名,表示数据在报表中的颜色
                                valueField                值为dataProvider提供数据中的字段名,表示占有数值的多少
                                balloonText                鼠标悬停时气球中的内容,用[[value]], [[description]], [[percents]], [[open]], [[category]] 等标记来引用数据
                                                        也可以用html标签,如: "<span style='font-size:14px'>[[category]]: <b>[[value]]</b></span>"
                                lineAlpha                0或1,代表数据图形是否有边界
                                fillAlpha                代表数据图形是否透明,0为透明
                                
                        AmSerialChart中AGraph的属性
                                type                        数据图形的形状,如"column"代表方块柱状图
                AmCharts.ChartCursor()                光标
                        # 通过 AmCharts对象中图对象的addChartCursor()方法给图添加本属性
                        属性
                                cursorAlpha                0或1,是否显示鼠标跟随线
                                zoomable                true或false 是否可以用鼠标选中来放大
                                categoryBalloonEnabled                        true或false 是否跟随鼠标显示横坐标种类名
            方法2                # 动态创建
                AmCharts.makeChart("" , json);
                        参数1 : 要产生图形的div的id
                        参数2 : json格式的产生条件
                                type : 图形类型,如"pie"
                                dataProvider : 图形数据
                                titleField : 需要显示的种类名对应在dataProvider中的字段名
                                valueField : 需要显示的权重对应在dataProvider中的字段名
                                legend : json数据,图例的产生条件
                                        align : 对齐条件,如"center"
                                        markerType : 图例的形状,如"circle"
        使用1
                var chart;
                var chartData = [ {
                        "country" : "USA",
                        "visits" : 4025,
                        "color" : "#FF0F00"
                }, {
                        "country" : "China",
                        "visits" : 1882,
                        "color" : "#FF6600"
                } ];

                AmCharts.ready(function() {
                                        // SERIAL CHART
                                        chart = new AmCharts.AmSerialChart();
                                        chart.dataProvider = chartData;
                                        chart.categoryField = "country";
                                        // the following two lines makes chart 3D
                                        chart.depth3D = 20;
                                        chart.angle = 30;

                                        // AXES
                                        // category
                                        var categoryAxis = chart.categoryAxis;
                                        categoryAxis.labelRotation = 0;
                                        categoryAxis.gridPosition = "start";

                                        // value
                                        var valueAxis = new AmCharts.ValueAxis();
                                        valueAxis.title = "Visitors";
                                        chart.addValueAxis(valueAxis);

                                        // GRAPH
                                        var graph = new AmCharts.AmGraph();
                                        graph.valueField = "visits";
                                        graph.colorField = "color";
                                        graph.balloonText = "<span style='font-size:14px'>[[category]]: <b>[[value]]</b></span>";
                                        graph.type = "column";
                                        graph.lineAlpha = 0;
                                        graph.fillAlphas = 1;
                                        chart.addGraph(graph);

                                        // CURSOR
                                        var chartCursor = new AmCharts.ChartCursor();
                                        chartCursor.cursorAlpha = 0;
                                        chartCursor.zoomable = false;
                                        chartCursor.categoryBalloonEnabled = false;
                                        chart.addChartCursor(chartCursor);

                                        chart.creditsPosition = "top-right";

                                        // WRITE
                                        chart.write("chartdiv");
                                });
        使用2
                AmCharts.makeChart("chartdiv", {
                        type: "pie",
                        dataProvider: [{
                            "country": "Czech Republic",
                                "litres": 156.9
                        }, {
                            "country": "Ireland",
                                "litres": 131.1
                        }, {
                            "country": "Germany",
                                "litres": 115.8
                        }, {
                            "country": "Australia",
                                "litres": 109.9
                        }, {
                            "country": "Austria",
                                "litres": 108.3
                        }, {
                            "country": "UK",
                                "litres": 65
                        }, {
                            "country": "Belgium",
                                "litres": 50
                        }],
                        titleField: "country",
                        valueField: "litres",
                        balloonText: "[[title]]<br><span style='font-size:14px'><b>[[value]]</b> ([[percents]]%)</span>",
                        legend: {
                            align: "center",
                            markerType: "circle"
                        }

                    });

习惯 #

命名方式规律
        jquery.插件名.功能名.js
        
存储
        网站js/下        分子文件夹存放不同插件的文件

自定义 #

函数
        jQuery.extend(object);          # 直接调用
        jQuery.fn.extend(object);      # 对象调用 $.extend($.fn,{})或$fn.extend({})
例子
        $.extend({
                max : function(a, b) {
                        return a > b ? a : b;
                },
                min : function(a, b) {
                        return a < b ? a : b;
                }
        });
        $.fn.extend({
                max1 : function(a, b) {
                        return a > b ? a : b;
                }
        });
        $.extend($.fn, {
                min1 : function(a, b) {
                        return a < b ? a : b;
                }
        })
        alert($.max(1, 2));
        alert($("html").max1(2, 1));
        alert($("html").min1(1, 2));

问题 #

页面中引用jquery
        只能用<script></script>的形式,而不能用<script/>的形式
        引用的src必须写相对路径
        引用的<script></script>代码必须写在使用之前
        webroot/web-inf/不能用相对路径访问webRoot/下的文件,所以不能包含jquery文件。所以要用${pageContext.request.contextPath}/来访问

jquery mobile #

React

介绍 #

facebook推出的用于build user interfaces 的类库

使用 #

o-> webpack
# webpack.config.js
var webpack = require('webpack')
module.exports = {
        devtool: 'inline-source-map',
        entry: ['webpack/hot/dev-server', __dirname + '/app/main.js'],
        output: {
                path: __dirname + '/build',
                filename: 'bundle.js'
        },
        module: {
                loaders: [
                        {
                                test: /\.(js|jsx)$/,
                                exclude: /node_modules/,
                                loader: 'babel-loader',
                        }
                ]
        },
        plugins: [
                new webpack.HotModuleReplacementPlugin(),
                new webpack.DefinePlugin({
                        'process.env': {
                                NODE_ENV: JSON.stringify('production')
                        }
                })
        ],
        devServer: {
                contentBase: __dirname + '/build',
                historyApiFallback: true,
                inline: true,
                port: 3031,
        }
}

# index.html
<div id="content"></div>
<script src="bundle.js"></script>


o-> browser
# index.html
<script src="build/react.js"></script>
<script src="build/react-dom.js"></script>
<script src="browser.min.js"></script>
<body>
        <div id="example"></div>
        <script type="text/babel">
                ReactDOM.render(
                        <h1>Hello</h1>
                        document.getElementById('example')
                )
        </script>
</body>

api #

ReactDOM
        render
                render(
                        <h1>Hello</h1>
                        document.getElementById('example')
                )
React
        # createClass
        createClass({
                getInitialState () {return {liked: false}},
                handleClick(event) {
                        this.setState({liked: !this.state.liked})
                },
                getDefaultProps () {
                        # 设定属性默认值
                        return {title: 'Hello'}
                },
                propTypes: {
                        # 限定属性的类型
                        title: React.PropTypes.string,isRequired
                },
                render () {return <h1></h1>}
        })
        # createElement
        createElement('h1', {title: 'a'}, 'b')
        # Component
        class List extends React.Component{
                constructor() {super()}
                render() {return ()}
        }
        
this
        # 代表当前标签
        props
                # 属性
                children
                        # 代表所有子节点的text
                        # 没有子节点, 是undefined, 有一个子节点, 是Object, 多个子节点是array
                        # React.Children来处理children
        refs
                # 获取dom
        state
jsx
    介绍
            < 开头解析为html, { 开头解析为js
    例子
    # Profile.jsx
    import React from 'react';
    export default Class Profile extends React.Component {
            constructor (props) {
                    super(props)
                    this.state = {
                            list: [1,2,3],
                            activeIndex: -1
                    }
            },
            activate (index) {
                    this.setState({activeIndex: index})
            },
            render () {
                    const {list, activeIndex} = this.state
                    const lis = list.map((item, index) => {
                            const cls = index === activeIndex ? 'active' : ''
                            return (
                                    <li key={index} className={cls} onClick={() => this.activate(index)}></li>
                            )
                    })
                    return (<ul>{lis}</ul>)
            }
    }


    o->
    <div>
    {/*注释*/}
    {
            names.map((name) => {return <div>{name}</div>})
    }
    </div>

    o-> ref
    <input ref="domNam">

    o-> 事件
    <p onClick={this.handleClick}>

    o-> 属性
    <Profile {...props} name='a'>
            # 后面的覆盖前面的

插件 #

react-big-calendar
    日历

工具 #

JSXTransformer
        # 浏览器中引入,编译jsx
https://babeljs.io/repl/
        # 在线编译jsx

前端

基础 #

AJAX
    # Asynchronous JavaScript and XML
    特点
        异步,提升了用户体验
            局部刷新
        优化传输,减少了数据和带宽
        客户端运行,承担服务器压力
    XMLHttpRequest
        # IE5首次引入
        readyState
            0 未初始化, 1 正在加载, 2 已加载, 3 交互中, 4 完成
        status      # 服务器http状态码
        responseXML     # 响应结果,表示为xml
        responseText    # 响应结果,表示为串
        open("method", url)
        send()
        abort()     # 停止当前请求

        创建
            new ActiveXObject()     # IE
            new XMLHttpRequest()        # firefox
        callback种类
            onSuccess
            onFailure
            onUninitialized
            onLoading
            onLoaded
            onInteractive
            onComplete
            onException
jsonp
    来源
        js在浏览器有同源策略(Same-Origin Policy), 只访问同一域下文件
        <script>标签没有同源策略限制
    原理
        编程时
            客户端注册callback f(), 名字传给服务器
            跨域服务器以文本方式写js函数, 并构造应传的json数据, 函数中调用f(json)
        运行时
            动态添加<script>标签, 请求跨域服务器的js函数

开发框架 #

模块化 #

bower
browserify
require.js
mod.js
        # 百度模块化开发工具
curl.js
        # amd load
sea.js
when
        # amd 加载

测试 #

vConsole    # APP HTML页面显示console按钮,打印请求参数

bigpipe #

介绍
    facebook的页面异步加载框架
    不同于ajax的http调用,需要更多的网线连接。bigpipe与当前页面共用http连接

使用
    前端
        <script src="jquery.js"></script>
        <script src="underscore.js"></script>
        <script src="bigpipe.js"></script>
        <div id="body"></div>
        <script type="text/template" id="tpl_body">
                <div><%=articles%></div>
        </script>
        <script>
        var bigpipe = new Bigpipe()
        bigpipe.ready('articles', function(data) {
                $('#body').html(_.render($('#tpl_body').html(), {articles: data}))
        })
        </script>

    服务器端
        app.get('/profile', function (req, res) {
            if (!cache[layout]) {
                    cache[layout] = fs.readFileSync(path.join(VIEW_FOLDER, layout), 'utf8')
            }
            res.writeHead(200, {'Content-Type': 'text/html'})
            res.write(render(complie(cache[layout])))
            ep.all('users', 'articles', function () {
                    res.end()
            })
            ep.fail(function(err) {
                    res.end()
            })
            db.getData('sql1', function (err, data) {
                    data = err ? {} : data
                    res.write('<script>bigpipe.set("articles", ' + JSON.stringify(data) + ');</script>')
            })
        })

    nodejs使用
        'use strict'
        var BigPipe = require('bigpipe');
        var bigpipe = BigPipe.createServer(8080, {
            pagelets: __dirname + '/pagelets',
                # 页面路径
            dist: __dirname + '/dist'
                # 静态资源路径
        });
        o-> 开启https
        var bigpipe = BigPipe.createServer(443, {
            key: fs.readFileSync(__dirname + '/ssl.key', 'utf-8'),
            cert: fs.readFileSync(__dirname + '/ssl.cert', 'utf-8')
        });
        o-> 嫁接
        var server = require('http').createServer(),
            BigPipe = require('bigpipe');
        var bigpipe = new BIgPipe(server, {options});
        bigpipe.listen(8080, function listening(){
            console.log('listening on port 8080.');
        });

        bigpipe.define('../pagelets', function done(err){
        });        # 合并pagelets, 结束后调用done
        o-> AMD 方式define,与链式编程
        bigpipe.define([Pagelet1, Pagelet2, Pagelet3], function done(err){
        }).define('../more/pagelets', function done(err){});
        # bigpipe.before来添加中间件, remove来删除中间件, disable、enable来跳过和重新启用中间件
        # bigpipe.use来引用插件
api
    BigPipe所有组件继承EventEmitter interface
功能
    pagelets
        var Pagelet = require('bigpipe').Pagelet;
                # var Pagelet = require('pagelet');
        Pagelet.extend({
                js: 'client.js',
                css: 'sidebar.styl',
                view: 'templ.jade',
                name: 'sidebar‘,            // 唯一路由路径
                get: function get(){
                        // 接收get请求时的业务逻辑
                }
        }).on(module);
                # 自动写 module.export部分来导出
        # traverse方法自动调用来递归找additional child pagelets, 要手动指定名称时手动调用

脚手架 #

yeoman
        # google和外部贡献团队合作开发,通过grunt和bower包装一个易用的工作流。由yo(脚手架), grunt(构建), bower(包管理)三部分组成

webpack #

# 介绍
        模块打包

# 命令
        npm i -g webpack
        npm i css-loader style-loader
        webpack ./entry.js bundle.js
                # --progress
                # --colors
                # --watch
                # --module-bind
                ## jade, 'css=style!css'
                webpack ./entry.js bundle.js --module-bind 'css=style!css'
                webpack
                        # use webpack.config.js
        npm i webpack-dev-server -g
        webpack-dev-server
                # --progress --colors
                # --hot 热部署
                # 启动一个express在8080端口
# 配置
    # webpack.config.js

    var webpack = require('webpack')
    var merge = require('webpack-merge')
    var path = require('path')
    var HtmlwebpackPlugin = require('html-webpack-plugin')

    var ROOT_PATH = path.resolve(__dirname)
    var APP_PATH = path.resolve(ROOT_PATH, 'app')
    var BUILD_PATH = path.resolve(ROOT_PATH, 'build')

    var baseWebpackConfig = {
            entry: {
                    app: path.resolve(APP_PATH, 'app.jsx')
            },
            output: {
                    path: BUILD_PATH,
                    filename: '[name].js',
                        chunkFilename: '[id].chunk.js',
                    publicPath: '/',
                            # 浏览器路径
            },
            devtool: 'eval-source-map',
            devServer: {
                contentBase: path.resolve(ROOT_PATH, 'build') ,
                historyApiFallback: true,
                inline: true,
                port: 3031
        }
            resolve: {
                    extensions: ['', '.js', '.vue', 'jsx'],
                        # 这样可以在js import 中加载扩展名
                    fallback: [path.join(__dirname, '../node_modules')],
                    alias: {
                            'src': path.resolve(__dirname, '../src'),
                            'assets': path.resolve(_dirname, '../src/assets'),
                            'components': path.resolve(__dirname, '../src/components')
                    }
            },
            resolveLoader: {
                    fallback: [path.join(__dirname, '../node_modules')]
            },
            module: {
                preLoaders: [
                        {
                                test: /\.jsx?$/,
                                loaders: ['eslint'],
                                include: APP_PATH
                        }
                ]
                    loaders: [
                    {
                            test: /\.vue$/,
                            loader: 'vue'
                    },
                    {
                            test: /\.js$/,
                            loader: 'babel',
                            include: projectRoot,
                            exclude: /node_modules/
                    },
                    {
                            test: /\.json$/,
                            loader: 'json'
                    },
                    {
                            test: /\.html$/,
                            loader: 'vue-html'
                    },
                    {
                            test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
                            loader: 'url',
                            query: {
                                    limit: 10000,
                                    name: path.posix.join('static', 'img/[name].[hash:7].[ext]')
                            }
                    },
                    {
                            test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
                            loader: 'url',
                            query: {
                                    limit: 10000,
                                    name: path.posix.join('static', 'fonts/[name].[hash:7].[ext]')
                            }
                    }
                    ]
            },
        plugins: [
                    new HtmlwebpackPlugin({title: 'a'})
            ]
    }
    module.exports = merge(baseWebpackConfig, {
    })
# 插件
    内置
            # 通过webpack.BannerPlugin获得
            bannerPlugin
    htmlWebpackPlugin
    hotModuleReplacement

grunt #

介绍
        压缩js代码
        合并js文件
        单元测试
        js代码检查
        监控文件修改重启任务
命令
        grunt dist
                # 重新生成dist目录,将编译后的css,js放入
        grunt watch
                # 监测less源码文件改动,自动重新编译为css
        grunt test
                # 运行测试用例
        grunt docs
                # 编译并测试
        grunt 重新构建所有内容并运行测试用例
安装
        # grunt模块以grunt-contrib-开头
        npm i -g grunt grunt-init grunt-cli

例子
    o->
    // Gruntfile.js
    module.exports = function (grunt) {
            grunt.loadNpmTasks('grunt-contrib-clean')
            grunt.loadNpmTasks('grunt-contrib-concat')
            grunt.loadNpmTasks('grunt-contrib-jshint')
            grunt.loadNpmTasks('grunt-contrib-uglify')
            grunt.loadNpmTasks('grunt-replace')

            grunt.initConfig({
                    pkg: grunt.file.readJSON('package.json'),
                    jshint: {
                            all: {
                                    src: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'],
                                    options: {
                                            jshintrc: 'jshint.json'
                                    }
                            }
                    },
                    clean: ['lib'],
                    concat: {
                            htmlhint: {
                                    src: ['src/core.js', 'src/reporter.js', 'src/htmlparser.js', 'src/rules/*.js'],
                                    dest: 'lib/htmlhint.js'
                            }
                    },
                    uglify: {
                            htmlhint: {
                                    options: {
                                            banner: 'a',
                                            beautify: {
                                                    ascii_only: true
                                            }
                                    },
                                    files: {
                                            'lib/<%= pkg.name %>.js': ['<%= concat.htmlhint.dest %>']
                                    }
                            }
                    },
                    relace: {
                            htmlhint: {
                                    files: {'lib/htmlhint.js': 'lib/htmlhint.js'},
                                    options: {
                                            prefix: '@',
                                            variables: {
                                                    'VERSION': '<%= pkg.version %>'
                                            }
                                    }
                            }
                    }
            })
            grunt.registerTask('dev', ['jshint', 'concat'])
            grunt.registerTask('default', ['jshint', 'clean', 'concat', 'uglify', 'replace'])
    }

gulp #

介绍
        自动化构建项目工具
使用
    安装
            npm install --global gulp
                    # npm install --save-dev gulp
            // gulpfile.js 在项目根目录
            var gulp = require('gulp');
            gulp.task('default', function () {
                    // 默认任务代码
            })
    命令
            shell> gulp
                    # gulp <task> <othertask>
插件
    gulp-dom-src
            合并src, 改写html
    gulp-if
    gulp-useref
    gulp-usemin
    gulp-htmlreplace
    google-closure-compiler
    gulp-add-src
    gulp-autoprefixer
    gulp-changed
    gulp-clean
    gulp-clean-css
    gulp-concat
    gulp-concat-css
    gulp-consolidate
    gulp-html-replace
            # 替换html内容
    gulp-htmlmin
    gulp-imagemin
    gulp-less
    gulp-make-css-url-version
    gulp-minify-css
    gulp-rev-append
    gulp-uglify

fis #

介绍
        npm的形式发布
        百度前端工具框架,为前端开发提供底层架构
        所有js文件都用模块书写,一个文件一个模块
                F.module(name, function(require, exports){}, deps);

安装
        npm install -g fis
命令
    fis install                        # 安装模块
    fis release                        # 编译和发布, -h 查看帮助
                            ## 默认会调整资源引用的相对路径到绝对路径
                            ### 不想对路径做调整,可以使用spt工具https://github.com/fouber/spt
                            ## --optimize 或 -o 压缩。--md5对不同静态资源生成版本,也可以配置时间戳
                            ## --dest 或 -d。指定项目发布配置,在执行编译后发布。可以远程发布、发布多个
                            ## --pack 开启打包处理
                            ## -omp 简化 --optimize --md5 --pack
                            ## --watch 或 -w 自动监听文件修改,自动编译
                            ### 该监视考虑了各种嵌入关系, a.css中嵌入了b.css, b修改时会重构这两个文件
                            ### --live 或 -L 。在-w基础上实现,监视到修改后自动刷新浏览器页面
    fis server start                # 启动本地调试服务器
                            ## -p [port] 指定新端口
                            ## --type node 如果没有java, php环境,指定用node环境启动
    fis server stop
    fis server open                # 查看默认产出目录
配置
    o->
    fis.config.set('pack', {
            'pkg/lib.js': [
                    '/lib/mod.js',
                    '/modules/underscore/**.js',
                    'modules/backbone/**.js'
            ]
    });                # 文件合并成lib.js,但是不替换页面中的静态资源引用
                    ## 为了替换引用,使用fis的后端静态资源管理来加载引用,或者用fis-postpackager-simple插件
    o->
    fis.config.set('roadmap.path', [{
            reg: '**.css',
            useSprite: true
    }]);                # 为所有样式资源开启csssprites, 该插件在fis中内置
    fis.config.set('settings.spriter.csssprites.margin', 20);                # 设置图片合并间距
                                                    ## 要在要合并的图片引用路径后面加?__sprite来标识
                                                    ## 被合并图片中的小图, background-position来分图的情况也支持
组件
    yogurt
        基于express 的nodejs框架
    fis-plus
        fis + php + smarty
    gois
        fis + go + margini
    jello
        fis + java + velocity
    pure
        纯前端框架

插件
    fis-postpackager-simple
        介绍
                fis-plus和yogurt不需要
        安装
                npm install -g fis-postpackager-simple
        配置
                // fis-conf.js
                fis.config.set('modules.postpackager', 'simple');                        # 打包时自动更改静态资源引用
                fis.config.set('settings.postpackager.simple.autoCombine', true)        # 开启按页面自动合并css, js文件
    fis-parser-less
        介绍
                less模板
                npm install -g fis-parser-less
        配置
                fis.config.set('modules.parser.less', 'less');
                        # 'modules.parser.less'表示后缀名less的文件,'less'表示用fis-parser-less编译
                fis.config.set('roadmap.ext.less', css)
                        # 将less文件编译为css

写法 #

jquery
prototype
    $()     # 简写document.getElementById()
    $F()    # 返回表单
    $A()    # 参数转成数组对象
mootools
    # 浏览器原生对象扩展
underscore
    # 函数式
underscore-contrib
    # 扩展underscore
ramda
    # 函数式,较正确
lodash
    # 函数式
functional javascript
bilby
    # 函数式库,包含dispatch, 蹦床, monadic, validator等
allong.es
    # 提供函数组合子
sweet
    # 支持宏
zepto
    # 小型jquery
kissy
    # 小型jquery
rxjs
    # 微软开发,将异步流捕获成值的库
tangram
    # 百度前端工具集
qwrap
    # 360前端工具集

解释器 #

typescript
    # 扩展语言
coffeescript
    # 扩展语言
system.js
    介绍
        一个垫片库, 浏览器端l加载es6模块、AMD模块、CommonJS模块 到es5。内部调用traceur

    <script src='system.js'></script>
    <script>
        System.import('./app').then(function(m) {
            # app.js是一个es6模块
            m.f()
        })
    </script>
traceur
    介绍
        在线转换,将ES6代码编译为ES5
    使用
        npm install -g traceur
        traceur /path/es6                                # 运行ES6文件
        traceur --script /path/es6 --out /path/es5        # 转换
babel
    使用
        npm install -g babel-cli
        npm install --save babel-core babel-preset-es2015
        // .babelrc
        {
            "presets": ["es2015"],
            "env": {
                "dev": {
                    # 在NODE_ENV=dev时使用特性
                    "presets": ["react-hmre"]
                }
            }
        }
        babel-node
        babel es6.js
            # babel es6.js -o es5.js
            # babel -d build source -s
            ## -s 是产生source-map
    插件
        babel-preset-react-hmre
            # react热加载
            .babelrc中配置 "react-hmre"
transpiler
    介绍
        google的es6模块加载转为CommonJS或AMD模块加载的工具
    使用
        npm install -g es6-module-transpiler
        compile-modules convert es6.js es5.js
            # compile-modules convert -o out.js file1.js

数据绑定 #

mobx
    # 状态管理,应用(ui, 数据, 服务器)状态可自动获得

终端 #

跨平台 #

atom electron
node-webkit
atom-shell
nw.js
polymer
    # 构建在底层的html扩展,构建跨desktop, mobile等平台的web应用
mpx
    # 小程序框架
wepy
    # 小程序
taro
    # 生成多端
chameleon
uniapp
    # vue到多端
mpvue
    # vue小程序
megalo
    # vue小程序

运行时跨平台 #

微信小程序
华为快应用
react native
rax
weex
fuse
nativeScript
tabris

android #

结构
    applications:                                                        如browser
    application framework(相当于api):                        如window manager
    libraries(库):                                                        如openGL,SQLite
            runtime(运行环境):                                                core libraries + Dalvik VM
    linux kernel(系统api):                                        如wifi Driver
android sdk
    命令
        platform-tools/adb
            adb install *.apk                                      # 当前模拟器中安
    装软件

            adb remount
            adb shell
            su                                                      # 当前模拟器中执
    行linux命令

        tools/emulator-arm @test                                    # 启动一个模拟器
框架
    atlas
        # 阿里开源的android native容器化组件框架
    webview
    litho
        # 声明式ui
    jetpack compose
        # 声明式ui

ios #

componentKit
    # 声明式ui

功能 #

格式 #

uglifyjs2
    # 序列化

模板 #

介绍
    引擎的一个优点就是可以直接把数据渲染到js中使用
优点
    可以把动态页面的模板缓存起来,第一次请求之后,只需要更新数据
        # 应该可以后端nginx缓存静态模板来提高性能

velocity
    # java模板
ejs
hogan.js
handlebars
    # 写法类似anglarjs模板
jstl
    # java模板
less
    # css模板
stylus
    # css模板

swig #

{% autoescape true %} {{ myvar }} {% endautoescape %}

{% block body %} ... {% endblock %}

{% if false %}
{% elseif true%}
{% else %}
{% endif %}

{% extends "./layout.html" %}

{% filter uppercase %} oh hi, {{ name }} {% endfilter %}                # => OH HI, PAUL
{% filter replace(".", "!", 'g") %} Hi. My name is Paul. {% endfilter %}        # => Hi! My name is Paul!

{% for x in obj %}
        {% if loop.first %}<ul>{% endif %}
        <li>{{ loop.index }} - {{ loop.key }}: {{ x }}</li>
        {% if loop.last %}</ul>{% endif %}
{% endfor %}
{% for key, val in arr|reverse %}
{{ key }} -- {{ val }}
{% endfor %}

{% import './formmacros.html' as forms %}
{{ form.input("text", "name") }}                        # => <input type="text" name="name">
{% import "../shared/tags.html" as tags%}
{{ tags.stylesheet('global')}}                        // => <link rel="stylesheet" href="/global.css">

{% include "./partial.html" %}
{% include "./partial.html" with my_obj only%}
{% include "/this/file/does/not/exist" ignore missing%}

{% macro input(type, name, id, label, value, error)%}
        <label for="{{ name }}">{{ label }}</label>
        <input type="{{ type }}" name="{{ name }}" id="{{ id }}" value="{{ value }}" {% if error%} class="error" {% endif %}>
{% endmacro %}
{{ input("text", "fname",  "fname", "First Name", fname.value, fname.errors) }}

{% extends "./foo.html" %}
{% block content %}
        My content
        {% parent %}
{% endblock %}

{% raw %}{{ foobar }}{% endraw %}

{% set foo = "anything!"%}
{{ foo }}

{% spaceless %}
        {% for num in foo %}
        <li>{{ loop.index }}</li>
        {% endfor %}
{% endspaceless %}                                # 除去空白

显示 #

highcharts
nvd3.js
    # svg报表
echarts

d3 #

介绍
    数据可视化, 使用svg, css3
使用
    node
        npm install d3
        //
        var d3 = require('d3'), jsdom = require('jsdom');
        var document = jsdom.jsdom(),
            svg = d3.select(document.body).append('svg');
    web
        <script src="//d3js.org/d3.v3.min.js"></script>
        <script>d3.version</script>
d3对象
    // 选择器
    event
    mouse
    select
    selectAll
    selection
    touch
    touches
    // 过渡
    ease
            # ease对象
    timer
            flush
    interpolate
            # interpolate对象
    interpolateArray
    interpolateHcl
    interpolateHsl
    interpolateLab
    interpolateNumber
    interpolateObject
    interpolateRgb
    interpolateRound
    interpolateString
    interpolateTransform
    interpolateZoom
    interpolators
    transition
    // 数组
    ascending
    bisectLeft
    bisector
    bisectRight
    bisect
    descending
    deviation
    entries
    extent
    keys
    map
    max
    mean
    median
    merge
    min
    nest
    pairs
    permute
    quantile
    range
    set
    shuffle
    sum
    transpose
    values
    variance
    zip
    // 数学
    random
    transform
    // 请求
    csv
    html
    json
    text
    tsv
    xhr
    xml
    // 格式化
    format
    formatPrefix
    requote
    round
    // 本地化
    locale
    // 颜色
    hcl
    hsl
    lab
    rgb
    // 命名空间
    ns
    // 内部
    dispatch
    functor
    rebind
    // 比例尺
    scale
    // 时间
    time
    // 布局
    layout
    // 地理
    geo
    // 几何
    geom
    // 行为
    behavior

效果 #

touch.js
    # 触摸
move.js
    # div运动
swiper
    # 滑动效果

cordova
    # 访问原生设备,如摄像头、麦克风等
egret.js
    # 使用TypeScript的HTML5开发引擎, 一套完整的HTML5游戏开发解决方案
tweenMax
    # 扩展TweenLite, 用于制作html5动画
juliusjs
    # 语音识别
babylon
    # microsoft webgl框架
cubicVR
    # 高性能webgl框架, paladin游戏引擎的一部分
scenejs
    # webgl模型
glge
    # webgl框架
pose
    # mvvm
react-motion
    # mvvm
react-transition-group
    # mvvm

视频 #

ezuikit
    # 萤石sdk, 直播, 监控, 支持多平台

应用框架 #

显示 #

bootstrap
flutter
    # google移动端框架, 声明式ui
extjs
    介绍
        2.0之前是免费的,但有内在泄漏总是
        GPLv3版本后收费

    Sencha
        1.是ExtJS、jQTouch(一个用于手机浏览器的jquery插件) 以及 Raphael(一个网页上绘制矢量图形的js库) 三个项目合并而成的一个开源项目。
        2.Sencha Touch 是全球领先的应用程序开发框架,其设计旨在充分
            利用HTML5、CSS3 和Javascript 来实现最高级别的功能、灵活性和优化。
            Sencha Touch 是针对下一代具有触摸屏设备的跨平台框架。
jquery ui
dojo
    # 语法较难用
easy ui
    文件
        jquery.js
        easyui.js
        easyui-lang-zh_CN.js
        easyui.css
        icon.css
layui
    # 模块化ui
mini ui
    # 收费
wijmo
    # 收费
dwz
    # 卖文档
vaadin
    # apache webkit
foundation
    # 响应式,移动优先
boilerplate
    # h5模板
meteor
    # 融合前后端, 后端node
knockout
    # mvvm, 利于单页应用

jingle
    # 手机
ionic
    # angular手机框架
framework7
    # ios(兼容android)组件
mui
    # 手机
zui
    # 手机,类bootstrap
frozenui
    # 手机

数据可视化 #

highcharts
chart.js
    # api不好用
three.js
d3
    # 太底层, 概念已陈旧
mapbox
    # 地图
echarts
    # 开源
recharts
    # 新出现
v-charts
    # vue+echarts, 饿了么开发
superset
    # apache
antv
    # 蚂蚁金服, 图表丰富
thingJS
    # 3d建模
cityBuilder
    # 3d建模
dataV
    # 收费, 阿里
sugar
    # 收费, 百度
云图
    # 收费, 腾讯
fineReport
    # 收费, 帆软, 大屏
tableau
    # 收费, 大屏
easyV
    # 收费, 袋鼠云

gitDataV
    # https://github.com/HongqingCao/GitDataV

富应用 #

react
angular
    # google开发, mvvm
    ng(core module)包含的核心组件
        directive   # 指令
            ngClick
            ngInclude
            ngRepeat
        service     # 服务, 依赖注入后使用
            $compile
            $http
            $location
        filter      # 过滤器,转换模板数据
            filter
            date
            currency
            lowercase
        function    # 函数
            angular.copy()
            angular.equals()
            angular.element()
    组件
        ngRoute     # url后#地址(hash) 来实现单面路由
            使用
                引入angular-route.js
                依赖注入ngRoute模块
            服务
                $routeParams    # 解析路由参数
                $route          # 构建url, view, controller的关系
                $routeProvider  # 配置
            指令
                ngView      # 路由模板插入视图
        ngAnimate   # 动画效果
            使用
                引入angular-animate.js
                注入ngAnimate
            服务
                $animate    # 触发
            css动画   # 用nganimate结构定义,通过引用css到html模板触发
            js动画    # 用module.animation注册,通过引用css到html模板触发
        ngResource  # 动画
        ngMock      # 动画
        ngTouch     # 触摸
        ngAria      # 帮助制作自定义模块
        ngCookies
riot
ember
vue
    <div id="app">
        {{ message }}
    </div>

    var app = new Vue({
        el: '#app',
        data: {
            message: "hi"
        },
        created: function () {}
    })
backbone

效果 #

three.js

createjs #

# easeljs
    介绍
        处理canvas
    使用
        var stage = new createjs.Stage("canvasName");
        stage.x = 100;
        stage.y = 100;
        var text = new createjs.Text("Hello", "36px Arial", "#777");
        stage.addChild(text);
        stage.update();
# tweenjs
    介绍
        处理动画调整和js属性
    使用
        var circle = new createjs.Shape();
        circle.graphics.beginFill("#FF0000").drawCircle(0, 0, 50);
        stage.addChild(circle);
        createjs.Tween.get(circle, {loop: true})
            .wait(1000)
            .to({scaleX: 0.2, scaleY: 0.2})
            .wait(1000)
            .to({scaleX:1, scaleY:1}, 1000, createjs.Ease.bounceInOut)
        createjs.Ticker.setFPS(20);
        createjs.Ticker.addEventListener("tick", stage);
# soundjs
    介绍
        简化处理音频
    使用
        var displayStatus;
        displayStatus = document.getElementById("status");
        var src = "1.mp3";
        createjs.Sound.alternateExtensions = ["mp3"];
        createjs.Sound.addEventListener("fileload", playSound());
        createjs.Sound.registerSound(src);
        displayStatus.innerHTML = "Waiting for load to complete";

        function playSound(event){
            soundIntance = createjs.Sound.play(event.src);
            displayStatus.innerHTML = "Playing source: " + event.src;
        }

# preloadjs
    介绍
        协调程序加载项的类库
    使用
        var preload = new createjs.LoadQueue(false, "assets/");
        var plugin= {
            getPreloadHandlers: function(){
                return{
                    types: ["image"],
                    callback: function(src){
                        var id = src.toLowerCase().split("/").pop().split(".")[0];
                        var img = document.getElementById(id);
                        return {tag: img};
                    }
                }
            }
        }
        preload.installPlugin(plugin);
        preload.loadManifest([
            "Autumn.png",
            "BlueBird.png",
            "Nepal.jpg",
            "Texas.jpg"
        ]);

游戏 #

cocos2dx
    # 跨平台游戏