修改关于海威
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 455 KiB |
|
After Width: | Height: | Size: 1.9 MiB |
@ -0,0 +1,5 @@
|
||||
const files = require.context('./', false, /\.(png|jpe?g|gif|webp|svg)$/)
|
||||
|
||||
const logos = files.keys().map(key => files(key))
|
||||
|
||||
export default logos
|
||||
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 9.7 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 8.6 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 13 KiB |
@ -0,0 +1,248 @@
|
||||
<template>
|
||||
<div ref="viewport" class="infinite-image-scroller">
|
||||
<div
|
||||
ref="track"
|
||||
class="infinite-image-scroller__track"
|
||||
:style="trackStyle"
|
||||
@mouseenter="handleMouseEnter"
|
||||
@mouseleave="handleMouseLeave"
|
||||
>
|
||||
<div
|
||||
v-for="groupIndex in repeatCount"
|
||||
:key="groupIndex"
|
||||
class="infinite-image-scroller__group"
|
||||
>
|
||||
<div
|
||||
v-for="(image, index) in images"
|
||||
:key="groupIndex + '-' + index"
|
||||
class="infinite-image-scroller__item"
|
||||
>
|
||||
<img
|
||||
class="infinite-image-scroller__image"
|
||||
:src="getImageSrc(image)"
|
||||
:alt="getImageAlt(image, index)"
|
||||
draggable="false"
|
||||
@load="updateSize"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'InfiniteImageScroller',
|
||||
|
||||
props: {
|
||||
images: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
initialOffset: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
direction: {
|
||||
type: String,
|
||||
default: 'rtl',
|
||||
validator: function (value) {
|
||||
return [
|
||||
'ltr',
|
||||
'rtl'
|
||||
].indexOf(value) !== -1
|
||||
}
|
||||
},
|
||||
speed: {
|
||||
type: Number,
|
||||
default: 40
|
||||
},
|
||||
gap: {
|
||||
type: [
|
||||
Number,
|
||||
String
|
||||
],
|
||||
default: '1vw'
|
||||
},
|
||||
imageWidth: {
|
||||
type: Number,
|
||||
default: 160
|
||||
},
|
||||
imageHeight: {
|
||||
type: Number,
|
||||
default: 100
|
||||
},
|
||||
pauseOnHover: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
|
||||
data: function () {
|
||||
return {
|
||||
distance: 0,
|
||||
groupWidth: 0,
|
||||
viewportWidth: 0,
|
||||
animationFrameId: null,
|
||||
lastTime: 0,
|
||||
isPaused: false
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
repeatCount: function () {
|
||||
if (!this.groupWidth || !this.viewportWidth) {
|
||||
return 3
|
||||
}
|
||||
|
||||
return Math.max(3, Math.ceil(this.viewportWidth / this.groupWidth) + 2)
|
||||
},
|
||||
trackStyle: function () {
|
||||
return {
|
||||
transform: 'translate3d(' + this.translateX + 'px, 0, 0)',
|
||||
'--scroller-gap': this.formatSize(this.gap),
|
||||
'--scroller-image-width': this.imageWidth,
|
||||
'--scroller-image-height': this.imageHeight
|
||||
}
|
||||
},
|
||||
translateX: function () {
|
||||
if (!this.groupWidth) {
|
||||
return 0
|
||||
}
|
||||
|
||||
var phase = this.getPositiveModulo(this.initialOffset + this.distance, this.groupWidth)
|
||||
|
||||
return this.direction === 'ltr' ? phase - this.groupWidth : -phase
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
images: function () {
|
||||
this.$nextTick(this.updateSize)
|
||||
},
|
||||
gap: function () {
|
||||
this.$nextTick(this.updateSize)
|
||||
},
|
||||
imageWidth: function () {
|
||||
this.$nextTick(this.updateSize)
|
||||
}
|
||||
},
|
||||
|
||||
mounted: function () {
|
||||
this.$nextTick(function () {
|
||||
this.updateSize()
|
||||
this.startAnimation()
|
||||
})
|
||||
window.addEventListener('resize', this.updateSize)
|
||||
},
|
||||
|
||||
beforeDestroy: function () {
|
||||
this.stopAnimation()
|
||||
window.removeEventListener('resize', this.updateSize)
|
||||
},
|
||||
|
||||
methods: {
|
||||
getImageSrc: function (image) {
|
||||
return typeof image === 'string' ? image : image.src
|
||||
},
|
||||
getImageAlt: function (image, index) {
|
||||
if (typeof image === 'string') {
|
||||
return 'image-' + (index + 1)
|
||||
}
|
||||
|
||||
return image.alt || 'image-' + (index + 1)
|
||||
},
|
||||
getPositiveModulo: function (value, base) {
|
||||
return ((value % base) + base) % base
|
||||
},
|
||||
formatSize: function (value) {
|
||||
return typeof value === 'number' ? value + 'px' : value
|
||||
},
|
||||
updateSize: function () {
|
||||
var viewport = this.$refs.viewport
|
||||
var track = this.$refs.track
|
||||
|
||||
this.viewportWidth = viewport ? viewport.offsetWidth : 0
|
||||
|
||||
if (!track || !track.children.length) {
|
||||
this.groupWidth = 0
|
||||
return
|
||||
}
|
||||
|
||||
this.groupWidth = track.children[0].offsetWidth
|
||||
},
|
||||
startAnimation: function () {
|
||||
this.stopAnimation()
|
||||
this.lastTime = performance.now()
|
||||
this.animationFrameId = requestAnimationFrame(this.animate)
|
||||
},
|
||||
stopAnimation: function () {
|
||||
if (this.animationFrameId) {
|
||||
cancelAnimationFrame(this.animationFrameId)
|
||||
this.animationFrameId = null
|
||||
}
|
||||
},
|
||||
animate: function (time) {
|
||||
var delta = time - this.lastTime
|
||||
|
||||
this.lastTime = time
|
||||
|
||||
if (!this.isPaused && this.groupWidth) {
|
||||
this.distance += this.speed * delta / 1000
|
||||
}
|
||||
|
||||
this.animationFrameId = requestAnimationFrame(this.animate)
|
||||
},
|
||||
handleMouseEnter: function () {
|
||||
if (this.pauseOnHover) {
|
||||
this.isPaused = true
|
||||
}
|
||||
},
|
||||
handleMouseLeave: function () {
|
||||
this.isPaused = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.infinite-image-scroller {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
padding: 14px 0;
|
||||
|
||||
&__track {
|
||||
display: flex;
|
||||
width: max-content;
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
&__group {
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
gap: var(--scroller-gap);
|
||||
padding-right: var(--scroller-gap);
|
||||
}
|
||||
|
||||
&__item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: calc(var(--scroller-image-width) - 2px);
|
||||
height: calc(var(--scroller-image-height) - 2px);
|
||||
flex: 0 0 auto;
|
||||
box-shadow: 0 0 0 1px #e5e5e5, 0 2px 2px rgba(0, 0, 0, 0);
|
||||
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&__image {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
width: auto;
|
||||
height: auto;
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||