提交 f057cd79 作者: 方治民

合并分支 '3.x' 到 'main'

3.x

查看合并请求 !61
......@@ -49,12 +49,12 @@
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
"source.fixAll.eslint": "explicit"
},
"[vue]": {
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
"source.fixAll.stylelint": true
"source.fixAll.eslint": "explicit",
"source.fixAll.stylelint": "explicit"
}
},
......
......@@ -66,93 +66,93 @@
}
},
"dependencies": {
"@dcloudio/uni-app": "3.0.0-3090620231104002",
"@dcloudio/uni-app-plus": "3.0.0-3090620231104002",
"@dcloudio/uni-components": "3.0.0-3090620231104002",
"@dcloudio/uni-h5": "3.0.0-3090620231104002",
"@dcloudio/uni-mp-alipay": "3.0.0-3090620231104002",
"@dcloudio/uni-mp-baidu": "3.0.0-3090620231104002",
"@dcloudio/uni-mp-jd": "3.0.0-3090620231104002",
"@dcloudio/uni-mp-kuaishou": "3.0.0-3090620231104002",
"@dcloudio/uni-mp-lark": "3.0.0-3090620231104002",
"@dcloudio/uni-mp-qq": "3.0.0-3090620231104002",
"@dcloudio/uni-mp-toutiao": "3.0.0-3090620231104002",
"@dcloudio/uni-mp-weixin": "3.0.0-3090620231104002",
"@dcloudio/uni-quickapp-webview": "3.0.0-3090620231104002",
"@dcloudio/uni-app": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-app-plus": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-components": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-h5": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-mp-alipay": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-mp-baidu": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-mp-jd": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-mp-kuaishou": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-mp-lark": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-mp-qq": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-mp-toutiao": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-mp-weixin": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-quickapp-webview": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-ui": "^1.4.28",
"@faker-js/faker": "^8.2.0",
"@vue/runtime-core": "~3.2.47",
"@vueuse/core": "^10.5.0",
"axios": "^1.6.0",
"@faker-js/faker": "^8.3.1",
"@vue/runtime-core": "3.3.11",
"@vueuse/core": "^10.7.0",
"axios": "^1.6.2",
"crypto-js": "^4.2.0",
"dayjs": "^1.11.10",
"lodash-es": "^4.17.21",
"nanoid": "^5.0.2",
"nanoid": "^5.0.4",
"pinia": "~2.0.36",
"qs": "~6.9.7",
"stompjs": "^2.3.3",
"urijs": "^1.19.11",
"vue": "~3.2.47",
"vue-i18n": "^9.6.5",
"vue": "3.3.11",
"vue-i18n": "^9.8.0",
"vue-request": "^2.0.4",
"vue-types": "^5.1.1"
},
"devDependencies": {
"@antfu/eslint-config": "^0.43.1",
"@commitlint/cli": "^18.2.0",
"@commitlint/config-conventional": "^18.1.0",
"@commitlint/cli": "^18.4.3",
"@commitlint/config-conventional": "^18.4.3",
"@dcloudio/types": "^3.4.3",
"@dcloudio/uni-automator": "3.0.0-3090620231104002",
"@dcloudio/uni-cli-shared": "3.0.0-3090620231104002",
"@dcloudio/uni-automator": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-cli-shared": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-helper-json": "^1.0.13",
"@dcloudio/uni-stacktracey": "3.0.0-3090620231104002",
"@dcloudio/vite-plugin-uni": "3.0.0-3090620231104002",
"@iconify/json": "^2.2.137",
"@types/crypto-js": "^4.1.3",
"@types/lodash-es": "^4.17.10",
"@types/node": "^20.8.10",
"@types/qs": "^6.9.9",
"@types/stompjs": "^2.3.7",
"@types/urijs": "^1.19.22",
"@typescript-eslint/eslint-plugin": "^6.9.1",
"@typescript-eslint/parser": "^6.9.1",
"@dcloudio/uni-stacktracey": "3.0.0-alpha-4000020231218001",
"@dcloudio/vite-plugin-uni": "3.0.0-alpha-4000020231218001",
"@iconify/json": "^2.2.160",
"@types/crypto-js": "^4.2.1",
"@types/lodash-es": "^4.17.12",
"@types/node": "^20.10.5",
"@types/qs": "^6.9.10",
"@types/stompjs": "^2.3.9",
"@types/urijs": "^1.19.25",
"@typescript-eslint/eslint-plugin": "^6.15.0",
"@typescript-eslint/parser": "^6.15.0",
"commitizen": "^4.3.0",
"conventional-changelog-cli": "^4.1.0",
"cz-conventional-changelog": "^3.3.0",
"cz-customizable": "^7.0.0",
"cz-git": "^1.7.1",
"czg": "^1.7.1",
"cz-git": "^1.8.0",
"czg": "^1.8.0",
"dotenv": "^16.3.1",
"eslint": "^8.53.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.1",
"eslint-plugin-vue": "^9.18.1",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.0",
"eslint-plugin-vue": "^9.19.2",
"husky": "^8.0.3",
"jest": "27.0.4",
"jest-environment-node": "27.5.1",
"less": "^4.2.0",
"lint-staged": "^14.0.1",
"lint-staged": "^15.2.0",
"npm-run-all": "^4.1.5",
"picocolors": "^1.0.0",
"pont-engine": "^1.5.12",
"postcss": "^8.4.31",
"postcss": "^8.4.32",
"postcss-html": "^1.5.0",
"postcss-less": "^6.0.0",
"prettier": "^3.0.3",
"prettier": "^3.1.1",
"rimraf": "^5.0.5",
"sass": "^1.69.5",
"sort-package-json": "^2.6.0",
"stylelint": "^15.11.0",
"stylelint": "^16.0.2",
"stylelint-config-html": "^1.1.0",
"stylelint-config-recommended": "^13.0.0",
"stylelint-config-standard": "^34.0.0",
"stylelint-order": "^6.0.3",
"stylelint-config-recommended": "^14.0.0",
"stylelint-config-standard": "^35.0.0",
"stylelint-order": "^6.0.4",
"typescript": "~5.1.6",
"unocss": "^0.56.5",
"unocss-preset-weapp": "^0.56.1",
"unplugin-auto-import": "^0.16.7",
"unplugin-vue-components": "^0.25.2",
"vite": "^4.5.0",
"unocss": "^0.58.0",
"unocss-preset-weapp": "^0.58.0",
"unplugin-auto-import": "^0.17.2",
"unplugin-vue-components": "^0.26.0",
"vite": "^4.5.1",
"vue-eslint-parser": "^9.3.2"
},
"engines": {
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -398,6 +398,9 @@
/* #ifdef APP-NVUE || MP-TOUTIAO */
.fui-as__safe-weex {
/* #ifdef APP-NVUE */
height: 168rpx;
/* #endif */
padding-bottom: 34px;
}
......
<template>
<view class="fui-popup__animation" :class="[ani.in]" :style="'transform:' + transform + ';' + stylesObject"
@tap="change" v-if="isShow" ref="fui_ani">
<view class="fui-popup__animation" :class="[ani.in]" :style="transformStyles" @tap="change" v-if="isShow"
ref="fui_ani">
<slot></slot>
</view>
</template>
......@@ -57,7 +57,7 @@
if (newVal) {
this.open();
} else {
this.close();
this.isShow && this.close();
}
},
immediate: true
......@@ -89,6 +89,9 @@
transfrom += line + ':' + styles[i] + ';';
}
return transfrom;
},
transformStyles() {
return `transform:${this.transform};${this.stylesObject}`
}
},
methods: {
......
......@@ -152,7 +152,6 @@
<style scoped>
.fui-badge__wrap {
height: 36rpx;
padding: 0 12rpx;
color: #FFFFFF;
font-size: 24rpx;
line-height: 36rpx;
......
......@@ -6,13 +6,13 @@ class FillStyleLinearGradient {
this._stop_count = 0;
this._stops = [0, 0, 0, 0, 0];
}
addColorStop = function (pos, color) {
// 新特性待增加
addColorStop = function (pos, color) {// 2021-5-6变更
if (this._stop_count < 5 && 0.0 <= pos && pos <= 1.0) {
this._stops[this._stop_count] = { _pos: pos, _color: color };
this._stop_count++;
}
this._stop_count++;// echo建议
}// todo: 待修改
}
}
// 2021-5-6变更
export default FillStyleLinearGradient;
......@@ -42,7 +42,7 @@
<script>
export default {
name: 'fui-button',
emits: ['click', 'getuserinfo', 'contact', 'getphonenumber', 'error', 'opensetting'],
emits: ['click', 'getuserinfo', 'contact', 'getphonenumber', 'error', 'opensetting','chooseavatar','launchapp'],
// #ifdef MP-WEIXIN
behaviors: ['wx://form-field-button'],
// #endif
......
......@@ -40,6 +40,10 @@
:style="{color:getColor(index,idx,values)}">{{getText(index,idx) || descrArr[idx]}}</text>
<text class="fui-calendar__date-descr" v-if="!showLunar || language==='en'"
:style="{color:getColor(index,idx,values)}">{{getText(index,idx) || descrArr[idx]}}</text>
<view class="fui-calendar__badge"
:style="{background:badgeColor || dangerColor,right:badgeRight+'rpx',top:badgeTop+'rpx'}"
v-if="badgeArr[idx]">
</view>
</view>
</view>
</swiper-item>
......@@ -58,6 +62,10 @@
:style="{color:getColor(month-1,idx,values)}">{{getText(month-1,idx) || descrArr[idx]}}</text>
<text class="fui-calendar__date-descr" v-if="!showLunar || language==='en'"
:style="{color:getColor(month-1,idx,values)}">{{getText(month-1,idx) || descrArr[idx]}}</text>
<view class="fui-calendar__badge"
:style="{background:badgeColor || dangerColor,right:badgeRight+'rpx',top:badgeTop+'rpx'}"
v-if="badgeArr[idx]">
</view>
</view>
</view>
</view>
......@@ -213,6 +221,21 @@
btnColor: {
type: String,
default: '#FFFFFF'
},
//v2.2.0+
badgeColor: {
type: String,
default: ''
},
//v2.2.0+
badgeTop: {
type: [Number, String],
default: 16
},
//v2.2.0+
badgeRight: {
type: [Number, String],
default: 16
}
},
data() {
......@@ -225,6 +248,7 @@
daysArr: []
},
descrArr: [],
badgeArr: [],
dateWidth: '100%',
title: '',
year: 0,
......@@ -243,7 +267,7 @@
},
itemWidth() {
// #ifdef APP-NVUE
return (Number(this.dateWidth.replace('px', '').replace('%','')) - 1) / 7 + 'px'
return (Number(this.dateWidth.replace('px', '').replace('%', '')) - 1) / 7 + 'px'
// #endif
// #ifndef APP-NVUE
......@@ -253,6 +277,10 @@
primaryColor() {
const app = uni && uni.$fui && uni.$fui.color;
return (app && app.primary) || '#465CFF';
},
dangerColor() {
const app = uni && uni.$fui && uni.$fui.color;
return (app && app.danger) || '#FF2B2B';
}
},
watch: {
......@@ -276,6 +304,7 @@
title(val) {
if (this.year === 0) return;
this.descrArr = []
this.badgeArr = []
this.$emit('dateChange', {
year: this.year,
month: this.month
......@@ -705,6 +734,18 @@
this.descrArr = []
})
}
},
// 传入一个返回Promise的函数,设置当前日历数据角标
//返回当前日历数据
setBadge(callback) {
const item = this.monthArr[this.month - 1]
if (item && callback && typeof callback === 'function') {
callback(this.year, this.month, item.daysArr).then(res => {
this.badgeArr = res
}).catch(err => {
this.badgeArr = []
})
}
}
}
}
......@@ -902,4 +943,17 @@
.fui-calendar__btn-active:active {
background: rgba(0, 0, 0, .2);
}
.fui-calendar__badge {
position: absolute;
height: 8px;
width: 8px;
/* #ifdef APP-NVUE */
border-radius: 100px;
/* #endif */
/* #ifndef APP-NVUE */
border-radius: 50%;
z-index: 3;
/* #endif */
}
</style>
/*
===========================================
当前组件库版本号为:V2.1.0
如果与文档最新版本不一致,请更新至最新版本使用!
===========================================
*/
/*
组件属性全局配置文件。优先级:全局配置文件props < 直接设置组件props
目前支持配置的组件:fui-button、fui-icon、fui-text、fui-input、fui-form-item、fui-list-cell
fui-section、fui-white-space、fui-wing-blank
*/
// 主色(V1.9.8+),仅Nvue端以及无法使用css变量控制颜色的组件使用【保持与fui-theme中一致】
......@@ -107,6 +115,20 @@ const fuiConfig = {
descrColor: '#B2B2B2',
descrTop: 12
},
//v2.1.0+
fuiWhiteSpace: {
size: 'default',
//设置了height则size失效
height: 0,
background: 'transparent'
},
//v2.1.0+
fuiWingBlank: {
size: 'default',
//设置了gap则size失效
gap: 0,
background: 'transparent'
},
color,
...app
}
......
<template>
<view class="fui-data__tag-wrap" :style="{marginBottom:'-'+gap+'rpx'}">
<view class="fui-data__tag-wrap" :class="[nowrap?'fui-data__tag-nowrap':'fui-data__tag-flexwrap']"
:style="{marginBottom:'-'+gap+'rpx'}">
<!-- #ifndef APP-NVUE -->
<view class="fui-data__tag-item" :class="{'fui-data__tag-disable':item.disable}"
:style="{width:width?width+'rpx':'auto',height:height?height+'rpx':'auto',paddingTop:padding[0] || 0,paddingRight:padding[1] || 0,paddingBottom:padding[2] || padding[0] || 0,paddingLeft:padding[3] || padding[1] || 0,borderRadius:radius+'rpx',marginRight:gap+'rpx',marginBottom:gap+'rpx',background:item.selected?activeBgColor:background,borderColor:item.selected?(borderColor || primaryColor):(defaultBorderColor || background)}"
......@@ -142,6 +143,11 @@
markColor: {
type: String,
default: ''
},
//V2.1.0+ 标签选择 是否强制一行显示,外层需要自行设置横向滚动容器
nowrap: {
type: Boolean,
default: false
}
},
watch: {
......@@ -374,9 +380,16 @@
flex-direction: row;
align-items: center;
justify-content: flex-start;
}
.fui-data__tag-flexwrap {
flex-wrap: wrap;
}
.fui-data__tag-nowrap {
flex-wrap: nowrap;
}
.fui-data__tag-item {
/* #ifndef APP-NVUE */
display: inline-flex;
......
......@@ -207,7 +207,7 @@
:mask-bottom-style="theme==='dark'?darkBottomStyle:''" :mask-style="theme==='dark'?darkStyle:''"
:indicator-style="theme==='dark'?indicatorStyl:'height: 44px;border-top-width:0.5px;border-bottom-width:0.5px;'"
:indicator-class="theme==='dark'?'fui-date__picker-indicator':''" class="fui-date__picker-view"
:style="{height:height+'rpx'}" :key="theme+type" :value="vals" immediate-change
:style="{height:height+'rpx'}" :key="theme+type" :value="vals" :immediate-change="immediate"
@change="pickerChange">
<picker-view-column v-if="type==1 || type==2 || type==3 || type==4 || type==5">
<text :style="contentStyl" v-for="(item,index) in years" :key="index"
......@@ -526,7 +526,12 @@
}
},
data() {
let immediate = true;
// #ifdef MP-TOUTIAO
immediate = false
// #endif
return {
immediate,
years: [],
months: [],
days: [],
......@@ -740,16 +745,23 @@
const startValues = this.getValueToDate(val);
if (this.valueEnd) {
const endValues = this.getValueToDate(this.valueEnd);
this.values = endValues;
if (endValues.join(',') !== this.values.join(',')) {
this.values = endValues;
}
this.startDate = this.getRangeInitRes(startValues);
this.endDate = this.getRangeInitRes(endValues);
this.isActive = 2;
} else {
this.values = startValues;
if (startValues.join(',') !== this.values.join(',')) {
this.values = startValues;
}
this.startDate = this.getRangeInitRes(startValues);
}
} else {
this.values = this.getValueToDate(val);
const sVals = this.getValueToDate(val);
if (sVals.join(',') !== this.values.join(',')) {
this.values = sVals;
}
}
},
toDate(date, def, isMin) {
......
......@@ -10,7 +10,7 @@
<text :key="theme" :style="{fontSize:`${index===3 && idx===0? spareSize:40}rpx`}"
class="fui-digital__keyboard-key"
:class="{'fui-dk__key-dark':theme==='dark','fui-dk__key-light':theme!=='dark','fui-dk__highlight-dark':theme==='dark','fui-dk__highlight':theme==='light' && val}"
@tap.stop="keyClick(index,idx,val)">{{val}}</text>
@tap="keyClick(index,idx,val)">{{val}}</text>
</view>
</view>
</view>
......@@ -18,7 +18,7 @@
<view class="fui-dk__grid-right">
<view :key="theme" class="fui-digital__keyboard-key"
:class="{'fui-dk__key-dark':theme==='dark','fui-dk__key-light':theme!=='dark','fui-dk__highlight-dark':theme==='dark','fui-dk__highlight':theme!=='dark'}"
@tap.stop="backspace">
@tap="backspace">
<fui-icon :name="name" :size="56" :color="theme==='dark'?'#d1d1d1':'#333'"></fui-icon>
</view>
</view>
......
......@@ -62,7 +62,9 @@ function touchmove(e, ins, event) {
var touch = {}
if (isH5 && isPC()) {
touch = e;
state = event.instance.getState()
if (event && event.instance) {
state = event.instance.getState()
}
} else {
touch = e.touches[0] || e.changedTouches[0]
state = e.instance.getState()
......
......@@ -15,6 +15,12 @@
export default {
name: "fui-form",
props: {
model: {
type: Object,
default () {
return {};
}
},
//表单padding值(上,右,下,左),同css顺序
padding: {
type: Array,
......@@ -22,7 +28,7 @@
return []
}
},
//是否显示校验错误信息
//是否显示校验错误信息,设置false时,则触发formItem校验
show: {
type: Boolean,
default: true
......@@ -107,6 +113,16 @@
asteriskPosition: {
type: String,
default: ''
},
//v2.1.0+ 1-absolute 2-relative
errorPosition: {
type: [Number, String],
default: 1
},
//v2.1.0+ left/center/right
errorAlign: {
type: String,
default: 'center'
}
},
provide() {
......@@ -126,12 +142,41 @@
return color;
}
},
watch: {
/* // 备用方案,暂时未启用
model: {
handler: function(vals, oldVal) {
if (this.children && vals && !this.show) {
this.children.forEach(item => {
if (item.prop && item.prop !== true) {
item.setValue(vals[item] || '')
}
})
}
},
deep: true
},
*/
show(val) {
if (this.children && this.children.length > 0) {
this.children.forEach(item => {
item.showError = val ? false : true
})
}
}
},
data() {
return {
errorMsg: '',
timer: null
timer: null,
rules: [],
mergeRules: [],
isRealTime: false
};
},
created() {
this.children = []
},
// #ifndef VUE3
beforeDestroy() {
this.clearTimer()
......@@ -144,28 +189,142 @@
// #endif
methods: {
clearTimer() {
this.children = null
clearTimeout(this.timer)
this.timer = null;
},
/*
@param model 表单数据对象
@param rules 表单验证规则
@param checkAll 校验所有元素
*/
getFormItemRules() {
let rules = []
if (this.children && this.children.length > 0) {
this.children.forEach(child => {
let rule = child.getRules()
rule && rules.push(rule)
})
}
return rules;
},
getMergeRules(rules) {
if (this.mergeRules.length === 0) return rules;
let formRules = [...rules]
//合并并替换当前rules数据
this.mergeRules.forEach(item => {
const index = rules.findIndex(e => e.name === item.name)
if (index === -1) {
formRules.push(item)
} else {
formRules[index] = item;
}
})
return formRules;
},
/**
* 校验方法
* @param {Object} model 表单数据对象
* @param {Array} rules 表单验证规则
* @param {Boolean} checkAll 校验所有元素,结合FormItem组件显示校验提示时必须传true
*/
validator(model, rules, checkAll = false) {
model = model || this.model
rules = rules || []
return new Promise((resolve, reject) => {
try {
if (rules.length === 0) {
rules = this.getFormItemRules()
} else {
rules = this.getMergeRules(rules)
}
let res = form.validator(model, rules, checkAll);
if (!res.isPassed && this.show) {
this.clearTimer()
if (!res.isPassed) {
let errors = res.errorMsg;
if (this.show) {
this.clearTimer()
if (checkAll) {
errors = errors[0].msg
}
this.errorMsg = errors;
this.timer = setTimeout(() => {
this.errorMsg = ''
}, this.duration)
} else {
if (checkAll && this.children && this.children.length > 0) {
//formItem 显示提示
this.children.forEach(item => {
const index = errors.findIndex(err => err.name === item.prop)
if (item.prop && item.prop !== true && ~index) {
item.errorMsg = errors[index].msg
item.itemValue = this.model[item.prop]
}
})
}
}
}
resolve(res)
} catch (e) {
reject({
isPassed: false,
errorMsg: '校验出错,请检查传入的数据格式是否有误!'
})
}
})
},
/**
* 验证具体的某个字段
* @param {Array<string> | String} props 字段key
* @param {Object} model 表单数据对象,传null则使用属性中model值
* @param {Array} rules 表单验证规则,当传null 或空数组时使用FormItem组件内rules
*/
validateField(props, model, rules) {
if (!rules || rules.length === 0) {
rules = this.getFormItemRules()
} else {
rules = this.getMergeRules(rules)
}
const isString = typeof props === 'string';
const formRules = rules.filter(item => props === item.name || (!isString && props
.indexOf(item.name) !== -1));
model = model || this.model
return this.validator(model, formRules, true)
},
//v2.1.0+ 通知formItem组件重置props参数
resetFormItemParam() {
if (this.children && this.children.length > 0) {
this.children.forEach(item => {
item.initParam(true)
})
}
},
//v2.1.0+ 通知formItem组件开启实时校验
switchRealTimeValidator(isOpen, rules = []) {
this.isRealTime = isOpen;
if (isOpen) {
if (!rules || rules.length === 0) {
rules = this.getFormItemRules()
} else {
rules = this.getMergeRules(rules)
}
this.rules = rules || []
}
if (this.children && this.children.length > 0) {
this.children.forEach(item => {
item.switchRealTimeValidator(isOpen)
})
}
},
//内部方法,提供给FormItem组件使用
realTimeValidator(prop, model, rules) {
return new Promise((resolve, reject) => {
try {
let res = form.validator(model || this.model, rules || this.rules, true);
if (!res.isPassed) {
//formItem 显示提示
let errors = res.errorMsg;
if (checkAll) {
errors = errors[0].msg
const index = errors.findIndex(err => err.name === prop)
if (~index) {
res.errorMsg = errors[index].msg
} else {
res.isPassed = true
res.errorMsg = ''
}
this.errorMsg = errors;
this.timer = setTimeout(() => {
this.errorMsg = ''
}, this.duration)
}
resolve(res)
} catch (e) {
......@@ -175,6 +334,43 @@
})
}
})
},
clearValidate(props = []) {
let arr = props;
arr = !arr ? [] : arr
if (typeof props === 'string') {
arr = [props]
}
if (this.children && this.children.length > 0) {
//清除指定字段的表单验证信息
if (arr && arr.length > 0) {
this.children.forEach(item => {
if (item.prop && ~arr.indexOf(item.prop)) {
item.errorMsg = ''
}
})
} else {
//清除所有字段的表单验证信息
this.children.forEach(item => {
item.errorMsg = ''
})
}
}
},
// 移除表单项
uninstall(instance) {
if (this.children && this.children.length > 0) {
const index = this.children.findIndex(item => item === instance)
if (index !== -1) {
this.children.splice(index, 1)
}
const rules = instance.getRules() || {}
const prop = instance.prop || rules.name || ''
const idx = this.mergeRules.findIndex(ru => ru.name === prop)
if (idx !== -1) {
this.mergeRules.splice(idx, 1)
}
}
}
}
}
......
......@@ -3,11 +3,12 @@ const BindingX = uni.requireNativePlugin('bindingx');
export default {
methods: {
getEl(el) {
return this.$refs[el].ref;
return this.$refs[el] ? this.$refs[el].ref : null;
},
nvueScrollHandler(e) {
const anchor = this.getEl('fui_scroller_view')
const element = this.getEl('fui_hor_indicator')
if (!anchor || !element) return;
const scrollLeft = e.contentOffset.x
const contentWidth = e.contentSize.width
if (this.scroll && element) {
......
......@@ -258,7 +258,9 @@
position: absolute;
left: 0;
top: 0;
/* #ifndef APP-NVUE */
transition: all 0.1s linear;
/* #endif */
}
/* #ifndef APP-NVUE */
......
<template>
<!-- #ifndef APP-NVUE -->
<text :style="{ color:getColor, fontSize: getSize, fontWeight: fontWeight}" class="fui-icon"
:class="[!getColor && !primary?'fui-icon__color':'',primary && (!color || color===true)?'fui-icon__active-color':'',disabled?'fui-icon__not-allowed':'',customPrefix,customPrefix?name:'']"
:class="[!getColor && !primary?'fui-icon__color':'',primary && (!color || color===true)?'fui-icon__active-color':'',disabled?'fui-icon__not-allowed':'',customPrefix && customPrefix!==true?customPrefix:'',customPrefix && customPrefix!==true?name:'']"
@click="handleClick">{{ icons[name] || '' }}</text>
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<text
:style="{ color: primary && (!color || color===true)?primaryColor:getColor, fontSize: getSize,lineHeight:getSize, fontWeight: fontWeight}"
class="fui-icon" :class="[customPrefix]" @click="handleClick">{{ customPrefix?name:icons[name] }}</text>
class="fui-icon" :class="[customPrefix && customPrefix!==true?customPrefix:'']"
@click="handleClick">{{ customPrefix && customPrefix!==true?name:icons[name] }}</text>
<!-- #endif -->
</template>
......@@ -84,8 +85,10 @@
},
getColor() {
const app = uni && uni.$fui && uni.$fui.fuiIcon;
let color = this.color || (app && app.color)
let color = this.color;
if (!color || (color && color === true)) {
color = (app && app.color)
}
// #ifdef APP-NVUE
if (!color || color === true) {
color = '#333333'
......
<template>
<view class="fui-index__list" ref="fui_index_list" id="fui_index_list">
<!-- #ifdef APP-NVUE -->
<list class="fui-index__list-sv" scrollable="true" show-scrollbar="false">
<list class="fui-index__list-sv" :scrollable="true" :show-scrollbar="false" :loadmoreoffset="10"
@loadmore="scrolltolower">
<cell>
<slot></slot>
</cell>
......@@ -27,7 +28,8 @@
<!-- #endif -->
<!-- #endif -->
<!-- #ifndef APP-NVUE -->
<scroll-view class="fui-index__list-sv" scroll-y :scroll-into-view="scrollViewId">
<scroll-view class="fui-index__list-sv" scroll-y :scroll-into-view="scrollViewId"
@scrolltolower="scrolltolower">
<slot></slot>
<view :id="'fui_il_letter_'+idx" v-for="(list, idx) in lists" :key="list.key">
<view class="fui-index__list-letter" :class="{'fui-il__key-bg':!background}"
......@@ -146,7 +148,7 @@
// #endif
export default {
name: 'fui-index-list',
emits: ['click', 'init'],
emits: ['click', 'init', 'scrolltolower'],
components: {
fIndexListItem
},
......@@ -283,6 +285,10 @@
})
},
methods: {
//滚动到底部,会触发 scrolltolower 事件
scrolltolower() {
this.$emit('scrolltolower', {})
},
getIndex(y) {
let index = -1;
// #ifdef H5
......
......@@ -21,18 +21,34 @@
<text :style="{fontSize:getLabelSize,color:labelColor}">{{label}}</text>
</view>
<slot name="left"></slot>
<!-- #ifndef APP-NVUE -->
<input class="fui-input__self"
:class="{'fui-input__text-right':textRight,'fui-input__disabled-styl':disabled && disabledStyle,'fui-input__disabled':disabled}"
:style="{fontSize:getSize,color:color,textAlign:textRight?'right':textAlign}"
placeholder-class="fui-input__placeholder" :type="type" :name="name" :value="val"
:placeholder="val?'':placeholder" :password="password || type === 'password' || null"
:placeholder-style="placeholderStyl" :disabled="disabled || readonly" :cursor-spacing="cursorSpacing"
:maxlength="maxlength" :focus="focused" :confirm-type="confirmType" :confirm-hold="confirmHold"
:cursor="cursor" :selection-start="selectionStart" :selection-end="selectionEnd"
:adjust-position="adjustPosition" :hold-keyboard="holdKeyboard" :auto-blur="autoBlur" :enableNative="false"
:always-embed="alwaysEmbed" @focus="onFocus" @blur="onBlur" @input="onInput" @confirm="onConfirm"
@keyboardheightchange="onKeyboardheightchange" />
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<view class="fui-input__self-wrap">
<input class="fui-input__self" :class="{'fui-input__text-right':textRight}"
:style="{fontSize:getSize,color:color}" placeholder-class="fui-input__placeholder" :type="type" :name="name"
:value="val" :placeholder="placeholder" :password="password || type === 'password' || undefined"
<input ref="fuiInput" class="fui-input__self" :class="{'fui-input__text-right':textRight}"
:style="{fontSize:getSize,color:color,textAlign:textRight?'right':textAlign}"
placeholder-class="fui-input__placeholder" :type="type" :name="name" :value="val"
:placeholder="placeholder" :password="password || type === 'password'"
:placeholder-style="placeholderStyl" :disabled="disabled || readonly" :cursor-spacing="cursorSpacing"
:maxlength="maxlength" :focus="focused" :confirm-type="confirmType" :confirm-hold="confirmHold"
:cursor="cursor" :selection-start="selectionStart" :selection-end="selectionEnd"
:adjust-position="adjustPosition" :hold-keyboard="holdKeyboard" :auto-blur="autoBlur" :enableNative="false"
:always-embed="alwaysEmbed" @focus="onFocus" @blur="onBlur" @input="onInput" @confirm="onConfirm"
@keyboardheightchange="onKeyboardheightchange" />
<view class="fui-input__cover" v-if="disabled || readonly" @tap="fieldClick"></view>
:adjust-position="adjustPosition" :hold-keyboard="holdKeyboard" :auto-blur="autoBlur"
:enableNative="false" :always-embed="alwaysEmbed" @focus="onFocus" @blur="onBlur" @input="onInput"
@confirm="onConfirm" @keyboardheightchange="onKeyboardheightchange" />
<view class="fui-input__cover" v-if="disabled || readonly" @tap="fieldClickAndroid"></view>
</view>
<!-- #endif -->
<view class="fui-input__clear-wrap" :style="{background:clearColor}" v-if="clearable && val != ''"
@tap.stop="onClear">
<view class="fui-input__clear">
......@@ -156,6 +172,11 @@
type: Boolean,
default: false
},
//V2.1.0+
disabledStyle: {
type: Boolean,
default: false
},
readonly: {
type: Boolean,
default: false
......@@ -272,10 +293,16 @@
type: Boolean,
default: true
},
//即将废弃,请使用textAlign属性
textRight: {
type: Boolean,
default: false
},
//V2.2.0+ 可选值:left/center/right
textAlign: {
type: String,
default: 'left'
},
padding: {
type: Array,
default () {
......@@ -329,9 +356,25 @@
watch: {
focus(val) {
this.$nextTick(() => {
this.focused = val
setTimeout(() => {
this.focused = val
}, 20)
})
},
// #ifdef APP-NVUE
focused(val) {
if (!this.$refs.fuiInput) return;
this.$nextTick(() => {
setTimeout(() => {
if (val) {
this.$refs.fuiInput.focus()
} else {
this.$refs.fuiInput.blur()
}
}, 50)
})
},
// #endif
placeholderStyle() {
this.fieldPlaceholderStyle()
},
......@@ -345,32 +388,26 @@
}
},
created() {
// #ifndef VUE3
this.val = this.value
// #endif
// #ifdef VUE3
if (this.value && !this.modelValue) {
this.fieldPlaceholderStyle()
setTimeout(() => {
// #ifndef VUE3
this.val = this.value
} else {
this.val = this.modelValue
}
// #endif
// #endif
this.fieldPlaceholderStyle()
// #ifdef VUE3
if (this.value && !this.modelValue) {
this.val = this.value
} else {
this.val = this.modelValue
}
// #endif
}, 50)
},
mounted() {
this.$nextTick(() => {
// #ifdef MP-TOUTIAO
setTimeout(() => {
this.focused = this.focus
}, 300)
// #endif
// #ifndef MP-TOUTIAO
setTimeout(() => {
this.focused = this.focus
}, 120)
// #endif
})
},
methods: {
......@@ -404,7 +441,7 @@
}
this.$nextTick(() => {
//当输入框为空时,输入框显示不赋值为0
event.detail.value !== '' && (this.val = value);
event.detail.value !== '' && (this.val = String(value));
})
//如果为空时返回0 ,当双向绑定会将输入框赋值0
const inputValue = event.detail.value !== '' ? value : ''
......@@ -556,12 +593,14 @@
/* #endif */
}
.fui-input__self-wrap{
/* #ifdef APP-NVUE */
.fui-input__self-wrap {
flex: 1;
flex-direction: row;
position: relative;
}
.fui-input__cover{
.fui-input__cover {
position: absolute;
left: 0;
right: 0;
......@@ -569,6 +608,8 @@
bottom: 0;
}
/* #endif */
.fui-input__self {
flex: 1;
padding-right: 12rpx;
......@@ -660,6 +701,10 @@
/* #endif */
/* #ifndef APP-NVUE */
.fui-input__disabled {
pointer-events: none;
}
.fui-input__border {
position: absolute;
height: 200%;
......@@ -683,7 +728,19 @@
/* #endif */
.fui-input__text-left {
text-align: left;
}
.fui-input__text-right {
text-align: right;
}
.fui-input__text-center {
text-align: center;
}
.fui-input__disabled-styl {
opacity: .6;
}
</style>
......@@ -94,6 +94,7 @@
local: isLocalFile,
show: isLocalFile,
visible: false,
isMounted: false,
elId: `fui_lazy_${Math.ceil(Math.random() * 10e5).toString(36)}`
};
},
......
......@@ -65,8 +65,8 @@
}
},
mounted() {
this.init(this.options)
setTimeout(() => {
this.init(this.options)
this.isInit = true;
}, 200)
}
......@@ -153,10 +153,10 @@
mounted() {
this.actionVal = this.getAction(this.action)
// #ifdef MP
this.$nextTick(()=>{
setTimeout(()=> {
this.$nextTick(() => {
setTimeout(() => {
this.initMp()
}, 10);
}, 50);
})
// #endif
},
......
......@@ -87,7 +87,9 @@ function touchmove(e, ins, event) {
var touch = {}
if (isH5 && isPC()) {
touch = e;
state = event.instance.getState()
if (event && event.instance) {
state = event.instance.getState()
}
} else {
touch = e.touches[0] || e.changedTouches[0]
state = e.instance.getState()
......
......@@ -171,7 +171,6 @@
}
.fui-nav__header {
flex: 1;
height: 44px;
/* #ifndef APP-NVUE */
width: 100%;
......
......@@ -9,12 +9,14 @@
:class="{'fui-picker__header-dark':theme==='dark','fui-picker__radius':radius}" :style="headerStyl">
<text class="fui-picker__btn-cancel"
:class="[theme==='dark'?'fui-pk__cancel-color_dark':'fui-pk__cancel-color']" :style="cancelStyl"
@tap.stop="btnCancel">取消</text>
<text class="fui-picker__title"
:class="[theme==='dark'?'fui-pk__title-color_dark':'fui-pk__title-color']"
:style="titleStyl">{{title}}</text>
@tap.stop="btnCancel">{{cancelText}}</text>
<slot>
<text class="fui-picker__title"
:class="[theme==='dark'?'fui-pk__title-color_dark':'fui-pk__title-color']"
:style="titleStyl">{{title}}</text>
</slot>
<text class="fui-picker__btn-sure fui-pk__sure-color" :style="confrimStyl"
@tap.stop="btnConfirm">确定</text>
@tap.stop="btnConfirm">{{confirmText}}</text>
</view>
<view @touchstart.stop="pickerstart">
<!--支付宝小程序不支持动态切换 picker-view-column ... 设置高度也不行-->
......@@ -96,7 +98,7 @@
:mask-bottom-style="theme==='dark'?darkBottomStyle:''" :mask-style="theme==='dark'?darkStyle:''"
:indicator-style="theme==='dark'?indicatorStyl:'height: 44px;border-top-width:0.5px;border-bottom-width:0.5px;'"
:indicator-class="theme==='dark'?'fui-picker__indicator':''" class="fui-picker__view"
:style="{height:height+'rpx'}" :key="theme+layer" :value="vals" immediate-change
:style="{height:height+'rpx'}" :key="theme+layer" :value="vals" :immediate-change="immediate"
@change="pickerChange">
<picker-view-column>
<text :style="contentStyl" class="fui-picker__text"
......@@ -343,7 +345,13 @@
}
},
data() {
//抖音小程序此属性有问题,设置为true,change事件可能不触发
let immediate = true;
// #ifdef MP-TOUTIAO
immediate = false
// #endif
return {
immediate,
firstArr: [],
secondArr: [],
thirdArr: [],
......@@ -476,7 +484,13 @@
},
initData() {
let data = this.options;
if (!data || data.length === 0) return;
if (!data || data.length === 0) {
this.firstArr = [];
this.secondArr = [];
this.thirdArr = [];
this.fourthArr = [];
return;
}
if (this.layer == 1 && !Array.isArray(data[0])) {
this.firstArr = data
} else {
......@@ -574,6 +588,7 @@
vals.push(this.fourthArr.indexOf(values[i]))
}
}
if (this.vals.join('') === vals.join('')) return;
this.vals = []
this.$nextTick(() => {
setTimeout(() => {
......
......@@ -8,6 +8,7 @@
* 生成海报
* nvue端专用,需真机运行查看效果,其他端请使用fui-poster组件
* poster - v1.0.0 (2021/7/19, 16:52:14 PM)
* updated V2.2.0+ 2023/11/07
*
* 官网地址:https://firstui.cn/
* 文档地址:https://doc.firstui.cn/
......@@ -16,6 +17,7 @@
enable,
WeexBridge
} from './gcanvas/index.js';
import fuiQr from './fui-qr/index.js'
export default {
name: "fui-poster-weex",
emits: ['ready'],
......@@ -59,7 +61,7 @@
this.h = this._toPx(this.height)
},
mounted() {
this.$nextTick(()=>{
this.$nextTick(() => {
let ganvas = this.$refs[this.canvasId];
/*通过元素引用获取canvas对象*/
let canvasObj = enable(ganvas, {
......@@ -74,7 +76,7 @@
},
methods: {
_toPx(rpx) {
// * Number(this.pixelRatio)
// * Number(this.pixelRatio)
return uni.upx2px(Number(rpx))
},
_getTextWidth(context, text, fontSize) {
......@@ -344,6 +346,38 @@
context.closePath();
context.restore();
},
_drawQrcode(context, params) {
let {
x,
y,
width,
height,
value,
foreground = "#181818",
background = "#ffffff"
} = params;
x = poster._toPx(x)
y = poster._toPx(y)
width = poster._toPx(width)
height = poster._toPx(height)
const qrcode = fuiQr(this.utf16to8(value), {
typeNumber: -1,
errorCorrectLevel: 2,
})
const cells = qrcode.modules
const tileW = width / cells.length
const tileH = height / cells.length
cells.forEach((row, rdx) => {
row.forEach((cell, cdx) => {
context.setFillStyle(cell ? foreground : background)
const w = (Math.ceil((cdx + 1) * tileW) - Math.floor(cdx * tileW))
const h = (Math.ceil((rdx + 1) * tileH) - Math.floor(rdx * tileH))
context.fillRect(Math.round(cdx * tileW) + x, Math.round(rdx * tileH) + y, w, h)
})
})
context.restore();
},
//ios用户拒绝相册访问 ,引导用户到设置页面,开启相册访问权限
//-1=未请求 1 = 已允许,0 = 拒绝|受限
_judgeIosPermissionPhotoLibrary() {
......@@ -465,7 +499,7 @@
}
}
},
_getPosterData(texts, blocks, lines, imgs) {
_getPosterData(texts, blocks, lines, imgs, qrcode) {
let queue = [].concat(texts.map((item) => {
item.type = 'text';
item.zIndex = item.zIndex || 0;
......@@ -478,6 +512,10 @@
item.type = 'line';
item.zIndex = item.zIndex || 0;
return item;
})).concat(qrcode.map((item) => {
item.type = 'qrcode';
item.zIndex = item.zIndex || 0;
return item;
})).concat(imgs.map((item) => {
item.type = 'image';
item.zIndex = item.zIndex || 0;
......@@ -534,6 +572,8 @@
this._drawBlock(context, params)
} else if (params.type === 'line') {
this._drawLine(context, params)
} else if (params.type === 'qrcode') {
this._drawQrcode(context, params)
}
});
const sys = uni.getSystemInfoSync();
......@@ -566,7 +606,7 @@
//生成海报
generatePoster(params, callback) {
let {
texts = [], imgs = [], blocks = [], lines = []
texts = [], imgs = [], blocks = [], lines = [], qrcode = []
} = params;
//需要看平台支持情况,如果对应平台不支持将会绘制失败
//图片处理 type:1-无需处理(base64或者网络路径,需在平台支持下),2-网络图片,下载 3-base64转本地图片
......@@ -591,7 +631,7 @@
let item = imgs[idxArr[idx]]
item.imgResource = imgRes
})
const queue = this._getPosterData(texts, blocks, lines, imgs);
const queue = this._getPosterData(texts, blocks, lines, imgs, qrcode);
this._generatePoster(this.width, this.height, queue, callback)
}).catch(err => {
......@@ -602,11 +642,11 @@
})
})
} else {
const queue = this._getPosterData(texts, blocks, lines, imgs);
const queue = this._getPosterData(texts, blocks, lines, imgs, qrcode);
this._generatePoster(this.width, this.height, queue, callback)
}
} else {
const queue = this._getPosterData(texts, blocks, lines, imgs);
const queue = this._getPosterData(texts, blocks, lines, imgs, qrcode);
this._generatePoster(this.width, this.height, queue, callback)
}
},
......@@ -633,6 +673,27 @@
})
}
})
},
utf16to8(str) {
const len = str.length
let out = ''
for (let i = 0; i < len; i++) {
const c = str.charCodeAt(i)
if ((c >= 0x0001) && (c <= 0x007F)) {
out += str.charAt(i)
} else if (c > 0x07FF) {
out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F))
out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F))
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F))
} else {
out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F))
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F))
}
}
return out
}
}
}
......
import QRCode from './lib/QRCode.js'
import ErrorCorrectLevel from './lib/ErrorCorrectLevel.js'
var qrcode = function(data, opt) {
opt = opt || {};
var qr = new QRCode(opt.typeNumber || -1,
opt.errorCorrectLevel || ErrorCorrectLevel.H);
qr.addData(data);
qr.make();
return qr;
};
qrcode.ErrorCorrectLevel = ErrorCorrectLevel;
export default qrcode;
import mode from './mode.js'
function QR8bitByte(data) {
this.mode = mode.MODE_8BIT_BYTE;
this.data = data;
}
QR8bitByte.prototype = {
getLength : function(buffer) {
return this.data.length;
},
write : function(buffer) {
for (var i = 0; i < this.data.length; i++) {
// not JIS ...
buffer.put(this.data.charCodeAt(i), 8);
}
}
};
export default QR8bitByte;
function QRBitBuffer() {
this.buffer = new Array();
this.length = 0;
}
QRBitBuffer.prototype = {
get : function(index) {
var bufIndex = Math.floor(index / 8);
return ( (this.buffer[bufIndex] >>> (7 - index % 8) ) & 1) == 1;
},
put : function(num, length) {
for (var i = 0; i < length; i++) {
this.putBit( ( (num >>> (length - i - 1) ) & 1) == 1);
}
},
getLengthInBits : function() {
return this.length;
},
putBit : function(bit) {
var bufIndex = Math.floor(this.length / 8);
if (this.buffer.length <= bufIndex) {
this.buffer.push(0);
}
if (bit) {
this.buffer[bufIndex] |= (0x80 >>> (this.length % 8) );
}
this.length++;
}
};
export default QRBitBuffer;
Copyright (c) 2009 Kazuhiko Arase <kazuhiko.arase@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import math from './math.js'
function QRPolynomial(num, shift) {
if (num.length == undefined) {
throw new Error(num.length + "/" + shift);
}
var offset = 0;
while (offset < num.length && num[offset] == 0) {
offset++;
}
this.num = new Array(num.length - offset + shift);
for (var i = 0; i < num.length - offset; i++) {
this.num[i] = num[i + offset];
}
}
QRPolynomial.prototype = {
get : function(index) {
return this.num[index];
},
getLength : function() {
return this.num.length;
},
multiply : function(e) {
var num = new Array(this.getLength() + e.getLength() - 1);
for (var i = 0; i < this.getLength(); i++) {
for (var j = 0; j < e.getLength(); j++) {
num[i + j] ^= math.gexp(math.glog(this.get(i) ) + math.glog(e.get(j) ) );
}
}
return new QRPolynomial(num, 0);
},
mod : function(e) {
if (this.getLength() - e.getLength() < 0) {
return this;
}
var ratio = math.glog(this.get(0) ) - math.glog(e.get(0) );
var num = new Array(this.getLength() );
for (var i = 0; i < this.getLength(); i++) {
num[i] = this.get(i);
}
for (var i = 0; i < e.getLength(); i++) {
num[i] ^= math.gexp(math.glog(e.get(i) ) + ratio);
}
// recursive call
return new QRPolynomial(num, 0).mod(e);
}
};
export default QRPolynomial;
import BitByte from './8BitByte.js'
import RSBlock from './RSBlock.js'
import BitBuffer from './BitBuffer.js'
import util from './util.js'
import Polynomial from './Polynomial.js'
function QRCode(typeNumber, errorCorrectLevel) {
this.typeNumber = typeNumber;
this.errorCorrectLevel = errorCorrectLevel;
this.modules = null;
this.moduleCount = 0;
this.dataCache = null;
this.dataList = [];
}
// for client side minification
var proto = QRCode.prototype;
proto.addData = function(data) {
var newData = new BitByte(data);
this.dataList.push(newData);
this.dataCache = null;
};
proto.isDark = function(row, col) {
if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) {
throw new Error(row + "," + col);
}
return this.modules[row][col];
};
proto.getModuleCount = function() {
return this.moduleCount;
};
proto.make = function() {
// Calculate automatically typeNumber if provided is < 1
if (this.typeNumber < 1 ){
var typeNumber = 1;
for (typeNumber = 1; typeNumber < 40; typeNumber++) {
var rsBlocks = RSBlock.getRSBlocks(typeNumber, this.errorCorrectLevel);
var buffer = new BitBuffer();
var totalDataCount = 0;
for (var i = 0; i < rsBlocks.length; i++) {
totalDataCount += rsBlocks[i].dataCount;
}
for (var i = 0; i < this.dataList.length; i++) {
var data = this.dataList[i];
buffer.put(data.mode, 4);
buffer.put(data.getLength(), util.getLengthInBits(data.mode, typeNumber) );
data.write(buffer);
}
if (buffer.getLengthInBits() <= totalDataCount * 8)
break;
}
this.typeNumber = typeNumber;
}
this.makeImpl(false, this.getBestMaskPattern() );
};
proto.makeImpl = function(test, maskPattern) {
this.moduleCount = this.typeNumber * 4 + 17;
this.modules = new Array(this.moduleCount);
for (var row = 0; row < this.moduleCount; row++) {
this.modules[row] = new Array(this.moduleCount);
for (var col = 0; col < this.moduleCount; col++) {
this.modules[row][col] = null;//(col + row) % 3;
}
}
this.setupPositionProbePattern(0, 0);
this.setupPositionProbePattern(this.moduleCount - 7, 0);
this.setupPositionProbePattern(0, this.moduleCount - 7);
this.setupPositionAdjustPattern();
this.setupTimingPattern();
this.setupTypeInfo(test, maskPattern);
if (this.typeNumber >= 7) {
this.setupTypeNumber(test);
}
if (this.dataCache == null) {
this.dataCache = QRCode.createData(this.typeNumber, this.errorCorrectLevel, this.dataList);
}
this.mapData(this.dataCache, maskPattern);
};
proto.setupPositionProbePattern = function(row, col) {
for (var r = -1; r <= 7; r++) {
if (row + r <= -1 || this.moduleCount <= row + r) continue;
for (var c = -1; c <= 7; c++) {
if (col + c <= -1 || this.moduleCount <= col + c) continue;
if ( (0 <= r && r <= 6 && (c == 0 || c == 6) )
|| (0 <= c && c <= 6 && (r == 0 || r == 6) )
|| (2 <= r && r <= 4 && 2 <= c && c <= 4) ) {
this.modules[row + r][col + c] = true;
} else {
this.modules[row + r][col + c] = false;
}
}
}
};
proto.getBestMaskPattern = function() {
var minLostPoint = 0;
var pattern = 0;
for (var i = 0; i < 8; i++) {
this.makeImpl(true, i);
var lostPoint = util.getLostPoint(this);
if (i == 0 || minLostPoint > lostPoint) {
minLostPoint = lostPoint;
pattern = i;
}
}
return pattern;
};
proto.createMovieClip = function(target_mc, instance_name, depth) {
var qr_mc = target_mc.createEmptyMovieClip(instance_name, depth);
var cs = 1;
this.make();
for (var row = 0; row < this.modules.length; row++) {
var y = row * cs;
for (var col = 0; col < this.modules[row].length; col++) {
var x = col * cs;
var dark = this.modules[row][col];
if (dark) {
qr_mc.beginFill(0, 100);
qr_mc.moveTo(x, y);
qr_mc.lineTo(x + cs, y);
qr_mc.lineTo(x + cs, y + cs);
qr_mc.lineTo(x, y + cs);
qr_mc.endFill();
}
}
}
return qr_mc;
};
proto.setupTimingPattern = function() {
for (var r = 8; r < this.moduleCount - 8; r++) {
if (this.modules[r][6] != null) {
continue;
}
this.modules[r][6] = (r % 2 == 0);
}
for (var c = 8; c < this.moduleCount - 8; c++) {
if (this.modules[6][c] != null) {
continue;
}
this.modules[6][c] = (c % 2 == 0);
}
};
proto.setupPositionAdjustPattern = function() {
var pos = util.getPatternPosition(this.typeNumber);
for (var i = 0; i < pos.length; i++) {
for (var j = 0; j < pos.length; j++) {
var row = pos[i];
var col = pos[j];
if (this.modules[row][col] != null) {
continue;
}
for (var r = -2; r <= 2; r++) {
for (var c = -2; c <= 2; c++) {
if (r == -2 || r == 2 || c == -2 || c == 2
|| (r == 0 && c == 0) ) {
this.modules[row + r][col + c] = true;
} else {
this.modules[row + r][col + c] = false;
}
}
}
}
}
};
proto.setupTypeNumber = function(test) {
var bits = util.getBCHTypeNumber(this.typeNumber);
for (var i = 0; i < 18; i++) {
var mod = (!test && ( (bits >> i) & 1) == 1);
this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod;
}
for (var i = 0; i < 18; i++) {
var mod = (!test && ( (bits >> i) & 1) == 1);
this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod;
}
};
proto.setupTypeInfo = function(test, maskPattern) {
var data = (this.errorCorrectLevel << 3) | maskPattern;
var bits = util.getBCHTypeInfo(data);
// vertical
for (var i = 0; i < 15; i++) {
var mod = (!test && ( (bits >> i) & 1) == 1);
if (i < 6) {
this.modules[i][8] = mod;
} else if (i < 8) {
this.modules[i + 1][8] = mod;
} else {
this.modules[this.moduleCount - 15 + i][8] = mod;
}
}
// horizontal
for (var i = 0; i < 15; i++) {
var mod = (!test && ( (bits >> i) & 1) == 1);
if (i < 8) {
this.modules[8][this.moduleCount - i - 1] = mod;
} else if (i < 9) {
this.modules[8][15 - i - 1 + 1] = mod;
} else {
this.modules[8][15 - i - 1] = mod;
}
}
// fixed module
this.modules[this.moduleCount - 8][8] = (!test);
};
proto.mapData = function(data, maskPattern) {
var inc = -1;
var row = this.moduleCount - 1;
var bitIndex = 7;
var byteIndex = 0;
for (var col = this.moduleCount - 1; col > 0; col -= 2) {
if (col == 6) col--;
while (true) {
for (var c = 0; c < 2; c++) {
if (this.modules[row][col - c] == null) {
var dark = false;
if (byteIndex < data.length) {
dark = ( ( (data[byteIndex] >>> bitIndex) & 1) == 1);
}
var mask = util.getMask(maskPattern, row, col - c);
if (mask) {
dark = !dark;
}
this.modules[row][col - c] = dark;
bitIndex--;
if (bitIndex == -1) {
byteIndex++;
bitIndex = 7;
}
}
}
row += inc;
if (row < 0 || this.moduleCount <= row) {
row -= inc;
inc = -inc;
break;
}
}
}
};
QRCode.PAD0 = 0xEC;
QRCode.PAD1 = 0x11;
QRCode.createData = function(typeNumber, errorCorrectLevel, dataList) {
var rsBlocks = RSBlock.getRSBlocks(typeNumber, errorCorrectLevel);
var buffer = new BitBuffer();
for (var i = 0; i < dataList.length; i++) {
var data = dataList[i];
buffer.put(data.mode, 4);
buffer.put(data.getLength(), util.getLengthInBits(data.mode, typeNumber) );
data.write(buffer);
}
// calc num max data.
var totalDataCount = 0;
for (var i = 0; i < rsBlocks.length; i++) {
totalDataCount += rsBlocks[i].dataCount;
}
if (buffer.getLengthInBits() > totalDataCount * 8) {
throw new Error("code length overflow. ("
+ buffer.getLengthInBits()
+ ">"
+ totalDataCount * 8
+ ")");
}
// end code
if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {
buffer.put(0, 4);
}
// padding
while (buffer.getLengthInBits() % 8 != 0) {
buffer.putBit(false);
}
// padding
while (true) {
if (buffer.getLengthInBits() >= totalDataCount * 8) {
break;
}
buffer.put(QRCode.PAD0, 8);
if (buffer.getLengthInBits() >= totalDataCount * 8) {
break;
}
buffer.put(QRCode.PAD1, 8);
}
return QRCode.createBytes(buffer, rsBlocks);
};
QRCode.createBytes = function(buffer, rsBlocks) {
var offset = 0;
var maxDcCount = 0;
var maxEcCount = 0;
var dcdata = new Array(rsBlocks.length);
var ecdata = new Array(rsBlocks.length);
for (var r = 0; r < rsBlocks.length; r++) {
var dcCount = rsBlocks[r].dataCount;
var ecCount = rsBlocks[r].totalCount - dcCount;
maxDcCount = Math.max(maxDcCount, dcCount);
maxEcCount = Math.max(maxEcCount, ecCount);
dcdata[r] = new Array(dcCount);
for (var i = 0; i < dcdata[r].length; i++) {
dcdata[r][i] = 0xff & buffer.buffer[i + offset];
}
offset += dcCount;
var rsPoly = util.getErrorCorrectPolynomial(ecCount);
var rawPoly = new Polynomial(dcdata[r], rsPoly.getLength() - 1);
var modPoly = rawPoly.mod(rsPoly);
ecdata[r] = new Array(rsPoly.getLength() - 1);
for (var i = 0; i < ecdata[r].length; i++) {
var modIndex = i + modPoly.getLength() - ecdata[r].length;
ecdata[r][i] = (modIndex >= 0)? modPoly.get(modIndex) : 0;
}
}
var totalCodeCount = 0;
for (var i = 0; i < rsBlocks.length; i++) {
totalCodeCount += rsBlocks[i].totalCount;
}
var data = new Array(totalCodeCount);
var index = 0;
for (var i = 0; i < maxDcCount; i++) {
for (var r = 0; r < rsBlocks.length; r++) {
if (i < dcdata[r].length) {
data[index++] = dcdata[r][i];
}
}
}
for (var i = 0; i < maxEcCount; i++) {
for (var r = 0; r < rsBlocks.length; r++) {
if (i < ecdata[r].length) {
data[index++] = ecdata[r][i];
}
}
}
return data;
};
export default QRCode;
// ErrorCorrectLevel
import ECL from './ErrorCorrectLevel.js'
function QRRSBlock(totalCount, dataCount) {
this.totalCount = totalCount;
this.dataCount = dataCount;
}
QRRSBlock.RS_BLOCK_TABLE = [
// L
// M
// Q
// H
// 1
[1, 26, 19],
[1, 26, 16],
[1, 26, 13],
[1, 26, 9],
// 2
[1, 44, 34],
[1, 44, 28],
[1, 44, 22],
[1, 44, 16],
// 3
[1, 70, 55],
[1, 70, 44],
[2, 35, 17],
[2, 35, 13],
// 4
[1, 100, 80],
[2, 50, 32],
[2, 50, 24],
[4, 25, 9],
// 5
[1, 134, 108],
[2, 67, 43],
[2, 33, 15, 2, 34, 16],
[2, 33, 11, 2, 34, 12],
// 6
[2, 86, 68],
[4, 43, 27],
[4, 43, 19],
[4, 43, 15],
// 7
[2, 98, 78],
[4, 49, 31],
[2, 32, 14, 4, 33, 15],
[4, 39, 13, 1, 40, 14],
// 8
[2, 121, 97],
[2, 60, 38, 2, 61, 39],
[4, 40, 18, 2, 41, 19],
[4, 40, 14, 2, 41, 15],
// 9
[2, 146, 116],
[3, 58, 36, 2, 59, 37],
[4, 36, 16, 4, 37, 17],
[4, 36, 12, 4, 37, 13],
// 10
[2, 86, 68, 2, 87, 69],
[4, 69, 43, 1, 70, 44],
[6, 43, 19, 2, 44, 20],
[6, 43, 15, 2, 44, 16],
// 11
[4, 101, 81],
[1, 80, 50, 4, 81, 51],
[4, 50, 22, 4, 51, 23],
[3, 36, 12, 8, 37, 13],
// 12
[2, 116, 92, 2, 117, 93],
[6, 58, 36, 2, 59, 37],
[4, 46, 20, 6, 47, 21],
[7, 42, 14, 4, 43, 15],
// 13
[4, 133, 107],
[8, 59, 37, 1, 60, 38],
[8, 44, 20, 4, 45, 21],
[12, 33, 11, 4, 34, 12],
// 14
[3, 145, 115, 1, 146, 116],
[4, 64, 40, 5, 65, 41],
[11, 36, 16, 5, 37, 17],
[11, 36, 12, 5, 37, 13],
// 15
[5, 109, 87, 1, 110, 88],
[5, 65, 41, 5, 66, 42],
[5, 54, 24, 7, 55, 25],
[11, 36, 12],
// 16
[5, 122, 98, 1, 123, 99],
[7, 73, 45, 3, 74, 46],
[15, 43, 19, 2, 44, 20],
[3, 45, 15, 13, 46, 16],
// 17
[1, 135, 107, 5, 136, 108],
[10, 74, 46, 1, 75, 47],
[1, 50, 22, 15, 51, 23],
[2, 42, 14, 17, 43, 15],
// 18
[5, 150, 120, 1, 151, 121],
[9, 69, 43, 4, 70, 44],
[17, 50, 22, 1, 51, 23],
[2, 42, 14, 19, 43, 15],
// 19
[3, 141, 113, 4, 142, 114],
[3, 70, 44, 11, 71, 45],
[17, 47, 21, 4, 48, 22],
[9, 39, 13, 16, 40, 14],
// 20
[3, 135, 107, 5, 136, 108],
[3, 67, 41, 13, 68, 42],
[15, 54, 24, 5, 55, 25],
[15, 43, 15, 10, 44, 16],
// 21
[4, 144, 116, 4, 145, 117],
[17, 68, 42],
[17, 50, 22, 6, 51, 23],
[19, 46, 16, 6, 47, 17],
// 22
[2, 139, 111, 7, 140, 112],
[17, 74, 46],
[7, 54, 24, 16, 55, 25],
[34, 37, 13],
// 23
[4, 151, 121, 5, 152, 122],
[4, 75, 47, 14, 76, 48],
[11, 54, 24, 14, 55, 25],
[16, 45, 15, 14, 46, 16],
// 24
[6, 147, 117, 4, 148, 118],
[6, 73, 45, 14, 74, 46],
[11, 54, 24, 16, 55, 25],
[30, 46, 16, 2, 47, 17],
// 25
[8, 132, 106, 4, 133, 107],
[8, 75, 47, 13, 76, 48],
[7, 54, 24, 22, 55, 25],
[22, 45, 15, 13, 46, 16],
// 26
[10, 142, 114, 2, 143, 115],
[19, 74, 46, 4, 75, 47],
[28, 50, 22, 6, 51, 23],
[33, 46, 16, 4, 47, 17],
// 27
[8, 152, 122, 4, 153, 123],
[22, 73, 45, 3, 74, 46],
[8, 53, 23, 26, 54, 24],
[12, 45, 15, 28, 46, 16],
// 28
[3, 147, 117, 10, 148, 118],
[3, 73, 45, 23, 74, 46],
[4, 54, 24, 31, 55, 25],
[11, 45, 15, 31, 46, 16],
// 29
[7, 146, 116, 7, 147, 117],
[21, 73, 45, 7, 74, 46],
[1, 53, 23, 37, 54, 24],
[19, 45, 15, 26, 46, 16],
// 30
[5, 145, 115, 10, 146, 116],
[19, 75, 47, 10, 76, 48],
[15, 54, 24, 25, 55, 25],
[23, 45, 15, 25, 46, 16],
// 31
[13, 145, 115, 3, 146, 116],
[2, 74, 46, 29, 75, 47],
[42, 54, 24, 1, 55, 25],
[23, 45, 15, 28, 46, 16],
// 32
[17, 145, 115],
[10, 74, 46, 23, 75, 47],
[10, 54, 24, 35, 55, 25],
[19, 45, 15, 35, 46, 16],
// 33
[17, 145, 115, 1, 146, 116],
[14, 74, 46, 21, 75, 47],
[29, 54, 24, 19, 55, 25],
[11, 45, 15, 46, 46, 16],
// 34
[13, 145, 115, 6, 146, 116],
[14, 74, 46, 23, 75, 47],
[44, 54, 24, 7, 55, 25],
[59, 46, 16, 1, 47, 17],
// 35
[12, 151, 121, 7, 152, 122],
[12, 75, 47, 26, 76, 48],
[39, 54, 24, 14, 55, 25],
[22, 45, 15, 41, 46, 16],
// 36
[6, 151, 121, 14, 152, 122],
[6, 75, 47, 34, 76, 48],
[46, 54, 24, 10, 55, 25],
[2, 45, 15, 64, 46, 16],
// 37
[17, 152, 122, 4, 153, 123],
[29, 74, 46, 14, 75, 47],
[49, 54, 24, 10, 55, 25],
[24, 45, 15, 46, 46, 16],
// 38
[4, 152, 122, 18, 153, 123],
[13, 74, 46, 32, 75, 47],
[48, 54, 24, 14, 55, 25],
[42, 45, 15, 32, 46, 16],
// 39
[20, 147, 117, 4, 148, 118],
[40, 75, 47, 7, 76, 48],
[43, 54, 24, 22, 55, 25],
[10, 45, 15, 67, 46, 16],
// 40
[19, 148, 118, 6, 149, 119],
[18, 75, 47, 31, 76, 48],
[34, 54, 24, 34, 55, 25],
[20, 45, 15, 61, 46, 16]
];
QRRSBlock.getRSBlocks = function(typeNumber, errorCorrectLevel) {
var rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel);
if (rsBlock == undefined) {
throw new Error("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + errorCorrectLevel);
}
var length = rsBlock.length / 3;
var list = new Array();
for (var i = 0; i < length; i++) {
var count = rsBlock[i * 3 + 0];
var totalCount = rsBlock[i * 3 + 1];
var dataCount = rsBlock[i * 3 + 2];
for (var j = 0; j < count; j++) {
list.push(new QRRSBlock(totalCount, dataCount) );
}
}
return list;
}
QRRSBlock.getRsBlockTable = function(typeNumber, errorCorrectLevel) {
switch(errorCorrectLevel) {
case ECL.L :
return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];
case ECL.M :
return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];
case ECL.Q :
return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];
case ECL.H :
return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];
default :
return undefined;
}
}
export default QRRSBlock;
var QRMath = {
glog : function(n) {
if (n < 1) {
throw new Error("glog(" + n + ")");
}
return QRMath.LOG_TABLE[n];
},
gexp : function(n) {
while (n < 0) {
n += 255;
}
while (n >= 256) {
n -= 255;
}
return QRMath.EXP_TABLE[n];
},
EXP_TABLE : new Array(256),
LOG_TABLE : new Array(256)
};
for (var i = 0; i < 8; i++) {
QRMath.EXP_TABLE[i] = 1 << i;
}
for (var i = 8; i < 256; i++) {
QRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4]
^ QRMath.EXP_TABLE[i - 5]
^ QRMath.EXP_TABLE[i - 6]
^ QRMath.EXP_TABLE[i - 8];
}
for (var i = 0; i < 255; i++) {
QRMath.LOG_TABLE[QRMath.EXP_TABLE[i] ] = i;
}
export default QRMath;
export default {
MODE_NUMBER : 1 << 0,
MODE_ALPHA_NUM : 1 << 1,
MODE_8BIT_BYTE : 1 << 2,
MODE_KANJI : 1 << 3
};
import Mode from './mode.js'
import Polynomial from './Polynomial.js'
import math from './math.js'
var QRMaskPattern = {
PATTERN000 : 0,
PATTERN001 : 1,
PATTERN010 : 2,
PATTERN011 : 3,
PATTERN100 : 4,
PATTERN101 : 5,
PATTERN110 : 6,
PATTERN111 : 7
};
var QRUtil = {
PATTERN_POSITION_TABLE : [
[],
[6, 18],
[6, 22],
[6, 26],
[6, 30],
[6, 34],
[6, 22, 38],
[6, 24, 42],
[6, 26, 46],
[6, 28, 50],
[6, 30, 54],
[6, 32, 58],
[6, 34, 62],
[6, 26, 46, 66],
[6, 26, 48, 70],
[6, 26, 50, 74],
[6, 30, 54, 78],
[6, 30, 56, 82],
[6, 30, 58, 86],
[6, 34, 62, 90],
[6, 28, 50, 72, 94],
[6, 26, 50, 74, 98],
[6, 30, 54, 78, 102],
[6, 28, 54, 80, 106],
[6, 32, 58, 84, 110],
[6, 30, 58, 86, 114],
[6, 34, 62, 90, 118],
[6, 26, 50, 74, 98, 122],
[6, 30, 54, 78, 102, 126],
[6, 26, 52, 78, 104, 130],
[6, 30, 56, 82, 108, 134],
[6, 34, 60, 86, 112, 138],
[6, 30, 58, 86, 114, 142],
[6, 34, 62, 90, 118, 146],
[6, 30, 54, 78, 102, 126, 150],
[6, 24, 50, 76, 102, 128, 154],
[6, 28, 54, 80, 106, 132, 158],
[6, 32, 58, 84, 110, 136, 162],
[6, 26, 54, 82, 110, 138, 166],
[6, 30, 58, 86, 114, 142, 170]
],
G15 : (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0),
G18 : (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0),
G15_MASK : (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1),
getBCHTypeInfo : function(data) {
var d = data << 10;
while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {
d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) ) );
}
return ( (data << 10) | d) ^ QRUtil.G15_MASK;
},
getBCHTypeNumber : function(data) {
var d = data << 12;
while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {
d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) ) );
}
return (data << 12) | d;
},
getBCHDigit : function(data) {
var digit = 0;
while (data != 0) {
digit++;
data >>>= 1;
}
return digit;
},
getPatternPosition : function(typeNumber) {
return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1];
},
getMask : function(maskPattern, i, j) {
switch (maskPattern) {
case QRMaskPattern.PATTERN000 : return (i + j) % 2 == 0;
case QRMaskPattern.PATTERN001 : return i % 2 == 0;
case QRMaskPattern.PATTERN010 : return j % 3 == 0;
case QRMaskPattern.PATTERN011 : return (i + j) % 3 == 0;
case QRMaskPattern.PATTERN100 : return (Math.floor(i / 2) + Math.floor(j / 3) ) % 2 == 0;
case QRMaskPattern.PATTERN101 : return (i * j) % 2 + (i * j) % 3 == 0;
case QRMaskPattern.PATTERN110 : return ( (i * j) % 2 + (i * j) % 3) % 2 == 0;
case QRMaskPattern.PATTERN111 : return ( (i * j) % 3 + (i + j) % 2) % 2 == 0;
default :
throw new Error("bad maskPattern:" + maskPattern);
}
},
getErrorCorrectPolynomial : function(errorCorrectLength) {
var a = new Polynomial([1], 0);
for (var i = 0; i < errorCorrectLength; i++) {
a = a.multiply(new Polynomial([1, math.gexp(i)], 0) );
}
return a;
},
getLengthInBits : function(mode, type) {
if (1 <= type && type < 10) {
// 1 - 9
switch(mode) {
case Mode.MODE_NUMBER : return 10;
case Mode.MODE_ALPHA_NUM : return 9;
case Mode.MODE_8BIT_BYTE : return 8;
case Mode.MODE_KANJI : return 8;
default :
throw new Error("mode:" + mode);
}
} else if (type < 27) {
// 10 - 26
switch(mode) {
case Mode.MODE_NUMBER : return 12;
case Mode.MODE_ALPHA_NUM : return 11;
case Mode.MODE_8BIT_BYTE : return 16;
case Mode.MODE_KANJI : return 10;
default :
throw new Error("mode:" + mode);
}
} else if (type < 41) {
// 27 - 40
switch(mode) {
case Mode.MODE_NUMBER : return 14;
case Mode.MODE_ALPHA_NUM : return 13;
case Mode.MODE_8BIT_BYTE : return 16;
case Mode.MODE_KANJI : return 12;
default :
throw new Error("mode:" + mode);
}
} else {
throw new Error("type:" + type);
}
},
getLostPoint : function(qrCode) {
var moduleCount = qrCode.getModuleCount();
var lostPoint = 0;
// LEVEL1
for (var row = 0; row < moduleCount; row++) {
for (var col = 0; col < moduleCount; col++) {
var sameCount = 0;
var dark = qrCode.isDark(row, col);
for (var r = -1; r <= 1; r++) {
if (row + r < 0 || moduleCount <= row + r) {
continue;
}
for (var c = -1; c <= 1; c++) {
if (col + c < 0 || moduleCount <= col + c) {
continue;
}
if (r == 0 && c == 0) {
continue;
}
if (dark == qrCode.isDark(row + r, col + c) ) {
sameCount++;
}
}
}
if (sameCount > 5) {
lostPoint += (3 + sameCount - 5);
}
}
}
// LEVEL2
for (var row = 0; row < moduleCount - 1; row++) {
for (var col = 0; col < moduleCount - 1; col++) {
var count = 0;
if (qrCode.isDark(row, col ) ) count++;
if (qrCode.isDark(row + 1, col ) ) count++;
if (qrCode.isDark(row, col + 1) ) count++;
if (qrCode.isDark(row + 1, col + 1) ) count++;
if (count == 0 || count == 4) {
lostPoint += 3;
}
}
}
// LEVEL3
for (var row = 0; row < moduleCount; row++) {
for (var col = 0; col < moduleCount - 6; col++) {
if (qrCode.isDark(row, col)
&& !qrCode.isDark(row, col + 1)
&& qrCode.isDark(row, col + 2)
&& qrCode.isDark(row, col + 3)
&& qrCode.isDark(row, col + 4)
&& !qrCode.isDark(row, col + 5)
&& qrCode.isDark(row, col + 6) ) {
lostPoint += 40;
}
}
}
for (var col = 0; col < moduleCount; col++) {
for (var row = 0; row < moduleCount - 6; row++) {
if (qrCode.isDark(row, col)
&& !qrCode.isDark(row + 1, col)
&& qrCode.isDark(row + 2, col)
&& qrCode.isDark(row + 3, col)
&& qrCode.isDark(row + 4, col)
&& !qrCode.isDark(row + 5, col)
&& qrCode.isDark(row + 6, col) ) {
lostPoint += 40;
}
}
}
// LEVEL4
var darkCount = 0;
for (var col = 0; col < moduleCount; col++) {
for (var row = 0; row < moduleCount; row++) {
if (qrCode.isDark(row, col) ) {
darkCount++;
}
}
}
var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;
lostPoint += ratio * 10;
return lostPoint;
}
};
export default QRUtil;
......@@ -80,7 +80,7 @@
_toPx(rpx) {
return uni.upx2px(Number(rpx) * Number(this.pixelRatio))
},
_getPosterData(texts, blocks, lines, imgs) {
_getPosterData(texts, blocks, lines, imgs, qrcode) {
let queue = [].concat(texts.map((item) => {
item.type = 'text';
item.zIndex = item.zIndex || 0;
......@@ -93,6 +93,10 @@
item.type = 'line';
item.zIndex = item.zIndex || 0;
return item;
})).concat(qrcode.map((item) => {
item.type = 'qrcode';
item.zIndex = item.zIndex || 0;
return item;
})).concat(imgs.map((item) => {
item.type = 'image';
item.zIndex = item.zIndex || 0;
......@@ -105,7 +109,7 @@
//生成海报
generatePoster(params, callback) {
let {
texts = [], imgs = [], blocks = [], lines = []
texts = [], imgs = [], blocks = [], lines = [], qrcode = []
} = params;
//需要看平台支持情况,如果对应平台不支持将会绘制失败
//图片处理 type:1-无需处理(base64、本地路径、网络路径等,需在平台支持下),2-网络图片,下载 3-base64转本地图片(只支持App,微信小程序,H5)
......@@ -131,7 +135,7 @@
item.imgResource = imgRes
// console.log(imgRes)
})
const queue = this._getPosterData(texts, blocks, lines, imgs);
const queue = this._getPosterData(texts, blocks, lines, imgs, qrcode);
poster.generatePoster(this.width, this.height, queue, callback)
}).catch(err => {
......@@ -142,11 +146,11 @@
})
})
} else {
const queue = this._getPosterData(texts, blocks, lines, imgs);
const queue = this._getPosterData(texts, blocks, lines, imgs, qrcode);
poster.generatePoster(this.width, this.height, queue, callback)
}
} else {
const queue = this._getPosterData(texts, blocks, lines, imgs);
const queue = this._getPosterData(texts, blocks, lines, imgs, qrcode);
poster.generatePoster(this.width, this.height, queue, callback)
}
},
......
import QRCode from './lib/QRCode.js'
import ErrorCorrectLevel from './lib/ErrorCorrectLevel.js'
var qrcode = function(data, opt) {
opt = opt || {};
var qr = new QRCode(opt.typeNumber || -1,
opt.errorCorrectLevel || ErrorCorrectLevel.H);
qr.addData(data);
qr.make();
return qr;
};
qrcode.ErrorCorrectLevel = ErrorCorrectLevel;
export default qrcode;
import mode from './mode.js'
function QR8bitByte(data) {
this.mode = mode.MODE_8BIT_BYTE;
this.data = data;
}
QR8bitByte.prototype = {
getLength : function(buffer) {
return this.data.length;
},
write : function(buffer) {
for (var i = 0; i < this.data.length; i++) {
// not JIS ...
buffer.put(this.data.charCodeAt(i), 8);
}
}
};
export default QR8bitByte;
function QRBitBuffer() {
this.buffer = new Array();
this.length = 0;
}
QRBitBuffer.prototype = {
get : function(index) {
var bufIndex = Math.floor(index / 8);
return ( (this.buffer[bufIndex] >>> (7 - index % 8) ) & 1) == 1;
},
put : function(num, length) {
for (var i = 0; i < length; i++) {
this.putBit( ( (num >>> (length - i - 1) ) & 1) == 1);
}
},
getLengthInBits : function() {
return this.length;
},
putBit : function(bit) {
var bufIndex = Math.floor(this.length / 8);
if (this.buffer.length <= bufIndex) {
this.buffer.push(0);
}
if (bit) {
this.buffer[bufIndex] |= (0x80 >>> (this.length % 8) );
}
this.length++;
}
};
export default QRBitBuffer;
Copyright (c) 2009 Kazuhiko Arase <kazuhiko.arase@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import math from './math.js'
function QRPolynomial(num, shift) {
if (num.length == undefined) {
throw new Error(num.length + "/" + shift);
}
var offset = 0;
while (offset < num.length && num[offset] == 0) {
offset++;
}
this.num = new Array(num.length - offset + shift);
for (var i = 0; i < num.length - offset; i++) {
this.num[i] = num[i + offset];
}
}
QRPolynomial.prototype = {
get : function(index) {
return this.num[index];
},
getLength : function() {
return this.num.length;
},
multiply : function(e) {
var num = new Array(this.getLength() + e.getLength() - 1);
for (var i = 0; i < this.getLength(); i++) {
for (var j = 0; j < e.getLength(); j++) {
num[i + j] ^= math.gexp(math.glog(this.get(i) ) + math.glog(e.get(j) ) );
}
}
return new QRPolynomial(num, 0);
},
mod : function(e) {
if (this.getLength() - e.getLength() < 0) {
return this;
}
var ratio = math.glog(this.get(0) ) - math.glog(e.get(0) );
var num = new Array(this.getLength() );
for (var i = 0; i < this.getLength(); i++) {
num[i] = this.get(i);
}
for (var i = 0; i < e.getLength(); i++) {
num[i] ^= math.gexp(math.glog(e.get(i) ) + ratio);
}
// recursive call
return new QRPolynomial(num, 0).mod(e);
}
};
export default QRPolynomial;
import BitByte from './8BitByte.js'
import RSBlock from './RSBlock.js'
import BitBuffer from './BitBuffer.js'
import util from './util.js'
import Polynomial from './Polynomial.js'
function QRCode(typeNumber, errorCorrectLevel) {
this.typeNumber = typeNumber;
this.errorCorrectLevel = errorCorrectLevel;
this.modules = null;
this.moduleCount = 0;
this.dataCache = null;
this.dataList = [];
}
// for client side minification
var proto = QRCode.prototype;
proto.addData = function(data) {
var newData = new BitByte(data);
this.dataList.push(newData);
this.dataCache = null;
};
proto.isDark = function(row, col) {
if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) {
throw new Error(row + "," + col);
}
return this.modules[row][col];
};
proto.getModuleCount = function() {
return this.moduleCount;
};
proto.make = function() {
// Calculate automatically typeNumber if provided is < 1
if (this.typeNumber < 1 ){
var typeNumber = 1;
for (typeNumber = 1; typeNumber < 40; typeNumber++) {
var rsBlocks = RSBlock.getRSBlocks(typeNumber, this.errorCorrectLevel);
var buffer = new BitBuffer();
var totalDataCount = 0;
for (var i = 0; i < rsBlocks.length; i++) {
totalDataCount += rsBlocks[i].dataCount;
}
for (var i = 0; i < this.dataList.length; i++) {
var data = this.dataList[i];
buffer.put(data.mode, 4);
buffer.put(data.getLength(), util.getLengthInBits(data.mode, typeNumber) );
data.write(buffer);
}
if (buffer.getLengthInBits() <= totalDataCount * 8)
break;
}
this.typeNumber = typeNumber;
}
this.makeImpl(false, this.getBestMaskPattern() );
};
proto.makeImpl = function(test, maskPattern) {
this.moduleCount = this.typeNumber * 4 + 17;
this.modules = new Array(this.moduleCount);
for (var row = 0; row < this.moduleCount; row++) {
this.modules[row] = new Array(this.moduleCount);
for (var col = 0; col < this.moduleCount; col++) {
this.modules[row][col] = null;//(col + row) % 3;
}
}
this.setupPositionProbePattern(0, 0);
this.setupPositionProbePattern(this.moduleCount - 7, 0);
this.setupPositionProbePattern(0, this.moduleCount - 7);
this.setupPositionAdjustPattern();
this.setupTimingPattern();
this.setupTypeInfo(test, maskPattern);
if (this.typeNumber >= 7) {
this.setupTypeNumber(test);
}
if (this.dataCache == null) {
this.dataCache = QRCode.createData(this.typeNumber, this.errorCorrectLevel, this.dataList);
}
this.mapData(this.dataCache, maskPattern);
};
proto.setupPositionProbePattern = function(row, col) {
for (var r = -1; r <= 7; r++) {
if (row + r <= -1 || this.moduleCount <= row + r) continue;
for (var c = -1; c <= 7; c++) {
if (col + c <= -1 || this.moduleCount <= col + c) continue;
if ( (0 <= r && r <= 6 && (c == 0 || c == 6) )
|| (0 <= c && c <= 6 && (r == 0 || r == 6) )
|| (2 <= r && r <= 4 && 2 <= c && c <= 4) ) {
this.modules[row + r][col + c] = true;
} else {
this.modules[row + r][col + c] = false;
}
}
}
};
proto.getBestMaskPattern = function() {
var minLostPoint = 0;
var pattern = 0;
for (var i = 0; i < 8; i++) {
this.makeImpl(true, i);
var lostPoint = util.getLostPoint(this);
if (i == 0 || minLostPoint > lostPoint) {
minLostPoint = lostPoint;
pattern = i;
}
}
return pattern;
};
proto.createMovieClip = function(target_mc, instance_name, depth) {
var qr_mc = target_mc.createEmptyMovieClip(instance_name, depth);
var cs = 1;
this.make();
for (var row = 0; row < this.modules.length; row++) {
var y = row * cs;
for (var col = 0; col < this.modules[row].length; col++) {
var x = col * cs;
var dark = this.modules[row][col];
if (dark) {
qr_mc.beginFill(0, 100);
qr_mc.moveTo(x, y);
qr_mc.lineTo(x + cs, y);
qr_mc.lineTo(x + cs, y + cs);
qr_mc.lineTo(x, y + cs);
qr_mc.endFill();
}
}
}
return qr_mc;
};
proto.setupTimingPattern = function() {
for (var r = 8; r < this.moduleCount - 8; r++) {
if (this.modules[r][6] != null) {
continue;
}
this.modules[r][6] = (r % 2 == 0);
}
for (var c = 8; c < this.moduleCount - 8; c++) {
if (this.modules[6][c] != null) {
continue;
}
this.modules[6][c] = (c % 2 == 0);
}
};
proto.setupPositionAdjustPattern = function() {
var pos = util.getPatternPosition(this.typeNumber);
for (var i = 0; i < pos.length; i++) {
for (var j = 0; j < pos.length; j++) {
var row = pos[i];
var col = pos[j];
if (this.modules[row][col] != null) {
continue;
}
for (var r = -2; r <= 2; r++) {
for (var c = -2; c <= 2; c++) {
if (r == -2 || r == 2 || c == -2 || c == 2
|| (r == 0 && c == 0) ) {
this.modules[row + r][col + c] = true;
} else {
this.modules[row + r][col + c] = false;
}
}
}
}
}
};
proto.setupTypeNumber = function(test) {
var bits = util.getBCHTypeNumber(this.typeNumber);
for (var i = 0; i < 18; i++) {
var mod = (!test && ( (bits >> i) & 1) == 1);
this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod;
}
for (var i = 0; i < 18; i++) {
var mod = (!test && ( (bits >> i) & 1) == 1);
this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod;
}
};
proto.setupTypeInfo = function(test, maskPattern) {
var data = (this.errorCorrectLevel << 3) | maskPattern;
var bits = util.getBCHTypeInfo(data);
// vertical
for (var i = 0; i < 15; i++) {
var mod = (!test && ( (bits >> i) & 1) == 1);
if (i < 6) {
this.modules[i][8] = mod;
} else if (i < 8) {
this.modules[i + 1][8] = mod;
} else {
this.modules[this.moduleCount - 15 + i][8] = mod;
}
}
// horizontal
for (var i = 0; i < 15; i++) {
var mod = (!test && ( (bits >> i) & 1) == 1);
if (i < 8) {
this.modules[8][this.moduleCount - i - 1] = mod;
} else if (i < 9) {
this.modules[8][15 - i - 1 + 1] = mod;
} else {
this.modules[8][15 - i - 1] = mod;
}
}
// fixed module
this.modules[this.moduleCount - 8][8] = (!test);
};
proto.mapData = function(data, maskPattern) {
var inc = -1;
var row = this.moduleCount - 1;
var bitIndex = 7;
var byteIndex = 0;
for (var col = this.moduleCount - 1; col > 0; col -= 2) {
if (col == 6) col--;
while (true) {
for (var c = 0; c < 2; c++) {
if (this.modules[row][col - c] == null) {
var dark = false;
if (byteIndex < data.length) {
dark = ( ( (data[byteIndex] >>> bitIndex) & 1) == 1);
}
var mask = util.getMask(maskPattern, row, col - c);
if (mask) {
dark = !dark;
}
this.modules[row][col - c] = dark;
bitIndex--;
if (bitIndex == -1) {
byteIndex++;
bitIndex = 7;
}
}
}
row += inc;
if (row < 0 || this.moduleCount <= row) {
row -= inc;
inc = -inc;
break;
}
}
}
};
QRCode.PAD0 = 0xEC;
QRCode.PAD1 = 0x11;
QRCode.createData = function(typeNumber, errorCorrectLevel, dataList) {
var rsBlocks = RSBlock.getRSBlocks(typeNumber, errorCorrectLevel);
var buffer = new BitBuffer();
for (var i = 0; i < dataList.length; i++) {
var data = dataList[i];
buffer.put(data.mode, 4);
buffer.put(data.getLength(), util.getLengthInBits(data.mode, typeNumber) );
data.write(buffer);
}
// calc num max data.
var totalDataCount = 0;
for (var i = 0; i < rsBlocks.length; i++) {
totalDataCount += rsBlocks[i].dataCount;
}
if (buffer.getLengthInBits() > totalDataCount * 8) {
throw new Error("code length overflow. ("
+ buffer.getLengthInBits()
+ ">"
+ totalDataCount * 8
+ ")");
}
// end code
if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {
buffer.put(0, 4);
}
// padding
while (buffer.getLengthInBits() % 8 != 0) {
buffer.putBit(false);
}
// padding
while (true) {
if (buffer.getLengthInBits() >= totalDataCount * 8) {
break;
}
buffer.put(QRCode.PAD0, 8);
if (buffer.getLengthInBits() >= totalDataCount * 8) {
break;
}
buffer.put(QRCode.PAD1, 8);
}
return QRCode.createBytes(buffer, rsBlocks);
};
QRCode.createBytes = function(buffer, rsBlocks) {
var offset = 0;
var maxDcCount = 0;
var maxEcCount = 0;
var dcdata = new Array(rsBlocks.length);
var ecdata = new Array(rsBlocks.length);
for (var r = 0; r < rsBlocks.length; r++) {
var dcCount = rsBlocks[r].dataCount;
var ecCount = rsBlocks[r].totalCount - dcCount;
maxDcCount = Math.max(maxDcCount, dcCount);
maxEcCount = Math.max(maxEcCount, ecCount);
dcdata[r] = new Array(dcCount);
for (var i = 0; i < dcdata[r].length; i++) {
dcdata[r][i] = 0xff & buffer.buffer[i + offset];
}
offset += dcCount;
var rsPoly = util.getErrorCorrectPolynomial(ecCount);
var rawPoly = new Polynomial(dcdata[r], rsPoly.getLength() - 1);
var modPoly = rawPoly.mod(rsPoly);
ecdata[r] = new Array(rsPoly.getLength() - 1);
for (var i = 0; i < ecdata[r].length; i++) {
var modIndex = i + modPoly.getLength() - ecdata[r].length;
ecdata[r][i] = (modIndex >= 0)? modPoly.get(modIndex) : 0;
}
}
var totalCodeCount = 0;
for (var i = 0; i < rsBlocks.length; i++) {
totalCodeCount += rsBlocks[i].totalCount;
}
var data = new Array(totalCodeCount);
var index = 0;
for (var i = 0; i < maxDcCount; i++) {
for (var r = 0; r < rsBlocks.length; r++) {
if (i < dcdata[r].length) {
data[index++] = dcdata[r][i];
}
}
}
for (var i = 0; i < maxEcCount; i++) {
for (var r = 0; r < rsBlocks.length; r++) {
if (i < ecdata[r].length) {
data[index++] = ecdata[r][i];
}
}
}
return data;
};
export default QRCode;
// ErrorCorrectLevel
import ECL from './ErrorCorrectLevel.js'
function QRRSBlock(totalCount, dataCount) {
this.totalCount = totalCount;
this.dataCount = dataCount;
}
QRRSBlock.RS_BLOCK_TABLE = [
// L
// M
// Q
// H
// 1
[1, 26, 19],
[1, 26, 16],
[1, 26, 13],
[1, 26, 9],
// 2
[1, 44, 34],
[1, 44, 28],
[1, 44, 22],
[1, 44, 16],
// 3
[1, 70, 55],
[1, 70, 44],
[2, 35, 17],
[2, 35, 13],
// 4
[1, 100, 80],
[2, 50, 32],
[2, 50, 24],
[4, 25, 9],
// 5
[1, 134, 108],
[2, 67, 43],
[2, 33, 15, 2, 34, 16],
[2, 33, 11, 2, 34, 12],
// 6
[2, 86, 68],
[4, 43, 27],
[4, 43, 19],
[4, 43, 15],
// 7
[2, 98, 78],
[4, 49, 31],
[2, 32, 14, 4, 33, 15],
[4, 39, 13, 1, 40, 14],
// 8
[2, 121, 97],
[2, 60, 38, 2, 61, 39],
[4, 40, 18, 2, 41, 19],
[4, 40, 14, 2, 41, 15],
// 9
[2, 146, 116],
[3, 58, 36, 2, 59, 37],
[4, 36, 16, 4, 37, 17],
[4, 36, 12, 4, 37, 13],
// 10
[2, 86, 68, 2, 87, 69],
[4, 69, 43, 1, 70, 44],
[6, 43, 19, 2, 44, 20],
[6, 43, 15, 2, 44, 16],
// 11
[4, 101, 81],
[1, 80, 50, 4, 81, 51],
[4, 50, 22, 4, 51, 23],
[3, 36, 12, 8, 37, 13],
// 12
[2, 116, 92, 2, 117, 93],
[6, 58, 36, 2, 59, 37],
[4, 46, 20, 6, 47, 21],
[7, 42, 14, 4, 43, 15],
// 13
[4, 133, 107],
[8, 59, 37, 1, 60, 38],
[8, 44, 20, 4, 45, 21],
[12, 33, 11, 4, 34, 12],
// 14
[3, 145, 115, 1, 146, 116],
[4, 64, 40, 5, 65, 41],
[11, 36, 16, 5, 37, 17],
[11, 36, 12, 5, 37, 13],
// 15
[5, 109, 87, 1, 110, 88],
[5, 65, 41, 5, 66, 42],
[5, 54, 24, 7, 55, 25],
[11, 36, 12],
// 16
[5, 122, 98, 1, 123, 99],
[7, 73, 45, 3, 74, 46],
[15, 43, 19, 2, 44, 20],
[3, 45, 15, 13, 46, 16],
// 17
[1, 135, 107, 5, 136, 108],
[10, 74, 46, 1, 75, 47],
[1, 50, 22, 15, 51, 23],
[2, 42, 14, 17, 43, 15],
// 18
[5, 150, 120, 1, 151, 121],
[9, 69, 43, 4, 70, 44],
[17, 50, 22, 1, 51, 23],
[2, 42, 14, 19, 43, 15],
// 19
[3, 141, 113, 4, 142, 114],
[3, 70, 44, 11, 71, 45],
[17, 47, 21, 4, 48, 22],
[9, 39, 13, 16, 40, 14],
// 20
[3, 135, 107, 5, 136, 108],
[3, 67, 41, 13, 68, 42],
[15, 54, 24, 5, 55, 25],
[15, 43, 15, 10, 44, 16],
// 21
[4, 144, 116, 4, 145, 117],
[17, 68, 42],
[17, 50, 22, 6, 51, 23],
[19, 46, 16, 6, 47, 17],
// 22
[2, 139, 111, 7, 140, 112],
[17, 74, 46],
[7, 54, 24, 16, 55, 25],
[34, 37, 13],
// 23
[4, 151, 121, 5, 152, 122],
[4, 75, 47, 14, 76, 48],
[11, 54, 24, 14, 55, 25],
[16, 45, 15, 14, 46, 16],
// 24
[6, 147, 117, 4, 148, 118],
[6, 73, 45, 14, 74, 46],
[11, 54, 24, 16, 55, 25],
[30, 46, 16, 2, 47, 17],
// 25
[8, 132, 106, 4, 133, 107],
[8, 75, 47, 13, 76, 48],
[7, 54, 24, 22, 55, 25],
[22, 45, 15, 13, 46, 16],
// 26
[10, 142, 114, 2, 143, 115],
[19, 74, 46, 4, 75, 47],
[28, 50, 22, 6, 51, 23],
[33, 46, 16, 4, 47, 17],
// 27
[8, 152, 122, 4, 153, 123],
[22, 73, 45, 3, 74, 46],
[8, 53, 23, 26, 54, 24],
[12, 45, 15, 28, 46, 16],
// 28
[3, 147, 117, 10, 148, 118],
[3, 73, 45, 23, 74, 46],
[4, 54, 24, 31, 55, 25],
[11, 45, 15, 31, 46, 16],
// 29
[7, 146, 116, 7, 147, 117],
[21, 73, 45, 7, 74, 46],
[1, 53, 23, 37, 54, 24],
[19, 45, 15, 26, 46, 16],
// 30
[5, 145, 115, 10, 146, 116],
[19, 75, 47, 10, 76, 48],
[15, 54, 24, 25, 55, 25],
[23, 45, 15, 25, 46, 16],
// 31
[13, 145, 115, 3, 146, 116],
[2, 74, 46, 29, 75, 47],
[42, 54, 24, 1, 55, 25],
[23, 45, 15, 28, 46, 16],
// 32
[17, 145, 115],
[10, 74, 46, 23, 75, 47],
[10, 54, 24, 35, 55, 25],
[19, 45, 15, 35, 46, 16],
// 33
[17, 145, 115, 1, 146, 116],
[14, 74, 46, 21, 75, 47],
[29, 54, 24, 19, 55, 25],
[11, 45, 15, 46, 46, 16],
// 34
[13, 145, 115, 6, 146, 116],
[14, 74, 46, 23, 75, 47],
[44, 54, 24, 7, 55, 25],
[59, 46, 16, 1, 47, 17],
// 35
[12, 151, 121, 7, 152, 122],
[12, 75, 47, 26, 76, 48],
[39, 54, 24, 14, 55, 25],
[22, 45, 15, 41, 46, 16],
// 36
[6, 151, 121, 14, 152, 122],
[6, 75, 47, 34, 76, 48],
[46, 54, 24, 10, 55, 25],
[2, 45, 15, 64, 46, 16],
// 37
[17, 152, 122, 4, 153, 123],
[29, 74, 46, 14, 75, 47],
[49, 54, 24, 10, 55, 25],
[24, 45, 15, 46, 46, 16],
// 38
[4, 152, 122, 18, 153, 123],
[13, 74, 46, 32, 75, 47],
[48, 54, 24, 14, 55, 25],
[42, 45, 15, 32, 46, 16],
// 39
[20, 147, 117, 4, 148, 118],
[40, 75, 47, 7, 76, 48],
[43, 54, 24, 22, 55, 25],
[10, 45, 15, 67, 46, 16],
// 40
[19, 148, 118, 6, 149, 119],
[18, 75, 47, 31, 76, 48],
[34, 54, 24, 34, 55, 25],
[20, 45, 15, 61, 46, 16]
];
QRRSBlock.getRSBlocks = function(typeNumber, errorCorrectLevel) {
var rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel);
if (rsBlock == undefined) {
throw new Error("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + errorCorrectLevel);
}
var length = rsBlock.length / 3;
var list = new Array();
for (var i = 0; i < length; i++) {
var count = rsBlock[i * 3 + 0];
var totalCount = rsBlock[i * 3 + 1];
var dataCount = rsBlock[i * 3 + 2];
for (var j = 0; j < count; j++) {
list.push(new QRRSBlock(totalCount, dataCount) );
}
}
return list;
}
QRRSBlock.getRsBlockTable = function(typeNumber, errorCorrectLevel) {
switch(errorCorrectLevel) {
case ECL.L :
return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];
case ECL.M :
return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];
case ECL.Q :
return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];
case ECL.H :
return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];
default :
return undefined;
}
}
export default QRRSBlock;
var QRMath = {
glog : function(n) {
if (n < 1) {
throw new Error("glog(" + n + ")");
}
return QRMath.LOG_TABLE[n];
},
gexp : function(n) {
while (n < 0) {
n += 255;
}
while (n >= 256) {
n -= 255;
}
return QRMath.EXP_TABLE[n];
},
EXP_TABLE : new Array(256),
LOG_TABLE : new Array(256)
};
for (var i = 0; i < 8; i++) {
QRMath.EXP_TABLE[i] = 1 << i;
}
for (var i = 8; i < 256; i++) {
QRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4]
^ QRMath.EXP_TABLE[i - 5]
^ QRMath.EXP_TABLE[i - 6]
^ QRMath.EXP_TABLE[i - 8];
}
for (var i = 0; i < 255; i++) {
QRMath.LOG_TABLE[QRMath.EXP_TABLE[i] ] = i;
}
export default QRMath;
export default {
MODE_NUMBER : 1 << 0,
MODE_ALPHA_NUM : 1 << 1,
MODE_8BIT_BYTE : 1 << 2,
MODE_KANJI : 1 << 3
};
import Mode from './mode.js'
import Polynomial from './Polynomial.js'
import math from './math.js'
var QRMaskPattern = {
PATTERN000 : 0,
PATTERN001 : 1,
PATTERN010 : 2,
PATTERN011 : 3,
PATTERN100 : 4,
PATTERN101 : 5,
PATTERN110 : 6,
PATTERN111 : 7
};
var QRUtil = {
PATTERN_POSITION_TABLE : [
[],
[6, 18],
[6, 22],
[6, 26],
[6, 30],
[6, 34],
[6, 22, 38],
[6, 24, 42],
[6, 26, 46],
[6, 28, 50],
[6, 30, 54],
[6, 32, 58],
[6, 34, 62],
[6, 26, 46, 66],
[6, 26, 48, 70],
[6, 26, 50, 74],
[6, 30, 54, 78],
[6, 30, 56, 82],
[6, 30, 58, 86],
[6, 34, 62, 90],
[6, 28, 50, 72, 94],
[6, 26, 50, 74, 98],
[6, 30, 54, 78, 102],
[6, 28, 54, 80, 106],
[6, 32, 58, 84, 110],
[6, 30, 58, 86, 114],
[6, 34, 62, 90, 118],
[6, 26, 50, 74, 98, 122],
[6, 30, 54, 78, 102, 126],
[6, 26, 52, 78, 104, 130],
[6, 30, 56, 82, 108, 134],
[6, 34, 60, 86, 112, 138],
[6, 30, 58, 86, 114, 142],
[6, 34, 62, 90, 118, 146],
[6, 30, 54, 78, 102, 126, 150],
[6, 24, 50, 76, 102, 128, 154],
[6, 28, 54, 80, 106, 132, 158],
[6, 32, 58, 84, 110, 136, 162],
[6, 26, 54, 82, 110, 138, 166],
[6, 30, 58, 86, 114, 142, 170]
],
G15 : (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0),
G18 : (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0),
G15_MASK : (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1),
getBCHTypeInfo : function(data) {
var d = data << 10;
while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {
d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) ) );
}
return ( (data << 10) | d) ^ QRUtil.G15_MASK;
},
getBCHTypeNumber : function(data) {
var d = data << 12;
while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {
d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) ) );
}
return (data << 12) | d;
},
getBCHDigit : function(data) {
var digit = 0;
while (data != 0) {
digit++;
data >>>= 1;
}
return digit;
},
getPatternPosition : function(typeNumber) {
return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1];
},
getMask : function(maskPattern, i, j) {
switch (maskPattern) {
case QRMaskPattern.PATTERN000 : return (i + j) % 2 == 0;
case QRMaskPattern.PATTERN001 : return i % 2 == 0;
case QRMaskPattern.PATTERN010 : return j % 3 == 0;
case QRMaskPattern.PATTERN011 : return (i + j) % 3 == 0;
case QRMaskPattern.PATTERN100 : return (Math.floor(i / 2) + Math.floor(j / 3) ) % 2 == 0;
case QRMaskPattern.PATTERN101 : return (i * j) % 2 + (i * j) % 3 == 0;
case QRMaskPattern.PATTERN110 : return ( (i * j) % 2 + (i * j) % 3) % 2 == 0;
case QRMaskPattern.PATTERN111 : return ( (i * j) % 3 + (i + j) % 2) % 2 == 0;
default :
throw new Error("bad maskPattern:" + maskPattern);
}
},
getErrorCorrectPolynomial : function(errorCorrectLength) {
var a = new Polynomial([1], 0);
for (var i = 0; i < errorCorrectLength; i++) {
a = a.multiply(new Polynomial([1, math.gexp(i)], 0) );
}
return a;
},
getLengthInBits : function(mode, type) {
if (1 <= type && type < 10) {
// 1 - 9
switch(mode) {
case Mode.MODE_NUMBER : return 10;
case Mode.MODE_ALPHA_NUM : return 9;
case Mode.MODE_8BIT_BYTE : return 8;
case Mode.MODE_KANJI : return 8;
default :
throw new Error("mode:" + mode);
}
} else if (type < 27) {
// 10 - 26
switch(mode) {
case Mode.MODE_NUMBER : return 12;
case Mode.MODE_ALPHA_NUM : return 11;
case Mode.MODE_8BIT_BYTE : return 16;
case Mode.MODE_KANJI : return 10;
default :
throw new Error("mode:" + mode);
}
} else if (type < 41) {
// 27 - 40
switch(mode) {
case Mode.MODE_NUMBER : return 14;
case Mode.MODE_ALPHA_NUM : return 13;
case Mode.MODE_8BIT_BYTE : return 16;
case Mode.MODE_KANJI : return 12;
default :
throw new Error("mode:" + mode);
}
} else {
throw new Error("type:" + type);
}
},
getLostPoint : function(qrCode) {
var moduleCount = qrCode.getModuleCount();
var lostPoint = 0;
// LEVEL1
for (var row = 0; row < moduleCount; row++) {
for (var col = 0; col < moduleCount; col++) {
var sameCount = 0;
var dark = qrCode.isDark(row, col);
for (var r = -1; r <= 1; r++) {
if (row + r < 0 || moduleCount <= row + r) {
continue;
}
for (var c = -1; c <= 1; c++) {
if (col + c < 0 || moduleCount <= col + c) {
continue;
}
if (r == 0 && c == 0) {
continue;
}
if (dark == qrCode.isDark(row + r, col + c) ) {
sameCount++;
}
}
}
if (sameCount > 5) {
lostPoint += (3 + sameCount - 5);
}
}
}
// LEVEL2
for (var row = 0; row < moduleCount - 1; row++) {
for (var col = 0; col < moduleCount - 1; col++) {
var count = 0;
if (qrCode.isDark(row, col ) ) count++;
if (qrCode.isDark(row + 1, col ) ) count++;
if (qrCode.isDark(row, col + 1) ) count++;
if (qrCode.isDark(row + 1, col + 1) ) count++;
if (count == 0 || count == 4) {
lostPoint += 3;
}
}
}
// LEVEL3
for (var row = 0; row < moduleCount; row++) {
for (var col = 0; col < moduleCount - 6; col++) {
if (qrCode.isDark(row, col)
&& !qrCode.isDark(row, col + 1)
&& qrCode.isDark(row, col + 2)
&& qrCode.isDark(row, col + 3)
&& qrCode.isDark(row, col + 4)
&& !qrCode.isDark(row, col + 5)
&& qrCode.isDark(row, col + 6) ) {
lostPoint += 40;
}
}
}
for (var col = 0; col < moduleCount; col++) {
for (var row = 0; row < moduleCount - 6; row++) {
if (qrCode.isDark(row, col)
&& !qrCode.isDark(row + 1, col)
&& qrCode.isDark(row + 2, col)
&& qrCode.isDark(row + 3, col)
&& qrCode.isDark(row + 4, col)
&& !qrCode.isDark(row + 5, col)
&& qrCode.isDark(row + 6, col) ) {
lostPoint += 40;
}
}
}
// LEVEL4
var darkCount = 0;
for (var col = 0; col < moduleCount; col++) {
for (var row = 0; row < moduleCount; row++) {
if (qrCode.isDark(row, col) ) {
darkCount++;
}
}
}
var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;
lostPoint += ratio * 10;
return lostPoint;
}
};
export default QRUtil;
/*!
* 生成海报
* poster - v1.8.0 (2023/02/02, 16:52:14 PM)
* updated V2.2.0+ 2023/11/07
*
*
* 官网地址:https://firstui.cn/
* 文档地址:https://doc.firstui.cn/
*/
import fuiQr from './fui-qr/index.js'
const poster = {
_pixelRatio: 2,
_ctx: null,
......@@ -320,6 +322,38 @@ const poster = {
context.closePath();
context.restore();
},
_drawQrcode(context, params) {
let {
x,
y,
width,
height,
value,
foreground = "#181818",
background = "#ffffff"
} = params;
x = poster._toPx(x)
y = poster._toPx(y)
width = poster._toPx(width)
height = poster._toPx(height)
const qrcode = fuiQr(poster.utf16to8(value), {
typeNumber: -1,
errorCorrectLevel: 2,
})
const cells = qrcode.modules
const tileW = width / cells.length
const tileH = height / cells.length
cells.forEach((row, rdx) => {
row.forEach((cell, cdx) => {
context.setFillStyle(cell ? foreground : background)
const w = (Math.ceil((cdx + 1) * tileW) - Math.floor(cdx * tileW))
const h = (Math.ceil((rdx + 1) * tileH) - Math.floor(rdx * tileH))
context.fillRect(Math.round(cdx * tileW) + x, Math.round(rdx * tileH) + y, w, h)
})
})
context.restore();
},
//ios用户拒绝相册访问 ,引导用户到设置页面,开启相册访问权限
//-1=未请求 1 = 已允许,0 = 拒绝|受限
_judgeIosPermissionPhotoLibrary() {
......@@ -559,6 +593,8 @@ const poster = {
poster._drawBlock(context, params)
} else if (params.type === 'line') {
poster._drawLine(context, params)
} else if (params.type === 'qrcode') {
poster._drawQrcode(context, params)
}
});
const platform = uni.getSystemInfoSync().platform;
......@@ -631,6 +667,27 @@ const poster = {
urls: [file]
});
// #endif
},
utf16to8(str) {
const len = str.length
let out = ''
for (let i = 0; i < len; i++) {
const c = str.charCodeAt(i)
if ((c >= 0x0001) && (c <= 0x007F)) {
out += str.charAt(i)
} else if (c > 0x07FF) {
out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F))
out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F))
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F))
} else {
out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F))
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F))
}
}
return out
}
}
......
......@@ -36,11 +36,11 @@
<view class="fui-preview__ft" :style="{'border-top-color':borderColor}"
v-if="pvd[buttons] && pvd[buttons].length>0">
<view :style="{'border-right-color':idx!==pvd[buttons].length-1?borderColor : 'transparent'}"
:class="[highlight?'fui-preview__hover-weex':'',idx!==pvd[buttons].length-1?'fui-preview__btn-def':'fui-preview__btn']"
:hover-class="highlight?'fui-preview_hover':''" :hover-stay-time="150" v-for="(btn,idx) in pvd[buttons]"
:key="idx" @tap="handleClick(idx)">
:class="[highlight && !btn[disabled]?'fui-preview__hover-weex':'',idx!==pvd[buttons].length-1?'fui-preview__btn-def':'fui-preview__btn']"
:hover-class="highlight && !btn[disabled]?'fui-preview_hover':''" :hover-stay-time="150"
v-for="(btn,idx) in pvd[buttons]" :key="idx" @tap="handleClick(idx)">
<text :style="{fontSize:btnSize+'rpx',color:btn[color] || '#465CFF'}"
:class="{'fui-preview__link':!btn[color]}">{{btn[text]}}</text>
:class="{'fui-preview__link':!btn[color],'fui-preview__button-disable':btn[disabled]}">{{btn[text]}}</text>
</view>
</view>
</view>
......@@ -217,7 +217,8 @@
valueColor: 'valueColor',
buttons: 'buttons',
text: 'text',
color: 'color'
color: 'color',
disabled: 'disabled'
};
},
methods: {
......@@ -231,6 +232,7 @@
this.buttons = this.fields.buttons || 'buttons';
this.text = this.fields.text || 'text';
this.color = this.fields.color || 'color';
this.disabled = this.fields.disabled || 'disabled';
}
},
initData(val) {
......@@ -242,6 +244,7 @@
},
handleClick(idx) {
let params = this.pvd[this.buttons][idx] || {}
if (params.disabled) return;
this.$emit('click', {
index: idx,
...params
......@@ -546,6 +549,12 @@
.fui-preview__hover-weex:active {
background-color: rgba(0, 0, 0, 0.2) !important;
}
/* #endif */
.fui-preview__button-disable {
opacity: .5;
/* #ifdef H5 */
cursor: not-allowed;
/* #endif */
}
</style>
......@@ -46,10 +46,10 @@ const base = {
let options = {
...config
};
['host', 'timeout', 'prevent', 'keys', 'brief', 'cancelToken', 'showLoading', 'loadingText', 'errorMsg',
'arrayFormat'
]
.forEach(item => {
const keys = ['host', 'timeout', 'prevent', 'keys', 'brief', 'cancelToken', 'showLoading', 'loadingText',
'errorMsg', 'arrayFormat'
];
keys.forEach(item => {
delete options[item];
})
return options;
......
......@@ -23,9 +23,11 @@ function bool(str) {
function touchstart(e, ins) {
var state = e.instance.getState()
var touch = e.touches[0] || e.changedTouches[0]
var touch = {}
if (isH5 && isPC()) {
touch = e;
} else {
touch = e.touches[0] || e.changedTouches[0]
}
var dataset = e.instance.getDataset()
state.startX = touch.pageX
......
......@@ -18,7 +18,7 @@ export default {
},
methods: {
styleChange(left, deg) {
if (left == 0 && deg == 0) {
if (left == 0 && deg == 0) {// 功能需要优化
this.resetAni = true
} else {
this.resetAni = false
......@@ -48,14 +48,14 @@ export default {
let left = this.sliderWidth - this.sliderHeight;
let deg = 360 / left * this.lastLeft
this.verify({
angle: deg
angle: deg// 2021-5-6变更
})
}
}// todo: 待修改
}
}
}// 新特性待增加
// #endif
// #ifdef APP-PLUS|| MP-WEIXIN || H5
export default {}
export default {}// 2021-5-6变更
// #endif
......@@ -13,7 +13,7 @@
</view>
<input ref="searchBarRef" class="fui-search__bar-input" :class="{'fui-sb__input-color':!color}"
:style="{color:color,height: height+'rpx'}" placeholder-class="fui-search__bar-pl"
:placeholder="placeholder" :value="val" :focus="isFocus" :disabled="disabled" confirm-type="search"
:placeholder="plholder" :value="val" :focus="isFocus" :disabled="disabled" confirm-type="search"
@blur="inputBlur" @focus="inputFocus" @input="inputChange" @confirm="search" />
<view class="fui-sbi__clear-wrap" v-if="val.length > 0 && !disabled" @tap.stop="clearInput">
<view class="fui-sbi__clear">
......@@ -137,10 +137,25 @@
showLabel: {
type: Boolean,
default: true
},
//v2.1.0
fixed: {
type: Boolean,
default: false
}
},
created() {
this.val = this.value;
// #ifndef MP-WEIXIN
this.plholder = this.placeholder;
// #endif
// #ifdef MP-WEIXIN
if(!this.showLabel || !this.fixed || this.focus || this.val.length > 0){
this.plholder = this.placeholder;
}
// #endif
if (this.focus || this.val.length > 0) {
this.isSearch = true;
}
......@@ -177,6 +192,17 @@
if (this.focus || this.val.length > 0) {
this.isSearch = true;
}
},
placeholder(val) {
// #ifndef MP-WEIXIN
this.plholder = this.placeholder;
// #endif
// #ifdef MP-WEIXIN
if(!this.showLabel || !this.fixed){
this.plholder = this.placeholder;
}
// #endif
}
},
computed: {
......@@ -195,8 +221,8 @@
return {
isSearch: false,
isFocus: false,
val: ''
val: '',
plholder: ''
};
},
methods: {
......@@ -224,6 +250,11 @@
inputBlur(e) {
this.isFocus = false;
if (!this.cancel && !this.val) {
// #ifdef MP-WEIXIN
if(this.fixed && this.showLabel){
this.plholder = '';
}
// #endif
this.isSearch = false;
}
this.$emit('blur', e);
......@@ -231,6 +262,11 @@
onShowInput() {
if (!this.disabled && this.showInput) {
this.isSearch = true;
// #ifdef MP-WEIXIN
if(this.fixed && this.showLabel){
this.plholder = this.placeholder;
}
// #endif
this.$nextTick(() => {
setTimeout(() => {
this.isFocus = true;
......@@ -240,6 +276,11 @@
this.$emit('click', {});
},
hideInput() {
// #ifdef MP-WEIXIN
if(this.fixed && this.showLabel){
this.plholder = '';
}
// #endif
this.isSearch = false;
this.isFocus = false;
uni.hideKeyboard()
......
......@@ -420,7 +420,7 @@
let items = []
this.itemList.forEach((item, idx) => {
if (item.checked) {
items.push(this.options[idx])
items.push(item)
}
})
this.$emit('confirm', {
......
......@@ -579,6 +579,9 @@
/* #ifdef APP-NVUE || MP-TOUTIAO */
.fui-ss__safe-weex {
/* #ifdef APP-NVUE */
height: 164rpx;
/* #endif */
padding-bottom: 34px;
}
......
......@@ -239,17 +239,11 @@
this.getVals(val, true)
},
mounted() {
// #ifndef MP-TOUTIAO
setTimeout(() => {
this.initFocus(this.isFocus)
}, 200)
// #endif
// #ifdef MP-TOUTIAO
setTimeout(() => {
this.initFocus(this.isFocus)
}, 300)
// #endif
this.$nextTick(()=>{
setTimeout(() => {
this.initFocus(this.isFocus)
}, 300)
})
},
//nvue暂不支持vue3,所以不需要做兼容,此处以防后续兼容
// #ifdef APP-NVUE
......@@ -499,7 +493,7 @@
margin: 0;
padding: 0;
opacity: 0;
/* #ifdef MP-ALIPAY || MP-BAIDU || MP-TOUTIAO */
/* #ifdef MP-BAIDU || MP-TOUTIAO */
font-size: 0;
/* #endif */
......
......@@ -2,7 +2,7 @@
<view class="fui-skeleton__wrap" :style="{background:background,height:height+'px'}" ref="fui_skeleton">
<view class="fui-skeleton__item"
:class="{'fui-skeleton__dark':theme==='dark','fui-skeleton__dark-ani':active && theme==='dark','fui-skeleton__light-ani':active && theme!=='dark'}"
:style="{width: item.width+'px', height:item.height+'px', left: item.left+'px', top: item.top+'px',borderRadius:item.type==='round'?(isNvue?item.width/2+'px':'50%'):'6rpx'}"
:style="{width: item.width+'px', height:item.height+'px', left: item.left+'px', top: (item.top-top)+'px',borderRadius:item.type==='round'?(isNvue?item.width/2+'px':'50%'):'6rpx'}"
v-for="(item,index) in elList" :key="index">
</view>
</view>
......@@ -50,6 +50,16 @@
theme: {
type: String,
default: 'light'
},
//v2.1.0+ 组件初始化完成后是否立即显示骨架【仅在页面使用及component为false时有效】
immediate: {
type: Boolean,
default: true
},
//v2.1.0+ 是否在自定义组件内使用,需要调用方法显示骨架
component: {
type: Boolean,
default: false
}
},
data() {
......@@ -62,7 +72,8 @@
stop: false,
//round、rect
elList: [],
height: 0
height: 0,
top: 0
};
},
created() {
......@@ -73,25 +84,12 @@
}
},
mounted() {
// #ifndef APP-NVUE
this.$nextTick(() => {
this.nodesRef(this.outerClass).then((res) => {
if (res && res[0]) {
this.height = res[0].height
}
});
if (!this.preloadList || this.preloadList.length === 0) {
this.selectorQuery()
if (this.immediate && !this.component) {
//页面使用无需传
this.shown()
}
})
// #endif
// #ifdef APP-NVUE
this.$nextTick(() => {
setTimeout(() => {
this._animation(false)
}, 50)
})
// #endif
},
// #ifdef APP-NVUE
// #ifndef VUE3
......@@ -106,6 +104,24 @@
// #endif
// #endif
methods: {
shown(instance) {
// #ifndef APP-NVUE
this.nodesRef(this.outerClass, instance).then((res) => {
if (res && res[0]) {
this.height = res[0].height
this.top = this.component ? res[0].top : 0
}
});
if (!this.preloadList || this.preloadList.length === 0) {
this.selectorQuery(instance)
}
// #endif
// #ifdef APP-NVUE
setTimeout(() => {
this._animation(false)
}, 50)
// #endif
},
// #ifdef APP-NVUE
_animation(type) {
if (!this.$refs['fui_skeleton'] || this.stop || !this.active) return;
......@@ -127,11 +143,11 @@
// #endif
// #ifndef APP-NVUE
//nvue端暂不支持动态获取节点信息
async selectorQuery() {
async selectorQuery(instance) {
let selector = this.selector || []
let nodes = []
for (let item of selector) {
await this.nodesRef(item).then((res) => {
await this.nodesRef(item, instance).then((res) => {
res.map(d => {
d.type = item.indexOf('round') === -1 ? 'rect' : 'round';
})
......@@ -143,17 +159,32 @@
nodes: nodes
})
},
async nodesRef(name) {
async nodesRef(name, instance) {
return await new Promise((resolve, reject) => {
uni.createSelectorQuery()
.selectAll(`.${name}`)
.boundingClientRect((res) => {
if (res) {
resolve(res);
} else {
reject(res)
}
}).exec();
if (this.component) {
uni.createSelectorQuery()
// #ifndef MP-ALIPAY
.in(instance)
// #endif
.selectAll(`.${name}`)
.boundingClientRect((res) => {
if (res) {
resolve(res);
} else {
reject(res)
}
}).exec();
} else {
uni.createSelectorQuery()
.selectAll(`.${name}`)
.boundingClientRect((res) => {
if (res) {
resolve(res);
} else {
reject(res)
}
}).exec();
}
})
}
// #endif
......
......@@ -25,9 +25,11 @@ function bool(str) {
function touchstart(e, ins) {
var state = e.instance.getState()
var touch = e.touches[0] || e.changedTouches[0]
var touch = {}
if (isH5 && isPC()) {
touch = e;
} else {
touch = e.touches[0] || e.changedTouches[0]
}
var dataset = e.instance.getDataset()
state.startX = touch.pageX
......
......@@ -8,10 +8,10 @@
:class="[direction==='row'?'fui-steps__flex-row':'fui-steps__flex-col',direction==='row'?'':'fui-steps__node-weex']"
:style="getStyles">
<view class="fui-steps__line"
:class="['fui-steps__line-'+direction+(lineBold?'_bold':''),index<=current && index!==0 && !getActiveColor?'fui-steps__background':'']"
:style="{background:index===0?'transparent':(index<=current?getActiveColor:nodeColor)}"
:class="['fui-steps__line-'+direction+(lineBold?'_bold':''),index<=current && index!==0 && !getColor(index,current,true)?'fui-steps__background':'']"
:style="{background:index===0?'transparent':(index<=current?getColor(index,current,true):nodeColor)}"
v-if="direction==='row'"></view>
<view class="fui-steps__node">
<view class="fui-steps__node" :class="{'fui-steps__node-size':direction!='row' || (direction==='row' && !lineThrough)}">
<text class="fui-steps__node-text"
:class="{'fui-steps__background':index<=current && !getActiveColor,'fui-steps__border':index<=current && !getActiveColor}"
v-if="item.text && !(isMark && index==current)"
......@@ -36,13 +36,13 @@
:style="{borderRadius:radius || 0}"></image>
</view>
<view class="fui-steps__line"
:class="['fui-steps__line-'+direction+(lineBold?'_bold':''),index!==items.length-1 && !getActiveColor && (index<current || (index==current && isWait && direction==='row' && !processColor))?'fui-steps__background':'']"
:style="{background:index===items.length-1?'transparent':((index<current) || (index==current && isWait && direction==='row')?getColor(index,current):nodeColor)}">
:class="['fui-steps__line-'+direction+(lineBold?'_bold':''),index!==items.length-1 && !getColor(index,current,true,true) && (index<current || (index==current && isWait && direction==='row' && !processColor))?'fui-steps__background':'']"
:style="{background:index===items.length-1?'transparent':((index<current) || (index==current && isWait && direction==='row')?getColor(index,current,true,true):nodeColor)}">
</view>
</view>
<view class="fui-steps__content"
:class="[direction==='row'?'fui-steps__content-row':'fui-steps__content-col']"
:style="{paddingBottom:index===items.length-1 || direction==='row'? '0rpx':'64rpx',paddingLeft:direction==='row'?'20rpx':(isNvue?`${height+24}rpx`:'24rpx')}">
:style="{paddingBottom:index===items.length-1 || direction==='row'? '0rpx':(itemGap+'rpx'),paddingLeft:direction==='row'?'20rpx':(isNvue?`${height+24}rpx`:'24rpx')}">
<text class="fui-steps__title"
:class="{'fui-steps__text-row':direction==='row','fui-steps__color':(index<current && !getActiveColor) || (index===current && !processColor && !getActiveColor)}"
v-if="item.title"
......@@ -118,7 +118,7 @@
type: String,
default: ''
},
//V1.9.8+ 设置当前步骤的状态 wait / error / success
//V1.9.8+ 设置当前步骤的状态 wait / fail / success
processStatus: {
type: String,
default: ''
......@@ -145,6 +145,16 @@
lineBold: {
type: Boolean,
default: false
},
//V2.1.0+ item项之间间隔,仅纵向有效
itemGap: {
type: [Number, String],
default: 64
},
//V2.1.0+ 当默认节点为小圆点时线条是否贯穿,仅横向有效
lineThrough: {
type: Boolean,
default: false
}
},
computed: {
......@@ -176,9 +186,9 @@
}
},
methods: {
getColor(index, current) {
getColor(index, current, isLine, isRight) {
let color = this.getActiveColor
if (index === current) {
if (index === current || (index === current - 1 && !this.isWait && isLine && isRight)) {
color = this.processColor || color
}
return color;
......@@ -310,6 +320,11 @@
justify-content: center;
}
.fui-steps__node-size {
width: 44rpx;
height: 44rpx;
}
.fui-steps__node-text {
/* #ifndef APP-NVUE */
display: flex;
......
......@@ -29,7 +29,7 @@ export default {
}
},
mounted() {
this.$nextTick(()=>{
this.$nextTick(() => {
this.box = this.getEl(this.$refs['fui_swipea_wrap'])
this.selector = this.getEl(this.$refs['fui_swipea_content']);
this.rightButton = this.getEl(this.$refs['fui_swipea_buttons']);
......@@ -90,7 +90,7 @@ export default {
});
},
touchend(e) {
if (this.isopen && !this.isclick) {
if (this.isopen && !this.isclick && this.clickClose) {
this.open(false)
}
},
......
......@@ -2,10 +2,11 @@
<!-- #ifdef APP-VUE || MP-WEIXIN || H5 -->
<view class="fui-swipe__action-wrap" :style="{marginTop:marginTop+'rpx',marginBottom:marginBottom+'rpx'}">
<view class="fui-swipe__action-inner" :show="isShow" :change:show="handler.showChange" :threshold="thresholdVal"
:change:threshold="handler.thresholdChange" :disabled="isDisabled" :change:disabled="handler.disabledChange"
@touchstart="handler.touchstart" @touchmove="handler.touchmove" @touchend="handler.touchend"
@mousedown="handler.mousedown" @mousemove="handler.mousemove" @mouseup="handler.mouseup"
@mouseleave="handler.mouseleave">
:change:threshold="handler.thresholdChange" :clickclose="clickClose"
:change:clickclose="handler.clickCloseChange" :disabled="isDisabled"
:change:disabled="handler.disabledChange" @touchstart="handler.touchstart" @touchmove="handler.touchmove"
@touchend="handler.touchend" @mousedown="handler.mousedown" @mousemove="handler.mousemove"
@mouseup="handler.mouseup" @mouseleave="handler.mouseleave">
<view class="fui-swipe__action-left">
<slot></slot>
</view>
......@@ -110,6 +111,11 @@
type: Boolean,
default: true
},
//v2.1.0+ 点击当前菜单是否立即关闭菜单
clickClose: {
type: Boolean,
default: true
},
//1.9.9+
marginTop: {
type: [Number, String],
......
......@@ -150,7 +150,7 @@ function moveDirection(left, ins, ownerInstance) {
var position = state.position
var open = state.open || 'none'
var rightWidth = state.rightWidth
if (state.deltaX === 0) {
if (state.deltaX === 0 && state.clickclose) {
openState('none', ins, ownerInstance)
return
}
......@@ -228,6 +228,15 @@ function thresholdChange(newVal, oldVal, ownerInstance, ins) {
st.threshold = newVal || 30
}
function clickCloseChange(newVal, oldVal, ownerInstance, ins) {
var st = ins.getState()
if (newVal || newVal === null || newVal === undefined) {
st.clickclose = true
} else {
st.clickclose = false
}
}
module.exports = {
touchstart: touchstart,
......@@ -239,5 +248,6 @@ module.exports = {
mouseleave: mouseleave,
disabledChange: disabledChange,
thresholdChange: thresholdChange,
showChange: showChange
showChange: showChange,
clickCloseChange:clickCloseChange
}
......@@ -103,7 +103,7 @@ export default {
const open = this.open || false
const leftWidth = this.leftWidth
const rightWidth = this.rightWidth
if (this.deltaX === 0) {
if (this.deltaX === 0 && this.clickClose) {
this.openState(false)
return
}
......
......@@ -9,7 +9,7 @@ export default {
},
watch: {
show(newVal) {
this.isShow = this.show
this.isShow = this.show ? 'right' : 'none'
},
disabled(val) {
this.isDisabled = this.disabled
......@@ -27,7 +27,7 @@ export default {
mounted() {
this.$nextTick(() => {
setTimeout(() => {
this.isShow = this.show
this.isShow = this.show ? 'right' : 'none'
this.isDisabled = this.disabled
this.thresholdVal = Number(this.threshold)
}, 10)
......@@ -39,8 +39,9 @@ export default {
this.group && this.group.closeAuto(this)
},
change(e) {
const isOpen = e.open === 'right'
this.$emit('change', {
isOpen: e.open === 'right',
isOpen: isOpen,
param: this.param
})
if (this.isShow !== e.open) {
......
......@@ -6,14 +6,19 @@
<view class="fui-tabbar__item" v-for="(item,index) in tabs" :key="index" @tap="itemClick(index)">
<view class="fui-tabbar__icon-wrap"
:style="{width:(isNvue && item.midButton && item.width?item.width:56)+'rpx',height:(isNvue && item.midButton && item.height?item.height:56)+'rpx'}"
v-if="item.iconPath">
v-if="item.iconPath || item.iconName">
<image class="fui-tabbar__icon" :src="current==index?item.selectedIconPath:item.iconPath"
v-if="!item.midButton"></image>
v-if="!item.midButton && item.iconPath"></image>
<!-- #ifdef APP-NVUE -->
<image v-if="item.midButton" class="fui-tabbar__icon" :src="item.iconPath"
:style="{width:(item.width || 56)+'rpx',height:(item.height || 56)+'rpx'}">
</image>
<!-- #endif -->
<fui-icon v-if="item.iconName && !item.iconPath && !item.midButton"
:name="current==index?item.selectedIconName:item.iconName" :size="item.iconSize || iconSize"
:unit="item.iconUnit || iconUnit"
:color="current==index?(item.selectedColor || getSelectedColor):(item.color || color)"
:customPrefix="item.customPrefix || ''"></fui-icon>
<text
:class="[item.dot?'fui-tabbar__dot':'fui-tabbar__badge',badgeBackground?'':'fui-tabbar__badge-color']"
:style="{background:getBadgeBgColor,color:badgeColor,width:getWidth(item.badge,item.dot)}"
......@@ -39,9 +44,13 @@
</template>
<script>
// import fuiIcon from "@/components/firstui/fui-icon/fui-icon.vue"
export default {
name: 'fui-tabbar',
emits: ['init', 'click'],
// components: {
// fuiIcon
// },
props: {
tabBar: {
type: Array,
......@@ -62,6 +71,16 @@
type: [Number, String],
default: 400
},
//V2.2.0+ 字体图标字体大小 rpx
iconSize: {
type: [Number, String],
default: 56
},
//V2.2.0+ 字体图标字体大小 rpx
iconUnit: {
type: String,
default: 'rpx'
},
//字体颜色
color: {
type: String,
......@@ -124,12 +143,10 @@
computed: {
getSelectedColor() {
let color = this.selectedColor
// #ifdef APP-NVUE
if (!color || color === true) {
const app = uni && uni.$fui && uni.$fui.color;
color = (app && app.primary) || '#465CFF';
}
// #endif
return color
},
getBadgeBgColor() {
......@@ -370,12 +387,14 @@
background-color: transparent;
}
/* #ifndef APP-NVUE */
/* #ifdef APP-NVUE || MP-TOUTIAO */
.fui-tabbar__safe-weex {
padding-bottom: 34px;
}
/* #endif */
/* #ifndef APP-NVUE */
.fui-tabbar__selected-color {
color: var(--fui-color-primary, #465CFF) !important;
}
......
<template>
<view class="fui-table__wrap" :style="{height:height>0 || height!=0?height+'rpx':'auto',width:width+'px'}">
<!-- #ifdef MP-BAIDU -->
<scroll-view :show-scrollbar="false" scroll-x
<scroll-view :show-scrollbar="false" :scroll-x="true"
:style="{width:width+'px',height:height>0 || height!=0?height+'rpx':'auto'}" class="fui-table__scroll-view"
:class="{'fui-table__flex-row':!height || height==0}">
<!-- #endif -->
......@@ -21,7 +21,7 @@
v-for="(item,index) in hData" :key="index" @tap.stop="tableSort(index,false)">
<view class="fui-table__checkbox"
:class="{'fui-table__checkbox-color':(!checkboxColor || checkboxColor===true) && chkAll}"
:style="{background:chkAll ?getCheckboxColor:'transparent',borderColor:chkAll ?getCheckboxColor:checkboxBorderColor}"
:style="{background:chkAll?getCheckboxColor:'transparent',borderColor:chkAll ?getCheckboxColor:checkboxBorderColor}"
v-if="item.type==='selection'" @tap.stop="selectionAll">
<view class="fui-table__checkmark"
:style="{borderBottomColor:checkmarkColor,borderRightColor:checkmarkColor}"></view>
......@@ -77,6 +77,11 @@
</view>
</view>
</scroll-view>
<view class="fui-table--empty" :style="{width:width+'px'}"
:class="{'fui-table__empty-ab':totalW>width && (height>0 && height!=0)}"
v-if="itemList.length===0 && emptyText!==true && emptyText!==''">
<text class="fui-table__empty-text" :style="{fontSize:emptySize+'rpx',color:emptyColor}">{{emptyText}}</text>
</view>
</view>
</template>
......@@ -216,6 +221,19 @@
checkmarkColor: {
type: String,
default: '#fff'
},
//V2.1.0+
emptyText: {
type: String,
default: '暂无数据'
},
emptySize: {
type: [String, Number],
default: 24
},
emptyColor: {
type: String,
default: '#B2B2B2'
}
},
watch: {
......@@ -327,7 +345,9 @@
this.hData = vals;
},
handleData(vals) {
if (!vals || vals.length === 0) return;
if (!vals) {
vals = []
}
let table = JSON.parse(JSON.stringify(vals))
table.map(item => {
item.is_disabled = item.is_disabled || false;
......@@ -543,7 +563,7 @@
setSort(prop, sortOrder = 'ascending') {
const index = this.hData.findIndex(item => item.prop === prop)
if (index !== -1) {
this.tableSort(index,sortOrder)
this.tableSort(index, sortOrder)
}
}
}
......@@ -591,6 +611,37 @@
flex-direction: row;
}
.fui-table--empty {
/* #ifndef APP-NVUE */
width: 100%;
display: flex;
box-sizing: border-box;
/* #endif */
flex-direction: row;
justify-content: center;
}
.fui-table__empty-ab {
position: absolute;
left: 0;
top: 96rpx;
/* #ifndef APP-NVUE */
z-index: 2;
/* #endif */
}
.fui-table__empty-text {
/* #ifndef APP-NVUE */
width: 100%;
/* #endif */
/* #ifdef APP-NVUE */
flex: 1;
/* #endif */
font-weight: 400;
text-align: center;
padding: 48rpx 0;
}
.fui-table--td {
/* #ifndef APP-NVUE */
display: flex;
......
......@@ -194,7 +194,9 @@
})
if (this.call) {
uni.makePhoneCall({
phoneNumber: this.text
phoneNumber: this.text,
success: function() {},
fail: function() {}
})
}
}
......@@ -239,9 +241,10 @@
/* #endif */
/* #ifdef APP-NVUE */
.fui-text__nvue{
.fui-text__nvue {
flex: 1;
}
/* #endif */
.fui-text__center {
......
......@@ -27,9 +27,10 @@
</view>
<slot name="left"></slot>
<view class="fui-textarea__flex-1">
<textarea ref="fuiTextarea" class="fui-textarea__self" :class="{'fui-text__right':textRight}"
<textarea ref="fuiTextarea" class="fui-textarea__self"
:class="{'fui-text__right':textRight,'fui-textarea__disabled-styl':disabled && disabledStyle}"
:style="{height:height,minHeight:minHeight,fontSize:size+'rpx',color:color}"
placeholder-class="fui-textarea-placeholder" :name="name" :value="val" :placeholder="placeholder"
placeholder-class="fui-textarea-placeholder" :name="name" :value="val" :placeholder="val?'':placeholder"
:placeholderStyle="placeholderStyl" :disabled="disabled" :cursor-spacing="cursorSpacing"
:maxlength="maxlength" :focus="focused" :auto-height="autoHeight" :fixed="fixed"
:show-confirm-bar="showConfirmBar" :cursor="cursor" :selection-start="selectionStart"
......@@ -142,6 +143,11 @@
type: Boolean,
default: false
},
//V2.1.0+
disabledStyle: {
type: Boolean,
default: false
},
maxlength: {
type: [Number, String],
default: 140
......@@ -353,19 +359,21 @@
}
},
created() {
// #ifndef VUE3
this.val = this.getVal(this.value)
// #endif
// #ifdef VUE3
if (this.value && !this.modelValue) {
this.val = this.getVal(this.value)
} else {
this.val = this.getVal(this.modelValue)
}
// #endif
this.count = this.getCount(String(this.val).length)
this.fieldPlaceholderStyle()
setTimeout(() => {
// #ifndef VUE3
this.val = this.getVal(this.value)
// #endif
// #ifdef VUE3
if (this.value && !this.modelValue) {
this.val = this.getVal(this.value)
} else {
this.val = this.getVal(this.modelValue)
}
// #endif
this.count = this.getCount(String(this.val).length)
}, 50)
},
mounted() {
this.$nextTick(() => {
......@@ -630,4 +638,8 @@
.fui-text__right {
text-align: right;
}
.fui-textarea__disabled-styl {
opacity: .6;
}
</style>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论