Apache多的端口指向不同目录

首先需要修改根目录权限为如下所示
<Directory />
AllowOverride none
Require all granted
</Directory>
然后在httpd.conf末尾添加如下配置即可
Listen 8001

<VirtualHost *:8001>
ServerAdmin xtiqin@163.com
DocumentRoot /opt/lampp/static
ServerName yunp.top:8001
<Directory "/opt/lampp/static">
Options All
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>

NativeScript介绍

NativeScript is how you build cross-platform, native iOS and Android apps without web views. Use Angular, TypeScript or modern JavaScript to get truly native UI and performance while sharing skills and code with the web. Get 100% access to native APIs via JavaScript and reuse of packages from npm, CocoaPods and Gradle. Open source and backed by Progress.

官网链接

指定TypeScript的编译目标

TypeScript的默认编译目标是ES3,当在代码中使用了ES5的特性时(如:set和get方法),就会无法编译,此时需要指明编译目标为ES5,具体操作方式就是在命令行中加入如下参数
--target ES5
则完整示例如下
tsc --target ES5 app.ts

HTML5实现本地预览图片

在传统的图片预览编程中,必须上传到服务器,获取到服务器生成的图片路径,才能在页面中呈现该图片,但是在HTML5中就不需要这么麻烦了,HTML5提供了文件读取的API,可以直接读取本机图片,然后用img标签将该图片呈现出来即可。 效果演示:http://plter.github.io/learnjs/ReadLocalFile/ 示例代码如下
/**
 * Created by plter on 10/10/16.
 */
(function () {

    var fileInput = $("input[type='file']");
    var btnBrowse = $("#btn-browse");
    btnBrowse.button();

    var fileReader = new FileReader();
    fileReader.onload = function (e) {
        var img = new Image();
        img.src = this.result;
        img.style.display = "block";
        document.body.appendChild(img);
    };

    btnBrowse.click(function () {
        fileInput.click();
    });

    fileInput.on("change", function (e) {
        if (this.files && this.files.length) {
            fileReader.readAsDataURL(this.files[0]);
        }
    });
})();

Linux nohup命令后台运行程序

  1. 将一个程序后台运行使用的是nohup命令,比如,把turnserver运行于后台,则命令如下
    nohup turnserver &
    其中,nohup命令的用途是在终端关闭后turnserver不再关闭,而 & 符号的作用是将该程序后台运行。
  2. 使用ps命令可以查看所有正在运行的进程及其id,命令示例如下:
    ps -A
    也可以使用如下方式只呈现turnserver的进程信息
    ps -A | grep turnserver
  3. 如果想关闭,则使用kill命令进行关闭,如果通过上述命令获得的进程号为29116,则对应的关闭命令如下:
    kill 29116

在Electron中使用jQuery

在electron中使用jQuery会出现一些问题,问题原因请参考 https://github.com/electron/electron/issues/254 想要解决该问题,需要换一种方式来引入jQuery文件,代码如下所示:
window.$ = window.jQuery = require("./node_modules/jqueryui/external/jquery/jquery.js");

颜色渐变之JavaScript实现

虽然css3新增的动画效果非常好用,但是仍然有很多场合是使用JavaScript控制动画效果的,而颜色渐变的动画效果的实现很意思。 原理:
  1. 将传入的颜色值提取出rgb通道
  2. 分别对3个通道执行动画操作
  3. 将3个通道的合成为一个颜色值应用在指定的对象上
效果演示:http://plter.github.io/learnjs/ChangeColor/
/**
 * Created by plter on 8/20/16.
 */

