Merge branch 'master' of github.com:9th-js/wcui

master
yutent 2023-04-12 18:56:41 +08:00
commit 076bcca29d
2 changed files with 167 additions and 37 deletions

View File

@ -48,8 +48,9 @@
- [ ] `wc-timepicker`时间选择器
- [x] `wc-code`代码高亮插件
- [x] `wc-scroll`滚动组件
- [x] `wc-silder`面包屑组件
- [x] `wc-breadcrumb`滑块组件
- [x] `wc-silder`滑块组件
- [x] `wc-swipe`轮播图组件
- [x] `wc-breadcrumb` 面包屑组件
- [ ] `wc-progress`进度条组件
- [ ] `wc-tree`树形菜单组件
- [ ] `wc-uploader`上传组件

View File

@ -1,10 +1,10 @@
/**
* {}
* 轮播图组件
* @author chensbox<chensbox@foxmail.com>
* @date 2023/03/26 16:14:10
*/
import { css, html, Component, nextTick } from '@bd/core'
import { css, html, Component, nextTick, styleMap } from '@bd/core'
import '../icon/index.js'
const CARD_SCALE = 0.83
function createWatcher(object, key, effect) {
@ -19,7 +19,7 @@ function createWatcher(object, key, effect) {
}
})
}
class Carousel extends Component {
class Swipe extends Component {
static props = {
'initial-index': {
type: Number,
@ -34,7 +34,7 @@ class Carousel extends Component {
},
trigger: {
type: String,
default: 'hover'
default: 'hover' // hover or click
},
autoplay: {
type: Boolean,
@ -47,23 +47,26 @@ class Carousel extends Component {
type: Number,
default: 3000
},
'indicator-position': { String, attributes: false },
indicator: {
type: Boolean,
default: true
},
arrow: {
type: String,
default: 'hover'
default: 'hover' // hover or alway
},
type: {
type: String,
default: '', // '' or card
attributes: false
},
type: { type: String, default: '', attributes: false },
loop: {
type: Boolean,
default: true
},
direction: {
type: String,
default: 'horizontal'
default: 'horizontal' // horizontal or vertical
},
'pause-on-hover': {
type: Boolean,
@ -77,7 +80,34 @@ class Carousel extends Component {
display: block;
width: 100%;
}
:host([direction='vertical']) {
.indicator {
flex-direction: column;
left: calc(100% - 26px);
top: 50%;
height: 80%;
width: 26px;
transform: translatey(-50%);
li {
width: 26px;
height: 24px;
margin: 5px 0;
&::after {
position: absolute;
content: '';
left: calc(50% - 2px);
top: 0;
height: 100%;
width: 2px;
background-color: #fff;
opacity: 0.48;
}
&.active::after {
opacity: 1;
}
}
}
}
.toggle-btn {
z-index: 4;
user-select: none;
@ -86,7 +116,7 @@ class Carousel extends Component {
display: flex;
align-items: center;
justify-content: center;
opacity: 0.8;
opacity: 0;
width: 33px;
height: 33px;
font-size: 24px;
@ -95,6 +125,10 @@ class Carousel extends Component {
border-color: #fff;
border-radius: 50%;
--size: 12px;
transition: opacity ease-in-out 0.2s;
&:hover {
opacity: 1 !important;
}
}
.left,
.right {
@ -102,10 +136,43 @@ class Carousel extends Component {
transform: translateY(-50%);
}
.left {
left: 5%;
left: 3%;
}
.right {
right: 5%;
right: 3%;
}
.indicator {
display: flex;
align-items: center;
justify-content: center;
position: absolute;
width: 80%;
bottom: 0px;
left: 50%;
transform: translateX(-50%);
li {
position: relative;
width: 24px;
height: 26px;
margin: 0 5px;
list-style: none;
&::after {
position: absolute;
content: '';
left: 0;
top: calc(50% - 2px);
width: 100%;
height: 2px;
background-color: #fff;
opacity: 0.48;
}
&:hover {
cursor: pointer;
}
&.active::after {
opacity: 1;
}
}
}
`
items = []
@ -114,7 +181,7 @@ class Carousel extends Component {
updateItems() {
this.items = Array.from(this.children).filter(
item => item.tagName === 'WC-CAROUSEL-ITEM'
item => item.tagName === 'WC-SWIPE-ITEM'
)
nextTick(() => this.$requestUpdate())
}
@ -147,6 +214,7 @@ class Carousel extends Component {
this.items.forEach((item, index) => {
item.translateItem(index, this.activeIndex, oldIndex)
})
nextTick(() => this.$requestUpdate())
}
setActiveItem(index) {
const now = Date.now()
@ -176,12 +244,18 @@ class Carousel extends Component {
if (oldIndex !== this.activeIndex) {
this.resetItemPosition(oldIndex)
}
// this.resetItemPosition(oldIndex)
this.resetTimer()
nextTick(() => this.$requestUpdate())
}
handleIndicatorHover(index) {
handleIndicatorHover(event) {
let index = +event.target.getAttribute('index')
if (this.trigger === 'hover' && index !== this.activeIndex) {
// this.activeIndex = index
this.setActiveItem(index)
}
}
handleClickIndicator(event) {
let index = +event.target.getAttribute('index')
if (this.trigger === 'click' && index !== this.activeIndex) {
this.setActiveItem(index)
}
}
@ -191,6 +265,18 @@ class Carousel extends Component {
next() {
this.setActiveItem(this.activeIndex + 1)
}
showArrow() {
this.showArrowBtn = true
this.$requestUpdate()
}
hideArrow() {
this.showArrowBtn = false
this.$requestUpdate()
}
handleSlotChange() {
this.updateItems()
this.resetItemPosition()
}
mounted() {
this.updateItems()
nextTick(() => {
@ -202,6 +288,17 @@ class Carousel extends Component {
this.resizeObserve.observe(this)
this.startTimer()
})
if (this['pause-on-hover']) {
this.$on('mouseenter', () => this.pauseTimer())
this.$on('mouseleave', () => this.startTimer())
}
if (this.arrow === 'hover') {
this.$on('mouseenter', () => this.showArrow())
this.$on('mouseleave', () => this.hideArrow())
} else if (this.arrow === 'alway') {
this.showArrow()
}
}
unmounted() {
this.resizeObserve.disconnect()
@ -209,23 +306,46 @@ class Carousel extends Component {
this.pauseTimer()
}
render() {
return html`
<div class="container" style=${`height:${this.height}px`}>
<slot></slot>
<div class="left toggle-btn" @click=${this.prev}>
let styles = styleMap({
opacity: this.showArrowBtn ? 0.6 : 0
})
let toggleBtns =
this.direction === 'horizontal'
? html`
<div class="left toggle-btn" style=${styles} @click=${this.prev}>
<wc-icon name="left"></wc-icon>
</div>
<div class="right toggle-btn" @click=${this.next}>
<div class="right toggle-btn" style=${styles} @click=${this.next}>
<wc-icon name="right"></wc-icon>
</div>
</div>
<ul>
${this.items.map(_ => html`<li>3</li>`)}
`
: ''
let indicator = this.indicator
? html`
<ul class="indicator" @click=${this.handleClickIndicator}>
${this.items.map(
(item, index) =>
html` <li
index=${index}
class=${this.activeIndex === index ? 'active' : ''}
@mouseenter=${this.handleIndicatorHover}
></li>`
)}
</ul>
`
: ''
return html`
<div class="container" style=${`height:${this.height}px`}>
<slot @slotchange=${this.handleSlotChange}></slot>
${toggleBtns}
</div>
${indicator}
`
}
}
class CarouselItem extends Component {
class SwipeItem extends Component {
static props = {
name: { String, attributes: false }
}
@ -248,7 +368,8 @@ class CarouselItem extends Component {
:host([card]) {
width: 50%;
transition-duration: 400ms;
transition-property: transform, opacity;
transition-property: transform, opacity, filter;
cursor: pointer;
}
`
static watch = {
@ -269,16 +390,22 @@ class CarouselItem extends Component {
if (this.$parent.type !== 'card') {
return
}
this.style.opacity = 1
let style = {
opacity: 1,
'z-index': 1,
filter: 'brightness(0.8)'
}
if (this.inStage) {
this.style['z-index'] = 1
style['z-index'] = 1
} else {
this.style['z-index'] = -1
this.style.opacity = 0
style['z-index'] = -1
style.opacity = 0
}
if (val) {
this.style['z-index'] = 2
style['z-index'] = 2
style.filter = 'brightness(1)'
}
Object.assign(this.style, style)
}
}
processIndex(index, activeIndex, length) {
@ -347,9 +474,11 @@ class CarouselItem extends Component {
this.$parent = this.parentNode
if (this.$parent.type === 'card') {
this.setAttribute('card', '')
const index = this.$parent.items.indexOf(this)
this.$on('click', () => this.$parent.setActiveItem(index))
}
}
}
Carousel.reg('carousel')
CarouselItem.reg('carousel-item')
Swipe.reg('swipe')
SwipeItem.reg('swipe-item')