1. 程式人生 > >模擬生成打字(支援無數段)

模擬生成打字(支援無數段)

一個基於type.js demo

 

自己寫的打字多段.vue檔案

<template>
	<div class="typer">
		<div class="typer-content" v-for="(itemDiv, indexDiv) in totalArray">
			<!--<p class="typer-static">I'm&nbsp;</p>-->
			<!-- 動態變化的內容-->
			<p class="typer-dynamic">
				<span class="cut">
            		<span class="word" v-for="(letter,index) in itemDiv.words" :key="index">{{letter}}</span>
					<!-- 模擬游標-->
					<span class="typer-cursor"></span>
					<br>
				</span>
				
			</p>
		</div>
		<p :id="'ppp'+index" v-for='(item,index) in responseData'></p>
		<!--<ul class="btnUl">
			<li v-for="(item, index) in btnArray" @click="changeSentence($event)">{{item}}</li>
		</ul>-->
	</div> 
</template>

<script>
	export default {
		data() {
			return {
				words: [], 		// 字母陣列push,pop的載體
				str: "我正在變成", 	// str初始化
				str_2: "我正在程式設計,你呢", // str初始化
				letters: [], 	// str分解後的字母陣列
				
				totalArray: [	// 總資料
					{"id": 1, "words": ['first first first sentent!']},
//					{"id": 2, "words": ['second second second sentent!']}
				],
				sentenceId: 0,	// 表示顯示第幾句話
				btnArray: ['sentence1', 'sentence2', 'sentence3', 'sentence4'],
				isWipe: false,
				int_diff_i: 1, 	// 從第幾個開始不同
				index1:-1,
				curentindex:0,
				responseData: [
					{"beginTime":"1000","sentenceId":1,"words":"我是第一段","endTime":"5595"},
					{"beginTime":"7080","sentenceId":2,"words":"我第二段","endTime":"19585"},
					{"beginTime":"20670","sentenceId":3,"words":"我第四段","endTime":"29605"},
					{"beginTime":"31170","sentenceId":4,"words":"我第五。","endTime":"42915"},
					{"beginTime":"31170","sentenceId":4,"words":"我第6。","endTime":"42915"},{"beginTime":"31170","sentenceId":4,"words":"我第7。","endTime":"42915"},
					{"beginTime":"31170","sentenceId":4,"words":"我第8。","endTime":"42915"}
				],
			}
		},
		mounted() {
			this.begin();
            this.getwords();
		},
		methods: {
			// 點選按鈕
			changeSentence(e) {
				this.back();
			},
			getwords(){
				let timer=setInterval(()=>{
					let classn='ppp'+this.curentindex;
					if(this.curentindex>this.responseData.length-1){
						clearInterval(timer);
						return;
					}
					if(this.index1<this.responseData[this.curentindex].words.length){
						this.index1++;
					}					
					if(this.index1>this.responseData[this.curentindex].words.length-1){
						this.index1=-1;
						this.curentindex++;
						clearInterval(timer);
						this.getwords();
					}else{
						document.getElementById(classn).innerHTML+=this.responseData[this.curentindex].words[this.index1];
					}
                   
				}, 200);
             

			},
			// 開始輸入的效果動畫
			begin() {
				if(this.isWipe) {	// 改值了之後
					this.letters = this.str_2.split("").slice(this.int_diff_i);
					for(var i = 0; i < this.letters.length; i++) {
						setTimeout(this.write(i), i * 100);
					}
				}else {				// 初始化
					this.str = '';
					for(var i = 0; i < this.responseData.length; i++) {
						this.str += this.responseData[i].words;
					}
					this.letters = this.str.split("");
					this.totalArray[this.sentenceId].words = [];
					for(var i = 0; i < this.letters.length; i++) {
						setTimeout(this.write(i), i * 100);
					}
				}
			},
			// 開始刪除的效果動畫
			back() {
				if(this.str.indexOf(this.str_2) > -1) {	// 新的值包含原始值,沒有改值
					alert("前一句與後一句的翻譯結果一致,不需要改值!")
				}else {									// 新的值有改動的地方
					var str_2_obj = this.str_2.split("");
					var str_obj = this.str.split("");
					var int_i = 0;
					for(let i = 0; i < str_2_obj.length; i++) {
						if(str_2_obj[i] != str_obj[i]) {
							int_i = i;
							this.int_diff_i = i;
							break;
						}
					}
					
					// 擦除之前的值
					if(!this.isWipe) {
						// let L = this.letters.length;
						var int_slice_start = str_obj.length - int_i;
						for(var i = 0; i < int_slice_start; i++) {
							setTimeout(this.wipe(i), i * 50);
						}	
						this.isWipe = true;
					}
				}
			},
			// 輸入字母
			write(i) {
				return() => {
					let L = this.letters.length;
					this.totalArray[this.sentenceId].words.push(this.letters[i]);
				}
			},
			// 擦掉(刪除)字母
			wipe(i) {
				return() => {
					this.totalArray[this.sentenceId].words.pop(this.letters[i]);
					
					// 判斷兩個字串從第幾個字開始不同的,拿到index值,刪除完畢,在300ms後開始輸入
					// 當不再刪除的時候,開始呼叫
					if(this.totalArray[this.sentenceId].words.length == this.int_diff_i) {
						var str_2_obj = this.str_2.split("");
						var str_obj = this.str.split("");
						var int_i = 0;
						for(let j = 0; j < str_2_obj.length; j++) {
							if(str_2_obj[j] != str_obj[j]) {
								int_i = j;
								let that = this;
								setTimeout(function() {
									that.begin();
								}, 300);
								break;
							}
						}
					}
				}
			},
		}
	}
</script>
<style type="text/css" scoped="scoped">
	.typer {
		margin-top: 2%;
		box-sizing: border-box;
	}
	
	.typer .typer-content {
		font-weight: bold;
		font-size: 50px;
		display: flex;
		flex-direction: row;
		letter-spacing: 2px;
		color: #000;
	}
	
	.typer-dynamic {
		position: relative;
	}
	
	.cut {
		color: #000;    display: block;
    width: 1000px;    font-size: 24px;
    font-weight: 500;
	}
	
	.typer-cursor {
		display: inline-block;
	    /* position: absolute; */
	    height: 31px;
	    width: 3px;
	    /* top: 0; */
	    /* right: -10px; */
	    background-color: #000;
	    -webkit-animation: flash 1.5s linear infinite;
	    animation: flash 1.5s linear infinite;
	        vertical-align: text-bottom;
	}
	.btnUl>li {
		font-size: 15px;
		border: 1px solid #000000;
		border-radius: 5px;
		width: 150px;
		height: 35px;
		text-align: center;
		line-height: 35px;
		margin-top: 20px;
		color: #000;
		cursor: pointer;
	}
</style>