前端应用 - 实现100以内加减法的连线习题兼容移动端

html主页面(index.html):

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="viewport" content="width=device-width,user-scalable=no, initial-scale=1">
    <title>连线习题 - 100以内加减法</title>
    <link rel="stylesheet" href="./static/css/app.css">
</head>
<body>
<div class="demo1">
    <div class="show clearfix">
        <div class="showleft" first="0">
            <!--左侧 内容根据需要调整-->
        </div>
        <div class="showright" first="0">
            <!--右侧-->                                        
        </div>
        <canvas class="canvas"></canvas>
        <!--连线画布-->
        <canvas class="backcanvas"></canvas>
        <!--提示线画布-->

    </div>
    <div class="toolsImageBtn">
        <input type="button" title="重做"   value="重做" class="btn resetCanvasBtn">        
        <input type="button" title="回退"   value="回退" class="btn goBackBtn">
        <input type="button" title="下一题" value="下一题" class="btn submit">
    </div>
</div>
</body>
</html>
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="./static/js/app.js"></script>

css页面样式文件(app.css)

* {
    margin: 0;
    padding: 0;
    touch-action: pan-y;
}
body {
    font-size: 1.86662vw;
    background-color: #f4eae5;
}
.clearfix:after {
    content: ".";
    display: block;
    height: 0;
    clear: both;
    overflow: hidden;
}
.clearfix {zoom: 1;}
.demo1 {
    width: 100vw;
    height: calc(100vh - 12vw);
    margin: 0 auto;
    border-radius: 1.99995vw;
}
.show {
    position: relative;
    width: 95vw;
    margin: 5.3332vw 1vw;
    cursor: pointer;
}
.canvas {
    position: absolute;
    left: 0px;
    top: 0px;
    z-index: -1;
}
.backcanvas {
    position: absolute;
    left: 0px;
    top: 0px;
    z-index: -2;

}
.showleft {
    float: left;
    width: 26.66vw;
}
.showright {
    float: right;
    width: 20.93281vw;
}
.show .showitem {
    width: 100%;
    height: 15%;
    display: block;
    margin: 1.3333vw 0;
    border-radius: 1.99995vw;
    padding: 1.3333vw;
    text-align: center;
    background-color: #ffffff;
}
.showleft .showitem,.showright .showitem {
    color: #aaa39f;
    font-size: 2.39994vw;
}
.showleft .showitem img,.showright .showitem img {
    padding-right: 0px;
}
.showleft .showitem p,.showright .showitem p {
    text-align: center;
    position: relative;
    top:50%;
    transform: translateY(-50%);
    font-size: 4.26656vw;
}
.toolsImageBtn{
    width: 95vw;
    margin: 0 auto;
}
.btn {
    width: 17.99928vw;
    height: 9.83294vw;
    border: 0;
    cursor: pointer;
    float:left;
    margin-right: 1.3333vw;
    font-size: 2.39994vw;
    text-align: center;
    color: #355742;
    background:url(../images/btn_bg.png);  
    filter:"progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='scale')";  
    -moz-background-size:100% 100%;  
        background-size:100% 100%;
}
.submit{float: right;}
@media screen and (min-width: 640px) {
    /* 屏幕宽度大于640px */
    body {
        font-size: 14px;
    }
    .demo1 {
        width: 640px;
        /* height: 640px; */
        border-radius: 15px;
    }
    .show {
        width: 600px;
        margin: 40px 20px;
    }
    .showleft {
        width: 200px;
    }
    .showright {
        width: 140px;
    }
    .show .showitem {
        margin: 10px 0;
        border-radius: 15px;
        padding: 0px;
    }
    .showleft .showitem,.showright .showitem {
        font-size: 18px;
    }
    .showleft .showitem p,.showright .showitem p {
        font-size: 32px;
    }
    .toolsImageBtn{
        width: 600px;
    }
    .btn {
        width: 108px;
        height: 59px;
        margin-right: 10px;
        font-size: 18px;
    }
}
@media screen and (min-height: 640px) {
    .demo1 {
        height: 640px;
    }
}

