原生微信小程序实现导航漫游(Tour)

news/2025/3/16 8:56:04/

效果:

小程序实现导航漫游

1、组件

miniprogram/components/tour/index.wxml

<!--wxml-->
<view class="guide" wx:if="{{showGuide}}"><view style="{{guideStyle}}" class="guide-box"><view class="tips guide-step-tips" style="{{tipPosition}}"><view class="text">{{ guideList[index].tips }}</view><view class="step-indicator"><text class="step-text">{{index + 1}}/{{guideList.length}}</text></view><view class="tool-btn"><text bind:tap="skip">跳过</text><view class="btn-group"><view class="prev" bind:tap="prev" wx:if="{{index > 0}}">上一步</view><view class="next" bind:tap="next">{{index === guideList.length - 1 ? '完成' : '下一步'}}</view></view></view></view><view class="arrow" style="{{arrowTop}}"></view></view><!-- 遮罩层,防止点击 --><view class="v-model"></view>
</view>

miniprogram/components/tour/index.ts 

// components/xky-guideStep/xky-guideStep.jsimport { handleChangeTourType } from "@/utils/util";// 添加必要的接口定义
interface GuideItem {el: string;width: number;height: number;left: number;top: number;style?: string;
}interface Step {name: string;guideList: GuideItem[];
}interface DomInfo {width: number;height: number;left: number;top: number;[key: string]: any;
}Component({/*** 组件的属性列表*/properties: {step: {type: Object,value: {} as Step,},},/*** 组件的初始数据*/data: {stepName: "step", //该提示步骤的名称,用于不在重复展示guideList: [] as GuideItem[],index: 0, // 当前展示的索引showGuide: true, // 是否显示引导guideStyle: "", // 默认样式arrowTop: "", //步骤提示三角形的定位tipPosition: "", //步骤提示的定位systemInfo: null as WechatMiniprogram.SystemInfo | null, //屏幕宽度高度等信息tipWidth: 200, //步骤提示默认的宽度},/*** 组件的方法列表*/methods: {// 展示新手提示viewTips(data: DomInfo | null, scrollTop: number) {let {systemInfo,tipWidth,index,guideList,arrowTop,tipPosition,guideStyle,} = this.data;if (data && systemInfo) {// 如果dom宽度大于或者等于窗口宽度,需要重新调整dom展示宽度let newWidth = systemInfo.windowWidth - 20;if (data.width >= newWidth) {data.width = newWidth;}// 如果距离左边为0,自动增加一点左边距if (data.left == 0) {data.left = 10;}let domRW = systemInfo.windowWidth - data.left;let left = 0;// 如果dom距离右边没有tips的宽度大的话,就要让tips向左便宜if (domRW < tipWidth) {left = domRW - tipWidth - 30;}// const index = index;// 步骤条展示的高度需要加上屏幕滚动的高度data.top += scrollTop;// 根据实际情况需要滚动到展示区域wx.pageScrollTo({scrollTop: data.top > 20 ? data.top - 20 : 0,duration: 100,});let obj = Object.assign(guideList[index], data);// 设置三角形高度let arrArrowTop = data.height + 9;arrowTop = "top:" + arrArrowTop + "px;";// 设置提示框定位tipPosition = "top:" + (arrArrowTop + 5) + "px;left:" + left + "px;";// 重新设置guideList的值guideList.splice(index, 1, obj);guideStyle = this.getStyle();this.setData({arrowTop,tipPosition,guideList,guideStyle,});} else {index += 1;this.setData({index,});this.getDomInfo();}},// 获取步骤提示的主要样式getStyle() {const { guideList, index } = this.data;const { width, height, left, top, style } = guideList[index];let newStyle = "width:" + width + "px;";newStyle += "height:" + height + "px;";newStyle += "left:" + left + "px;";newStyle += "top:" + top + "px;";newStyle +="box-shadow: rgb(33 33 33 / 80%) 0px 0px 0px 0px, rgb(33 33 33 / 50%) 0px 0px 0px 5000px;";newStyle += style;return newStyle;},// 获取dom信息getDomInfo() {const { guideList, index } = this.data;const { el } = guideList[index];const query = wx.createSelectorQuery();setTimeout(() => {query.select(el).boundingClientRect();query.selectViewport().scrollOffset();query.exec( (res)=> {let data = res[0]; // #the-id节点的上边界坐标let scrollTop = res[1].scrollTop; // 显示区域的竖直滚动位置this.viewTips(data, scrollTop);});}, 10);},updateTourMap() {handleChangeTourType(this.data.stepName)},skip() {this.setData({showGuide: false,});this.updateTourMap()},// 添加上一步方法prev() {let { index } = this.data;if (index > 0) {index -= 1;this.setData({index});this.getDomInfo();}},// 下一步,修改显示文案next() {let { index, guideList } = this.data;if (index === guideList.length - 1) {this.setData({showGuide: false,});this.updateTourMap()} else {index += 1;this.setData({index,});this.getDomInfo();}},},lifetimes: {attached () {const { step } = this.properties;let { guideList, stepName } = this.data;guideList = step.guideList;stepName = step.name;this.setData({guideList,stepName,systemInfo: wx.getSystemInfoSync(),});const guide = wx.getStorageSync('tourMap');if (!guide || !guide[step.name]) {this.getDomInfo();} else {this.setData({showGuide: false,});}},detached () {// 在组件实例被从页面节点树移除时执行},},
});

miniprogram/components/tour/index.scss 

/* wxss */
.v-model {position: fixed;left: 0;top: 0;width: 100%;height: 100%;z-index: 1000;
}
.guide {z-index: 1001;
}
.guide-box {position: absolute;z-index: 10001;transition: all 0.2s;}
.guide-box::before {content: '';height: 100%;width: 100%;border: 1px dashed #fff;border-radius: 8rpx;position: absolute;top: -8rpx;left: -8rpx;padding: 7rpx;
}
.arrow {height: 20rpx;width: 20rpx;background: #1cbbb4;position: absolute;top: 144rpx;left: 45%;transform: rotate(45deg);
}
.tips {width: 400rpx;background: linear-gradient(180deg, #1cbbb4, #0081ff);box-shadow: 0px 2px 9px 0px rgba(0, 0, 0, 0.1);color: #fff;position: absolute;top: 152rpx;left: -50%;padding: 15rpx 20rpx;font-size: 28rpx;border-radius: 12rpx;
}
.tool-btn {display: flex;justify-content: space-between;align-items: center;padding-right: 0rpx;margin-top: 20rpx;
}/* 新增样式 */
.step-indicator {display: flex;justify-content: flex-end;margin-top: 10rpx;
}
.step-text {font-size: 24rpx;color: rgba(255, 255, 255, 0.8);
}
.btn-group {display: flex;align-items: center;
}
.prev {background: rgba(255, 255, 255, 0.2);height: 48rpx;width: 100rpx;text-align: center;border-radius: 8rpx;color: #fff;line-height: 48rpx;font-size: 24rpx;margin-right: 10rpx;
}
.next {background: #fff;height: 48rpx;width: 100rpx;text-align: center;border-radius: 8rpx;color: #666;line-height: 48rpx;font-size: 24rpx
}

miniprogram/components/tour/index.json 

{"component": true,"usingComponents": {}
}

miniprogram/utils/util.ts

/** 修改本地的Tour状态 */
export const handleChangeTourType = (tourName: string) => {const tourMap = wx.getStorageSync('tourMap') || {};tourMap[tourName] = true;wx.setStorageSync('tourMap', tourMap);
};

部分转载:小程序>微信小程序首次进入引导提示自定义组件-CSDN博客


http://www.ppmy.cn/news/1579529.html

相关文章

linux下的进程

linux下的进程 1、冯诺依曼体系结构2、操作系统2.1 概念2.2 设计OS的目的2.3 定位2.4 如何理解 "管理" 3、进程3.1 基本概念3.2 描述进程-PCB3.3 最早版本task-struct&#xff08;linux&#xff09;3.4 查看进程3.5 getppid&#xff08;副id&#xff09; 4 系统调用&…

Spring @Bean注解使用场景二

bean:最近在写一篇让Successfactors顾问都能搞明白的sso的逻辑的文章&#xff0c;所以一致在研究IAS的saml2.0的协议&#xff0c;希望用代码去解释SP、idp的一些概念&#xff0c;让顾问了解SSO与saml的关系&#xff0c;在github找代码的时候发现一些代码的调用关系很难理解&…

mac利用“自动操作”扩展添加 Mac 访达右键菜单项

用惯了 Windows 的资源管理器&#xff0c;换到 Mac 的访达&#xff0c;最不习惯的就是不能通过右键菜单创建文件。 虽然 Mac 的 App Store 中有几个可以增加访达右键菜单的工具&#xff0c;但是居然都要收费&#xff08;就这么一点点活都能卖钱&#xff0c;真是了不起&#xf…

【Python 数据结构 15.哈希表】

目录 一、哈希表的基本概念 1.哈希表的概念 2.键值对的概念 3.哈希函数的概念 4.哈希冲突的概念 5.常用的哈希函数 Ⅰ、直接定址法 Ⅱ、平方取中法 Ⅲ、折叠法 Ⅳ、除留余数法 Ⅴ、位与法 6.哈希冲突的解决方案 Ⅰ、开放定址法 Ⅱ、链地址法 7.哈希表的初始化 8.哈希表的元素插…

利用亚马逊云科技”多模态AI知识库“获取非结构化数据总结

在多个行业的AI应用场景里&#xff0c;许多应用程序需要与不同多模态的内容交互和分析。其中一些应用程序需要处理复杂的文档&#xff0c;例如保险理赔单和医疗账单。移动应用还需要分析用户生成的一些图片、视频内容。企业需要在包括文档、图像、音频和视频文件的数字资产之上…

1Panel 搭建DeepSeek-R1,开启AI自由新体验

引言&#xff1a;AI 浪潮下的探索 在当下&#xff0c;AI 的热潮可谓是席卷全球&#xff0c;大模型领域更是呈现出百花齐放的繁荣景象。从 ChatGPT 掀起的全民 AI 狂欢&#xff0c;到各类国产大模型的争相崛起&#xff0c;我们正亲身经历着 AI 技术带来的巨大变革 。越来越多的…

Pycharm实用技巧

一、Pycharm 参数注释 在 PyCharm 中&#xff0c;在方法下输入三引号&#xff08;"""&#xff09;就能自动生成参数注释&#xff1a;def input_combo_detail(self, scale, ptype_data, ptype_info, sku_info, unit_info, price, qty):""":param…

单片机农业大棚浇花系统

标题:单片机农业大棚浇花系统 内容:1.摘要 本文针对传统农业大棚浇花方式效率低、精准度差的问题&#xff0c;提出了一种基于单片机的农业大棚浇花系统。该系统以单片机为核心控制器&#xff0c;通过土壤湿度传感器实时采集土壤湿度数据&#xff0c;并将数据传输至单片机进行处…