vue.js will move to achieve a resume (bottom comprising a navigation function, editing, adding a user-defined function writing speed)

In line to see a website like this, STRML it looked very interesting results, as shown below:

 

 

This site is a `react.js` to write, so I was thinking` vue.js` also used to write a version, start line and code.

We must first analyze the typing of the realization of the principle, suppose we define a string `str`, which is equal to a long list of comments add` CSS` code, and we see that when the code is written `css` a semicolon when it wrote the style will take effect. We know that to get some `CSS` code is live page and need to be placed in a pair of` <style> `tags can be. such as:

 

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
    Red coloured words
    <style>
        body{
            color:#f00;
        }
    </style>
</body>
</html>

 

 

You can click here to severely Specific examples see the effect.

When you see the results when typing, we can think of, which is to be called the `batch (timer function: setInterval ())` `or call a timeout (delay function: setTimeout ())` `added recursion` `to achieve simulation `intermittent call. A code comprising a string of long list, which is taken out one by one, and then written to the page, respectively, where we need to use the string interception method, such as `slice (), substr (), substring () `etc., with which the interception of personal choice, but to note the differences between them. Well, let's implement a simple effect of this type, as follows:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
    <div id="result"></div>
    <script>
        var r = document.getElementById('result'); var c = 0; var code = 'body{background-color:#f00;color:#fff};' var timer = setInterval(function(){ c++; r.innerHTML = code.substr(0,c); if(c >= code.length){ clearTimeout(timer); } },50) </script> </body> </html> 

 

You can click here to severely Specific examples see the effect. Well, let us examine the principles of the code above, first put a label containing the code for display, and then define a string of code contains, and then define a variable initial value `0`, why should define such a variables? We have seen from the actual results, which is written a word a word to the page. The initial value is not a character, so we first `0` is written from the beginning,` c` add a word by word, and then stop the interception of the string, and finally render the contents of the label were to go, when after the value of the `C` is not less than the length of the string, we need to clear the timer. Timing function looked some not so good, let's implement a combination of recursive calls timeout.

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>JS Bin</title>
</head>

<body>
    <div id="result"></div>
    <script>
        var r = document.getElementById('result'); var c = 0; var code = 'body{background-color:#f00;color:#fff};'; var timer; function write() { c++; r.innerHTML = code.substr(0, c); if (c >= code.length && timer) { clearTimeout(timer) } else { setTimeout(write, 50); } } write(); </script> </body> </html>

 



You can click here to severely Specific examples see the effect.

Well, so far, regarded as the first step to achieve, let us continue, then, we want to maintain the code and blank indentation, which you can use `<pre>` tag to achieve, but in fact we can use css `white-space` property Code to make a general label of` div` maintain this effect, why do it, because we need to implement a function, that is, edit it inside the code, it can take effect. Change the code as follows:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>JS Bin</title>
    <style>
        #result {
            white-space: pre-wrap;
            overflow: auto;
        } </style> </head> <body> <div id="result"></div> <script> var r = document.getElementById('result'); var c = 0; var code = ` body{ background-color:#f00; color:#fff; }`; var timer; function write() { c++; r.innerHTML = code.substr(0, c); if (c >= code.length && timer) { clearTimeout(timer) } else { setTimeout(write, 50); } } write(); </script> </body> </html>

 


You can click here to severely Specific examples see the effect.

Next, we have to let the styles to take effect, it is very simple, once the code is written in `style` tab, see:

 

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>JS Bin</title>
    <style>
        #result {
            white-space: pre-wrap;
            overflow: auto;
        } </style> </head> <body> <div id="result"></div> <style id="myStyle"></style> <script> var r = document.getElementById('result'), t = document.getElementById('myStyle'); var c = 0; var code = ` body{ background-color:#f00; color:#fff; }`; var timer; function write() { c++; r.innerHTML = code.substr(0, c); t.innerHTML = code.substr(0, c); if (c >= code.length) { clearTimeout(timer); } else { setTimeout(write, 50); } } write(); </script> </body> </html>

 

 

