shish 4 years ago
parent
commit
6c64d606e1

+ 40 - 0
ghsPad/src/components/keyboard-listener/keyboard-listener.vue

@@ -0,0 +1,40 @@
+<template>
+  <view></view>
+</template>
+
+<script>
+export default {
+  methods: {
+    onEvent(event) {
+      this.$emit(event.type, event)
+    },
+  },
+}
+</script>
+
+<script module="keyboard" lang="renderjs">
+export default {
+  mounted () {
+    const onKey = (event) => {
+      const keys1 = ['type', 'timeStamp']
+      const keys2 = ['altKey', 'code', 'ctrlKey', 'isComposing', 'key', 'location', 'metaKey', 'repeat', 'shiftKey']
+      const keys3 = ['char', 'charCode', 'keyCode', 'keyIdentifier', 'keyLocation', 'which']
+      const data = {}
+      keys1.concat(keys2, keys3).forEach(key => data[key] = event[key])
+      this.$ownerInstance.callMethod('onEvent', data)
+    }
+    const names = ['keydown', 'keyup']
+    names.forEach(name => {
+      document.addEventListener(name, onKey, false)
+    })
+    this.$on('hook:beforeDestroy', () => {
+      names.forEach(name => {
+        document.removeEventListener(name, onKey, false)
+      })
+    })
+  }
+}
+</script>
+
+<style>
+</style>

+ 368 - 0
ghsPad/src/components/vKeyboard/VKeyboard.vue

