OJ的前端界面实现

作者: 简心豆 | 来源:发表于2017-06-12 13:56 被阅读186次

    持续两周的课程设计结束了,本次已经是我们小组第三次合作了,相比以前大家都进步了很多,所以合作还是很顺利的。我们这次做的是一个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

    相关文章

      网友评论

        本文标题:OJ的前端界面实现

        本文链接:https://www.haomeiwen.com/subject/sfelqxtx.html