JSFiddle - React, Tailwind, and code Playground

by Alex Chizhov

HTML

<div class="graphic_editor">
    
    <div class="instruments">
        
        <div class="color">
            <a data-color="red"></a>
            <a data-color="green"></a>
            <a data-color="blue"></a>
            <a data-color="orange"></a>
            <a data-color="black"></a>
            <a data-color="white"></a>
            <a data-color="brown"></a>
            <a data-color="yellow"></a>
        </div>
        
        <div class="line_width">
            Line width<br>
            <input type="number" value="5">
        </div>

    </div>
    
    <div class="workarea">
        <canvas id="workarea"></canvas>
    </div>
        
    
</div>

<a class="download">Save</a>
<a class="print">Print</a>

SCSS

@mixin colorbutton($color){
    
    &[data-color=$color]{
        background-color:$color;
    }
    
}

.graphic_editor{
    width:500px;
    height:500px;  
    display:block;
    box-sizing:border-box;
    background-color:red;
    border:1px solid black;
    
    &.after{
        display:block;
        content:'';
        clear:both;
    }
    
    .instruments{
        width:98px;
        height:100%;
        float:left;
        display:block;
        background-color:pink;
        box-sizing:border-box;
        
        .color{
            width:100%;
            
            a{
                width:25px;
                height:25px;
                display:inline-block;
                background-color:pink;
                cursor:pointer;
                
                @include colorbutton(red);
                @include colorbutton(green);
                @include colorbutton(blue);
                @include colorbutton(orange);
                @include colorbutton(black);
                @include colorbutton(white);
                @include colorbutton(brown);
                @include colorbutton(yellow);
            }
            
            
            
            
        }
        
        .line_width{
            input{
                width:50px;
            }
        }
        
    }
    
    .workarea{
        width:400px;
        height:100%;
        display:block;
        float:left;
        background-color:#fff;
        box-sizing:border-box;
        
        canvas{
            width:100%;
            height:100%;
            display:block;
            background-color:#fff;
        }
        
    }
    
}

.download,
.print{
    display:inline-block;
    padding:10px;
    background-color:lightgreen;
    margin-top:10px;
    cursor:pointer;
}

JavaScript

jQuery(function($){
    
    var cnvColor = 'black';
    var cnvLineWidth = 5;
        
    $(document).on('click', '.color a', function(e){
        e.preventDefault();
        
        cnvColor = $(this).data('color');
    });
    
    $(document).on('change', '.line_width input', function(){
        cnvLineWidth = $(this).val();
    });
    
    var workarea = $('.workarea');
    var canvas = document.getElementById('workarea');
    canvas.width = 400;
    canvas.height = 498;
    
    var cnv = canvas.getContext('2d');
    var cnvOffset = $('#workarea').offset();
    
    var mouseDown = false;
    
    $(document).on('mousemove', canvas, function(e){
        if (mouseDown) {
            cnv.lineTo(e.pageX - cnvOffset.left, e.pageY - cnvOffset.top);
            cnv.stroke();
        }
    });
    
    $(document).on('mousedown', canvas, function(){
        mouseDown = true;
        
        cnv.strokeStyle = cnvColor;
        cnv.lineWidth = cnvLineWidth;
        cnv.lineCap = 'round';
        cnv.beginPath();
        cnv.moveTo(e.pageX - cnvOffset.left, e.pageY - cnvOffset.top);
        
    });
    
    $(document).on('mouseup', canvas, function(){
        mouseDown = false;
    });
    
    // Write canvas to PNG file
    $(document).on('click', '.download', function(e){
        e.preventDefault();
        var image = canvas.toDataURL('img/png');
        window.open(image);
    });
    
    // Print canvas
    $(document).on('click', '.print', function(e){
        e.preventDefault();
        var image = canvas.toDataURL('img/png');
        
        var printContent = '<!DOCTYPE html>';
    	printContent += '<html>'
    	printContent += '<head><title>Alex Chizhov Canvas</title></head>';
    	printContent += '<body>'
    	printContent += '<img src="' + image + '">';
    	printContent += '</body>';
    	printContent += '</html>';
        
        var win = window.open('', '', 'width=400, height=498');
        win.document.open();
   ...