打字软件带倒计时_使用VueJS创建打字速度效果-第2部分:计时器和计分板

打字软件带倒计时

Introduction In Part 1 - Create a Typing Speed Effect with VueJS We saw how to create a Typing Speed Effect. We are going to extend what we built previously, and include a timer and a score board, so that users can type and see the times they typed in faster.

简介在第1部分中-使用VueJS创建打字速度效果我们看到了如何创建打字速度效果。 我们将扩展以前构建的内容,包括一个计时器和一个计分板,以便用户可以更快地键入和查看输入时间。

In order to follow along, you must have read through part 1. Logic Since we already have the typing effect covered, we need to do the following.

为了继续学习,您必须已经阅读了第1部分 。 逻辑由于已经涵盖了打字效果,因此我们需要执行以下操作。

  1. There should be a 60 second timer that will count down whenever a user is typing.

    应该有一个60秒的计时器,每当用户键入内容时,该计时器就会倒计时。
  2. When the time reaches 0 (Zero), the typing area should be blured, and the typing speed calculated.

    时间到达0(零)时,应使打字区域模糊,并计算打字速度。
  3. The metrics for calculating the typing speed for a user is Number of correct words typed in a minute + typos.

    计算用户打字速度的指标是每分钟输入的正确字数+错字。
  4. We will also give the user the number of typos they made as a single number.

    我们还将为用户提供他们输入的错别字数量。
  5. We will then list the leading scores every time a session is ended.

    然后,我们将在每次会话结束时列出领先分数。

The Complete App will look something close to this. Here's a link to a deployed version: https://ganga.dev/vue-typer/

打字软件带倒计时_使用VueJS创建打字速度效果-第2部分:计时器和计分板_第1张图片

完整版应用程序看起来与此相似。 这是已部署版本的链接: https : //ganga.dev/vue-typer/

Project Setup Since this is a continuation from part 1, I created a repository that starts at the stage we left part 1 in.

项目设置由于这是第1部分的继续,因此我创建了一个存储库,该存储库从第1部分进入的阶段开始。

Clone this repository. https://github.com/gangachris/vue\-typer, and run the existing app.

克隆此存储库。 https://github.com/gangachris/vue\-typer ,然后运行现有的应用程序。

git clone https://github.com/gangachris/vue-typer
cd vue-typer
npm install
npm start

The repository has some slight modifications from where we left part 1. We now have a package.json, which installs httpster, and adds a start script npm start to start the app.

该存储库从第1部分开始进行了一些修改。现在,我们有一个package.json,它安装了httpster ,并添加了一个启动脚本npm start来启动该应用程序。

{
  "name": "vuetyper",
  "version": "1.0.0",
  "main": "script.js",
  "scripts": {
    "start": "httpster"
  },
  "license": "MIT",
  "devDependencies": {
    "httpster": "^1.0.3"
  }
}

At this point, after running npm start, you should see the following in your browser when you visit localhost:3333.

打字软件带倒计时_使用VueJS创建打字速度效果-第2部分:计时器和计分板_第2张图片

此时,运行npm start ,当您访问localhost:3333时,应在浏览器中看到以下内容。

You can type in the text area to see the typing speed and typos effect. We explained how this was achieved in part 1 of this article. Timer UI We're going to add a digital timer, which is just a countdown. Let's add some html where the timer will be.

您可以在文本区域中键入以查看键入速度和错别字效果。 我们在本文的第1部分中解释了如何实现这一点。 计时器用户界面我们将添加一个数字计时器,这只是一个倒计时。 让我们在计时器所在的位置添加一些html。

First of all add some styling.

首先添加一些样式。

index.html

index.html


<html lang="en">
    <head>
        <style>
        
        .timer {
          font-size: 100px;
          text-align: center;
          color: white;
          border-radius: 100;
          background-color: green;
        }
        style>
    head>
    
html>

The styles above adds a timer which will style our timer div.

上面的样式添加了一个timer ,它将为我们的计时器div设置样式。

Next, let's add in the relevant html for the timer.

接下来,让我们为计时器添加相关的html。

index.html

index.html


<html lang="en">

<head>
  
head>

