当前位置: 首页 > article >正文

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

效果:

小程序实现导航漫游

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博客

相关文章:

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

效果&#xff1a; 小程序实现导航漫游 1、组件 miniprogram/components/tour/index.wxml <!--wxml--> <view class"guide" wx:if"{{showGuide}}"><view style"{{guideStyle}}" class"guide-box"><view class&quo…...

LLM论文笔记 25: Chain-of-Thought Reasoning without Prompting

Arxiv日期&#xff1a;2024.5.31机构&#xff1a;Google DeepMind 关键词 cot-decoding推理路径pretrain 核心结论 1. LLMs 不需要prompting就可以生成链式推理路径&#xff0c;prompting只是将这些能力显性化的一种手段 2. cot path 往往与更高的model confidence相关&…...

新型XCSSET恶意软件利用增强混淆技术攻击macOS用户

微软威胁情报团队发现了一种新型的XCSSET变种&#xff0c;这是一种复杂的模块化macOS恶意软件&#xff0c;能够感染Xcode项目&#xff0c;并在开发者构建这些项目时执行。 这是自2022年以来的首个已知XCSSET变种&#xff0c;采用了增强的混淆方法、更新的持久化机制以及新的感…...

Redis存数据就像存钱:RDB定期存款 vs AOF实时记账

Redis持久化 ◆ 核心概念1. ◆ 持久化全景图2. ◆ 生产环境黄金法则 ◆ RDB深度优化1. ◆ 生产配置精要2. ◆ 高级触发场景3. ◆ 故障应急方案 ◆ AOF深度解析1. ◆ 7.0版本革命性改进2. ◆ 同步策略深度测试3. ◆ 重写过程优化 ◆ 混合持久化实战1. ◆ 配置示例2. ◆ 数据恢复…...

[C++面试] 关于deque

一、入门 1、deque与vector的区别 deque的迭代器包含以下信息&#xff1a; 当前缓冲区指针&#xff08;current_buffer&#xff09;当前元素在缓冲区内的位置&#xff08;current&#xff09;中控器的位置&#xff08;map&#xff09; 每次移动迭代器时&#xff0c;需检查是…...

施磊老师c++(七)

STL组件 文章目录 STL组件1.整体学习内容2.vector容器3.deque和listdeque--双端队列容器list--链表容器 4.vector,deque,list对比主要内容面经问题 5.详解容器适配器--stack, queue, priority_queue容器适配器stack-栈queue-队列priority_queue-优先级队列总结 6.无序关联容器关…...

八股文——C 语言宏、`volatile`、`static`、动态内存管理、堆与栈的区别

文章目录 1. #&#xff08;字符串化操作符&#xff09;作用&#xff1a;示例&#xff1a; 2. ##&#xff08;符号连接操作符&#xff09;作用&#xff1a;示例1&#xff1a;动态生成变量名 3. volatile 关键字作用&#xff1a;示例&#xff1a; 4. static 关键字作用&#xff1…...

C++初阶——类和对象(三) 构造函数、析构函数

C初阶——类和对象&#xff08;三&#xff09; 上期内容&#xff0c;我们围绕类对象模型的大小计算&#xff0c;成员存储方式&#xff0c;this指针&#xff0c;以及C实现栈和C语言的比较&#xff0c;进一步认识了C的封装特性。本期内容&#xff0c;我们开始介绍类的默认成员函…...

【Function】使用托管身份调用Function App触发器,以增强安全性

推荐超级课程: 本地离线DeepSeek AI方案部署实战教程【完全版】Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战目录 1. 背景介绍2. 设置3. 使用Web应用调用Function App触发器(Node.js示例)4. 执行结果此方法允许您使用托管身份(Managed Identity)调…...

x012-MSP430F249智能步进电动百叶窗_proteus_光敏电阻_步进电机_仿真

