龙空技术网

手把手教你7个有趣的JavaScript 项目-上「附源码」

Echa攻城狮 2587

前言:

此时看官们对“smartclientajax”都比较注意,同学们都想要学习一些“smartclientajax”的相关资讯。那么小编也在网络上网罗了一些关于“smartclientajax””的相关文章,希望我们能喜欢,各位老铁们快快来了解一下吧!

前言

JavaScript是最好的语言之一,尤其是在前端开发中。在本文中,您将找到7个为初学者提供免费源代码的最佳javascript项目。

手把手教你7个有趣的JavaScript 项目-上「附源码」(本篇)

手把手教你7个有趣的JavaScript 项目-下「附源码」

1.使用JavaScript创建待办事项列表应用

如果您是javascript语言的初学者,则待办事项列表应用程序是最好的和最容易的应用程序之一,如果您使用HTML CSS和一点点的javascript,则可以创建此简单的待办事项列表应用程序,您将找到源代码这个js项目的底部。

<!DOCTYPE html><html lang="zh"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta http-equiv="X-UA-Compatible" content="ie=edge" /><title>创建待办事项列表应用</title><style type="text/css">$primary: #313e50;$grey: #cdcdcd;$secondary: #1dd2af;%reset {    margin: 0;    padding: 0;    border: none;    outline: none;    background: transparent;}%transition {    transition: all 0.2s ease;    -webkit-transition: all 0.2s ease;}body {    background: #f1f1f1;    margin-top: 2rem;}/*PEN STYLES*/.tasker {    max-width: 400px;    margin: 0 auto;    .error {        display: none;        background: rgba(237, 28, 36, 0.7);        color: #fff;        padding: 14px;        margin-bottom: 10px;        border-radius: 5px;        text-align: center;    }    ul {        @extend %reset;        background: #fff;    }    li,    .error,    button,    input {        @extend %reset;        font: 18px/1.25em Helvetica, Arial, Sans-serif;    }}.tasker-header {    display: inline-flex;    background: $primary;    justify-content: space-between;    width: 100%;    input,    button {        color: #fff;        box-sizing: border-box;        font-size: 1.25em;        padding: 14px;    }    input {        flex-grow: 2;    }    button {        @extend %transition;        background: $secondary;        border-left: 1px solid ($secondary * 1.05);        &:hover {            background: $secondary * 1.1;        }    }}.tasker-body {    .task {        display: block;        position: relative;        padding: 14px 40px 14px 14px;        border-bottom: 1px solid rgba(0, 0, 0, 0.1);        &:last-child {            border-bottom: none;        }        &:hover > button {            opacity: 1;        }        &.completed {            color: $grey;            text-decoration: line-through;        }        input {            margin-right: 10px;        }        button {            @extend %transition;            color: $grey;            margin: 14px;            position: absolute;            top: 0;            right: 0;            opacity: 0;            &:hover {                color: #ed1c24;            }        }    }}</style></head><body><!--PEN CODE--><div id="tasker" class="tasker">    <div id="error" class="error">Please enter a task</div>    <div id="tasker-header" class="tasker-header">        <input type="text" id="input-task" placeholder="Enter a task">        <button id="add-task-btn"><i class="fa fa-fw fa-plus"></i>        </button>    </div>    <div class="tasker-body">        <ul id="tasks"></ul>    </div></div><!--END PEN CODE--><script type="text/javascript">(function() {    'use strict';    var tasker = {        init: function() {            this.cacheDom();            this.bindEvents();            this.evalTasklist();        },        cacheDom: function() {            this.taskInput = document.getElementById("input-task");            this.addBtn = document.getElementById("add-task-btn");            this.tasklist = document.getElementById("tasks");            this.tasklistChildren = this.tasklist.children;            this.errorMessage = document.getElementById("error");        },        bindEvents: function() {            this.addBtn.onclick = this.addTask.bind(this);            this.taskInput.onkeypress = this.enterKey.bind(this);        },        evalTasklist: function() {            var i, chkBox, delBtn;            //BIND CLICK EVENTS TO ELEMENTS            for (i = 0; i < this.tasklistChildren.length; i += 1) {                //ADD CLICK EVENT TO CHECKBOXES                chkBox = this.tasklistChildren[i].getElementsByTagName("input")[0];                chkBox.onclick = this.completeTask.bind(this, this.tasklistChildren[i], chkBox);                //ADD CLICK EVENT TO DELETE BUTTON                delBtn = this.tasklistChildren[i].getElementsByTagName("button")[0];                delBtn.onclick = this.delTask.bind(this, i);            }        },        render: function() {            var taskLi, taskChkbx, taskVal, taskBtn, taskTrsh;            //BUILD HTML            taskLi = document.createElement("li");            taskLi.setAttribute("class", "task");            //CHECKBOX            taskChkbx = document.createElement("input");            taskChkbx.setAttribute("type", "checkbox");            //USER TASK            taskVal = document.createTextNode(this.taskInput.value);            //DELETE BUTTON            taskBtn = document.createElement("button");            //TRASH ICON            taskTrsh = document.createElement("i");            taskTrsh.setAttribute("class", "fa fa-trash");            //INSTERT TRASH CAN INTO BUTTON            taskBtn.appendChild(taskTrsh);            //APPEND ELEMENTS TO TASKLI            taskLi.appendChild(taskChkbx);            taskLi.appendChild(taskVal);            taskLi.appendChild(taskBtn);            //ADD TASK TO TASK LIST            this.tasklist.appendChild(taskLi);        },        completeTask: function(i, chkBox) {            if (chkBox.checked) {                i.className = "task completed";            } else {                this.incompleteTask(i);            }        },        incompleteTask: function(i) {            i.className = "task";        },        enterKey: function(event) {            if (event.keyCode === 13 || event.which === 13) {                this.addTask();            }        },        addTask: function() {            var value = this.taskInput.value;            this.errorMessage.style.display = "none";            if (value === "") {                this.error();            } else {                this.render();                this.taskInput.value = "";                this.evalTasklist();            }        },        delTask: function(i) {            this.tasklist.children[i].remove();            this.evalTasklist();        },        error: function() {            this.errorMessage.style.display = "block";        }    };    tasker.init();}());</script></body></html>
2.使用JavaScript和CSS创建垂直时间轴(里程碑)