js主程序(app.js)

$(function() {
    var OAIndex = {
        initialised: false,
        version    : 1.0,
        touchstart : "touchstart",
        touchmove  : "touchmove",
        touchend   : "touchend",
        init: function (box) {
            if (!this.initialised) {this.initialised = true;}else{return;}
            if (this.isPC()) {
                this.touchstart = "mousedown";
                this.touchmove  = "mousemove";
                this.touchend   = "mouseup";
            }
            this.box       = box;
            this.linewidth = 2;
            this.linestyle = "#ff5500"; //连线绘制--线宽,线色
            //canvas 赋值
            this.canvasTag     = null;  //获取canvas 实际连线标签
            this.backcanvasTag = null;  //获取canvas 模拟连线标签
            this.context       = null;  //画板 实际连线
            this.backcanvas    = null;  //画板 模拟连线      
            //连线数据
            this.groupstate = false; //按下事件状态,标记按下后的移动,抬起参考
            this.mx         = [];    //连线坐标
            this.my         = [];
            this.ms         = [];
            this.temp       = {};    //存贮按下的对象
            this.pair       = 0 ;    //配对属性
            this.pairl      = [];
            this.pairr      = [];
            //存储虚拟连线起始坐标
            this.mid_startx = null;
            this.mid_starty = null;
            this.mid_endx   = null;
            this.mid_endy   = null;
            this.context    = null; //canvas追加2d画图
            //存放遍历坐标
            this.lastX      = null;
            this.lastY      = null;
            this.loadTouchFun(this.box);
        },
        isPC: function () {
            var ua = navigator.userAgent.toLowerCase();
            if(/AppleWebKit.*Mobile/i.test(navigator.userAgent) || (/MIDP|SymbianOS|NOKIA|SAMSUNG|LG|NEC|TCL|Alcatel|BIRD|DBTEL|Dopod|PHILIPS|HAIER|LENOVO|MOT-|Nokia|SonyEricsson|SIE-|Amoi|Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|ZTE/.test(navigator.userAgent)) || ua.match(/MicroMessenger/i) == "micromessenger"){
                return false;
            }else{
                return true;
            }
        },
        strockline: function () {
            var that = this;
            var box  = that.box;
            that.context.clearRect(0, 0, box.find(".show").width(), box.find(".show").height()); //整个画布清除
            that.context.save();
            that.context.beginPath();
            that.context.lineWidth = that.linewidth;
            for (var i = 0; i < that.ms.length; i++) { //遍历绘制
                lastX = that.mx[i];
                lastY = that.my[i];
                if (that.ms[i] == 0) {
                    that.context.moveTo(lastX, lastY);
                } else {
                    that.context.lineTo(lastX, lastY);
                }
            }
            that.context.strokeStyle = that.linestyle;
            that.context.stroke();
            that.context.restore();
        },                      
        clearline: function () {
            var that = this;
            var box  = that.box;
            that.context.clearRect(0, 0, box.find(".show").width(), box.find(".show").height());
            that.mx = []; //数据清除
            that.my = [];
            that.ms = [];
            that.pairl = [];
            that.pairr = [];
            that.pair = 0;
            box.find(".showleft").children("span").each(function(index, element) {
                $(this).removeClass("addstyle");
                $(this).attr("sel", "0");
                $(this).attr("check", "0");
                            
            });
            box.find(".showleft").attr('first', 0);
            box.find(".showright").children("span").each(function(index, element) {
                $(this).removeClass("addstyle");
                $(this).attr("sel", "0");
                $(this).attr("check", "0");
            });
            box.find(".showright").attr('first', 0);
        },                       
        backstrockline: function () {
            var that = this;
            var box  = that.box;
            that.backcanvas.clearRect(0, 0, box.find(".show").width(), box.find(".show").height());
            that.backcanvas.save();
            that.backcanvas.beginPath();
            that.backcanvas.lineWidth = that.linewidth;
            that.backcanvas.moveTo(that.mid_startx, that.mid_starty);
            that.backcanvas.lineTo(that.mid_endx, that.mid_endy);
            that.backcanvas.strokeStyle = that.linestyle;
            that.backcanvas.stroke();
            that.backcanvas.restore();
        },                      
        clearbackline: function () {
            var that = this;
            var box  = that.box;
            that.backcanvas.clearRect(0, 0, box.find(".show").width(), box.find(".show").height());
            that.mid_startx = null;
            that.mid_starty = null;
            that.mid_endx   = null;
            that.mid_endy   = null;
        },       
        goBack: function () {
            var that = this;
            var box  = that.box;
            var linenlastIndex = that.ms.join("").substr(0, that.ms.length - 1).lastIndexOf("0");
            if (linenlastIndex == 0) {
                that.clearline();
            } else {
                that.mx = that.mx.slice(0, linenlastIndex); //记录值
                that.my = that.my.slice(0, linenlastIndex); //坐标
                that.ms = that.ms.slice(0, linenlastIndex);
                that.context.clearRect(0, 0, box.find(".show").width(), box.find(".show").height());
                that.context.save();
                that.context.beginPath();
                that.context.lineWidth = that.linewidth;
                for (var i = 0; i < that.ms.length; i++) {
                    lastX = that.mx[i];
                    lastY = that.my[i];
                    if (that.ms[i] == 0) {
                        that.context.moveTo(lastX, lastY);
                    } else {
                        that.context.lineTo(lastX, lastY);
                    }
                }
                that.context.strokeStyle = that.linestyle;
                that.context.stroke();
                that.context.restore();
                var pairindex = that.pairl.length - 1;
                box.find(".showleft").children("span").each(function(index, element) {
                    if ($(this).attr("pair") == that.pairl[pairindex]) {
                        $(this).removeClass("addstyle");
                        $(this).attr("sel", "0");
                        $(this).attr("check", "0");
                        $(this).removeAttr("pair");
                    };
                });
                box.find(".showleft").attr('first', 0);
                box.find(".showright").children("span").each(function(index, element) {
                    if ($(this).attr("pair") == that.pairl[pairindex]) {
                        $(this).removeClass("addstyle");
                        $(this).attr("sel", "0");
                        $(this).attr("check", "0");
                        $(this).removeAttr("pair");
                    };
                });
                box.find(".showright").attr('first', 0);
                that.pair -= 1;
                that.pairl = that.pairl.slice(0, pairindex);
                that.pairr = that.pairr.slice(0, pairindex);
            };
        },                             
        loadTouchFun: function (box) {
            var that = this;
            //初始化赋值 列表内容
            box.find(".showleft").children("span").each(function(index, element) {
                $(this).attr({
                    group: "gpl",
                    left: $(this).position().left + $(this).outerWidth(),
                    top:  $(this).position().top + $(this).outerHeight() / 2,
                    sel:  "0",
                    check: "0"
                });
            });
            box.find(".showright").children("span").each(function(index, element) {
                $(this).attr({
                    group: "gpr",
                    left: $(this).position().left,
                    top: $(this).position().top + $(this).outerHeight() / 2,
                    sel: "0",
                    check: "0"
                });
            });
            box.find(".showleft").attr('first', 0); //初始赋值 列表内容容器
            box.find(".showright").attr('first', 0);
            //canvas 赋值
            that.canvasTag = box.find(".canvas")[0]; //获取canvas  实际连线标签
            that.canvasTag.width = box.find(".show").width(); //canvas宽度等于div容器宽度
            that.canvasTag.height = box.find(".show").height();
            
            that.backcanvasTag = box.find(".backcanvas")[0]; //获取canvas 模拟连线标签
            that.backcanvasTag.width = box.find(".show").width();
            that.backcanvasTag.height = box.find(".show").height();

            //事件处理---按下
            box.children(".show").children().children("span").on(that.touchstart, function(event) {
                that.groupstate = true;
                if ($(this).attr("check") == 1) {
                    $(this).attr("sel", "1").parent().attr("first", "1");
                    that.temp = $(this);
                } else {
                    $(this).attr("sel", "1").addClass("addstyle").parent().attr("first", "1");
                    that.temp = $(this);
                };
                that.mid_startx = $(this).attr("left");
                that.mid_starty = $(this).attr("top");
                event.preventDefault();
            });
            
            $(document).on(that.touchmove, function(event) {
                // 判断默认行为是否可以被禁用
                if (event.cancelable) {
                    // 判断默认行为是否已经被禁用
                    if (!event.defaultPrevented) {
                        if (that.isPC()) {
                            var $target = $(event.target);
                            var pageX = event.pageX;
                            var pageY = event.pageY;
                        }else{
                            var pageX = event.originalEvent.touches[0].pageX & event.originalEvent.changedTouches[0].pageX & event.originalEvent.targetTouches[0].pageX;
                            var pageY = event.originalEvent.touches[0].pageY & event.originalEvent.changedTouches[0].pageY & event.originalEvent.targetTouches[0].pageY
                            /**
                            *获取存储当前Dom位置的对象
                            **/
                            var myLocation = event.originalEvent.changedTouches[0];
                            /**
                            *取clientX及clientY并传入elementFromPoint获取当前手指触摸的Dom,大功告成,现在此Dom可以任你摆布了
                            **/
                            var realTarget = document.elementFromPoint(myLocation.clientX, myLocation.clientY);
                            var $target = $(realTarget);
                        }
                        if (that.groupstate) {
                            that.mid_endx = pageX - box.find(".show").offset().left;
                            that.mid_endy = pageY - box.find(".show").offset().top;
                            var targettrue = null;

                            if ($target.is("span") && $target.closest(".show").parent().attr("class") == box.attr("class")) {
                                targettrue = $target;
                            } else if ($target.closest(".showitem").is("span") && $target.closest(".show").parent().attr("class") == box.attr("class")) {
                                targettrue = $target.closest(".showitem");
                            } else {
                                targettrue = null;
                            };

                            if (targettrue) {
                                if (targettrue.parent().attr("first") == 0) {
                                    if (targettrue.attr("check") == 0) {
                                        targettrue.addClass("addstyle").attr("sel", "1").siblings("span[check=0]").removeClass("addstyle").attr("sel", "0");
                                    };
                                } else {
                                    if (targettrue.attr("check") == 0) {
                                        targettrue.addClass("addstyle").attr("sel", "1").siblings("span[check=0]").removeClass("addstyle").attr("sel", "0");
                                        that.mid_startx = targettrue.attr("left");
                                        that.mid_starty = targettrue.attr("top");
                                    };
                                    //temp=targettrue;
                                };
                            } else {
                                if (box.find(".showleft").attr("first") == 0) {
                                    box.find(".showleft").children("span").each(function(index, element) {
                                        if ($(this).attr('check') == 0) {
                                            $(this).attr("sel", "0").removeClass("addstyle");
                                        };
                                    });
                                };
                                if (box.find(".showright").attr("first") == 0) {
                                    box.find(".showright").children("span").each(function(index, element) {
                                        if ($(this).attr('check') == 0) {
                                            $(this).attr("sel", "0").removeClass("addstyle");
                                        };
                                    });
                                };

                            };
                            that.backstrockline();
                        };
                        event.preventDefault();
                    }
                }
            });

            $(document).on(that.touchend, function(event) {
                // 判断默认行为是否可以被禁用
                if (event.cancelable) {
                    // 判断默认行为是否已经被禁用
                    if (!event.defaultPrevented) {
                        if (that.isPC()) {
                            var $target    = $(event.target);
                        }else{
                            var myLocation = event.originalEvent.changedTouches[0];
                            var realTarget = document.elementFromPoint(myLocation.clientX, myLocation.clientY);
                            var $target    = $(realTarget);
                        }
                        if (that.groupstate) {
                            var targettrue;
                            if ($target.is("span") && $target.closest(".show").parent().attr("class") == box.attr("class")) {
                                targettrue = $target;
                            } else if ($target.closest(".showitem").is("span") && $target.closest(".show").parent().attr("class") == box.attr("class")) {
                                targettrue = $target.closest(".showitem");
                            } else {
                                targettrue = null;
                            };

                            if (targettrue) {
                                if (targettrue.parent().attr("first") == 0) {
                                    if (targettrue.attr("check") == 0) {
                                        if (that.temp.attr('check') == 1) {
                                            box.find(".showleft").children("span").each(function(index, element) {
                                                if ($(this).attr('sel') == 1) {
                                                    if ($(this).attr('check') == 0) {
                                                        $(this).attr("sel", "0").removeClass("addstyle");
                                                    } else {
                                                        $(this).attr("sel", "0").addClass("addstyle");
                                                    };
                                                }
                                            });
                                            box.find(".showleft").attr('first', 0);
                                            box.find(".showright").children("span").each(function(index, element) {
                                                if ($(this).attr('sel') == 1) {
                                                    if ($(this).attr('check') == 0) {
                                                        $(this).attr("sel", "0").removeClass("addstyle");
                                                    } else {
                                                        $(this).attr("sel", "0").addClass("addstyle");
                                                    };
                                                }
                                            });
                                            box.find(".showright").attr('first', 0);
                                        } else {
                                            box.find(".showleft").children("span").each(function(index, element) {
                                                if ($(this).attr('sel') == 1) {
                                                    that.mx.push($(this).attr('left'));
                                                    that.my.push($(this).attr('top'));
                                                    that.ms.push(0);
                                                    $(this).attr("check", "1");
                                                    $(this).attr("sel", "0");
                                                    $(this).attr("pair", that.pair);
                                                    that.pairl.push(that.pair);
                                                }
                                            });
                                            box.find(".showright").children("span").each(function(index, element) {
                                                if ($(this).attr('sel') == 1) {
                                                    that.mx.push($(this).attr('left'));
                                                    that.my.push($(this).attr('top'));
                                                    that.ms.push(1);
                                                    $(this).attr("check", "1");
                                                    $(this).attr("sel", "0");
                                                    $(this).attr("pair", that.pair);
                                                    that.pairr.push(that.pair);
                                                }
                                            });
                                            that.pair += 1;
                                            box.find(".showleft").attr('first', 0);
                                            box.find(".showright").attr('first', 0);
                                            that.strockline();
                                        };
                                    } else {
                                        box.find(".showleft").children("span").each(function(index, element) {
                                            if ($(this).attr('sel') == 1) {
                                                if ($(this).attr('check') == 0) {
                                                    $(this).attr("sel", "0").removeClass("addstyle");
                                                } else {
                                                    $(this).attr("sel", "0").addClass("addstyle");
                                                };
                                            }
                                        });
                                        box.find(".showleft").attr('first', 0);
                                        box.find(".showright").children("span").each(function(index, element) {
                                            if ($(this).attr('sel') == 1) {
                                                if ($(this).attr('check') == 0) {
                                                    $(this).attr("sel", "0").removeClass("addstyle");
                                                } else {
                                                    $(this).attr("sel", "0").addClass("addstyle");
                                                };
                                            }
                                        });
                                        box.find(".showright").attr('first', 0);
                                    };
                                } else {
                                    box.find(".showleft").children("span").each(function(index, element) {
                                        if ($(this).attr('check') == 0) {
                                            if ($(this).attr('sel') == 1) {
                                                $(this).attr("sel", "0").removeClass("addstyle");
                                            };
                                        } else {
                                            if ($(this).attr('sel') == 1) {
                                                $(this).attr("sel", "0").addClass("addstyle");
                                            };
                                        };
                                    });
                                    box.find(".showleft").attr('first', 0);
                                    box.find(".showright").children("span").each(function(index, element) {
                                        if ($(this).attr('check') == 0) {
                                            if ($(this).attr('sel') == 1) {
                                                $(this).attr("sel", "0").removeClass("addstyle");
                                            };
                                        } else {
                                            if ($(this).attr('sel') == 1) {
                                                $(this).attr("sel", "0").addClass("addstyle");
                                            };
                                        };
                                    });
                                    box.find(".showright").attr('first', 0);
                                };
                            } else {
                                box.find(".showleft").children("span").each(function(index, element) {
                                    if ($(this).attr('check') == 0) {
                                        if ($(this).attr('sel') == 1) {
                                            $(this).attr("sel", "0").removeClass("addstyle");
                                        };
                                    };
                                });
                                box.find(".showleft").attr('first', 0);
                                box.find(".showright").children("span").each(function(index, element) {
                                    if ($(this).attr('check') == 0) {
                                        if ($(this).attr('sel') == 1) {
                                            $(this).attr("sel", "0").removeClass("addstyle");
                                        };
                                    };
                                });
                                box.find(".showright").attr('first', 0);
                            };
                            that.clearbackline();
                            that.groupstate = false;
                        };
                        event.preventDefault();
                    }
                }
            });

            // canvas 追加2d画布
            that.context = that.canvasTag.getContext('2d'); //canvas追加2d画图
            // init 2d画布 虚拟绘制
            that.backcanvas = that.backcanvasTag.getContext('2d');

            //下载
            box.find(".downloadImageBtn").bind(that.touchend, function () {
                var myCanvas = box.find(".canvas")[0];
                var image = myCanvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
                window.location.href = image; //地址变为canvas图片路径,下载
            });

            //重置
            box.find(".resetCanvasBtn").bind(that.touchend, function () {
                that.clearline();
            });  

            //回退
            box.find(".goBackBtn").bind(that.touchend, function () {
                that.goBack();
            });
            //下一题
            box.find(".submit").bind(that.touchend, function () {
                location.reload();
            });            
        }
    }
    var OACalc = {
        initialised: false,
        version    : 1.0,
        init: function (a = null,b = null) {
            var that = this;
            if (!that.initialised) {that.initialised = true;}else{return;}
            that.maxRdm = a?a:101;
            that.operatorArr = ['+', '-'];
            that.tData = {tm:[],da:[]};
            var b = b?b:5;
            var count = 0;
            while(count < b){
                var tmp = that.create();
                if(tmp) count++;
            }
            that.tData.tm.sort(function(){ return 0.5 - Math.random()});
            that.tData.da.sort(function(){ return 0.5 - Math.random()});
            return that.tData;
        },
        getRandom: function () {
            return Math.floor(Math.random()*this.maxRdm);
        },
        getOperator: function () {
            var arr = this.operatorArr;
            return arr[Math.floor(Math.random()*arr.length)];
        },
        validate: function (num1, op, num2) {
            if (op === '÷' && num2 === 0) return false;
            if (num1%num2 != 0) return false;
            if (op === '-' && num1 < num2) return false;
            return true;
        },
        create: function () {
            var that = this;
            var num1 = that.getRandom();
            var num2 = that.getRandom();
            var op   = that.getOperator();
            var opTemp = op;
            if (op === '×') opTemp = '*';
            if (op === '÷') opTemp = '/';
            var answer = eval(num1 + (opTemp) + num2);
             
            if(!that.validate(num1, op, num2)) return;
            var str = num1 + " " + op + " " + num2 + " =";
            that.tData.tm.push(str);
            that.tData.da.push(answer);
            return true;
        },
        
    };
    var tData = OACalc.init(101,5);

    var leftHtml = '',rightHtml = '';
    $.each(tData.tm, function(k, v) {
        leftHtml += '<span class="showitem" group="gpl"  sel="0" check="0" pair="'+k+'">'+
                    '<p>'+v+'</p>'+
                    '</span> ';
    });
    $.each(tData.da, function(k, v) {
        rightHtml += '<span class="showitem" group="gpr"  sel="0" check="0" pair="'+k+'">'+
                    '<p>'+v+'</p>'+
                    '</span> ';
    });
    $('.showleft').html(leftHtml);    
    $('.showright').html(rightHtml);
    setTimeout(function() {
        OAIndex.init($(".demo1"));
    }, 500);
});

最终效果:

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值