171 lines
4.3 KiB
Vue
171 lines
4.3 KiB
Vue
<!-- 长宽比例组件 -->
|
||
<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>
|