@@ -0,0 +1,368 @@
+<template>
+	<view v-if="showKeyboard" :class="['enl-size', digital?'enl-size_custom':'',keyboardStyle]">
+		<view class="digit-keyboard" v-if="mode === 'digit' || digital">
+			<view class="digit-button-box">
+				<template v-for="(digit, index) in digits">
+					<!-- <view :key="index" class="enl-key-button enl-digit" @tap="typing('.')" v-if="index === 9">.</view> -->
+					<view :key="index" class="enl-key-button enl-digit" @tap="typing(digit)">
+						<text>{{digit}}</text>
+					</view>
+				</template>
+				<view class="enl-key-button enl-digit" v-if="!digital">
+					<!-- <i class="iconfont icon-shouqijianpan enl-middle"  @tap="deactivate"></i> -->
+					<i class="iconfont icon-ABC enl-middle" v-if="!digital" @tap="typingLetter"></i>
+				</view>
+			</view>
+			<view class="special-button-box">
+				<view class="enl-key-button special-button enl-gray" @tap="backspace"><i class="iconfont icon-backspace enl-large"></i></view>
+				<view class="enl-key-button special-button enl-gray" @tap="cancel"> <text>取消</text> </view>
+				<view class="enl-key-button special-button enl-gray" @tap="enter"> <text>确认</text> </view>
+			</view>
+		</view>
+		<view class="full-keyboard" v-else>
+			<view class="line" v-for="(letters, index) in lines" :key="index">
+				<view class="enl-letter enl-key-button special-key enl-gray" v-if="index === 2 && mode === 'letter'" @tap="toggleCase"><i
+					 :class="'iconfont ' + (lowercase ? 'icon-xiaoxie' : 'icon-daxie')"></i></view>
+				<view class="enl-letter enl-key-button normal" v-for="letter in letters" @tap="typing(letter)" :key="letter">
+					<text>{{letter}}</text>
+				</view>
+				<view class="enl-letter enl-key-button special-key enl-gray" v-if="index === 2" @tap="backspace"><i class="iconfont icon-backspace"></i></view>
+			</view>
+			<view class="line special-line">
+				<view class="enl-letter enl-key-button swith-key enl-gray">
+					<i class="iconfont icon-fuhao" @tap="typingSymbol" v-if="mode === 'letter'"></i>
+					<i class="iconfont icon-ABC" @tap="typingLetter" v-if="mode === 'symbol'"></i>
+				</view>
+				<view class="enl-letter enl-key-button space" @tap="typing(' ')"><text class="enl-logo"> </text></view>
+				<view class="enl-letter enl-key-button swith-key enl-gray" @tap="typingDigit"><i class="iconfont icon-shuzi"></i></view>
+				<view class="enl-letter enl-key-button swith-key enl-gray" @tap="enter"><text style="color:#666666;font-size:13upx;">清除</text></view>
+				<view class="enl-letter enl-key-button swith-key enl-gray" @tap="cancel"><text style="color:#666666;font-size:13upx;">取消</text></view>
+			</view>
+		</view>
+	</view>
+</template>
+<script>
+import { natural, order, disorder, symbols, digits, KEYBOARD_MODE } from './utils'
+export default {
+	props: {
+		//是否为纯数字键盘
+		digital: {
+			type: [Boolean, String],
+			default: false
+		},
+		//是否无序的排序键盘
+		disorderly: {
+			type: [Boolean, String],
+			default: false
+		},
+		pointIsShow:{
+			type: Boolean,
+			default: true
+		},
+		isEffect:{
+			type:Boolean,
+			default: false
+		}
+	},
+	computed: {
+		keyboardStyle() {
+			return 'v-keyboard ' + this.cls;
+		}
+	},
+	data() {
+		return {
+			cls: '',
+			visible: false, //是否显示
+			showKeyboard: false, //是否隐藏
+			digits: [], //自然数数组
+			lines: [], //字母+数字数组
+			lowercase: true, //是否小写输入状态
+			mode: KEYBOARD_MODE.LETTER, //键盘模式
+			keys: [] //键入的键值
+		}
+	},
+	methods: {
+		//大小写转换
+		toggleCase() {
+			this.lowercase = !this.lowercase;
+		},
+		//输入符号
+		typingSymbol() {
+			this.mode = KEYBOARD_MODE.SYMBOL;
+			this.lines = symbols;
+		},
+		//输入字母
+		typingLetter() {
+			this.mode = KEYBOARD_MODE.LETTER;
+			this.lines = this.disorderly ? disorder() : order;
+		},
+		//键入数字
+		typingDigit() {
+			this.mode = KEYBOARD_MODE.DIGIT;
+		},
+		//键盘键入
+		typing(input) {
+			this.$util.hitVoice()
+			this.keys.push(input);
+			//app中v-model不生效,改用事件方式在外处理
+			//this.$emit('typing', this.keys.join(''))
+			this.$emit('typing', {
+				backspace: false,
+				char: input
+			})
+		},
+		//退格键
+		backspace() {
+			this.$util.hitVoice()
+			if (this.keys.length) {
+				this.keys.pop()
+			}
+			//this.$emit('typing', this.keys.join(''));
+			this.$emit('typing', {
+				backspace: true
+			})
+		},
+		//键入回车
+		enter() {
+			this.$util.hitVoice()
+			//this.deactivate();
+			this.$emit('enter');
+		},
+		cancel(){
+			this.$util.hitVoice()
+			this.$emit('cancel')
+		},
+		//激活键盘
+		activate() {
+			// #ifdef APP-PLUS
+			plus.key.hideSoftKeybord();
+			// #endif
+			this.showKeyboard = true
+			this.$nextTick(() => {
+				this.visible = true;
+			})
+		},
+		//隐藏键盘
+		deactivate() {
+			this.visible = false;
+			setTimeout(() => {
+				this.showKeyboard = false
+			}, 250)
+		}
+	},
+	watch: {
+		lowercase(val) {
+			let [...temp] = this.lines;
+			temp.forEach(line => {
+				line.forEach((letter, index) => {
+					line[index] = val ? letter.toLowerCase() : letter.toUpperCase();
+				});
+			});
+			this.lines = temp;
+		},
+		visible(val) {
+			if(this.isEffect) {
+				this.cls = val ? 'slideup' : 'slidedown';
+			}
+		}
+	},
+	created() {
+		this.lines = this.disorderly ? disorder() : order;
+		this.digits = this.disorderly ? digits() : natural;
+
+		if(!this.pointIsShow) {
+			this.digits = this.digits.filter(i=>i!=='.')
+		}
+
+	}
+}
+</script>
+
+<style lang="scss" scoped>
+@import './css.scss'; //引入键盘样式
+@import './icon.css'; //引入键盘icon
+
+.iconfont {
+	font-family: "iconfont" !important;
+	font-size: 24upx;
+	font-style: normal;
+	-webkit-font-smoothing: antialiased;
+	-moz-osx-font-smoothing: grayscale;
+}
+.enl-size {
+	// font-size: 24upx;
+	height: 100%;
+}
+.enl-size_custom {
+	// width: 700upx!important;
+}
+.enl-key-button {
+	display: inline-block;
+	overflow: hidden;
+	// vertical-align: middle;
+	border: 1px solid #e6e6e6;
+	color: #333;
+	background-color: #fff;
+	box-shadow: 0 2px 2px rgba(230, 230, 230, .7);
+	border-radius: 3upx;
+	text-align: center;
+	white-space: nowrap;
+	user-select: none;
+	cursor: pointer;
+	&:active {
+		background: #d6d6d6;
+		scale: 0.7;
+	}
+}
+
+.v-keyboard {
+	width: 100%;
+	position: relative;
+	bottom: 0;
+	left: 0;
+	background: #f5f5f5;
+	padding: 1% 0;
+	height: 100%;
+	z-index: 100;
+	/*全键盘*/
+	.full-keyboard {
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		height: 48vh;
+		.line {
+			text-align: center;
+			flex: 1;
+			width: 100%;
+			&:not(:last-child) {
+				// margin-bottom: 1%;
+			}
+			.enl-letter {
+				height: 95%;
+				font-size: 20upx;
+				padding: 0upx 0upx;
+				&:not(:last-child) {
+					margin-right: 1%;
+				}
+			}
+
+			.normal {
+				// width: 1.73em;
+				width: 9%;
+			}
+
+			.special-key {
+				width: 9%;
+			}
+		}
+
+		.special-line {
+			padding: 0 1%;
+			display: flex !important;
+			justify-content: space-around;
+			font-size: 24upx;
+			.space {
+				flex: 1;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+			}
+
+			.swith-key {
+				width: 13%;
+
+			}
+
+			.enl-logo {
+				font-size: 30upx;
+			}
+		}
+	}
+	/*数字键盘*/
+	.digit-keyboard {
+		display: flex;
+		flex-direction: row;
+		font-size: 24upx;
+		justify-content: center;
+		height: 100%;
+		.digit-button-box {
+			padding: 0 1%;
+			flex: 80;
+			display: flex;
+			align-items: center;
+			flex-wrap: wrap;
+			.enl-digit {
+				width: 32%;
+				height: 23%;
+				// line-height: 20%;
+				margin-bottom: 1%;
+				// vertical-align: middle;
+				// display: flex;
+				// align-items: center;
+				&:nth-child(10),
+				&:nth-child(11),
+				&:nth-child(12) {
+					margin-bottom: 0;
+				}
+				&:not(:last-child) {
+					margin-right: 1%;
+				}
+			}
+			& .enl-key-button {
+				display: flex;
+				align-items: center;
+				justify-content: center;
+			}
+		}
+
+		.special-button-box {
+			flex: 20;
+			padding: 0 3% 0 0;
+			.special-button {
+				width: 100%;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				&:not(:last-child) {
+					margin-bottom: 3%;
+				}
+			}
+			& > view:nth-child(1){
+				line-height: 26%;
+				height: 26%;
+				font-size:10upx;
+				color:#666666;
+			}
+			& > view:nth-child(2){
+				line-height: 26%;
+				height: 26%;
+				font-size:12upx;
+				color:#666666;
+			}
+			& > view:nth-child(3){
+				line-height: 45%;
+				height: 45%;
+				color:green;
+				font-size:15upx;
+			}
+		}
+	}
+
+	.enl-gray {
+		background: #e1e1e1 !important;
+
+		&:active {
+			background: #fff !important;
+		}
+	}
+
+	.enl-large {
+		font-size: 24upx !important;
+	}
+
+	.enl-middle {
+		font-size: 24upx !important;
+		display: block;
+	}
+}
+</style>