<body>
  <div id="app"
       class="container mt-2">
    <h1>{{ title }}h1>
    <div class="row">
      <div class="col-8">
         
        <div class="typer mt-3">
          
        div>
      div>
      <div class="col-4">
        <div class="timer">
          60
        div>
      div>
    div>
  div>
  
body>

html>

We've added a

below the div that has the paragraph and the typing effect. We've also added the the class that we added earlier: .timer. Refreshing the page should on the browser show this.

打字软件带倒计时_使用VueJS创建打字速度效果-第2部分:计时器和计分板_第3张图片 Timer Logic Here's the logic we are trying to achieve.

我们添加了一个

下面div具有段落和打字的效果。 我们还添加了之前添加的类: .timer 。 刷新页面应在浏览器上显示出来。

  1. When a user starts typing, the timer will start counting down.

    当用户开始打字时,计时器将开始倒计时。
  2. The timer and the text area should be reset when countdown ends.

    倒计时结束时,应重置计时器和文本区域。

倒计时器 ( Countdown Timer )

Let's add the countdown logic.

让我们添加倒数逻辑。

We'll start by adding a state variable called timer.

我们将从添加一个名为timer的状态变量开始。

script.js

script.js

new Vue({
  el: '#app',
  data: {
    title: 'Vue Typer',
    originalText: PARAGRAPH,
    typedText: '',
    typoIndex: -1,
    timer: 60 // add timer state variable
  }
})
/// code commented out for brevity

Next bind the timer to the html.

接下来将计时器绑定到html。


<div class="col-4">
    <div class="timer">
      {{timer}}
    div>
div>

Next, we'll use the JavaScript function setInterval, which allows us to run a function at intervals.

接下来,我们将使用JavaScript函数setInterval ,它使我们能够定期运行一个函数。

The setInterval() method of the WindowOrWorkerGlobalScope mixin repeatedly calls a function or executes a code snippet, with a fixed time delay between each call. It returns an interval ID which uniquely identifies the interval, so you can remove it later by calling clearInterval(). This method is offered on the Window and Worker interfaces.

WindowOrWorkerGlobalScope mixin的setInterval()方法重复调用函数或执行代码段,每次调用之间有固定的时间延迟。 它返回一个唯一标识该间隔的间隔ID,因此您以后可以通过调用clearInterval()将其删除。 在Window和Worker界面上提供此方法。

script.js

script.js

// code commented out for brevity
new Vue({
  el: '#app',
  // code commented out for brevity
  methods: {
    startTypingSpeed: function () {
      // start the typing speed
    },
    startTimer: function () {
      setInterval(function () {
        if (this.timer === 0) {
          this.endTypingSpeed()
          return;
        }
        this.timer--
      }, 1000)
    },
    endTypingSpeed: function () {
      // end the typing speed
    },
    reset: function() {
      // reset everything
    }
  }
})

We have three methods.

我们有三种方法。

  • startTypingSpeed: will be used to start the typing speed

    startTypingSpeed :将用于启动打字速度
  • startTimer: will be used to start the timer

    startTimer :将用于启动计时器
  • endTypingSpeed: will be used to end the typing speed

    endTypingSpeed :将用于结束打字速度

We can now trigger the timer to start when we start typing. To do this, we'll add another state variable called typing which is a boolean representing whether we have started typing.

现在,我们可以在开始打字时触发计时器开始计时。 为此,我们将添加另一个名为typing状态变量,它是一个布尔值,表示我们是否已开始键入。

new Vue({
  el: '#app',
  data: {
    // code commented out for brevity
   typing: false
  }
})
/// code commented out for brevity

NOTE While making this, I ran into a bug that seasonal javascript developers might be aware of. If you look at this part of the code.

注意进行此操作时,我遇到了一个季节性JavaScript开发人员可能会意识到的错误。 如果您看一下这部分代码。

startTimer: function () {
      setInterval(function () {
        if (this.timer === 0) {
          this.endTypingSpeed()
          return;
        }
        this.timer--
      }, 1000)
 },

Notice we have a the main function startTimer, and another function inside the setInterval. This means that the second function creates it's own this variable, and therefore replaces the VueJS instance this.

注意,我们有一个主要函数startTimer ,以及另一个在setInterval内部的函数。 这意味着第二个函数创建了它自己的this变量,因此替换了VueJS实例this