(function () {

    var start = 0xff0000;
    var end = 0x00ff00;
    var frames = 60;
    var frameIndex = 0;
    var color = start;
    var speedRed = (getRedChannel(end) - getRedChannel(start)) / frames;
    var speedGreen = (getGreenChannel(end) - getGreenChannel(start)) / frames;
    var speedBlue = (getBlueChannel(end) - getBlueChannel(start)) / frames;
    var greenChannel = getGreenChannel(start);
    var redChannel = getRedChannel(start);
    var blueChannel = getBlueChannel(start);

    function getColorString(red, green, blue) {
        return "rgb(" +
            Math.round(redChannel) + "," +
            Math.round(greenChannel) + "," +
            Math.round(blueChannel) + ")";
    }

    var div = document.createElement("div");
    div.style.width = "200px";
    div.style.height = "200px";
    div.style.backgroundColor = getColorString(getRedChannel(start), getGreenChannel(start), getBlueChannel(start));
    document.body.appendChild(div);

    function getRedChannel(color) {
        return (color & 0xff0000) >> 16;
    }

    function getGreenChannel(color) {
        return (color & 0x00ff00) >> 8;
    }

    function getBlueChannel(color) {
        return color & 0x0000ff;
    }

    function runAnimation() {
        frameIndex++;
        if (frameIndex <= frames) {
            requestAnimationFrame(runAnimation);
        } else {
            color = end;
            blueChannel = getBlueChannel(end);
            redChannel = getRedChannel(end);
            greenChannel = getGreenChannel(end);
        }

        var colorString = getColorString(redChannel, greenChannel, blueChannel);
        div.style.backgroundColor = colorString;

        console.log(frameIndex, colorString);

        blueChannel += speedBlue;
        redChannel += speedRed;
        greenChannel += speedGreen;
    }

    div.onclick = runAnimation;

})();

HTML5文件拖放API示例

本示例演示如何拖入文件并且打开,效果如下 http://plter.github.io/learnjs/DragAndOpen/index.html 代码如下
/**
 * Created by plter on 6/21/16.
 */


(function () {

    function Main() {
        this.addListeners();
    }

    Main.prototype.addListeners = function () {
        (function (self) {
            document.ondragover = function (event) {
                event.preventDefault();
            };

            document.ondrop = function (event) {
                event.preventDefault();

                var files = event.dataTransfer.files;
                if (files && files.length) {
                    var file = files[0];

                    var reader = new FileReader();
                    reader.onload = function () {
                        self.showContent(reader.result, file.type);
                    };
                    reader.readAsDataURL(file);
                }
            };
        })(this);
    };

    Main.prototype.createNewCurrentElement = function (tagName, src) {
        if (this._currentElement) {
            document.body.removeChild(this._currentElement);
        }
        this._currentElement = document.createElement(tagName);
        this._currentElement.src = src;
        document.body.appendChild(this._currentElement);
        return this._currentElement;
    };


    Main.prototype.showContent = function (url, type) {
        var e;

        switch (type) {
            case "image/png":
            case "image/jpeg":
                this.createNewCurrentElement("img", url);
                break;
            case "audio/mp3":
                e = this.createNewCurrentElement("audio", url);
                e.controls = true;
                e.autoplay = true;
                break;
            case "video/mp4":
                e = this.createNewCurrentElement("video", url);
                e.controls = true;
                e.autoplay = true;
                break;
        }
    };

    new Main();
})();

使用HTML5技术将视频变成黑白的

原理是不直接将video呈现出来,而是使用canvas不断的绘制video的画面,绘制中将video画面的像素调成黑白的。 效果如:http://plter.github.io/learnjs/PlayVideo/CanvasVideo.html js源码如下:
/**
 * Created by plter on 6/19/16.
 */