+ 61 - 0
ghsPad/src/components/vKeyboard/css.scss

@@ -0,0 +1,61 @@
+@mixin transform($trans) {
+  -webkit-transform: $trans;
+  -moz-transform: $trans;
+  -ms-transform: $trans;
+  -o-transform: $trans;
+  transform: $trans;
+}
+
+@mixin transition($trans) {
+  -moz-transition: $trans;
+  -ms-transition: $trans;
+  transition: $trans;
+}
+
+/*平滑动画,向上滑入,向下滑出*/
+@keyframes slidedown {
+  from {
+    transform: translateY(0);
+  }
+  to {
+    transform: translateY(100%);
+  }
+}
+
+@-webkit-keyframes slidedown {
+  from {
+    -webkit-transform: translateY(0);
+  }
+  to {
+    -webkit-transform: translateY(100%);
+  }
+}
+
+@-webkit-keyframes slideup {
+  from {
+    -webkit-transform: translateY(100%);
+  }
+  to {
+    -webkit-transform: translateY(0);
+  }
+}
+
+@keyframes slideup {
+  from {
+    transform: translateY(100%);
+  }
+  to {
+    transform: translateY(0);
+  }
+}
+
+.slidedown {
+  animation: slidedown 0.3s linear;
+  animation-fill-mode:forwards;
+  @include transform(translateY(100%));
+}
+.slideup {
+  animation: slideup 0.3s linear;
+  animation-fill-mode:forwards;
+  @include transform(translateY(0));
+}

