在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 = "颜色:<span style="width: 100px; display: inline-block;">" + color + "</span>" + "色相:" + 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();