(function () {

    function App() {

        this._videoMetaLoaded = false;

        /**
         *
         * @type {HTMLCanvasElement}
         * @private
         */
        this._canvas = document.getElementById("canvas");
        this._context2d = this._canvas.getContext("2d");

        this._memoryCanvas = document.createElement("canvas");
        this._memoryCanvas.width = 1000;
        this._memoryCanvas.height = 800;
        this._memoryContext2d = this._memoryCanvas.getContext("2d");

        this.createVideo();

        this.render();
    }


    App.prototype.render = function () {

        if (this._videoMetaLoaded) {
            this._memoryContext2d.drawImage(this._video, 0, 0);

            /**
             *
             * @type {ImageData}
             */
            this._tmpImageData = this._memoryContext2d.getImageData(0, 0, this._video.videoWidth, this._video.videoHeight);
            for (var i = 0; i < this._tmpImageData.data.length; i += 4) {
                this._tmpPixelValue = (this._tmpImageData.data[i] + this._tmpImageData.data[i + 1] + this._tmpImageData.data[i + 2]) / 3;
                this._videoFrame.data[i] = this._tmpPixelValue;
                this._videoFrame.data[i + 1] = this._tmpPixelValue;
                this._videoFrame.data[i + 2] = this._tmpPixelValue;
                this._videoFrame.data[i + 3] = 255;
            }

            this._context2d.putImageData(this._tmpImageData, 0, 0);
            this._context2d.putImageData(this._videoFrame, this._video.videoWidth, 0);
        }

        requestAnimationFrame(this.render.bind(this));
    };

    App.prototype.createVideo = function () {
        /**
         *
         * @type {HTMLVideoElement}
         * @private
         */
        this._video = document.createElement("video");
        this._video.autoplay = true;
        this._video.src = "video.mp4";
        this._video.addEventListener("loadedmetadata", function (e) {
            //create video image
            this._videoFrame = this._context2d.createImageData(this._video.videoWidth, this._video.videoHeight);

            this._videoMetaLoaded = true;
        }.bind(this));
    };

    new App();
})();

理解色相

如果把颜色用hsl来表示的话,其中的h就是色相,本示例代码用来演示色相的变化 
演示效果请看:http://plter.github.io/learnjs/ColorHue/index.html 
源码代码如下:
/**
 * Created by plter on 6/7/16.
 */

class Main {

    canvas:HTMLCanvasElement;
    context2d:CanvasRenderingContext2D;
    WIDTH:number = 550;
    HEIGHT:number = 400;
    colorH:number = 0;
    msgContainer:HTMLDivElement;

    constructor() {

        this.msgContainer = document.createElement('div') as HTMLDivElement;
        document.body.appendChild(this.msgContainer);

        this.canvas = document.createElement('canvas') as HTMLCanvasElement;
        this.canvas.width = this.WIDTH;
        this.canvas.height = this.HEIGHT;
        document.body.appendChild(this.canvas);

        this.context2d = this.canvas.getContext('2d');

        this.render();
    }

    formatToRadix16(num:number):String {
        return num < 16 ? "0" + num.toString(16) : num.toString(16);
    }

    makeColorByH(h):string {
        h %= 360;

        var r:number = 0;
        var g:number = 0;
        var b:number = 0;

        if (h <= 60) {
            r = 255;
            g = 255 * h / 60;
        } else if (h <= 120) {
            r = 255 * (120 - h) / 60;
            g = 255;
        } else if (h <= 180) {
            g = 255;
            b = 255 * (h - 120) / 60;
        } else if (h <= 240) {
            g = 255 * (240 - h) / 60;
            b = 255;
        } else if (h <= 300) {
            b = 255;
            r = 255 * (h - 240) / 60;
        } else {
            b = 255 * (360 - h) / 60;
            r = 255;
        }

        r = Math.round(r);
        g = Math.round(g);
        b = Math.round(b);

        var color = "#" + this.formatToRadix16(r) + this.formatToRadix16(g) + this.formatToRadix16(b);
        this.msgContainer.innerHTML = "颜色:" + color + "" + "色相:" + Math.round(h);
        return color;
    }

    render() {
        this.context2d.save();
        this.context2d.fillStyle = this.makeColorByH(this.colorH);
        this.context2d.fillRect(0, 0, this.WIDTH, this.HEIGHT);
        this.context2d.restore();

        this.colorH += 0.6;

        requestAnimationFrame(this.render.bind(this));
    }
}
new Main();