File diff suppressed because it is too large
+ 3 - 0
ghsPad/src/components/vKeyboard/icon.css


+ 22 - 0
ghsPad/src/components/vKeyboard/index.js

@@ -0,0 +1,22 @@
+import Vue from 'vue'
+import vKeyboard from './VKeyboard'
+
+//extend创建Vue组件类
+const vKeyboardClass = Vue.extend(vKeyboard)
+
+let instance;
+
+export default {
+  activate(options) {
+    options = options || {};
+    instance = new vKeyboardClass({propsData: options});
+    instance.vm = instance.$mount();
+    document.body.appendChild(instance.vm.$el);
+    /*document.body.appendChild(instance.vm.$el);*/
+    instance.activate();
+    return instance;
+  },
+  deactivate() {
+    instance.deactivate();
+  }
+}

+ 61 - 0
ghsPad/src/components/vKeyboard/utils.js

@@ -0,0 +1,61 @@
+//所有自然数
+export const natural = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '0','00'];
+//所有英文字母
+export const chars = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
+	'v', 'w', 'x', 'y', 'z'
+];
+
+//顺序排序全键盘
+export const order = [
+	// ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0','00'],
+	['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p'],
+	['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l'],
+	['z', 'x', 'c', 'v', 'b', 'n', 'm']
+];
+
+//随机排序全键盘
+export const disorder = () => {
+	let lines = [10, 9, 7];
+	let array = [];
+	array.push(digits());
+
+	let [...temp] = chars;
+
+	const random = (length) => {
+		let randoms = [];
+		for (let i = 0; i < length; i++) {
+			let index = Math.floor(Math.random() * temp.length);
+			randoms.push(temp[index]);
+			temp.splice(index, 1);
+		}
+		return randoms;
+	};
+
+	for (let i = 0; i < lines.length; i++) {
+		array.push(random(lines[i]));
+	}
+	return array;
+};
+
+//所有符号
+export const symbols = [
+	['~', '`', '!', '@', '#', '$', '%', '^', '&', '*'],
+	['(', ')', '-', '+', '=', '{', '}', '[', ']'],
+	['_', '|', '\\', ':', ';', '\'', '<', ',', '>'],
+	['"', '?', '.', '/', '€', '£', '¥']
+];
+
+//所有数字
+export const digits = () => {
+	let [...temp] = natural;
+	return temp.sort(function() {
+		return Math.random() > 0.5 ? -1 : 1; //用Math.random()函数生成0~1之间的随机数与0.5比较,返回-1或1
+	});
+};
+
+//键盘模式
+export const KEYBOARD_MODE = {
+	SYMBOL: 'symbol', //符号键盘
+	DIGIT: 'digit', //数字键盘
+	LETTER: 'letter' //字母键盘
+};

Some files were not shown because too many files changed in this diff