LOADING...

Preview

Pen ID
Unlock Campus Themeforest adv

 

Code
Drag mouse to paint.
CSS
body {
    font-family: 'Anaheim', sans-serif;
    padding: 0;
    margin: 0;
    background: #f7f6f2;
    overflow: hidden;
    -webkit-user-select: none;
       -moz-user-select: none;
         -o-user-select: none;
        -ms-user-select: none;
            user-select: none;
}

canvas {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 1;
}

#message {
    color: #e2e2de;
    font-size: 32px;
    text-align: center;
    letter-spacing: 2px;
    position: fixed;
    top: 50%;
    z-index: 0;
    width: 100%;
    margin-top: -0.5em;
    text-shadow: 0 -1px 0 #d3d3d1;
}

.dg.ac {
  z-index: 2;
}
JS
/**
 * requestAnimationFrame
 */
window.requestAnimationFrame = (function(){
    return  window.requestAnimationFrame       ||
            window.webkitRequestAnimationFrame ||
            window.mozRequestAnimationFrame    ||
            window.oRequestAnimationFrame      ||
            window.msRequestAnimationFrame     ||
            function (callback) {
                window.setTimeout(callback, 1000 / 60);
            };
})();


/**
 * Brush
 */
var Brush = (function() {

    /**
     * @constructor
     * @public
     */
    function Brush(x, y, color, size, inkAmount) {
        this.x = x || 0;
        this.y = y || 0;
        if (color !== undefined) this.color = color;
        if (size !== undefined) this.size = size;
        if (inkAmount !== undefined) this.inkAmount = inkAmount;

        this._drops = [];
        this._resetTip();
    }

    Brush.prototype = {
        _SPLASHING_BRUSH_SPEED: 75,

        x:          0,
        y:          0,
        color:      '#000',
        size:       35,
        inkAmount:  7,
        splashing:  true,
        dripping:   true,
        _latestPos: null,
        _strokeId:  null,
        _drops:     null,

        isStroke: function() {
            return Boolean(this._strokeId);
        },

        startStroke: function() {
            if (this.isStroke()) return;
			
            this._resetTip();

            // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript
            this._strokeId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
                var r, v;
                r = Math.random() * 16 | 0;
                v = c === 'x' ? r : (r & 0x3 | 0x8);
                return v.toString(16);
            });
        },

        endStroke: function() {
            this._strokeId = this._latestPos = null;
        },

        render: function(ctx, x, y) {
            var isStroke = this.isStroke(),
                dx, dy,
                i, len;

            if (!this._latestPos) this._latestPos = {};
            this._latestPos.x = this.x;
            this._latestPos.y = this.y;
            this.x = x;
            this.y = y;

            if (this._drops.length) {
                var drops  = this._drops,
                    drop,
                    sizeSq = this.size * this.size;

                for (i = 0, len = drops.length; i < len; i++) {
                    drop = drops[i];

                    dx = this.x - drop.x;
                    dy = this.y - drop.y;

                    if (
                        (isStroke && sizeSq > dx * dx + dy * dy && this._strokeId !== drop.strokeId) ||
                        drop.life <= 0
                    ) {
                        drops.splice(i, 1);
                        len--;
                        i--;
                        continue;
                    }

                    drop.render(ctx);
                }
            }

            if (isStroke) {
                var tip = this._tip,
                    strokeId = this._strokeId,
                    dist;

                dx = this.x - this._latestPos.x;
                dy = this.y - this._latestPos.y;
                dist = Math.sqrt(dx * dx + dy * dy);

                if (this.splashing && dist > this._SPLASHING_BRUSH_SPEED) {
                    var maxNum = (dist - this._SPLASHING_BRUSH_SPEED) * 0.5 | 0,
                        r, a, sr, sx, sy;

                    ctx.save();
                    ctx.fillStyle = this.color;
                    ctx.beginPath();
                    for (i = 0, len = maxNum * Math.random() | 0; i < len; i++) {
                        r = (dist - 1) * Math.random() + 1;
                        a = Math.PI * 2 * Math.random();
                        sr = 5 * Math.random();
                        sx = this.x + r * Math.sin(a);
                        sy = this.y + r * Math.cos(a);
                        ctx.moveTo(sx + sr, sy);
                        ctx.arc(sx, sy, sr, 0, Math.PI * 2, false);
                    }
                    ctx.fill();
                    ctx.restore();

                } else if (this.dripping && dist < this.inkAmount * 2 && Math.random() < 0.05) {
                    this._drops.push(new Drop(
                        this.x,
                        this.y,
                        (this.size + this.inkAmount) * 0.5 * ((0.25 - 0.1) * Math.random() + 0.1),
                        this.color,
                        this._strokeId
                    ));
                }

                for (i = 0, len = tip.length; i < len; i++) {
                    tip[i].render(ctx, dx, dy, dist);
                }
            }
        },

        dispose: function() {
            this._tip.length = this._drops.length = 0;
        },

        _resetTip: function() {
            var tip = this._tip = [],
                rad = this.size * 0.5,
                x0, y0, a0, x1, y1, a1, cv, sv,
                i, len;

            a1  = Math.PI * 2 * Math.random();
            len = rad * rad * Math.PI / this.inkAmount | 0;
            if (len < 1) len = 1;

            for (i = 0; i < len; i++) {
                x0 = rad * Math.random();
                y0 = x0 * 0.5;
                a0 = Math.PI * 2 * Math.random();
                x1 = x0 * Math.sin(a0);
                y1 = y0 * Math.cos(a0);
                cv = Math.cos(a1);
                sv = Math.sin(a1);

                tip.push(new Hair(
                    this.x + x1 * cv - y1 * sv,
                    this.y + x1 * sv + y1 * cv,
                    this.inkAmount,
                    this.color
                ));
            }
        }
    };


    /**
     * Hair
     * @private
     */
    function Hair(x, y, inkAmount, color) {
        this.x = x || 0;
        this.y = y || 0;
        this.inkAmount = inkAmount;
        this.color = color;

        this._latestPos = { x: this.x, y: this.y };
    }

    Hair.prototype = {
        x:          0,
        y:          0,
        inkAmount:  7,
        color:      '#000',
        _latestPos: null,

        render: function(ctx, offsetX, offsetY, offsetLength) {
            this._latestPos.x = this.x;
            this._latestPos.y = this.y;
            this.x += offsetX;
            this.y += offsetY;

            var per = offsetLength ? this.inkAmount / offsetLength : 0;
            if      (per > 1) per = 1;
            else if (per < 0) per = 0;

            ctx.save();
            ctx.lineCap = ctx.lineJoin = 'round';
            ctx.strokeStyle = this.color;
            ctx.lineWidth = this.inkAmount * per;
            ctx.beginPath();
            ctx.moveTo(this._latestPos.x, this._latestPos.y);
            ctx.lineTo(this.x, this.y);
            ctx.stroke();
            ctx.restore();
        }
    };


    /**
     * Drop
     * @private
     */
    function Drop(x, y, size, color, strokeId) {
        this.x = x || 0;
        this.y = y || 0;
        this.size = size;
        this.color = color;
        this.strokeId = strokeId;

        this.life = this.size * 1.5;
        this._latestPos = { x: this.x, y: this.y };
    }

    Drop.prototype = {
        x:          0,
        y:          0,
        size:       7,
        color:      '#000',
        strokeId:   null,
        life:       0,
        _latestPos: null,
        _xOffRatio: 0,

        render: function(ctx) {
            if (Math.random() < 0.03) {
                this._xOffRatio += 0.06 * Math.random() - 0.03;
            } else if (Math.random() < 0.1) {
                this._xOffRatio *= 0.003;
            }

            this._latestPos.x = this.x;
            this._latestPos.y = this.y;
            this.x += this.life * this._xOffRatio;
            this.y += (this.life * 0.5) * Math.random();

            this.life -= (0.05 - 0.01) * Math.random() + 0.01;

            ctx.save();
            ctx.lineCap = ctx.lineJoin = 'round';
            ctx.strokeStyle = this.color;
            ctx.lineWidth = this.size + this.life * 0.3;
            ctx.beginPath();
            ctx.moveTo(this._latestPos.x, this._latestPos.y);
            ctx.lineTo(this.x, this.y);
            ctx.stroke();
            ctx.restore();
            ctx.restore();
        }
    };

    return Brush;

})();