There are two ways to solve this problem.

有两种方法可以解决此问题。

  1. use var self = this - this allows us to save the Vue instance this into a new variable, and since objects are passed by reference in JavaScript, everything will work fine.

    使用var self = this this-这使我们可以将Vue实例保存到新变量中,并且由于对象是通过JavaScript中的引用传递的,因此一切正常。
  2. use arrow functions

    使用箭头功能

This is from Mozilla Developer Network on arrow functions

这是来自Mozilla开发人员网络上的箭头功能

An arrow function does not have its own this; the this value of the enclosing execution context is used. Thus, in the following code, the this within the function that is passed to setInterval has the same value as this in the enclosing function:

箭头函数没有它自己的; 使用封闭执行上下文的this值。 因此,在以下代码中,传递给setInterval的函数中的this与封闭函数中的this具有相同的值:

function Person(){
  this.age = 0;

  setInterval(() => {
    this.age++; // |this| properly refers to the Person object
  }, 1000);
}

var p = new Person();

I decide to go with arrow functions. This is the new script.js

我决定使用箭头功能。 这是新的script.js

const PARAGRAPH = "..."
new Vue({
  el: '#app',
  data: {
    // code commented out for brevity
    typing: false,
    timerInterval: {} // new timerInterval state variable to allow clearInterval
  },
  methods: {
   // we start the typing speed here by changing typing to true
   // and starting the timer
    startTypingSpeed: function() {
        this.typing = true
        this.startTimer()
    },
    startTimer: function() {
     // replace the timer function to use arrow functions
     // because arrow functions use a `this` that belongs to the
      // context wrapping it.
      this.timerInterval  =  setInterval(() => {
        if (this.timer === 0) {
          this.endTypingSpeed()
          return
        }
        this.timer--
      }, 1000)
    },
    endTypingSpeed: function() {
     // end the typing speed
     // change typing back to false and
     // blur the typing area
      clearInterval(this.timerInterval);
      this.typing = false;
      this.timer = 60;
      document.activeElement.blur();
    },
    reset: function() {
      // reset everything
      clearInterval(this.timerInterval);
      this.typing = false;
      this.typoIndex = -1;
      this.typedText = '';
      this.timer = 60;
    }
  },
  computed: {
    outputHTML: function() {
      // code commented out for brevity
    }
  },
  watch: {
    typedText: function(value) {
     // check if already typing, else start the timer.
      if (!this.typing) {
        this.startTypingSpeed()
      }
      for (let i = 0; i < value.length; i++) {
        if (value[i] !== this.originalText[i]) {
          this.typoIndex = i;
          break;
        }
        this.typoIndex = -1;
      }
    }
  }
});

I've made comments on every new thing changed in the codebase.

我已经对代码库中发生的每项新变化发表了评论。

Another change that needs to be explained is addition of another state variable timerInterval. This is then assigned the setInterval function value. The reason for this is so that at the end we can use clearInterval to stop the interval function from running forever.

需要说明的另一个更改是添加了另一个状态变量timerInterval 。 然后setInterval分配setInterval函数值。 这样做的原因是,最后我们可以使用clearInterval来阻止interval函数永远运行。

If we run the app again, and start typing, we'll see the timer counting down.

打字软件带倒计时_使用VueJS创建打字速度效果-第2部分:计时器和计分板_第4张图片 The GIF is a bit slow, but you get the idea.

如果我们再次运行该应用程序并开始输入,我们将看到计时器递减计数。

The final step here is to add a reset button, so that a user can start a bew session. The logic for this has already been implemented in the reset function.

这里的最后一步是添加一个重置按钮,以便用户可以启动bew会话。 reset功能中已实现了此逻辑。

reset: function() {
      // reset everything
      clearInterval(this.timerInterval);
      this.typing = false;
      this.typoIndex = -1;
      this.typedText = '';
      this.timer = 60;
    }

So we only need to add in the button. Let's add it on top of the timer.

所以我们只需要添加按钮。 让我们将其添加到计时器顶部。

index.html

index.html

<div class="col-4">
    <button class="btn btn-primary btn-block" @click="reset()">Resetbutton>
    <div class="timer mt-3">
      {{ timer }}
    div>
 div>

