|
|
@@ -0,0 +1,226 @@
|
|
|
+Component({
|
|
|
+ properties: {
|
|
|
+ list: {
|
|
|
+ type: Array,
|
|
|
+ value: []
|
|
|
+ },
|
|
|
+ // 是否展示指示器
|
|
|
+ showIndicators: {
|
|
|
+ type: Boolean,
|
|
|
+ value: true
|
|
|
+ },
|
|
|
+ // 左右边距(px)
|
|
|
+ paddingLR: {
|
|
|
+ type: Number,
|
|
|
+ value: 30
|
|
|
+ },
|
|
|
+ // 中间卡片高度(px)
|
|
|
+ centerHeight: {
|
|
|
+ type: Number,
|
|
|
+ value: 200
|
|
|
+ },
|
|
|
+ // 左右两侧卡片高度(px)
|
|
|
+ sideHeight: {
|
|
|
+ type: Number,
|
|
|
+ value: 130
|
|
|
+ },
|
|
|
+ duration: {
|
|
|
+ type: Number,
|
|
|
+ value: 300
|
|
|
+ },
|
|
|
+ // 当前项索引
|
|
|
+ current: {
|
|
|
+ type: Number,
|
|
|
+ value: 0
|
|
|
+ },
|
|
|
+ // 是否使用 navigator 进行跳转(仅当前项且有 url)
|
|
|
+ useNavigator: {
|
|
|
+ type: Boolean,
|
|
|
+ value: true
|
|
|
+ },
|
|
|
+ onlineIcon: {
|
|
|
+ type: String,
|
|
|
+ value: 'https://klmybwg.4dage.com/mini/wxImg/exhibition/online-kz.png'
|
|
|
+ },
|
|
|
+ // 是否自动轮播
|
|
|
+ autoplay: {
|
|
|
+ type: Boolean,
|
|
|
+ value: false
|
|
|
+ },
|
|
|
+ // 轮播间隔时间(毫秒)
|
|
|
+ interval: {
|
|
|
+ type: Number,
|
|
|
+ value: 3000
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ data: {
|
|
|
+ preloadedImages: {},
|
|
|
+ autoplayTimer: null, // 自动轮播定时器
|
|
|
+ isUserInteracting: false // 用户是否正在交互
|
|
|
+ },
|
|
|
+
|
|
|
+ observers: {
|
|
|
+ 'list': function(newList) {
|
|
|
+ if (newList && newList.length > 0) {
|
|
|
+ this.preloadImages(newList);
|
|
|
+ // 当列表数据更新时,重新启动自动轮播
|
|
|
+ this.restartAutoplay();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ 'autoplay, interval': function(autoplay, interval) {
|
|
|
+ // 当自动轮播设置改变时,重新启动
|
|
|
+ if (autoplay) {
|
|
|
+ this.startAutoplay();
|
|
|
+ } else {
|
|
|
+ this.stopAutoplay();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ lifetimes: {
|
|
|
+ attached() {
|
|
|
+ if (this.data.list && this.data.list.length > 0) {
|
|
|
+ this.preloadImages(this.data.list);
|
|
|
+ }
|
|
|
+ // 组件初始化时启动自动轮播
|
|
|
+ if (this.data.autoplay) {
|
|
|
+ this.startAutoplay();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ detached() {
|
|
|
+ // 组件销毁时清理定时器
|
|
|
+ this.stopAutoplay();
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ pageLifetimes: {
|
|
|
+ show() {
|
|
|
+ // 页面显示时重启自动轮播
|
|
|
+ if (this.data.autoplay && !this.data.isUserInteracting) {
|
|
|
+ this.startAutoplay();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ hide() {
|
|
|
+ // 页面隐藏时停止自动轮播
|
|
|
+ this.stopAutoplay();
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ methods: {
|
|
|
+ // 预加载图片
|
|
|
+ preloadImages(list) {
|
|
|
+ const preloadedImages = {};
|
|
|
+ list.forEach((item, index) => {
|
|
|
+ if (item.image && !this.data.preloadedImages[item.image]) {
|
|
|
+ // 创建图片对象进行预加载
|
|
|
+ const img = wx.createOffscreenCanvas().getContext('2d');
|
|
|
+ preloadedImages[item.image] = true;
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // 同时预加载在线观展图标
|
|
|
+ if (this.data.onlineIcon && !this.data.preloadedImages[this.data.onlineIcon]) {
|
|
|
+ const img = wx.createOffscreenCanvas().getContext('2d');
|
|
|
+ preloadedImages[this.data.onlineIcon] = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ this.setData({
|
|
|
+ preloadedImages: { ...this.data.preloadedImages, ...preloadedImages }
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ onSwiperChange(e) {
|
|
|
+ const index = e.detail.current;
|
|
|
+ this.setData({ current: index });
|
|
|
+ this.triggerEvent('change', { current: index });
|
|
|
+ // swiper滑动时暂停自动轮播一段时间
|
|
|
+ this.pauseAutoplayTemporarily();
|
|
|
+ },
|
|
|
+
|
|
|
+ // 左右图片可点击切换,不可跳转
|
|
|
+ onSlideTap(e) {
|
|
|
+ const index = e.currentTarget.dataset.index;
|
|
|
+ if (index === this.data.current) return; // 当前项点击保持
|
|
|
+ this.setData({ current: index });
|
|
|
+ this.triggerEvent('change', { current: index });
|
|
|
+ // 用户点击切换时暂停自动轮播一段时间
|
|
|
+ this.pauseAutoplayTemporarily();
|
|
|
+ },
|
|
|
+
|
|
|
+ // 当前项且无 url 的点击,向外抛事件处理
|
|
|
+ onCurrentTap(e) {
|
|
|
+ const index = e.currentTarget.dataset.index;
|
|
|
+ const item = this.data.list[index];
|
|
|
+ this.triggerEvent('exhibitiontap', { item, index });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 线上观展点击事件(有URL的情况)
|
|
|
+ onOnlineExhibitionTap(e) {
|
|
|
+ const index = e.currentTarget.dataset.index;
|
|
|
+ const item = this.data.list[index];
|
|
|
+ this.triggerEvent('onlineexhibitiontap', { item, index, url: item.url });
|
|
|
+ },
|
|
|
+
|
|
|
+
|
|
|
+ onDotTap(e) {
|
|
|
+ const index = e.currentTarget.dataset.index;
|
|
|
+ this.setData({ current: index });
|
|
|
+ this.triggerEvent('change', { current: index });
|
|
|
+ // 用户点击指示器时暂停自动轮播一段时间
|
|
|
+ this.pauseAutoplayTemporarily();
|
|
|
+ },
|
|
|
+
|
|
|
+ // 启动自动轮播
|
|
|
+ startAutoplay() {
|
|
|
+ if (!this.data.autoplay || this.data.list.length <= 1) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ this.stopAutoplay(); // 先清除可能存在的定时器
|
|
|
+
|
|
|
+ const timer = setInterval(() => {
|
|
|
+ if (!this.data.isUserInteracting) {
|
|
|
+ const nextIndex = (this.data.current + 1) % this.data.list.length;
|
|
|
+ this.setData({ current: nextIndex });
|
|
|
+ this.triggerEvent('change', { current: nextIndex });
|
|
|
+ }
|
|
|
+ }, this.data.interval);
|
|
|
+
|
|
|
+ this.setData({ autoplayTimer: timer });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 停止自动轮播
|
|
|
+ stopAutoplay() {
|
|
|
+ if (this.data.autoplayTimer) {
|
|
|
+ clearInterval(this.data.autoplayTimer);
|
|
|
+ this.setData({ autoplayTimer: null });
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 重启自动轮播
|
|
|
+ restartAutoplay() {
|
|
|
+ if (this.data.autoplay) {
|
|
|
+ this.stopAutoplay();
|
|
|
+ this.startAutoplay();
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 暂时暂停自动轮播(用户交互时)
|
|
|
+ pauseAutoplayTemporarily(duration = 3000) {
|
|
|
+ if (!this.data.autoplay) return;
|
|
|
+
|
|
|
+ this.setData({ isUserInteracting: true });
|
|
|
+ this.stopAutoplay();
|
|
|
+
|
|
|
+ setTimeout(() => {
|
|
|
+ this.setData({ isUserInteracting: false });
|
|
|
+ if (this.data.autoplay) {
|
|
|
+ this.startAutoplay();
|
|
|
+ }
|
|
|
+ }, duration);
|
|
|
+ }
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+
|