You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

171 lines
4.3 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!-- 长宽比例组件 -->
<template>
<view class="tm-ratio--wk d-inline-block">
<view class="tm-ratio" :class="[color,black=='true'||black===true?'bk':'']" :style="style">
<slot name="default" :data="style"></slot>
</view>
</view>
</template>
<script>
/**
*
* 长宽比例组件
* @property {String} ratio = [] 默认4/3比例
* @property {Number | String} width = [] 默认NaN默认会根据父组件自动计算宽高指定宽。
* @property {Number | String} height = [] 默认NaN默认会根据父组件自动计算宽高指定高。
* @property {String} color = [white] 默认white背景色主题名称。
* @property {Boolean} black = [true|false] 默认false暗黑模式
* @example <tm-ratio height="240" ratio="16/9" ><template v-slot="{data}">{{data.width}}</template></tm-ratio>
*
*/
export default {
props: {
// 比例如:16/9,4/3,5/4
ratio: {
type: String,
default: '4/3'
},
width: {
type: Number | String,
default: NaN
},
height: {
type: Number | String,
default: NaN
},
color: {
type: String,
default: "white"
},
black: {
type: String|Boolean,
default: false
},
},
data() {
return {
style: '',
style_obj:{}
};
},
mounted() {
let t = this;
const query = uni.createSelectorQuery().in(this);
query.select('.tm-ratio--wk').boundingClientRect().exec(dsd => {
var ds = dsd[0];
let wsys = uni.getSystemInfoSync();
let maxWidth = wsys.windowWidth - ds.left - ds.right;
if (maxWidth <= 0) maxWidth = ds.width;
query.select('.tm-ratio').boundingClientRect(data => {
let rt = t.ratio;
if (!rt || rt.indexOf('/') == -1 || rt.split('/').length !== 2) {
rt = '4/3'
}
let ro = rt.split('/');
let ws = !isNaN(parseInt(ro[0])) ? parseInt(ro[0]) : 4;
let hs = !isNaN(parseInt(ro[1])) ? parseInt(ro[1]) : 3;
let bl = hs / ws;
if (isNaN(t.width) && isNaN(t.height)) {
t.style ={
width: data.width + 'px',
height: data.width * bl + 'px',
minHeight: data.width + 'px',
minWidth: data.width + 'px'
};
t.style_obj = uni.$tm.objToString({
width: data.width,
height: data.width * bl,
minHeight: data.width ,
minWidth: data.width
});
return;
}
if (!isNaN(t.width) && isNaN(t.height)) {
let width = uni.upx2px(t.width)
t.style = {
width: (width > maxWidth ? maxWidth : width) + 'px',
height: width * bl + 'px',
minHeight: width * bl + 'px',
minWidth: (width > maxWidth ? maxWidth : width) + 'px'
};
t.style_obj = uni.$tm.objToString({
width: (width > maxWidth ? maxWidth : width) ,
height: width * bl,
minHeight: width * bl ,
minWidth: (width > maxWidth ? maxWidth : width)
});
return;
}
if (isNaN(t.width) && !isNaN(t.height)) {
let height = uni.upx2px(t.height)
let xsw = height / bl;
t.style = {
width: (xsw > maxWidth ? maxWidth : xsw) + 'px',
height: height + 'px',
minHeight: height + 'px',
minWidth: (xsw > maxWidth ? maxWidth : xsw) + 'px'
};
t.style_obj = uni.$tm.objToString({
width: (xsw > maxWidth ? maxWidth : xsw) ,
height: height,
minHeight: height ,
minWidth: (xsw > maxWidth ? maxWidth : xsw)
});
return;
}
// 如果同时提供了宽高,那么按比例。以最长边为第一值。
if (!isNaN(t.width) && !isNaN(t.height)) {
// 第一值,默认为宽度。
let xnh = uni.upx2px(t.width);
let isW = true;
if (xnh < uni.upx2px(t.height)) {
xnh = uni.upx2px(t.height);
isW = false;
}
let w = 0;
let h = 0;
if (isW) {
w = xnh;
h = xnh * bl;
} else {
w = xnh / bl;
h = xnh;
}
t.style = {
width: w + 'px',
height: h + 'px',
minHeight: h + 'px',
minWidth: w + 'px'
};
t.style_obj = uni.$tm.objToString({
width: w ,
height: h ,
minHeight: h ,
minWidth: w
});
return;
}
}).exec();
})
}
}
</script>
<style lang="scss" scoped>
</style>