VueJS uses v-on directive to register events. It has a short hand @ which can be used too, and that is what we've used here. The rest is standard CSS buttons.

VueJS使用v-on指令注册事件。 它有一个简写@ ,也可以使用,这就是我们在这里使用的。 其余的是标准CSS按钮。

The page should now look like below

打字软件带倒计时_使用VueJS创建打字速度效果-第2部分:计时器和计分板_第5张图片

该页面现在应如下所示

You can start typing, and test it out. Score Board UI Since the idea is that you can type as many times as you want, we're adding in a score board.

您可以开始输入并进行测试。 记分板用户界面由于想法是您可以输入任意多次,因此我们添加了一个记分板。

Add the following html, below the timer div.

在timer div下面添加以下html。

<div class="scoreboard mt-3">
  <h2>Scoreboardh2>
  <div class="scores">
    <div class="alert-info mt-2">1. 20 WPM, 45 Typos div>
    <div class="alert-info mt-2">2. 20 WPM, 45 Typos div>
    <div class="alert-info mt-2">3. 20 WPM, 45 Typos div>
  div>
div>

The page should now look like this. Forgive my design skills ;-)

打字软件带倒计时_使用VueJS创建打字速度效果-第2部分:计时器和计分板_第6张图片

该页面现在应如下所示。 原谅我的设计技巧;-)

计分板逻辑 ( Score Board Logic )

Here's the logic for the Score Board.

这是计分板的逻辑。

  1. Whenever there's an endTypingSpeed event, we calculate the scores that particular session.

    每当发生endTypingSpeed事件时,我们都会计算该特定会话的得分。
  2. We need to also collect the typos, so this will happen during typing, and will be save in a variable.

    我们还需要收集拼写错误,因此这将在键入期间发生,并将其保存在变量中。
  3. We then rank the scores on the left, depending on the number of times the user plays.

    然后,根据用户播放的次数,将得分排在左侧。

First of all, let's add in a score state variable, and a typos state variable, since we will be counting typos, which will be an array.

首先,让我们添加一个得分状态变量和一个错别字状态变量,因为我们将要计算错别字,它是一个数组。

new Vue({
  el: '#app',
  data: {
    // code commented out for brevity
    typos: 0,
    scores: []
  }
})

Next, let's count the typos in the typedText watcher.

接下来,让我们计算typedText监视程序中的错别字。

// code commented out for brevity
watch: {
    typedText: function(value) {
      if (!this.typing) {
        this.startTypingSpeed();
      }
      for (let i = 0; i < value.length; i++) {
        if (value++[++i] !== this.originalText++[++i]) {
          this.typoIndex = i;
          this.typos++; // increase the typo count
          break;
        }
        this.typoIndex = -1;
      }
    }
  }
 // code commented out for brevity

Withing the loop, when we find a typo we increase the typo value by one.

随着循环的进行,当我们发现错字时,我们会将错字值增加一。

Next, We'll get the total number of correct values typed. The logic here is to get the typoIndex and use that to calculate the number of correct words typed. We'll add in a method called calculateScore. Add this under the methods property of the VueJS instance.

接下来,我们将获得键入的正确值的总数。 这里的逻辑是获取typoIndex并使用它来计算输入的正确单词的数量。 我们将添加一个名为calculateScore的方法。 将其添加到VueJS实例的methods属性下。

calculateScore: function() {
      let score = {};
      let correctlyTypedText = this.typedText
      if (this.typoIndex != -1) {
        correctlyTypedText = this.originalText.substring(0, this.typoIndex);
      }
      let words = correctlyTypedText.split(' ').length;
      score = {
        wpm: words,
        typos: this.typos
      };

      // reset typos
      this.typos = 0;
      this.scores.push(score);
    }

We get the correctly typed text by taking a substring of the original text, and the typo index, then we spit it by spaces to get the words with split method for javascript strings. If we do not have a typo, then we take the existing typed in text.

我们通过获取原始文本的子字符串和错字索引来获得正确键入的文本,然后将其吐入空格以使用split方法获取用于javascript字符串的单词。 如果我们没有错字,那么我们将使用现有的键入文本。

We then just do a count, and create a score object, which we push into the existing scores state variable. this.scores. Remember to reset the typos back to 0.

