mirror of
https://github.com/weilanwl/coloruicss.git
synced 2026-03-07 06:24:00 +08:00
2.1.1
This commit is contained in:
@@ -1,19 +1,86 @@
|
|||||||

|
<p style="text-align: center;"><img src="https://image.weilanwl.com/uni/UniAppReadme.jpg" title="ColorUI简介"></img></p>
|
||||||
|
|
||||||
## 简介
|
## 开始使用
|
||||||
这是一款适应于H5、小程序(其他平台未测试)的高颜值,高度自定义的Css组件库.
|
下载源码解压,复制根目录的 `colorui/` 文件夹到你的根目录
|
||||||
相比于同类小程序组件库,ColorUI更注重于视觉交互!
|
|
||||||
|
|
||||||
[浏览GitHub:https://github.com/weilanwl/ColorUI](https://github.com/weilanwl/ColorUI)
|
`App.vue` 引入关键Css `main.css` `icon.css`
|
||||||
|
```
|
||||||
|
<style>
|
||||||
|
@import "colorui/main.css";
|
||||||
|
@import "colorui/icon.css";
|
||||||
|
@import "app.css"; /* 你的项目css */
|
||||||
|
....
|
||||||
|
</style>
|
||||||
|
```
|
||||||
|
#### 元素
|
||||||
|
------
|
||||||
|
|
||||||
小程序端预览
|
|
||||||

|
|
||||||
|
|
||||||
H5端预览
|
## 使用自定义导航栏
|
||||||

|
`main.js` 引入 `cu-custom` 组件
|
||||||
|
```
|
||||||
|
import cuCustom from './colorui/components/cu-custom.vue'
|
||||||
|
Vue.component('cu-custom',cuCustom)
|
||||||
|
```
|
||||||
|
`App.vue` 获得系统信息
|
||||||
|
```
|
||||||
|
onLaunch: function() {
|
||||||
|
uni.getSystemInfo({
|
||||||
|
success: function(e) {
|
||||||
|
// #ifndef MP
|
||||||
|
Vue.prototype.StatusBar = e.statusBarHeight;
|
||||||
|
if (e.platform == 'android') {
|
||||||
|
Vue.prototype.CustomBar = e.statusBarHeight + 50;
|
||||||
|
} else {
|
||||||
|
Vue.prototype.CustomBar = e.statusBarHeight + 45;
|
||||||
|
};
|
||||||
|
// #endif
|
||||||
|
|
||||||
## 沉浸式导航
|
// #ifdef MP
|
||||||

|
Vue.prototype.StatusBar = e.statusBarHeight;
|
||||||
|
let custom = wx.getMenuButtonBoundingClientRect();
|
||||||
|
Vue.prototype.Custom = custom;
|
||||||
|
Vue.prototype.CustomBar = custom.bottom + custom.top - e.statusBarHeight;
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
## 自定义系统Tabbar
|
```
|
||||||

|
`page.vue` 页面可以直接调用了
|
||||||
|
```
|
||||||
|
<cu-custom bgColor="bg-gradual-blue" :isBack="true">
|
||||||
|
<block slot="backText">返回</block>
|
||||||
|
<block slot="content">导航栏</block>
|
||||||
|
</cu-custom>
|
||||||
|
```
|
||||||
|
| 参数 | 作用 |类型 | 默认值 |
|
||||||
|
| -------- | -----: |-----: | :----: |
|
||||||
|
| bgColor | 背景颜色类名 |String | '' |
|
||||||
|
| isBack | 是否开启返回 | Boolean | false |
|
||||||
|
| bgImage | 背景图片路径 | String | '' |
|
||||||
|
|
||||||
|
| slot块 | 作用 |
|
||||||
|
| -------- | -----: |
|
||||||
|
| backText | 返回时的文字 |
|
||||||
|
| content | 中间区域 |
|
||||||
|
| right | 右侧区域(小程序端可使用范围很窄!) |
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
## 使用自定义Tabbar
|
||||||
|
这部分暂时没有封装,思路可以参考下我的源码,原理是一个主页面引入多个页面,在主页面进行切换显示。这样可以解决切换时闪烁的问题。
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
## 更新日志
|
||||||
|
* 2019年3月27日 v2.1.1
|
||||||
|
* 新增多种扩展
|
||||||
|
* 优化堆叠轮播图
|
||||||
|
* 优化消息列表
|
||||||
|
* 优化导航栏的封装
|
||||||
|
|
||||||
|
* 2019年3月25日 v2.1.0
|
||||||
|
* 完成元素,组件移植
|
||||||
|
* icon文件更改名称,避免图标冲突
|
||||||
|
* 针对不同端口做了优化
|
||||||
139
Colorui-UniApp/colorui/components/curry-slide.vue
Normal file
139
Colorui-UniApp/colorui/components/curry-slide.vue
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
<template>
|
||||||
|
<view class="carousel-3d-slide" :style="slideStyle" :class="computedClasses" @click="goTo()">
|
||||||
|
<slot :index="index" :isCurrent="isCurrent" :leftIndex="leftIndex" :rightIndex="rightIndex"/>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/* eslint-disable */
|
||||||
|
export default {
|
||||||
|
name: 'curry-slide',
|
||||||
|
props: {
|
||||||
|
index: {
|
||||||
|
type: Number
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
parent: this.$parent,
|
||||||
|
styles: {},
|
||||||
|
zIndex: 999
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isCurrent () {
|
||||||
|
return this.index === this.parent.currentIndex
|
||||||
|
},
|
||||||
|
leftIndex () {
|
||||||
|
return this.getSideIndex(this.parent.leftIndices)
|
||||||
|
},
|
||||||
|
rightIndex () {
|
||||||
|
return this.getSideIndex(this.parent.rightIndices)
|
||||||
|
},
|
||||||
|
slideStyle () {
|
||||||
|
let styles = {}
|
||||||
|
if (!this.isCurrent) {
|
||||||
|
const rIndex = this.leftIndex
|
||||||
|
const lIndex = this.rightIndex
|
||||||
|
if (rIndex >= 0 || lIndex >= 0) {
|
||||||
|
styles = rIndex >= 0 ? this.calculatePosition(rIndex, true, this.zIndex) : this.calculatePosition(lIndex, false, this.zIndex)
|
||||||
|
styles.opacity = 1
|
||||||
|
styles.visibility = 'visible'
|
||||||
|
}
|
||||||
|
if (this.parent.hasHiddenSlides) {
|
||||||
|
if (this.matchIndex(this.parent.leftOutIndex)) {
|
||||||
|
styles = this.calculatePosition(this.parent.leftIndices.length - 1, false, this.zIndex)
|
||||||
|
} else if (this.matchIndex(this.parent.rightOutIndex)) {
|
||||||
|
styles = this.calculatePosition(this.parent.rightIndices.length - 1, true, this.zIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Object.assign(styles, {
|
||||||
|
'border-width': this.parent.border + 'px',
|
||||||
|
'width': this.parent.slideWidth + 'px',
|
||||||
|
'height': this.parent.slideHeight + 'px',
|
||||||
|
'transition': ' transform ' + this.parent.animationSpeed + 'ms, ' +
|
||||||
|
' opacity ' + this.parent.animationSpeed + 'ms, ' +
|
||||||
|
' visibility ' + this.parent.animationSpeed + 'ms'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
computedClasses () {
|
||||||
|
return {
|
||||||
|
[`left-${this.leftIndex + 1}`]: this.leftIndex >= 0,
|
||||||
|
[`right-${this.rightIndex + 1}`]: this.rightIndex >= 0,
|
||||||
|
'current': this.isCurrent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getSideIndex (array) {
|
||||||
|
let index = -1
|
||||||
|
array.forEach((pos, i) => {
|
||||||
|
if (this.matchIndex(pos)) {
|
||||||
|
index = i
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return index
|
||||||
|
},
|
||||||
|
matchIndex (index) {
|
||||||
|
return (index >= 0) ? this.index === index : (this.parent.total + index) === this.index
|
||||||
|
},
|
||||||
|
calculatePosition (i, positive, zIndex) {
|
||||||
|
const z = !this.parent.disable3d ? parseInt(this.parent.inverseScaling) + ((i + 1) * 100) : 0
|
||||||
|
const y = !this.parent.disable3d ? parseInt(this.parent.perspective) : 0
|
||||||
|
const leftRemain = (this.parent.space === 'auto')
|
||||||
|
? parseInt((i + 1) * (this.parent.width / 1.2), 10) // 1.5
|
||||||
|
: parseInt((i + 1) * (this.parent.space), 10)
|
||||||
|
const transform = (positive)
|
||||||
|
? 'translateX(' + (leftRemain) + 'px) translateZ(-' + z + 'px) ' +
|
||||||
|
'rotateY(-' + y + 'deg)'
|
||||||
|
: 'translateX(-' + (leftRemain) + 'px) translateZ(-' + z + 'px) ' +
|
||||||
|
'rotateY(' + y + 'deg)'
|
||||||
|
const top = this.parent.space === 'auto' ? 0 : parseInt((i + 1) * (this.parent.space))
|
||||||
|
return {
|
||||||
|
transform: transform,
|
||||||
|
top: top,
|
||||||
|
zIndex: zIndex - (Math.abs(i) + 1)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
goTo () {
|
||||||
|
if (!this.isCurrent) {
|
||||||
|
if (this.parent.clickable === true) {
|
||||||
|
this.parent.goFar(this.index)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.parent.onMainSlideClick()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.carousel-3d-slide {
|
||||||
|
position: absolute;
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
overflow: hidden;
|
||||||
|
top: 0;
|
||||||
|
border-color: #023c41;
|
||||||
|
border-style: solid;
|
||||||
|
background-size: cover;
|
||||||
|
background-color: #ccc;
|
||||||
|
display: block;
|
||||||
|
margin: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.carousel-3d-slide {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.carousel-3d-slide img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.carousel-3d-slide.current {
|
||||||
|
opacity: 1 !important;
|
||||||
|
visibility: visible !important;
|
||||||
|
transform: none !important;
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
410
Colorui-UniApp/colorui/components/curry-swiper.vue
Normal file
410
Colorui-UniApp/colorui/components/curry-swiper.vue
Normal file
@@ -0,0 +1,410 @@
|
|||||||
|
<template>
|
||||||
|
<view class="carousel-3d-container" :style="{height: this.slideHeight + 'px'}">
|
||||||
|
<view class="carousel-3d-slider" :style="{width: this.slideWidth + 'px', height: this.slideHeight + 'px'}">
|
||||||
|
<slot></slot>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/* eslint-disable */
|
||||||
|
const noop = () => {
|
||||||
|
}
|
||||||
|
export default {
|
||||||
|
name: 'curry-swiper',
|
||||||
|
props: {
|
||||||
|
// Number of slides
|
||||||
|
count: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
// Slides perspective position
|
||||||
|
perspective: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 35
|
||||||
|
},
|
||||||
|
// Number of slides displayed on each page
|
||||||
|
display: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 3
|
||||||
|
},
|
||||||
|
loop: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// Animation between slides in milliseconds
|
||||||
|
animationSpeed: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 500
|
||||||
|
},
|
||||||
|
// Animation direction
|
||||||
|
dir: {
|
||||||
|
type: String,
|
||||||
|
default: 'ltr'
|
||||||
|
},
|
||||||
|
width: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 360
|
||||||
|
},
|
||||||
|
height: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 270
|
||||||
|
},
|
||||||
|
border: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 1
|
||||||
|
},
|
||||||
|
// Space between slides in pixels
|
||||||
|
space: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 'auto'
|
||||||
|
},
|
||||||
|
// Start slide index. First slide has 0 index
|
||||||
|
startIndex: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
// Enable navigation by clicking on slide
|
||||||
|
clickable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
disable3d: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// Minimum distance in pixels to swipe before a slide advance is triggered
|
||||||
|
minSwipeDistance: {
|
||||||
|
type: Number,
|
||||||
|
default: 10
|
||||||
|
},
|
||||||
|
// Slide inverse scaling
|
||||||
|
inverseScaling: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 300
|
||||||
|
},
|
||||||
|
onLastSlide: {
|
||||||
|
type: Function,
|
||||||
|
default: noop
|
||||||
|
},
|
||||||
|
onSlideChange: {
|
||||||
|
type: Function,
|
||||||
|
default: noop
|
||||||
|
},
|
||||||
|
bias: {
|
||||||
|
type: String,
|
||||||
|
default: 'left'
|
||||||
|
},
|
||||||
|
onMainSlideClick: {
|
||||||
|
type: Function,
|
||||||
|
default: noop
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
viewport: 0,
|
||||||
|
currentIndex: 0,
|
||||||
|
total: 0,
|
||||||
|
dragOffset: 0,
|
||||||
|
dragStartX: 0,
|
||||||
|
mousedown: false,
|
||||||
|
zIndex: 998
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
count () {
|
||||||
|
this.computeData()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isLastSlide () {
|
||||||
|
return this.currentIndex === this.total - 1
|
||||||
|
},
|
||||||
|
isFirstSlide () {
|
||||||
|
return this.currentIndex === 0
|
||||||
|
},
|
||||||
|
isNextPossible () {
|
||||||
|
return !(!this.loop && this.isLastSlide)
|
||||||
|
},
|
||||||
|
isPrevPossible () {
|
||||||
|
return !(!this.loop && this.isFirstSlide)
|
||||||
|
},
|
||||||
|
slideWidth () {
|
||||||
|
const vw = this.viewport
|
||||||
|
const sw = parseInt(this.width) + (parseInt(this.border, 10) * 2)
|
||||||
|
return vw < sw ? vw : sw
|
||||||
|
},
|
||||||
|
slideHeight () {
|
||||||
|
const sw = parseInt(this.width, 10) + (parseInt(this.border, 10) * 2)
|
||||||
|
const sh = parseInt(parseInt(this.height) + (this.border * 2), 10)
|
||||||
|
const ar = this.calculateAspectRatio(sw, sh)
|
||||||
|
return this.slideWidth / ar
|
||||||
|
},
|
||||||
|
visible () {
|
||||||
|
const v = (this.display > this.total) ? this.total : this.display
|
||||||
|
return v
|
||||||
|
},
|
||||||
|
hasHiddenSlides () {
|
||||||
|
return this.total > this.visible
|
||||||
|
},
|
||||||
|
leftIndices () {
|
||||||
|
let n = (this.visible - 1) / 2
|
||||||
|
n = (this.bias.toLowerCase() === 'left' ? Math.ceil(n) : Math.floor(n))
|
||||||
|
const indices = []
|
||||||
|
for (let m = 1; m <= n; m++) {
|
||||||
|
indices.push((this.dir === 'ltr')
|
||||||
|
? (this.currentIndex + m) % (this.total)
|
||||||
|
: (this.currentIndex - m) % (this.total))
|
||||||
|
}
|
||||||
|
return indices
|
||||||
|
},
|
||||||
|
rightIndices () {
|
||||||
|
let n = (this.visible - 1) / 2
|
||||||
|
n = (this.bias.toLowerCase() === 'right' ? Math.ceil(n) : Math.floor(n))
|
||||||
|
const indices = []
|
||||||
|
for (let m = 1; m <= n; m++) {
|
||||||
|
indices.push((this.dir === 'ltr')
|
||||||
|
? (this.currentIndex - m) % (this.total)
|
||||||
|
: (this.currentIndex + m) % (this.total))
|
||||||
|
}
|
||||||
|
return indices
|
||||||
|
},
|
||||||
|
leftOutIndex () {
|
||||||
|
let n = (this.visible - 1) / 2
|
||||||
|
n = (this.bias.toLowerCase() === 'left' ? Math.ceil(n) : Math.floor(n))
|
||||||
|
n++
|
||||||
|
if (this.dir === 'ltr') {
|
||||||
|
return ((this.total - this.currentIndex - n) <= 0)
|
||||||
|
? (-parseInt(this.total - this.currentIndex - n))
|
||||||
|
: (this.currentIndex + n)
|
||||||
|
} else {
|
||||||
|
return (this.currentIndex - n)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rightOutIndex () {
|
||||||
|
let n = (this.visible - 1) / 2
|
||||||
|
n = (this.bias.toLowerCase() === 'right' ? Math.ceil(n) : Math.floor(n))
|
||||||
|
n++
|
||||||
|
if (this.dir === 'ltr') {
|
||||||
|
return (this.currentIndex - n)
|
||||||
|
} else {
|
||||||
|
return ((this.total - this.currentIndex - n) <= 0)
|
||||||
|
? (-parseInt(this.total - this.currentIndex - n, 10))
|
||||||
|
: (this.currentIndex + n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* Go to next slide
|
||||||
|
*/
|
||||||
|
goNext () {
|
||||||
|
if (this.isNextPossible) {
|
||||||
|
this.isLastSlide ? this.goSlide(0) : this.goSlide(this.currentIndex + 1)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Go to previous slide
|
||||||
|
*/
|
||||||
|
goPrev () {
|
||||||
|
if (this.isPrevPossible) {
|
||||||
|
this.isFirstSlide ? this.goSlide(this.total - 1) : this.goSlide(this.currentIndex - 1)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Go to slide
|
||||||
|
* @param {String} index of slide where to go
|
||||||
|
*/
|
||||||
|
goSlide (index) {
|
||||||
|
this.currentIndex = (index < 0 || index > this.total - 1) ? 0 : index
|
||||||
|
if (this.isLastSlide) {
|
||||||
|
if (this.onLastSlide !== noop) {
|
||||||
|
console.warn('onLastSlide deprecated, please use @last-slide')
|
||||||
|
}
|
||||||
|
this.onLastSlide(this.currentIndex)
|
||||||
|
this.$emit('last-slide', this.currentIndex)
|
||||||
|
}
|
||||||
|
this.$emit('before-slide-change', this.currentIndex)
|
||||||
|
setTimeout(() => this.animationEnd(), this.animationSpeed)
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Go to slide far slide
|
||||||
|
*/
|
||||||
|
goFar (index) {
|
||||||
|
let diff = (index === this.total - 1 && this.isFirstSlide) ? -1 : (index - this.currentIndex)
|
||||||
|
if (this.isLastSlide && index === 0) {
|
||||||
|
diff = 1
|
||||||
|
}
|
||||||
|
const diff2 = (diff < 0) ? -diff : diff
|
||||||
|
let timeBuff = 0
|
||||||
|
let i = 0
|
||||||
|
while (i < diff2) {
|
||||||
|
i += 1
|
||||||
|
const timeout = (diff2 === 1) ? 0 : (timeBuff)
|
||||||
|
setTimeout(() => (diff < 0) ? this.goPrev(diff2) : this.goNext(diff2), timeout)
|
||||||
|
timeBuff += (this.animationSpeed / (diff2))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Trigger actions when animation ends
|
||||||
|
*/
|
||||||
|
animationEnd () {
|
||||||
|
if (this.onSlideChange !== noop) {
|
||||||
|
console.warn('onSlideChange deprecated, please use @after-slide-change')
|
||||||
|
}
|
||||||
|
this.onSlideChange(this.currentIndex)
|
||||||
|
this.$emit('after-slide-change', this.currentIndex)
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Trigger actions when mouse is released
|
||||||
|
* @param {Object} e The event object
|
||||||
|
*/
|
||||||
|
handleMouseup () {
|
||||||
|
this.mousedown = false
|
||||||
|
this.dragOffset = 0
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Trigger actions when mouse is pressed
|
||||||
|
* @param {Object} e The event object
|
||||||
|
*/
|
||||||
|
handleMousedown (e) {
|
||||||
|
if (!e.touches) {
|
||||||
|
e.preventDefault()
|
||||||
|
}
|
||||||
|
this.mousedown = true
|
||||||
|
this.dragStartX = ('ontouchstart' in window) ? e.touches[0].clientX : e.clientX
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Trigger actions when mouse is pressed and then moved (mouse drag)
|
||||||
|
* @param {Object} e The event object
|
||||||
|
*/
|
||||||
|
handleMousemove (e) {
|
||||||
|
if (!this.mousedown) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const eventPosX = ('ontouchstart' in window) ? e.touches[0].clientX : e.clientX
|
||||||
|
const deltaX = (this.dragStartX - eventPosX)
|
||||||
|
this.dragOffset = deltaX
|
||||||
|
if (this.dragOffset > this.minSwipeDistance) {
|
||||||
|
this.handleMouseup()
|
||||||
|
this.goNext()
|
||||||
|
} else if (this.dragOffset < -this.minSwipeDistance) {
|
||||||
|
this.handleMouseup()
|
||||||
|
this.goPrev()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* A mutation observer is used to detect changes to the containing node
|
||||||
|
* in order to keep the magnet container in sync with the height its reference node.
|
||||||
|
*/
|
||||||
|
attachMutationObserver () {
|
||||||
|
const MutationObserver = window.MutationObserver ||
|
||||||
|
window.WebKitMutationObserver ||
|
||||||
|
window.MozMutationObserver
|
||||||
|
if (MutationObserver) {
|
||||||
|
const config = {
|
||||||
|
attributes: true,
|
||||||
|
childList: true,
|
||||||
|
characterData: true
|
||||||
|
}
|
||||||
|
this.mutationObserver = new MutationObserver(() => {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.computeData()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
if (this.$el) {
|
||||||
|
this.mutationObserver.observe(this.$el, config)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Stop listening to mutation changes
|
||||||
|
*/
|
||||||
|
detachMutationObserver () {
|
||||||
|
if (this.mutationObserver) {
|
||||||
|
this.mutationObserver.disconnect()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Get the number of slides
|
||||||
|
* @return {Number} Number of slides
|
||||||
|
*/
|
||||||
|
getSlideCount () {
|
||||||
|
if (this.$slots.default !== undefined) {
|
||||||
|
return this.$slots.default.filter((value) => {
|
||||||
|
return value.tag !== void 0
|
||||||
|
}).length
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Calculate slide with and keep defined aspect ratio
|
||||||
|
* @return {Number} Aspect ratio number
|
||||||
|
*/
|
||||||
|
calculateAspectRatio (width, height) {
|
||||||
|
return Math.min(width / height)
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Re-compute the number of slides and current slide
|
||||||
|
*/
|
||||||
|
computeData (firstRun) {
|
||||||
|
this.total = this.getSlideCount()
|
||||||
|
if (firstRun || this.currentIndex >= this.total) {
|
||||||
|
this.currentIndex = parseInt(this.startIndex) > this.total - 1 ? this.total - 1 : parseInt(this.startIndex)
|
||||||
|
}
|
||||||
|
this.viewport = this.$el.clientWidth
|
||||||
|
},
|
||||||
|
setSize () {
|
||||||
|
this.$el.style.cssText += 'height:' + this.slideHeight + 'px;'
|
||||||
|
this.$el.childNodes[0].style.cssText += 'width:' + this.slideWidth + 'px;' + ' height:' + this.slideHeight + 'px;'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
this.computeData(true)
|
||||||
|
this.attachMutationObserver()
|
||||||
|
if (!this.$isServer) {
|
||||||
|
window.addEventListener('resize', this.setSize)
|
||||||
|
if ('ontouchstart' in window) {
|
||||||
|
this.$el.addEventListener('touchstart', this.handleMousedown)
|
||||||
|
this.$el.addEventListener('touchend', this.handleMouseup)
|
||||||
|
this.$el.addEventListener('touchmove', this.handleMousemove)
|
||||||
|
} else {
|
||||||
|
this.$el.addEventListener('mousedown', this.handleMousedown)
|
||||||
|
this.$el.addEventListener('mouseup', this.handleMouseup)
|
||||||
|
this.$el.addEventListener('mousemove', this.handleMousemove)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
beforeDestroy () {
|
||||||
|
if (!this.$isServer) {
|
||||||
|
this.detachMutationObserver()
|
||||||
|
if ('ontouchstart' in window) {
|
||||||
|
this.$el.removeEventListener('touchmove', this.handleMousemove)
|
||||||
|
} else {
|
||||||
|
this.$el.removeEventListener('mousemove', this.handleMousemove)
|
||||||
|
}
|
||||||
|
window.removeEventListener('resize', this.setSize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.carousel-3d-container {
|
||||||
|
min-height: 1px;
|
||||||
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
z-index: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
margin: 0px auto;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.carousel-3d-slider {
|
||||||
|
position: relative;
|
||||||
|
margin: 0 auto;
|
||||||
|
transform-style: preserve-3d;
|
||||||
|
-webkit-perspective: 1000px;
|
||||||
|
-moz-perspective: 1000px;
|
||||||
|
perspective: 1000px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
/* 快应用特有相关 */
|
/* 快应用特有相关 */
|
||||||
"mp-weixin" : {
|
"mp-weixin" : {
|
||||||
/* 小程序特有相关 */
|
/* 小程序特有相关 */
|
||||||
"appid" : "wxfd5241d66a07713f",
|
"appid" : "",
|
||||||
"setting" : {
|
"setting" : {
|
||||||
"urlCheck" : true
|
"urlCheck" : true
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user