OJ的前端界面实现

持续两周的课程设计结束了,本次已经是我们小组第三次合作了,相比以前大家都进步了很多,所以合作还是很顺利的。我们这次做的是一个OJ(Online
Judge在线检测代码的平台)。我想作为一个喜爱编程或者学习编程的人或多或少都有接触过算法,本人曾经也刷过一些算法,可是相对组长的题量简直是九牛一毛,我想一个对于算法这么有研究的大神,肯定特别想做个自己的OJ,这是一种情怀,最近觉得好像学习计算机的人都特别有情怀。废话不多说了,我是写前端的,所以后台就让专业的人说,我就总结下自己的前端知识。


一. 代码编辑框

我想大家最在乎的应该就是代码编辑框应该怎么实现,当然这不是我自己写的,毕竟只有两周的时间,造轮子搞出来个这个肯定是不可能的,所以就去github找了个开源的代码编辑器,然后搜了下用过的人还是挺多的。支持多种语言,像C/C++,Java等当然不在话下,这是链接:
https://github.com/ajaxorg/ace
需要的直接下载就行,下来就简单的说下怎么用吧:

html部分代码:

<div class="code">
    <form role="form">
        <div class="editor-header">
            <select class="form-control form-control-plus"onchange="choiceLang(this)">
                <option value="ace/mode/c_cpp">语言</option>
                <option value="ace/mode/c_cpp" selected="selected">C/C++语言</option>
                <option value="ace/mode/java">JAVA语言</option>
                <option value="ace/mode/javascript">JavaScript语言</option>
            </select>
            <select class="form-control form-control-plus" onchange="choiceBack(this)">
                <option>环境配色</option>
                <option value="ace/theme/xcode" selected="selected">高亮</option>
                <option value="ace/theme/monokai">暗色</option>
            </select>
            <select class="form-control form-control-plus" onchange="choiceSJ(this)">
                <option value="4">代码缩进</option>
                <option>2</option>
                <option selected="selected">4</option>
                <option>8</option>
            </select>
            <div class="flex-btn" onclick="expand('spanid')">
            <span class="glyphicon glyphicon-resize-full" id="spanid"></span>
            </div>
        </div>
    </form>
    <pre id="editor" style="height:400px"></pre> 
    <button class="btn btn-primary" onclick="submit()">提交</button>
</div>

form表单中的下拉框是用来选择语言,编辑器背景,以及代码的缩进的,将下拉框中的value值设为指定的值,传入对应的接口就可以了。
下面来简单的讲一下所要用到的接口:

初始化:将语言默认为C/C++,背景默认为高亮,缩进默认为4

var editor = ace.edit("editor");  //该值为编辑框的id值
window.onload = (function () {
    editor.setTheme("ace/theme/xcode"); //设置背景色为高亮
    editor.session.setMode("ace/mode/c_cpp");  //设置默认语言为c/c++
    editor.getSession().setTabSize(4);  //设置默认缩进大小
})();

更改语言,背景色,缩进大小,value为下拉框的值:

 //设置语言
function choiceLang(select){
    editor.session.setMode(select.value);
}
//设置背景色
function choiceBack(select){
    editor.setTheme(select.value); 
}
//设置缩进大小
function choiceSJ(select){
    editor.getSession().setTabSize(select.value);
}

获得所要提交的代码:

function submit(){
    var code  = editor.getValue();
}

放几张图看下效果:
这里写图片描述

这里写图片描述

二. 动态更改代码运行状态

先上图:

这里写图片描述

这里用到了一个加载转圈的插件,下载链接: https://github.com/fgnass/spin.js

//动画
window.onload = function(){
    //加载转圈,插件提供的配置接口
    var opts = {
          lines: 13, //小长条的数量
          length: 13, //小长条的长度
          width: 3, //小长条的宽度
          radius: 15, //内环的半径长
          corners: 1, // Corner roundness (0..1)
          rotate: 0, //旋转角度
          direction: 1, //1:顺时针方向 -1:逆时针方向
          color: '#000', //颜色
          speed: 1, //每秒转多少圈
          trail: 60, //余晖效果百分比
          shadow: false, //渲染阴影
          hwaccel: false, //加速
          className: 'spinner', //类名spinner
          zIndex: 2e9, //显示在最顶层
          top: 'auto', //相对父元素的top
          left: 'auto' //相对父元素的left ,默认情况spinner是显示于父元素居中位置

        };
        //foo为动画的载体
        var target = document.getElementById('foo');
        //实例化之后开始转圈
        var spinner = new Spinner(opts).spin(target);

    //进度条的变化
    var arr = ['正在上传Uploading','等待测试Pending','正在编译Compiling','正在评测Running','测试通过Accepted'];
    var colors = ['black', '#bbb', '#FC8A15', '#4FC1E9', 'rgb(39, 194, 76)'];
    var progress = document.getElementById('progress');
    var status = document.getElementById('status');
    for (var i = 0; i < 5; i++){
        (function (j){
            setTimeout(function (){
                progress.style.width = 20 * (j + 1) + '%';
                progress.innerHTML = 20 * (j + 1) + '%';
                status.innerHTML = arr[j];
                status.style.color = colors[j];
            }, 1000 * j);
        })(i);
    }

    //5s后停止旋转
    setTimeout(function (){
        spinner.stop();  //转圈停止
    }, 5000);
} 

这里只是一个模拟,具体的改变要根据后台传来的状态而定。

三. 提交代码记录的饼状图分布

运行截图:

这里写图片描述

这里用了一个很有名的插件,chart.js,可以引用cdn,也可以去github下载,cdn:
https://cdn.bootcss.com/Chart.js/2.6.0/Chart.min.js

github下载链接: https://github.com/chartjs/Chart.js

代码示例:

var ctx = document.getElementById("canvas").getContext('2d');
var myChart = new Chart(ctx, {
    type: 'pie',
    data: {
        labels: ["submit-failed", "pending", "judging", "accepted", "ComplieError", "RuntimeError"],
        datasets: [{
            label: '# of Votes',
            data: [12, 8, 3, 5, 2, 3],
            backgroundColor: [
                '#BE3144',
                '#bbb',
                '#4797B1',
                'rgb(39, 194, 76)',
                '#FC8A15',
                '#FF847C'
            ],
            borderWidth: 1
        }]
    },
    options: {

    }
});

具体的选项运行一下就很明白了,建议大家去看英文文档,很多中文的文档都过时了,不然肯定不能正确运行,英文文档链接:
http://www.chartjs.org/


以上是自己在项目中所用到的插件,大大减小了代码的编写难度,这也是第一次在项目中用别人写好的插件,确实写得很棒,向写插件的大牛致敬。在上面的陈述中都附有链接,希望对有需要的同学会有帮助,毕竟寻找更改还是很费功夫的。

备注:这是一个完整的项目,本人负责的是前端界面部分,后台的业务逻辑,以及判题部分都很全,另外项目已经上传至github,欢迎大家fork和start。项目链接:
https://github.com/shiyi1996/OJ

-------------本文结束感谢您的阅读-------------