You can click here to severely Specific examples see the effect.

We see the code will be a highlight effect, which can be achieved using regular expressions, such as the following a `demo`:

<!DOCTYPE html>
<html lang="en">

<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> Editor </ title>
    <style>
        * {
            margin: 0;
            padding: 0;
        } .ew-code { tab-size: 4; -moz-tab-size: 4; -o-tab-size: 4; margin-left: .6em; background-color: #345; white-space: pre-wrap; color: #f2f2f2; text-indent: 0; margin-right: 1em; display: block; overflow: auto; font-size: 20px; border-radius: 5px; font-style: normal; font-weight: 400; line-height: 1.4; font-family: Consolas, Monaco, "Times New Roman" ; Top-margin : 1em ; } .EW-code span {font-weight : Bold ; } </ style> </ head> <body> <code class = "EW-code"> & lt; div ID = "App" & gt; & lt; P & gt; {{Greeting}} World & lt;! / P & gt; & lt; / div & gt; </ code> <code class = "EW-code"> // define a javascript Object var obj = {greeting: "Hello ,"}; // create an instance var vm = new Vue ({data : obj}); / * the root element mounted onto instance * / vm $ mount (document. . the getElementById ( 'App')); </ code> <Script> var lightColorCode = {importantObj: [ ' the JSON ' , ' window ' ,'document', 'function', 'navigator', 'console', 'screen', 'location'], keywords: ['if', 'else if', 'var', 'this', 'alert', 'return', 'typeof', 'default', 'with', 'class', 'export', 'import', 'new' ], method: ['Vue', 'React', 'html', 'css', 'js', 'webpack', 'babel', 'angular', 'bootstap', 'jquery', {} () _ \ - +? |] / Gim, matchStrSpecial = htmlStr.match (regxSpecial), specialLen; were flag = false ; IF (!!matchStrSpecial) { specialLen = matchStrSpecial.length; } else { specialLen = 0; return; } for (var k = 0; k < specialLen; k++) { htmlStr = htmlStr.replace(matchStrSpecial[k], '<span style="color:#b9ff01;">' + matchStrSpecial[k] + '</span>'); } for (var key in lightColorCode) { if (key === 'keywords') { lightColorCode[key].forEach(function (imp) { htmlStr = htmlStr.replace(new RegExp(imp, 'gim'), '<span style="color:#00ff78;">' + imp + '</span>') }) flag = true; } else if (key === 'importantObj') { lightColorCode[key].forEach(function (kw) { htmlStr = htmlStr.replace(new RegExp(kw, 'gim'), '<span style="color:#ec1277;">'kw++ '</span>') }) flag = true; } else if (key === 'method') { lightColorCode[key].forEach(function (mt) { htmlStr = htmlStr.replace(new RegExp(mt, 'gim'), '<span style="color:#52eeff;">' + mt + '</span>') }) flag = true; } } if (flag) { if (!!matchStrSpace) { spaceLen = matchStrSpace.length; } else { spaceLen = 0; return; } for (var i = 0; i < spaceLen; i++) { var curFont; if (window.innerWidth <= 1200) { curFont = '12px'; } else { curFont = '14px'; } htmlStr = htmlStr.replace(matchStrSpace[i], '<span style="color:#899;font-size:' + curFont + ';">' + matchStrSpace[i] + '</span>'); } el.innerHTML = htmlStr; } } var codes = document.querySelectorAll('.ew-code'); for (var i = 0, len = codes.length; i < len; i++) { setHighLight(codes[i]) } </script> </body> </html>

 



You can click here to severely Specific examples see the effect.

But here, for convenience, I use the plug `Prism.js`, another here, we have to use a plain text will fight the plug` marked.js` `HTML` pages.

Then analyze how to pause and resume the movie animation, very simple, it is clear the timer, then you can recall. How to edit the code to make it take effect, which need to use a custom event `.sync` event modifiers, see the official website` vue.js` themselves.

While here you can achieve with native `js`, but the way we use` vue-cli` combination of components to achieve, which is more simpler. Well, let's get started:

`Vue-cli` a new project (step itself Baidu):

`StyleEditor.vue` a new component, as follows:

<template>
    <div class="container">
        <div class="code" v-html="codeInstyleTag"></div>
        <div class="styleEditor" ref="container" contenteditable="true" @blur="updateCode($event)"
            v-html="highlightedCode"></div>
    </div>
</template>
<script>
    import Prism from 'prismjs'
    export default {
        name: 'Editor', The props: [ 'code' ], computed: {highlightedCode: function () {// code highlighting Prism.highlight return (the this .code, Prism.languages.css);}, // the code to take effect so codeInstyleTag: function () return `{<style> this.code $ {} </ style>` }}, Methods: {// each type to the bottom, will scroll goBottom () {$ the this refs.container.scrollTop = 10000. ; }, // the code after modification, can be revalidated UPDATECODE (E) {$ the this EMIT. ( 'Update: code' , e.target.textContent);}}} </ Script> <style scoped> .code {the display: none;} </ style>

 



`ResumeEditor.vue` a new component, as follows:

<template>
    <div class="resumeEditor" :class="{htmlMode:enableHtml}" ref="container">
        <div v-if="enableHtml" v-html="result"></div>
        <pre v-else>{{result}}</pre>
    </div>
</template>
<script>
    import marked from 'marked'
    export default {
        props: ['markdown', 'enableHtml'],
        name: 'ResumeEditor',
        computed: {
            result: function () { return this.enableHtml ? marked(this.markdown) : this.markdown } }, methods: { goBottom: function () { this.$refs.container.scrollTop = 10000 } } } </script> <style scoped> .htmlMode { anmation: flip 3s; } @keyframes flip { 0% { opacity:0; } 100% { opacity: 1; } } </style>

 

A new navigation menu bottom assembly `bottomNav.vue`, code is as follows:

<template>
    <div id="bottom">
        <a id="pause" @click="pauseFun"> {! {paused 'suspended animation':? 'resume the movie ||'}} </a>
        <a id="skipAnimation" @click="skipAnimationFun">跳过动画</a>
        <p>
            <span v-for="(url,index) in demourl" :key="index">
                <a :href="url.url">{{ url.title }}</a>
            </span>
        </p>
        <div id="music" @click="musicPause" :class="playing ? 'rotate' : ''" ref="music"></div>
    </div>
</template>
<script>
    export default {
        name: 'bottom',
        data() {
            return {
                demourl: [{
                        url: 'http://eveningwater.com/', title: 'personal website' }, {url: 'https://github.com/eveningwater' , title: 'GitHub' }], paused: false, // Pause playing: false, // play icon animation autoPlaying: false // play audio audio: '' }}, Mounted () {}, Methods: {// music playMusic () = {this.playing to true ; = this.autoPlaying to true ; // create audio tag this.audio = new new Audio (); this.audio.loop = 'Loop' ; this.audio.autoplay = 'AutoPlay' ; this.audio.src = "http://eveningwater.com/project/newReact-music-player/audio/ % E9% BB% 84% E5 % 9B% BD% E4% BF% 8A% 20-% 20% E7% 9C% 9F% E7% 88% B1% E4% BD% A0% E7% 9A% 84% E4% 91.mp3% BA " ; $ refs.music.appendChild the this (the this. .Audio);}, // skip animation skipAnimationFun (e) {e.preventDefault () ;this.$emit('on-skip'); }, // 暂停动画  pauseFun(e) { e.preventDefault(); this.paused = !this.paused; this.$emit('on-pause', this.paused); }, // 暂停音乐  musicPause() { this.playing = !this.playing; if (!this.playing) { this.audio.pause(); } else { this.audio.play(); } } } } </script> <style scoped> #bottom { position: fixed; bottom: 5px; left: 0; right: 0; } #bottom p { float: right; } #bottom a { text-decoration: none; color: #999; cursor: pointer; margin-left: 5px; } #bottom a:hover, #bottom a:active { color: #010a11; } </style>

 



Next is the core of `APP.vue` Component Code:

<template>
    <div id="app">
        <div class="main">
            <StyleEditor ref="styleEditor" v-bind.sync="currentStyle"></StyleEditor>
            <ResumeEditor ref="resumeEditor" :markdown="currentMarkdown" :enableHtml="enableHtml"></ResumeEditor>
        </div>
        <BottomNav ref="bottomNav" @on-pause="pauseAnimation" @on-skip="skipAnimation"></BottomNav>
    </div>
</template>
<script>
    import ResumeEditor from './components/resumeEditor'
    import StyleEditor from './components/styleEditor'
    import BottomNav from './components/bottomNav' import './assets/common.css' import fullStyle from './style.js' import my from './my.js' export default { name: 'app', components: { ResumeEditor, StyleEditor, BottomNav }, data() { return { interval: 40, //写入字的速度  currentStyle: { code: '' }, enableHtml: false, //是否打造成HTML网页  fullStyle: fullStyle, currentMarkdown: '', fullMarkdown: my, timer: null } }, created() { this.makeResume(); }, methods:{// Pause Animation pauseAnimation(bool) { if (bool && this.timer) { clearTimeout(this.timer); } else { this.makeResume(); } }, // 快速跳过动画  skipAnimation() { if (this.timer) { clearTimeout(this.timer); } let str = ''; this.fullStyle.map((f) => { str += f; }) setTimeout(() => { this.$set(this.currentStyle, 'code', str); }, 100) this.currentMarkdown = my; this.enableHtml = true; this.$refs.bottomNav.playMusic(); }, // 加载动画 makeResume: async function () { await this.writeShowStyle(0) await this.writeShowResume() await this.writeShowStyle(1) await this.writeShowHtml () the await this.writeShowStyle (2 .) the await the this $ nextTick (() => {the this . refs.bottomNav.playMusic $ ()});}, // playing HTML page writeShowHtml: function () {return Promise new new ((Resolve, Reject) => {= this.enableHtml to true ; Resolve ();})}, // write css code writeShowStyle (n-) {return new new Promise ((Resolve, Reject) => {the let ShowStyle = (the async function () {the let the this style = .fullStyle [n-];! IF (style) return ; // calculate the length of each array let length = this.fullStyle.filter ((f, i) => I <= n-) .map ((IT) => it.length) .reduce ((T, C) => T + C, 0 ); // current length of the array to be written is equal to the length of each of the Save It is written to the current string length = length PrefixLength the let - style.length; IF (this.currentStyle.code.length < length) { let l = this.currentStyle.code.length - prefixLength; let char = style.substring(l, l + 1) || ' '; this.currentStyle.code += char; if (style.substring(l - 1, l) === '\n' && this.$refs.styleEditor) { this.$nextTick(() => { this.$refs.styleEditor.goBottom(); }) } this.timer = setTimeout(showStyle, this.interval); } else { resolve(); } }).bind(this) showStyle(); }) }, // 写入简历  writeShowResume() { return new Promise((resolve, reject) => { let length = this.fullMarkdown.length; let showResume = () => { if (this.currentMarkdown.length < length) { this.currentMarkdown = this.fullMarkdown.substring(0, this.currentMarkdown .length + 1); let lastChar = this.currentMarkdown[this.currentMarkdown.length - 1]; let prevChar = this.currentMarkdown[this.currentMarkdown.length - 2]; if (prevChar === '\n' && this.$refs.resumeEditor) { this.$nextTick(() => { this.$refs.resumeEditor.goBottom() }); } this.timer = setTimeout(showResume, this.interval); } else { resolve() } } showResume(); }) } } } </script> <style scoped> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } .main { position: relative; } html { min-height: 100vh; } * { transition: all 1.3s; } </style>


So far, a quick skip animations, you can pause the animation, as well as a music player, but also will resume moving freely edit the code has been completed, add the user to control the write speed of the speed function. Code has been uploaded to the git source code , welcomed the `fork`, also hope not mean` star`.

Online Preview .

 

Guess you like

Origin www.cnblogs.com/eveningwater/p/12439001.html