Skip to content
This repository has been archived by the owner on Jun 8, 2021. It is now read-only.

Commit

Permalink
Merge pull request #2 from ming-tsai/dev
Browse files Browse the repository at this point in the history
chore: separete ts, vue and css
  • Loading branch information
ming-tsai authored Jun 19, 2020
2 parents ae9489b + 58c6730 commit 8ea3208
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 157 deletions.
1 change: 0 additions & 1 deletion build/rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// rollup.config.js
import fs from 'fs';
import path from 'path';
import vue from 'rollup-plugin-vue';
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tsaibot/vue-typed",
"version": "0.1.0-preview7",
"version": "0.1.0-preview8",
"description": "Typed components for VueJs",
"repository": {
"type": "git",
Expand Down
33 changes: 33 additions & 0 deletions src/vue-typed.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
.caret {
display: inline-block;
vertical-align: baseline;
width: 1px;
background: black;
margin-left: 3px;
position: relative;
top: 2px;
-webkit-animation: caret-animation 0.5s linear infinite;
animation: caret-animation 0.5s linear infinite;
}

.caret:empty:before {
content: "\200b"; /* unicode zero width space character */
}

@keyframes caret-animation {
0% {
opacity: 1;
}
30% {
opacity: 1;
}
40% {
opacity: 0;
}
90% {
opacity: 0;
}
100% {
opacity: 1;
}
}
116 changes: 116 additions & 0 deletions src/vue-typed.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import Vue from 'vue';

interface VueType {
isDone: boolean;
arrayIndex: number;
bindingText: string;
}

export default Vue.extend({
name: 'VueTyped', // vue component name
props: {
timeTakes: {
type: Number,
validator: value => value >= 0.0,
default: 2000
},
text: {
type: [String, Array],
required: true,
validator: value => {
var result = value != undefined && value != null && value.length > 0;
if (result && Array.isArray(value)) {
value.forEach((v) => {
if(typeof v != 'string')
{
result = false;
}
});
}
return result;
}
},
tag: {
type: String,
default: 'span',
validator: value => ['p', 'h1', 'h2', 'h3', 'h4', 'span'].includes(value)
}
},
data(): VueType {
return {
isDone: false,
arrayIndex: 0,
bindingText: ''
};
},
methods: {
async writeInit() {
if (typeof this.text === "string") {
await this.writeText(this.text);
await this.delay(this.timeTakes);
this.isDone = true;
} else {
if (Array.isArray(this.text)) {
this.setIntervalImmediately(
async () => await this.managerArray(),
this.timeTakes * 1.4 * 2
);
}
}
},
async writeText(text: string) {
let index = 0;
this.bindingText = '';
const period = this.timeTakes / text.length;
const timer = setInterval(() => {
if (index >= text.length - 1) {
clearInterval(timer);
}
index = this.appendText(text[index], index);
}, period);
},
appendText(char: string, index: number) {
this.bindingText += char;
index++;
return index;
},
async eraseText(text: string) {
let index = text.length;
this.bindingText = text;
const period = this.timeTakes / text.length;
const timer = setInterval(() => {
if (index <= 0) {
clearInterval(timer);
}
index = this.removeText(index);
}, period);
},
removeText(index: number) {
this.bindingText = this.bindingText.substring(0, index);
index--;
return index;
},
async managerArray() {
const text = this.text as string[];
await this.writeText(text[this.arrayIndex]);
await this.delay(this.timeTakes * 1.5);
await this.eraseText(text[this.arrayIndex]);
if (this.arrayIndex >= this.text.length - 1) {
this.arrayIndex = 0;
} else {
this.arrayIndex++;
}
return;
},
delay(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
},
setIntervalImmediately(func: () => void, interval: number) {
func();
return setInterval(func, interval);
}
},
async mounted() {
await this.writeInit();
},
});
156 changes: 2 additions & 154 deletions src/vue-typed.vue
Original file line number Diff line number Diff line change
@@ -1,161 +1,9 @@
<script lang="ts">
import Vue from 'vue';
interface VueType {
isDone: boolean;
arrayIndex: number;
bindingText: string;
}
export default Vue.extend({
name: 'VueTyped', // vue component name
props: {
timeTakes: {
type: Number,
validator: value => value >= 0.0,
default: 2000
},
text: {
type: [String, Array],
required: true,
validator: value => {
var result = value != undefined && value != null && value.length > 0;
if (result && Array.isArray(value)) {
value.forEach((v) => {
if(typeof v != 'string')
{
result = false;
}
});
}
return result;
}
},
tag: {
type: String,
default: 'span',
validator: value => ['p', 'h1', 'h2', 'h3', 'h4', 'span'].includes(value)
}
},
data(): VueType {
return {
isDone: false,
arrayIndex: 0,
bindingText: ''
};
},
methods: {
async writeInit() {
if (typeof this.text === "string") {
await this.writeText(this.text);
await this.delay(this.timeTakes);
this.isDone = true;
} else {
if (Array.isArray(this.text)) {
this.setIntervalImmediately(
async () => await this.managerArray(),
this.timeTakes * 1.4 * 2
);
}
}
},
async writeText(text: string) {
let index = 0;
this.bindingText = '';
const period = this.timeTakes / text.length;
const timer = setInterval(() => {
if (index >= text.length - 1) {
clearInterval(timer);
}
index = this.appendText(text[index], index);
}, period);
},
appendText(char: string, index: number) {
this.bindingText += char;
index++;
return index;
},
async eraseText(text: string) {
let index = text.length;
this.bindingText = text;
const period = this.timeTakes / text.length;
const timer = setInterval(() => {
if (index <= 0) {
clearInterval(timer);
}
index = this.removeText(index);
}, period);
},
removeText(index: number) {
this.bindingText = this.bindingText.substring(0, index);
index--;
return index;
},
async managerArray() {
const text = this.text as string[];
await this.writeText(text[this.arrayIndex]);
await this.delay(this.timeTakes * 1.5);
await this.eraseText(text[this.arrayIndex]);
if (this.arrayIndex >= this.text.length - 1) {
this.arrayIndex = 0;
} else {
this.arrayIndex++;
}
return;
},
delay(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
},
setIntervalImmediately(func: () => void, interval: number) {
func();
return setInterval(func, interval);
}
},
async mounted() {
await this.writeInit();
},
});
</script>

<template>
<component :is="tag">
<span class="vue-typed">{{ bindingText }}</span>
<span class="caret" v-if="!isDone"></span>
</component>
</template>

<style scoped>
.caret {
display: inline-block;
vertical-align: baseline;
width: 1px;
background: black;
margin-left: 3px;
position: relative;
top: 2px;
-webkit-animation: caret-animation 0.5s linear infinite;
animation: caret-animation 0.5s linear infinite;
}
.caret:empty:before {
content: "\200b"; /* unicode zero width space character */
}
@keyframes caret-animation {
0% {
opacity: 1;
}
30% {
opacity: 1;
}
40% {
opacity: 0;
}
90% {
opacity: 0;
}
100% {
opacity: 1;
}
}
</style>
<script lang="ts" src="./vue-typed.ts"></script>
<style src="./vue-typed.css" scoped></style>

0 comments on commit 8ea3208

Please sign in to comment.