您可以使用javascript初学者创建的第二个小项目是时间轴,许多现代网站都使用该时间轴使网站更具交互性和动态性。

<!DOCTYPE html><html lang="zh"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta http-equiv="X-UA-Compatible" content="ie=edge" /><title>CSS创建垂直时间轴(里程碑)</title><style type="text/css">*,*::before,*::after {  margin: 0;  padding: 0;  box-sizing: border-box;}body {  font: normal 16px/1.5 "Helvetica Neue", sans-serif;  background: #456990;  color: #fff;  overflow-x: hidden;  padding-bottom: 50px;}  /* INTRO SECTION–––––––––––––––––––––––––––––––––––––––––––––––––– */.intro {  background: #F45B69;  padding: 100px 0;}.container {  width: 90%;  max-width: 1200px;  margin: 0 auto;  text-align: center;}h1 {  font-size: 2.5rem;}/* TIMELINE–––––––––––––––––––––––––––––––––––––––––––––––––– */.timeline ul {  background: #456990;  padding: 50px 0;}.timeline ul li {  list-style-type: none;  position: relative;  width: 6px;  margin: 0 auto;  padding-top: 50px;  background: #fff;}.timeline ul li::after {  content: '';  position: absolute;  left: 50%;  bottom: 0;  transform: translateX(-50%);  width: 30px;  height: 30px;  border-radius: 50%;  background: inherit;}.timeline ul li div {  position: relative;  bottom: 0;  width: 400px;  padding: 15px;  background: #F45B69;}.timeline ul li div::before {  content: '';  position: absolute;  bottom: 7px;  width: 0;  height: 0;  border-style: solid;}.timeline ul li:nth-child(odd) div {  left: 45px;}.timeline ul li:nth-child(odd) div::before {  left: -15px;  border-width: 8px 16px 8px 0;  border-color: transparent #F45B69 transparent transparent;}.timeline ul li:nth-child(even) div {  left: -439px;}.timeline ul li:nth-child(even) div::before {  right: -15px;  border-width: 8px 0 8px 16px;  border-color: transparent transparent transparent #F45B69;}time {  display: block;  font-size: 1.2rem;  font-weight: bold;  margin-bottom: 8px;}/* EFFECTS–––––––––––––––––––––––––––––––––––––––––––––––––– */.timeline ul li::after {  transition: background .5s ease-in-out;}.timeline ul li.in-view::after {  background: #F45B69;}.timeline ul li div {  visibility: hidden;  opacity: 0;  transition: all .5s ease-in-out;}.timeline ul li:nth-child(odd) div {  transform: translate3d(200px, 0, 0);}.timeline ul li:nth-child(even) div {  transform: translate3d(-200px, 0, 0);}.timeline ul li.in-view div {  transform: none;  visibility: visible;  opacity: 1;}/* GENERAL MEDIA QUERIES–––––––––––––––––––––––––––––––––––––––––––––––––– */@media screen and (max-width: 900px) {  .timeline ul li div {    width: 250px;  }  .timeline ul li:nth-child(even) div {    left: -289px;    /*250+45-6*/  }}@media screen and (max-width: 600px) {  .timeline ul li {    margin-left: 20px;  }  .timeline ul li div {    width: calc(100vw - 91px);  }  .timeline ul li:nth-child(even) div {    left: 45px;  }  .timeline ul li:nth-child(even) div::before {    left: -15px;    border-width: 8px 16px 8px 0;    border-color: transparent #F45B69 transparent transparent;  }}</style></head><body><section class="intro">  <div class="container">    <h1>Vertical Timeline ↓</h1>  </div></section><section class="timeline">  <ul>    <li>      <div>        <time>1934</time> demo1      </div>    </li>    <li>      <div>        <time>1937</time> demo1      </div>    </li>    <li>      <div>        <time>1940</time> demo1      </div>    </li>    <li>      <div>        <time>1943</time> demo1      </div>    </li>    <li>      <div>        <time>1946</time> demo1      </div>    </li>    <li>      <div>        <time>1956</time> demo1      </div>    </li>    <li>      <div>        <time>1957</time> demo1      </div>    </li>    <li>      <div>        <time>1967</time>demo1      </div>    </li>    <li>      <div>        <time>1977</time> demo1      </div>    </li>    <li>      <div>        <time>1985</time> demo1      </div>    </li>    <li>      <div>        <time>2000</time> demo1      </div>    </li>    <li>      <div>        <time>2005</time> demo1      </div>    </li>  </ul></section><script type="text/javascript">(function() {  'use strict';  // define variables  var items = document.querySelectorAll(".timeline li");  // check if an element is in viewport  //   function isElementInViewport(el) {    var rect = el.getBoundingClientRect();    return (      rect.top >= 0 &&      rect.left >= 0 &&      rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&      rect.right <= (window.innerWidth || document.documentElement.clientWidth)    );  }  function callbackFunc() {    for (var i = 0; i < items.length; i++) {      if (isElementInViewport(items[i])) {        items[i].classList.add("in-view");      }    }  }  // listen for events  window.addEventListener("load", callbackFunc);  window.addEventListener("resize", callbackFunc);  window.addEventListener("scroll", callbackFunc);})();</script></body></html>
3.用JavaScript构建一个简单的井字游戏

如果您想构建简单而有趣的东西来练习JavaScript知识,那么使用HTML CSS和JS创建TIC TAC TOE游戏对您来说是个不错的选择,该游戏虽然简单但并不容易,因此您需要专注于该项目的逻辑方面,因为它是该项目最具挑战性的部分。

<html>    <head>      <meta charset="utf-8" />      <meta http-equiv="X-UA-Compatible" content="IE=edge">      <meta name="description" content="">      <meta name="viewport" content="width=device-width, initial-scale=1.0" />      <title>FreeCodeCamp: Tictactoe</title><style type="text/css">@import url();$app-background-color : #508ABB;$app-row-height : 100%;$winAnimStartColor : cyan;$winAnimEndColor : #508ABB;// html, body, div, span, a, li, td, th {//  font-family: 'Lato', sans-serif;//  font-weight: 300;//// }@-webkit-keyframes winAnim{    0% {    background-color: $winAnimStartColor;  }  100% {    background-color: $winAnimEndColor;  }}@-moz-keyframes winAnim{  0% {    background-color: $winAnimStartColor;  }  100% {    background-color: $winAnimEndColor;  }}@-o-keyframes winAnim {  0% {    background-color: $winAnimStartColor;  }  100% {    background-color: $winAnimEndColor;  }}@keyframes winAnim {  0% {    background-color: $winAnimStartColor;  }  100% {    background-color: $winAnimEndColor;  }}@keyframes winAnim {  0% {    background-color: $winAnimStartColor;  }  100% {    background-color: $winAnimEndColor;  }}*{  -webkit-touch-callout: none;  -webkit-user-select: none;  -khtml-user-select: none;  -moz-user-select: none;  -ms-user-select: none;  user-select: none;  outline-style:none;/*IE*/}.center-box{    margin : auto;    position: absolute;    top : 0;    right : 0;    bottom : 0;    left : 0;}html,body{    //background-image: linear-gradient(to bottom,#dddbd1,#d2dbdc);    background-color: #d2dbdc;    height : 100%;    width  : 100%;}.app{    @extend .center-box;    width : 80%;    height : 70%;    max-width: 550px;    background-color : $app-background-color;    box-shadow: 0 5px 30px -5px rgba(0,0,0, .85);    border-radius: 10px;    .app-container,    .app-row{        height: $app-row-height;    }}.play-box,.symbol-option{    font-family: 'Yesteryear', cursive;}.play-box{    border-bottom : 2px solid #fff;    border-right : 2px solid #fff;    height : $app-row-height / 3;    cursor: pointer;    position: relative;    &.last-right{        border-right : none;    }    &.last-bottom{        border-bottom : none;    }    &.win {        -webkit-animation: winAnim .2s ease-out infinite;      -moz-animation:    winAnim .2s ease-out infinite;      -o-animation:      winAnim .2s ease-out infinite;      animation:         winAnim .2s ease-out infinite;        animation : winAnim .5s infinite;    }    .symbol{        @extend .center-box;        width: 50%;        height : 50px;        text-align: center;        line-height : 50px;        font-size: 35px;        color : white;    }}.modal-content{    .content{        padding : 15px;        text-align: center;        margin : 0;        &.body{            line-height: 2;        }    }    .symbol-options{        width: 200px;        margin-top: 10px;        .symbol-option{            &:first-child{                margin-right: 10px;            }            &:last-child{                margin-left: 10px;            }        }    }    .warning-hr{        margin: 0;    }}</style>    </head>    <body>        <div class="app">            <div class="container-fluid app-container">            <div class="row app-row">                <div class="col-xs-4 play-box" id="0">                    <div class="symbol"></div>                </div>                <div class="col-xs-4 play-box" id="1">                    <div class="symbol"></div>                </div>                <div class="col-xs-4 play-box last-right" id="2">                    <div class="symbol"></div>                </div>                <div class="col-xs-4 play-box" id="3">                    <div class="symbol"></div>                </div>                <div class="col-xs-4 play-box" id="4">                    <div class="symbol"></div>                </div>                <div class="col-xs-4 play-box last-right" id="5">                    <div class="symbol"></div>                </div>                <div class="col-xs-4 play-box last-bottom" id="6">                    <div class="symbol"></div>                </div>                <div class="col-xs-4 play-box last-bottom" id="7">                    <div class="symbol"></div>                </div>                <div class="col-xs-4 play-box last-right last-bottom" id="8">                    <div class="symbol"></div>                </div>            </div>            </div>        </div>        <div class="modal fade app-modal" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel">          <div class="modal-dialog modal-size">            <div class="modal-content">              <h3 class="content heading">Warning!!!</h3>              <hr class="warning-hr">              <div class="content body">                  Please save your time and don't even think you're smart. <br><strong><em>I'M SMARTER THAN YOU! HA-HA-HA!!!</em></strong> <br>                  Wana try me? Chose : <br>                  <div class="center-block symbol-options">                    <button class="symbol-option btn btn-default btn-md" data-dismiss="modal">X</button> OR <button class="symbol-option btn btn-default btn-md" data-dismiss="modal">O</button>                  </div>              </div>            </div>          </div>        </div><script src="../js/bundled/tictactoe.bundled.js">        </script>    </body></html>
4.创建一个JavaScript倒数计时器开始停止重置

许多现代网站和博客都使用倒数计时器来显示倒数,例如,我们通过使用倒数计时器来告诉在线商店的访问者,商品价格将在价格上涨后增加销售量。具体时间。

<!DOCTYPE html><html lang="zh"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta http-equiv="X-UA-Compatible" content="ie=edge" /><title>CSS创建垂直时间轴(里程碑)</title><style type="text/css"> /* Variabes */  $orange: #ffa600;$grey:#f3f3f3;$white: #fff;$base-color:$orange ;/* Mixin's */  @mixin transition {-webkit-transition: all 0.5s ease-in-out;-moz-transition: all 0.5s ease-in-out;transition: all 0.5s ease-in-out;}@mixin corners ($radius) {-moz-border-radius: $radius;-webkit-border-radius: $radius;border-radius: $radius; -khtml-border-radius: $radius; }body {background:$base-color;font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; height:100%;}.wrapper {width: 800px;margin: 30px auto;color:$white;text-align:center;}h1, h2, h3 {  font-family: 'Roboto', sans-serif;  font-weight: 100;  font-size: 2.6em;  text-transform: uppercase;}#seconds, #tens{  font-size:2em;}button{@include corners (5px);background:$base-color;color:$white;border: solid 1px $white;text-decoration:none;cursor:pointer;font-size:1.2em;padding:18px 10px;width:180px;margin: 10px; outline: none;  &:hover{    @include transition;    background:$white;    border: solid 1px $white;    color:$base-color;    }} </style>    </head><body><div class="wrapper"><h1>Stopwatch</h1><h2>Vanilla JavaScript Stopwatch</h2><p><span id="seconds">00</span>:<span id="tens">00</span></p><button id="button-start">Start</button><button id="button-stop">Stop</button><button id="button-reset">Reset</button></div> <script type="text/javascript">  window.onload = function () {    var seconds = 00;   var tens = 00;   var appendTens = document.getElementById("tens")  var appendSeconds = document.getElementById("seconds")  var buttonStart = document.getElementById('button-start');  var buttonStop = document.getElementById('button-stop');  var buttonReset = document.getElementById('button-reset');  var Interval ;  buttonStart.onclick = function() {         clearInterval(Interval);     Interval = setInterval(startTimer, 10);  }      buttonStop.onclick = function() {       clearInterval(Interval);  }    buttonReset.onclick = function() {     clearInterval(Interval);    tens = "00";    seconds = "00";    appendTens.innerHTML = tens;    appendSeconds.innerHTML = seconds;  }         function startTimer () {    tens++;         if(tens < 9){      appendTens.innerHTML = "0" + tens;    }        if (tens > 9){      appendTens.innerHTML = tens;          }         if (tens > 99) {      console.log("seconds");      seconds++;      appendSeconds.innerHTML = "0" + seconds;      tens = 0;      appendTens.innerHTML = "0" + 0;    }        if (seconds > 9){      appendSeconds.innerHTML = seconds;    }    }<script src="../js/bundled/tictactoe.bundled.js">        </script>} </script>    </body></html>
5.用JavaScript创建一个简单的乒乓球游戏

我可以用JavaScript构建游戏吗?答案是肯定的,使用javascript甚至可以创建复杂的游戏,但是在这种情况下,我们将专注于一个简单的游戏,该游戏可让您练习HTML CSS和javascript技能。

<!DOCTYPE html><html lang="zh"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta http-equiv="X-UA-Compatible" content="ie=edge" /><title>使用js调用设备摄像头并实现拍照</title><style type="text/css">  body {    text-align: center;}  </style></head><body>    <script type="text/javascript">      // Global Variablesvar DIRECTION = {    IDLE: 0,    UP: 1,    DOWN: 2,    LEFT: 3,    RIGHT: 4};var rounds = [5, 5, 3, 3, 2];var colors = ['#1abc9c', '#2ecc71', '#3498db', '#e74c3c', '#9b59b6'];// The ball object (The cube that bounces back and forth)var Ball = {    new: function (incrementedSpeed) {        return {            width: 18,            height: 18,            x: (this.canvas.width / 2) - 9,            y: (this.canvas.height / 2) - 9,            moveX: DIRECTION.IDLE,            moveY: DIRECTION.IDLE,            speed: incrementedSpeed || 9        };    }};// The paddle object (The two lines that move up and down)var Paddle = {    new: function (side) {        return {            width: 18,            height: 70,            x: side === 'left' ? 150 : this.canvas.width - 150,            y: (this.canvas.height / 2) - 35,            score: 0,            move: DIRECTION.IDLE,            speed: 10        };    }};var Game = {    initialize: function () {        this.canvas = document.querySelector('canvas');        this.context = this.canvas.getContext('2d');        this.canvas.width = 1400;        this.canvas.height = 1000;        this.canvas.style.width = (this.canvas.width / 2) + 'px';        this.canvas.style.height = (this.canvas.height / 2) + 'px';        this.player = Paddle.new.call(this, 'left');        this.paddle = Paddle.new.call(this, 'right');        this.ball = Ball.new.call(this);        this.paddle.speed = 8;        this.running = this.over = false;        this.turn = this.paddle;        this.timer = this.round = 0;        this.color = '#2c3e50';        Pong.menu();        Pong.listen();    },    endGameMenu: function (text) {        // Change the canvas font size and color        Pong.context.font = '50px Courier New';        Pong.context.fillStyle = this.color;        // Draw the rectangle behind the 'Press any key to begin' text.        Pong.context.fillRect(            Pong.canvas.width / 2 - 350,            Pong.canvas.height / 2 - 48,            700,            100        );        // Change the canvas color;        Pong.context.fillStyle = '#ffffff';        // Draw the end game menu text ('Game Over' and 'Winner')        Pong.context.fillText(text,            Pong.canvas.width / 2,            Pong.canvas.height / 2 + 15        );        setTimeout(function () {            Pong = Object.assign({}, Game);            Pong.initialize();        }, 3000);    },    menu: function () {        // Draw all the Pong objects in their current state        Pong.draw();        // Change the canvas font size and color        this.context.font = '50px Courier New';        this.context.fillStyle = this.color;        // Draw the rectangle behind the 'Press any key to begin' text.        this.context.fillRect(            this.canvas.width / 2 - 350,            this.canvas.height / 2 - 48,            700,            100        );        // Change the canvas color;        this.context.fillStyle = '#ffffff';        // Draw the 'press any key to begin' text        this.context.fillText('Press any key to begin',            this.canvas.width / 2,            this.canvas.height / 2 + 15        );    },    // Update all objects (move the player, paddle, ball, increment the score, etc.)    update: function () {        if (!this.over) {            // If the ball collides with the bound limits - correct the x and y coords.            if (this.ball.x <= 0) Pong._resetTurn.call(this, this.paddle, this.player);            if (this.ball.x >= this.canvas.width - this.ball.width) Pong._resetTurn.call(this, this.player, this.paddle);            if (this.ball.y <= 0) this.ball.moveY = DIRECTION.DOWN;            if (this.ball.y >= this.canvas.height - this.ball.height) this.ball.moveY = DIRECTION.UP;            // Move player if they player.move value was updated by a keyboard event            if (this.player.move === DIRECTION.UP) this.player.y -= this.player.speed;            else if (this.player.move === DIRECTION.DOWN) this.player.y += this.player.speed;            // On new serve (start of each turn) move the ball to the correct side            // and randomize the direction to add some challenge.            if (Pong._turnDelayIsOver.call(this) && this.turn) {                this.ball.moveX = this.turn === this.player ? DIRECTION.LEFT : DIRECTION.RIGHT;                this.ball.moveY = [DIRECTION.UP, DIRECTION.DOWN][Math.round(Math.random())];                this.ball.y = Math.floor(Math.random() * this.canvas.height - 200) + 200;                this.turn = null;            }            // If the player collides with the bound limits, update the x and y coords.            if (this.player.y <= 0) this.player.y = 0;            else if (this.player.y >= (this.canvas.height - this.player.height)) this.player.y = (this.canvas.height - this.player.height);            // Move ball in intended direction based on moveY and moveX values            if (this.ball.moveY === DIRECTION.UP) this.ball.y -= (this.ball.speed / 1.5);            else if (this.ball.moveY === DIRECTION.DOWN) this.ball.y += (this.ball.speed / 1.5);            if (this.ball.moveX === DIRECTION.LEFT) this.ball.x -= this.ball.speed;            else if (this.ball.moveX === DIRECTION.RIGHT) this.ball.x += this.ball.speed;            // Handle paddle (AI) UP and DOWN movement            if (this.paddle.y > this.ball.y - (this.paddle.height / 2)) {                if (this.ball.moveX === DIRECTION.RIGHT) this.paddle.y -= this.paddle.speed / 1.5;                else this.paddle.y -= this.paddle.speed / 4;            }            if (this.paddle.y < this.ball.y - (this.paddle.height / 2)) {                if (this.ball.moveX === DIRECTION.RIGHT) this.paddle.y += this.paddle.speed / 1.5;                else this.paddle.y += this.paddle.speed / 4;            }            // Handle paddle (AI) wall collision            if (this.paddle.y >= this.canvas.height - this.paddle.height) this.paddle.y = this.canvas.height - this.paddle.height;            else if (this.paddle.y <= 0) this.paddle.y = 0;            // Handle Player-Ball collisions            if (this.ball.x - this.ball.width <= this.player.x && this.ball.x >= this.player.x - this.player.width) {                if (this.ball.y <= this.player.y + this.player.height && this.ball.y + this.ball.height >= this.player.y) {                    this.ball.x = (this.player.x + this.ball.width);                    this.ball.moveX = DIRECTION.RIGHT;                    beep1.play();                }            }            // Handle paddle-ball collision            if (this.ball.x - this.ball.width <= this.paddle.x && this.ball.x >= this.paddle.x - this.paddle.width) {                if (this.ball.y <= this.paddle.y + this.paddle.height && this.ball.y + this.ball.height >= this.paddle.y) {                    this.ball.x = (this.paddle.x - this.ball.width);                    this.ball.moveX = DIRECTION.LEFT;                    beep1.play();                }            }        }        // Handle the end of round transition        // Check to see if the player won the round.        if (this.player.score === rounds[this.round]) {            // Check to see if there are any more rounds/levels left and display the victory screen if            // there are not.            if (!rounds[this.round + 1]) {                this.over = true;                setTimeout(function () { Pong.endGameMenu('Winner!'); }, 1000);            } else {                // If there is another round, reset all the values and increment the round number.                this.color = this._generateRoundColor();                this.player.score = this.paddle.score = 0;                this.player.speed += 0.5;                this.paddle.speed += 1;                this.ball.speed += 1;                this.round += 1;                beep3.play();            }        }        // Check to see if the paddle/AI has won the round.        else if (this.paddle.score === rounds[this.round]) {            this.over = true;            setTimeout(function () { Pong.endGameMenu('Game Over!'); }, 1000);        }    },    // Draw the objects to the canvas element    draw: function () {        // Clear the Canvas        this.context.clearRect(            0,            0,            this.canvas.width,            this.canvas.height        );        // Set the fill style to black        this.context.fillStyle = this.color;        // Draw the background        this.context.fillRect(            0,            0,            this.canvas.width,            this.canvas.height        );        // Set the fill style to white (For the paddles and the ball)        this.context.fillStyle = '#ffffff';        // Draw the Player        this.context.fillRect(            this.player.x,            this.player.y,            this.player.width,            this.player.height        );        // Draw the Paddle        this.context.fillRect(            this.paddle.x,            this.paddle.y,            this.paddle.width,            this.paddle.height        );        // Draw the Ball        if (Pong._turnDelayIsOver.call(this)) {            this.context.fillRect(                this.ball.x,                this.ball.y,                this.ball.width,                this.ball.height            );        }        // Draw the net (Line in the middle)        this.context.beginPath();        this.context.setLineDash([7, 15]);        this.context.moveTo((this.canvas.width / 2), this.canvas.height - 140);        this.context.lineTo((this.canvas.width / 2), 140);        this.context.lineWidth = 10;        this.context.strokeStyle = '#ffffff';        this.context.stroke();        // Set the default canvas font and align it to the center        this.context.font = '100px Courier New';        this.context.textAlign = 'center';        // Draw the players score (left)        this.context.fillText(            this.player.score.toString(),            (this.canvas.width / 2) - 300,            200        );        // Draw the paddles score (right)        this.context.fillText(            this.paddle.score.toString(),            (this.canvas.width / 2) + 300,            200        );        // Change the font size for the center score text        this.context.font = '30px Courier New';        // Draw the winning score (center)        this.context.fillText(            'Round ' + (Pong.round + 1),            (this.canvas.width / 2),            35        );        // Change the font size for the center score value        this.context.font = '40px Courier';        // Draw the current round number        this.context.fillText(            rounds[Pong.round] ? rounds[Pong.round] : rounds[Pong.round - 1],            (this.canvas.width / 2),            100        );    },    loop: function () {        Pong.update();        Pong.draw();        // If the game is not over, draw the next frame.        if (!Pong.over) requestAnimationFrame(Pong.loop);    },    listen: function () {        document.addEventListener('keydown', function (key) {            // Handle the 'Press any key to begin' function and start the game.            if (Pong.running === false) {                Pong.running = true;                window.requestAnimationFrame(Pong.loop);            }            // Handle up arrow and w key events            if (key.keyCode === 38 || key.keyCode === 87) Pong.player.move = DIRECTION.UP;            // Handle down arrow and s key events            if (key.keyCode === 40 || key.keyCode === 83) Pong.player.move = DIRECTION.DOWN;        });        // Stop the player from moving when there are no keys being pressed.        document.addEventListener('keyup', function (key) { Pong.player.move = DIRECTION.IDLE; });    },    // Reset the ball location, the player turns and set a delay before the next round begins.    _resetTurn: function(victor, loser) {        this.ball = Ball.new.call(this, this.ball.speed);        this.turn = loser;        this.timer = (new Date()).getTime();        victor.score++;        beep2.play();    },    // Wait for a delay to have passed after each turn.    _turnDelayIsOver: function() {        return ((new Date()).getTime() - this.timer >= 1000);    },    // Select a random color as the background of each level/round.    _generateRoundColor: function () {        var newColor = colors[Math.floor(Math.random() * colors.length)];        if (newColor === this.color) return Pong._generateRoundColor();        return newColor;    }};var Pong = Object.assign({}, Game);Pong.initialize();    </script></body></html>

本篇未完结,请继续看下一篇:手把手教你7个有趣的JavaScript 项目-下「附源码」

推荐JavaScript经典实例学习资料文章

《JavaScript 使用 mediaDevices API 访问摄像头自拍》

《手把手教你前端代码如何做错误上报「JS篇」》

《一文让你彻底搞懂移动前端和Web 前端区别在哪里》

《63个JavaScript 正则大礼包「值得收藏」》

《提高你的 JavaScript 技能10 个问答题》

《JavaScript图表库的5个首选》

《一文彻底搞懂JavaScript 中Object.freeze与Object.seal的用法》

《可视化的 JS:动态图演示 - 事件循环 Event Loop的过程》

《教你如何用动态规划和贪心算法实现前端瀑布流布局「实践」》

《可视化的 js:动态图演示 Promises & Async/Await 的过程》

《原生JS封装拖动验证滑块你会吗?「实践」》

《如何实现高性能的在线 PDF 预览》

《细说使用字体库加密数据-仿58同城》

《Node.js要完了吗?》

《Pug 3.0.0正式发布,不再支持 Node.js 6/8》

《纯JS手写轮播图(代码逻辑清晰,通俗易懂)》

《JavaScript 20 年 中文版之创立标准》

《值得收藏的前端常用60余种工具方法「JS篇」》

《箭头函数和常规函数之间的 5 个区别》

《通过发布/订阅的设计模式搞懂 Node.js 核心模块 Events》

《「前端篇」不再为正则烦恼》

《「速围」Node.js V14.3.0 发布支持顶级 Await 和 REPL 增强功能》

《深入细品浏览器原理「流程图」》

《JavaScript 已进入第三个时代,未来将何去何从?》

《前端上传前预览文件 image、text、json、video、audio「实践」》

《深入细品 EventLoop 和浏览器渲染、帧动画、空闲回调的关系》

《推荐13个有用的JavaScript数组技巧「值得收藏」》

《前端必备基础知识:window.location 详解》

《不要再依赖CommonJS了》

《犀牛书作者:最该忘记的JavaScript特性》

《36个工作中常用的JavaScript函数片段「值得收藏」》

《Node + H5 实现大文件分片上传、断点续传》

《一文了解文件上传全过程(1.8w字深度解析)「前端进阶必备」》

《【实践总结】关于小程序挣脱枷锁实现批量上传》

《手把手教你前端的各种文件上传攻略和大文件断点续传》

《字节跳动面试官:请你实现一个大文件上传和断点续传》

《谈谈前端关于文件上传下载那些事【实践】》

《手把手教你如何编写一个前端图片压缩、方向纠正、预览、上传插件》

《最全的 JavaScript 模块化方案和工具》

《「前端进阶」JS中的内存管理》

《JavaScript正则深入以及10个非常有意思的正则实战》

《前端面试者经常忽视的一道JavaScript 面试题》

《一行JS代码实现一个简单的模板字符串替换「实践」》

《JS代码是如何被压缩的「前端高级进阶」》

《前端开发规范:命名规范、html规范、css规范、js规范》

《【规范篇】前端团队代码规范最佳实践》

《100个原生JavaScript代码片段知识点详细汇总【实践】》

《关于前端174道 JavaScript知识点汇总(一)》

《关于前端174道 JavaScript知识点汇总(二)》

《关于前端174道 JavaScript知识点汇总(三)》

《几个非常有意思的javascript知识点总结【实践】》

《都2020年了,你还不会JavaScript 装饰器?》

《JavaScript实现图片合成下载》

《70个JavaScript知识点详细总结(上)【实践】》

《70个JavaScript知识点详细总结(下)【实践】》

《开源了一个 JavaScript 版敏感词过滤库》

《送你 43 道 JavaScript 面试题》

《3个很棒的小众JavaScript库,你值得拥有》

《手把手教你深入巩固JavaScript知识体系【思维导图】》

《推荐7个很棒的JavaScript产品步骤引导库》

《Echa哥教你彻底弄懂 JavaScript 执行机制》

《一个合格的中级前端工程师需要掌握的 28 个 JavaScript 技巧》

《深入解析高频项目中运用到的知识点汇总【JS篇】》

《JavaScript 工具函数大全【新】》

《从JavaScript中看设计模式(总结)》

《身份证号码的正则表达式及验证详解(JavaScript,Regex)》

《浏览器中实现JavaScript计时器的4种创新方式》

《Three.js 动效方案》

《手把手教你常用的59个JS类方法》

《127个常用的JS代码片段,每段代码花30秒就能看懂-【上】》

《深入浅出讲解 js 深拷贝 vs 浅拷贝》

《手把手教你JS开发H5游戏【消灭星星】》

《深入浅出讲解JS中this/apply/call/bind巧妙用法【实践】》

《手把手教你全方位解读JS中this真正含义【实践】》

《书到用时方恨少,一大波JS开发工具函数来了》

《干货满满!如何优雅简洁地实现时钟翻牌器(支持JS/Vue/React)》

《手把手教你JS 异步编程六种方案【实践】》

《让你减少加班的15条高效JS技巧知识点汇总【实践】》

《手把手教你JS开发H5游戏【黄金矿工】》

《手把手教你JS实现监控浏览器上下左右滚动》

《JS 经典实例知识点整理汇总【实践】》

《2.6万字JS干货分享,带你领略前端魅力【基础篇】》

《2.6万字JS干货分享,带你领略前端魅力【实践篇】》

《简单几步让你的 JS 写得更漂亮》

《恭喜你获得治疗JS this的详细药方》

《谈谈前端关于文件上传下载那些事【实践】》

《面试中教你绕过关于 JavaScript 作用域的 5 个坑》

《Jquery插件(常用的插件库)》

《【JS】如何防止重复发送ajax请求》

《JavaScript+Canvas实现自定义画板》

《Continuation 在 JS 中的应用「前端篇」》

标签: #smartclientajax