https://www.dong-blog.fun/post/1997 46 、智能步进电动百叶窗 基本要求&#xff1a; 用一台步进电机控制百叶窗叶片的旋转&#xff08;正转/反转&#xff09; 用 LED 数码管显示旋转角度 设置按键&#xff1a; 手动/自动切换、手动正转和手动反转&#xff0c;停止/启动键 用一…...

牛客周赛85 题解 Java ABCDEFG

A小紫的均势博弈 判断输入的 n 是奇数还是偶数 import java.io.*; import java.math.*; import java.util.*;public class Main {static IoScanner sc new IoScanner();static final int mod(int) (1e97);static void solve() throws IOException {int nsc.nextInt();if(n%2…...

# RAG 框架 # 一文入门 全链路RAG系统构建与优化 —— 架构、策略与实践

本文全面阐述了RAG系统从数据收集、数据清洗&#xff08;包括领域专有名词处理&#xff09;、智能数据分块与QA对生成&#xff0c;到向量化、向量数据库选择与配置&#xff0c;再到检索方式及重排序&#xff0c;直至整合输出、监控反馈和安全保障的全流程。通过这一完整方案&am…...

【Golang】第二弹-----变量、基本数据类型、标识符

笔上得来终觉浅,绝知此事要躬行 &#x1f525; 个人主页&#xff1a;星云爱编程 &#x1f525; 所属专栏&#xff1a;Golang &#x1f337;追光的人&#xff0c;终会万丈光芒 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 一、变量 1.1基本介绍…...

c#:使用Modbus RTU协议

Modbus是一种广泛应用于工业自动化领域的通信协议&#xff0c;支持多种传输方式&#xff0c;如RTU、TCP等。其中&#xff0c;Modbus RTU是一种基于串行通信的协议&#xff0c;具有高效、可靠的特点。本文将详细介绍Modbus RTU协议的基本原理&#xff0c;并重点解析功能码0x03&a…...

linux系统CentOS 7版本搭建NFS共享存储

一、什么是NFS共享存储方式 NFS共享存储方式 是一种分布式文件系统协议&#xff0c;允许客户端通过网络访问远程服务器上的文件&#xff0c;就像访问本地文件一样。 二、 NFS的基本概念 &#xff08;1&#xff09;服务器端&#xff1a;提供共享存储的机器&#xff0c;负责导…...

Matlab 基于SVPWM的VF三电平逆变器异步电机速度控制

1、内容简介 略 Matlab 167-基于SVPWM的VF三电平逆变器异步电机速度控制 可以交流、咨询、答疑 2、内容说明 略 3、仿真分析 略 4、参考论文 略...

Android Dagger2 框架依赖图构建模块深度剖析(三)

一、引言 在 Android 开发中&#xff0c;依赖注入&#xff08;Dependency Injection&#xff0c;简称 DI&#xff09;是一种重要的设计模式&#xff0c;它能够降低代码的耦合度&#xff0c;提高代码的可测试性和可维护性。Dagger 2 作为一款高效的依赖注入框架&#xff0c;在编…...

(一)微服务初见之 Spring Cloud 介绍

微服务架构简介 从单体应用架构发展到SOA架构&#xff0c;再到微服务架构&#xff0c;应用架构经历了多年的不断演进。微服务架构不是凭空产生的&#xff0c;而是技术发展的必然结果&#xff0c;分布式云平台的应用环境使得微服务代替单体应用成为互联网大型系统的架构选择。目…...

python--面试题--基础题

join() 和 split() 函数 join() 函数可以将指定的字符添加到字符串中。 a[my, name, shi, wzngz] print(..join(a)) 输出结果&#xff1a;my.name.shi.wzngz split() 函数可以用指定的字符分割字符串 a"my name shi wzngz " print(a.split()) 输出结果&#xff…...

架构思维:软件建模与架构设计的关键要点

文章目录 1. 软件建模的核心概念2. 七种常用UML图及其应用场景类图时序图组件图部署图用例图状态图活动图 3. 软件设计文档的三阶段结构4. 架构设计的关键实践1. 用例图&#xff1a;核心功能模块2. 部署图&#xff1a;架构演进阶段3. 技术挑战与解决方案4. 关键架构图示例5. 架…...

【RNN神经网络】序列模型与RNN神经网络

前言 清库存。正式切入大模型后&#xff0c;打算把基础知识都梳理一遍&#xff0c;然后写了两篇就发现写不动了&#xff0c;后面就捡重要的记录。RNN知识仅此一篇记录&#xff0c;扫盲记录。 【自然语言处理】 &#xff08;Natural Language Processing&#xff0c;NLP&#xf…...

Python文件管理

目录 一、文本文件读写 1、相关函数 2、读写文件 3、使用readline读取一行 4、读写文件的异常处理 5、添加内容 二、文本文件的编码 1、常见的编码 2、Python程序的编码 3、指定编码 三、文件的路径 1、相对路径 2、绝对路径 3、路径的改变 四、文件夹操作 五、…...

vue3 前端路由权限控制与字典数据缓存实践(附Demo)

目录 前言1. 基本知识2. Demo3. 实战 前言 &#x1f91f; 找工作&#xff0c;来万码优才&#xff1a;&#x1f449; #小程序://万码优才/r6rqmzDaXpYkJZF 从实战中出发&#xff1a; 1. 基本知识 Vue3 和 Java 通信时如何进行字典数据管理 需要了解字典数据的结构。通常&#x…...

基于javaweb的SpringBoot精美物流管理系统设计与实现(源码+文档+部署讲解)

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论…...

【极光 Orbit·STC8x】05. GPIO库函数驱动LED流动

【极光 OrbitSTC8】05. GPIO库函数驱动LED流动 七律 逐光流转 八灯列阵若星河&#xff0c;状态为舟渡长波。 寄存器中藏玄机&#xff0c;Switch语句定山河。 循环往复如潮涌&#xff0c;步骤变量掌沉浮。 单片机前展锋芒&#xff0c;代码织就光之舞。 摘要 本文基于STC8H8K6…...

DeepSeek进阶应用(二):结合Kimi制作PPT(双AI协作教程)

&#x1f31f;引言&#xff1a; DeepSeek作为国产AI大模型&#xff0c;以强大的逻辑推理和结构化内容生成能力著称&#xff0c;擅长根据用户需求生成PPT大纲或Markdown文本&#xff1b;Kimi的PPT助手则能解析结构化内容并套用模板快速生成美观的PPT&#xff0c;两者结合实现“内…...

【Aioredis实战总结】Aioredis简介

一、Aioredis简介 Aioredis 是一个基于Python asyncio框架的异步Redis客户端库&#xff0c;专为高并发场景设计。它允许开发者在不阻塞主线程的情况下执行Redis操作&#xff0c;显著提升I/O密集型任务&#xff08;如Web应用的缓存、实时消息队列等&#xff09;的性能。自4.2.0…...

SpringBoot——Maven篇

Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的工具。它具有许多特性&#xff0c;其中一些重要的特性包括&#xff1a; 1. 自动配置&#xff1a;Spring Boot 提供了自动配置的机制&#xff0c;可以根据应用程序的依赖和环境自动配置应用程序的各种组件&#xff…...

Python中的多态与Java、C#、C++中的多态的区别有哪些?

Python中的多态与Java、C#、C等静态类型语言的主要区别体现在以下几个方面&#xff1a; 1. 类型系统与多态实现方式 Python&#xff08;动态类型&#xff0c;鸭子类型&#xff09; 多态基于对象的行为&#xff08;方法的存在性&#xff09;&#xff0c;而非继承或接口。只要对…...

卷积神经网络(知识点)

一、为了使特征图变小&#xff1a; 由两种方法&#xff1a;1.增大步长&#xff1a;卷积的时候不是一次一步&#xff0c;而是一次多步&#xff0c;类似一张图片&#xff0c;在原来的像素基础上&#xff0c;每隔一个取一个像素点。 其中S就是步长 注意&#xff1a;扩大步长不经…...