tm-ratio.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. <!-- 长宽比例组件 -->
  2. <template>
  3. <view class="tm-ratio--wk d-inline-block">
  4. <view class="tm-ratio" :class="[color,black=='true'||black===true?'bk':'']" :style="style">
  5. <slot name="default" :data="style"></slot>
  6. </view>
  7. </view>
  8. </template>
  9. <script>
  10. /**
  11. *
  12. * 长宽比例组件
  13. * @property {String} ratio = [] 默认:4/3,比例
  14. * @property {Number | String} width = [] 默认:NaN,默认会根据父组件自动计算宽高,指定宽。
  15. * @property {Number | String} height = [] 默认:NaN,默认会根据父组件自动计算宽高,指定高。
  16. * @property {String} color = [white] 默认:white,背景色,主题名称。
  17. * @property {Boolean} black = [true|false] 默认:false,暗黑模式
  18. * @example <tm-ratio height="240" ratio="16/9" ><template v-slot="{data}">{{data.width}}</template></tm-ratio>
  19. *
  20. */
  21. export default {
  22. props: {
  23. // 比例如:16/9,4/3,5/4
  24. ratio: {
  25. type: String,
  26. default: '4/3'
  27. },
  28. width: {
  29. type: Number | String,
  30. default: NaN
  31. },
  32. height: {
  33. type: Number | String,
  34. default: NaN
  35. },
  36. color: {
  37. type: String,
  38. default: "white"
  39. },
  40. black: {
  41. type: String|Boolean,
  42. default: false
  43. },
  44. },
  45. data() {
  46. return {
  47. style: '',
  48. style_obj:{}
  49. };
  50. },
  51. mounted() {
  52. let t = this;
  53. const query = uni.createSelectorQuery().in(this);
  54. query.select('.tm-ratio--wk').boundingClientRect().exec(dsd => {
  55. var ds = dsd[0];
  56. let wsys = uni.getSystemInfoSync();
  57. let maxWidth = wsys.windowWidth - ds.left - ds.right;
  58. if (maxWidth <= 0) maxWidth = ds.width;
  59. query.select('.tm-ratio').boundingClientRect(data => {
  60. let rt = t.ratio;
  61. if (!rt || rt.indexOf('/') == -1 || rt.split('/').length !== 2) {
  62. rt = '4/3'
  63. }
  64. let ro = rt.split('/');
  65. let ws = !isNaN(parseInt(ro[0])) ? parseInt(ro[0]) : 4;
  66. let hs = !isNaN(parseInt(ro[1])) ? parseInt(ro[1]) : 3;
  67. let bl = hs / ws;
  68. if (isNaN(t.width) && isNaN(t.height)) {
  69. t.style ={
  70. width: data.width + 'px',
  71. height: data.width * bl + 'px',
  72. minHeight: data.width + 'px',
  73. minWidth: data.width + 'px'
  74. };
  75. t.style_obj = uni.$tm.objToString({
  76. width: data.width,
  77. height: data.width * bl,
  78. minHeight: data.width ,
  79. minWidth: data.width
  80. });
  81. return;
  82. }
  83. if (!isNaN(t.width) && isNaN(t.height)) {
  84. let width = uni.upx2px(t.width)
  85. t.style = {
  86. width: (width > maxWidth ? maxWidth : width) + 'px',
  87. height: width * bl + 'px',
  88. minHeight: width * bl + 'px',
  89. minWidth: (width > maxWidth ? maxWidth : width) + 'px'
  90. };
  91. t.style_obj = uni.$tm.objToString({
  92. width: (width > maxWidth ? maxWidth : width) ,
  93. height: width * bl,
  94. minHeight: width * bl ,
  95. minWidth: (width > maxWidth ? maxWidth : width)
  96. });
  97. return;
  98. }
  99. if (isNaN(t.width) && !isNaN(t.height)) {
  100. let height = uni.upx2px(t.height)
  101. let xsw = height / bl;
  102. t.style = {
  103. width: (xsw > maxWidth ? maxWidth : xsw) + 'px',
  104. height: height + 'px',
  105. minHeight: height + 'px',
  106. minWidth: (xsw > maxWidth ? maxWidth : xsw) + 'px'
  107. };
  108. t.style_obj = uni.$tm.objToString({
  109. width: (xsw > maxWidth ? maxWidth : xsw) ,
  110. height: height,
  111. minHeight: height ,
  112. minWidth: (xsw > maxWidth ? maxWidth : xsw)
  113. });
  114. return;
  115. }
  116. // 如果同时提供了宽高,那么按比例。以最长边为第一值。
  117. if (!isNaN(t.width) && !isNaN(t.height)) {
  118. // 第一值,默认为宽度。
  119. let xnh = uni.upx2px(t.width);
  120. let isW = true;
  121. if (xnh < uni.upx2px(t.height)) {
  122. xnh = uni.upx2px(t.height);
  123. isW = false;
  124. }
  125. let w = 0;
  126. let h = 0;
  127. if (isW) {
  128. w = xnh;
  129. h = xnh * bl;
  130. } else {
  131. w = xnh / bl;
  132. h = xnh;
  133. }
  134. t.style = {
  135. width: w + 'px',
  136. height: h + 'px',
  137. minHeight: h + 'px',
  138. minWidth: w + 'px'
  139. };
  140. t.style_obj = uni.$tm.objToString({
  141. width: w ,
  142. height: h ,
  143. minHeight: h ,
  144. minWidth: w
  145. });
  146. return;
  147. }
  148. }).exec();
  149. })
  150. }
  151. }
  152. </script>
  153. <style lang="scss" scoped>
  154. </style>