// Initialize

(function() {

    // Vars

    var canvas, context,
        centerX, centerY,
        mouseX = 0, mouseY = 0, isMouseDown = false,
        brush,
        gui, control, guiColorCtr, guiSizeCtr, guiIsRandColorCtr;

    // Event Listeners

    function resize(e) {
        canvas.width  = window.innerWidth;
        canvas.height = window.innerHeight;
        centerX = canvas.width * 0.5;
        centerY = canvas.height * 0.5;
        context = canvas.getContext('2d');
        control.clear();
    }

    function mouseMove(e) {
        mouseX = e.clientX;
        mouseY = e.clientY;
    }

    function mouseDown(e) {
        mouseX = e.clientX;
        mouseY = e.clientY;
        if (control.isRandomColor) {
            brush.color = randomColor();
            guiColorCtr.updateDisplay();
        }
        if (control.isRandomSize) {
            brush.size = random(51, 5) | 0;
            guiSizeCtr.updateDisplay();
        }
        brush.startStroke(mouseX, mouseY);
    }

    function mouseUp(e) {
        brush.endStroke();
    }
	
	
	var touched = false;

    function touchMove(e) {
		var t = e.touches[0];
        mouseX = t.clientX;
        mouseY = t.clientY;
    }

    function touchStart(e) {
		if (touched) return;
		touched = true;
		
		var t = e.touches[0];
        mouseX = t.clientX;
        mouseY = t.clientY;
        if (control.isRandomColor) {
            brush.color = randomColor();
            guiColorCtr.updateDisplay();
        }
        if (control.isRandomSize) {
            brush.size = random(51, 5) | 0;
            guiSizeCtr.updateDisplay();
        }
        brush.startStroke(mouseX, mouseY);
    }

    function touchEnd(e) {
		touched = false;
        brush.endStroke();
    }

    // Helpers

    function randomColor() {
        var r = random(256) | 0,
            g = random(256) | 0,
            b = random(256) | 0;
        return 'rgb(' + r + ',' + g + ',' + b + ')';
    }

    function random(max, min) {
        if (typeof max !== 'number') {
            return Math.random();
        } else if (typeof min !== 'number') {
            min = 0;
        }
        return Math.random() * (max - min) + min;
    }


    // GUI Control

    control = {
        isRandomColor: true,
        isRandomSize:  false,
        clear: function(e) {
            context.clearRect(0, 0, canvas.width, canvas.height);
            brush.dispose();
        }
    };


    // Init

    canvas = document.getElementById('c');

    brush = new Brush(centerX, centerY, randomColor());

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

    canvas.addEventListener('mousemove', mouseMove, false);
    canvas.addEventListener('mousedown', mouseDown, false);
    canvas.addEventListener('mouseout', mouseUp, false);
    canvas.addEventListener('mouseup', mouseUp, false);

    canvas.addEventListener('touchmove', touchMove, false);
    canvas.addEventListener('touchstart', touchStart, false);
    canvas.addEventListener('touchcancel', touchEnd, false);
    canvas.addEventListener('touchend', touchEnd, false);


    // GUI

    gui = new dat.GUI();
    guiColorCtr = gui.addColor(brush, 'color').name('Color').onChange(function() {
        control.isRandomColor = false;
        guiIsRandColorCtr.updateDisplay();
    });
    guiSizeCtr = gui.add(brush, 'size', 5, 50).name('Size');
    gui.add(brush, 'inkAmount', 1, 30).name('Ink Amount');
    gui.add(brush, 'splashing').name('Splashing');
    gui.add(brush, 'dripping').name('Dripping');
    guiIsRandColorCtr = gui.add(control, 'isRandomColor').name('Random Color');
    gui.add(control, 'isRandomSize').name('Random Size');
    gui.add(control, 'clear').name('Clear');
    gui.close();


    // Start Update

    var loop = function() {
        brush.render(context, mouseX, mouseY);
        requestAnimationFrame(loop);
    };
    loop();

})();
Host Instantly Drag and Drop Website Builder

 

Description

http://jsdo.it/akm2/zAOw
Term
Mon, 11/27/2017 - 21:37

Related Codes

Pen ID
Pen ID
Pen ID