然后,我们只做一个计数,并创建一个得分对象,将其推入现有的得分状态变量中。 this.scores 。 记住将错别字重设为0。

Next, add this function after the endTypingSpeed function is called, within the startTimer function.

接下来,在startTimer函数内调用endTypingSpeed函数后添加此函数。

startTimer: function() {
      this.timerInterval = setInterval(() => {
        if (this.timer === 0) {
          this.endTypingSpeed();
          this.calculateScore(); // calculate the typing speed
          return;
        }
        this.timer--;
      }, 1000);
    },

We now have to display the typing speed result on the score board. We do this by using a v-for directive like shown below.

现在,我们必须在记分板上显示打字速度结果。 我们通过使用如下所示的v-for指令来做到这一点。

<div class="scoreboard mt-3">
          <h2>Scoreboardh2>
          <div class="scores">
            <div class="alert-info mt-2"
                 v-for="(score, index) in scores">{{index + 1}}. {{score.wpm}} WPM, {{score.typos}} Typos div>
          div>
        div>

v-for directive for vue allows us to loop over lists, and can take the form of v-for="item in items", or v-for="(item, index) in items" when we need to access the indices.

vue的v-for指令允许我们遍历列表,并v-for="(item, index) in items"需要访问索引时可以采用v-for="item in items" ,或v-for="(item, index) in items"的形式。

Run the app, and type in a few times, you should see the results.

打字软件带倒计时_使用VueJS创建打字速度效果-第2部分:计时器和计分板_第7张图片

运行该应用程序,然后输入几次,您应该会看到结果。

The last step for this article is to sort/rank the results in the score board. We'll do this again using computed properties, so that the logic is clear. Add a computed property to the VueJS instance

本文的最后一步是在计分板上对结果进行排序/排名。 我们将使用计算属性再次进行此操作,以使逻辑清晰。 将计算的属性添加到VueJS实例

// code commented out for brevity
computed: {
    outputHTML: function() {
      // code commented out for brevity
    },
    sortedScores: function() {
      return this.scores.sort((a, b) => {
        return a.wpm + a.typos - (b.wpm + b.typos);
      });
    }
  },
 // code commented out for brevity

Then replace the scores list in the html to use sortedScores

然后替换html中的scores列表以使用sortedScores

<div class="alert-info mt-2"
                 v-for="(score, index) in sortedScores">{{index + 1}}. {{score.wpm}} WPM, {{score.typos}} Typos div>

The app should be running well if you check it in the browsers. Bugs/Cheats Like any other game out there, there are a couple of ways people can cheat the game. Here are a few:

如果在浏览器中检查该应用程序,则该应用程序应运行良好。 错误/作弊就像其他任何游戏一样,人们可以通过多种方式欺骗游戏。 这里有一些:

  1. Someone Copies and Pastes the content directly into the text area ¯_(ツ)_/¯

    有人将内容直接复制并粘贴到文本区域__(ツ)_ /
  2. Someone Opens the dev tools to increase the timer

    有人打开开发工具以增加计时器
  3. If you play about 100 times, the list will get long and messy.

    如果您播放约100次,该列表将变得冗长而混乱。

We are not really worried about this, because it's intended to run on a local machine. Can you think of ways to stop this, and leave a comment. Conclusion VueJS brings with it the purity of vanilla javascript and a bit of helpful tools. You can see that apart from the bindings, most of the code written is pure Javascript, with line by line thinking.

我们并不对此感到真正担心,因为它旨在在本地计算机上运行。 您能想到阻止这种情况的方法,并发表评论吗? 结束语VueJS带来了纯正的javascript JavaScript和一些有用的工具。 您可以看到,除了绑定之外,大多数编写的代码都是纯Javascript,而且是逐行思考的。

The full code can be found in the complete branch of the repository.

完整的代码可以在存储库的完整分支中找到。

I hope you enjoyed this, and Happy Coding.

希望您喜欢这个,并祝您编码愉快。

翻译自: https://scotch.io/tutorials/create-a-typing-speed-effect-with-vuejs-part-2-timer-and-score-board361

打字软件带倒计时

你可能感兴趣的:(打字软件带倒计时_使用VueJS创建打字速度效果-第2部分:计时器和计分板)