每个60秒让鼠标动一次

有时候想让屏幕不黑屏,可以写个小程序,让鼠标每1分钟动一次,一共执行3个小时:

import time
import pyautogui

for i in range(180): # 3 个小时
  pyautogui.moveTo(216, 316, 0.5)
  pyautogui.dragRel(0, -160, 0.5)
  time.sleep(60)
<think>我们需要实现一个全屏滚效果,每次滚鼠标滚轮时,页面会平滑地滚到下一个全屏区域。 我们可以使用Vue3的Composition API,结合鼠标滚轮事件和CSS滚行为来实现。 注意:这里我们使用`scroll-behavior: smooth`来实现平滑滚,同时监听鼠标滚轮事件来触发滚。 但是,由于一次一个屏幕,我们需要防止用户快速滚时连续触发多次滚事件,因此需要加入防抖或节流,并判断滚方向。 另一种更常见的做法是使用CSS的`scroll-snap-type`属性,这样可以更简单地实现每次滚一屏的效果,且不需要复杂的JS控制。 这里我们采用两种方案,但更推荐使用CSS方案,因为性能更好且更符合现代标准。 方案一(推荐):使用CSS scroll-snap 方案二:使用JS监听滚轮事件,然后通过window.scrollTo进行滚 由于问题要求滑鼠标一次一个屏幕,这里我们选择方案一,因为它更简洁,且能直接利用浏览器的原生滚行为。 但是,方案一在鼠标滚轮滚时,浏览器会平滑滚到下一个snap点,但并不是每次滚轮事件都正好滚一屏,而是根据滚轮幅度滚,然后自吸附到最近的snap点。所以严格来说,它并不是一次滚轮就固定滚一屏(如果用户滚的幅度小,可能不会触发到下一屏,而是停留在当前屏)。因此,如果需求是必须一次滚轮就滚一屏,那么我们需要使用JS方案。 考虑到需求是“一次一个屏幕”,这里我们采用JS方案,并加入节流和方向判断。 步骤: 1. 将页面分为多个全屏部分,每个部分高度为100vh。 2. 监听鼠标滚轮事件(注意兼容性)。 3. 当滚轮事件触发时,判断滚方向,然后滚到上一屏或下一屏。 4. 使用节流函数避免多次触发。 但是,注意:在JS方案中,我们需要阻止默认的滚行为,然后自己控制滚,否则会出现双重滚。 因此,我们采用以下步骤: 使用JS方案: - 设置容器样式,每个子元素高度100vh,并禁用页面默认滚条(html, body设置overflow:hidden) - 在组件挂载时添加滚轮事件监听,在销毁时移除 - 滚轮事件处理函数中: * 使用节流(例如300ms内只触发一次) * 判断滚轮方向(deltaY的正负) * 根据当前滚位置和窗口高度,计算下一屏的滚位置 * 使用window.scrollTo({ top: 目标位置, behavior: 'smooth' })进行滚 但是,由于我们禁用了默认滚,所以需要自己管理滚位置。 另一种做法是不禁用默认滚,而是通过事件阻止默认行为,但是这样可能会影响页面内的其他可滚区域。 考虑到简单性,我们这里使用全屏容器,并禁用body滚。 具体实现: 模板部分:每个section为一个全屏,设置高度100vh 样式部分:设置body和html的overflow为hidden,并设置每个section的样式 脚本部分:监听滚轮事件,并滚到下一个或上一个section 注意:我们使用Vue3的Composition API。 由于滚轮事件需要节流,我们可以使用lodash的throttle或者自己实现一个简单的节流。 这里为了减少依赖,自己实现一个节流函数。 代码实现如下:</think>以下是一个在 Vue3 中实现全屏滚效果的完整实现,每次鼠标会滚一整个屏幕高度: ```vue <template> <div class="scroll-container" ref="container"> <section v-for="(section, index) in sections" :key="index" :class="{ 'active': currentIndex === index }" :style="{ backgroundColor: section.color }"> <h1>{{ section.title }}</h1> <p>{{ section.content }}</p> <div class="scroll-indicator">↓ 继续滑 ↓</div> </section> </div> </template> <script setup> import { ref, onMounted, onUnmounted } from 'vue' // 页面内容数据 const sections = ref([ { title: "第一屏", content: "这是页面第一个全屏区块", color: "#f0f4ff" }, { title: "第二屏", content: "向下滑进入第二个区块", color: "#e0f7fa" }, { title: "第三屏", content: "第三个全屏内容区域", color: "#fff8e1" }, { title: "最后屏", content: "您已到达页面底部", color: "#f1f8e9" } ]) const container = ref(null) const currentIndex = ref(0) let isScrolling = false // 处理滚事件 const handleWheel = (e) => { if (isScrolling) return isScrolling = true const direction = e.deltaY > 0 ? 1 : -1 const newIndex = Math.min(Math.max(currentIndex.value + direction, 0), sections.value.length - 1) if (newIndex !== currentIndex.value) { currentIndex.value = newIndex container.value.scrollTo({ top: window.innerHeight * newIndex, behavior: 'smooth' }) } setTimeout(() => { isScrolling = false }, 800) } // 添加键盘支持 const handleKeyDown = (e) => { if (e.key === 'ArrowDown') { currentIndex.value = Math.min(currentIndex.value + 1, sections.value.length - 1) } else if (e.key === 'ArrowUp') { currentIndex.value = Math.max(currentIndex.value - 1, 0) } container.value.scrollTo({ top: window.innerHeight * currentIndex.value, behavior: 'smooth' }) } // 添加触摸滑支持 let touchStartY = 0 const handleTouchStart = (e) => { touchStartY = e.touches[0].clientY } const handleTouchEnd = (e) => { const touchEndY = e.changedTouches[0].clientY const diff = touchStartY - touchEndY if (Math.abs(diff) > 50) { const direction = diff > 0 ? 1 : -1 const newIndex = Math.min(Math.max(currentIndex.value + direction, 0), sections.value.length - 1) if (newIndex !== currentIndex.value) { currentIndex.value = newIndex container.value.scrollTo({ top: window.innerHeight * newIndex, behavior: 'smooth' }) } } } // 生命周期钩子 onMounted(() => { window.addEventListener('wheel', handleWheel, { passive: false }) window.addEventListener('keydown', handleKeyDown) container.value.addEventListener('touchstart', handleTouchStart) container.value.addEventListener('touchend', handleTouchEnd) }) onUnmounted(() => { window.removeEventListener('wheel', handleWheel) window.removeEventListener('keydown', handleKeyDown) container.value.removeEventListener('touchstart', handleTouchStart) container.value.removeEventListener('touchend', handleTouchEnd) }) </script> <style scoped> .scroll-container { height: 100vh; overflow-y: hidden; scroll-snap-type: y mandatory; scroll-behavior: smooth; } section { height: 100vh; display: flex; flex-direction: column; justify-content: center; align-items: center; scroll-snap-align: start; transition: background-color 0.5s ease; position: relative; } h1 { font-size: 3rem; margin-bottom: 1.5rem; } p { font-size: 1.5rem; max-width: 600px; text-align: center; } .scroll-indicator { position: absolute; bottom: 2rem; animation: bounce 2s infinite; opacity: 0.7; } @keyframes bounce { 0%, 20%, 50%, 80%, 100% {transform: translateY(0);} 40% {transform: translateY(-20px);} 60% {transform: translateY(-10px);} } /* 最后一个区块不显示指示器 */ section:last-child .scroll-indicator { display: none; } /* 响应式设计 */ @media (max-width: 768px) { h1 { font-size: 2rem; } p { font-size: 1.2rem; } } </style> ``` ### 功能说明: 1. **全屏滚效果**: - 每次鼠标一整个屏幕高度 - 使用 CSS `scroll-snap` 实现精准定位 - 平滑的滚画效果 2. **交互支持**: - 鼠标滚轮滑 - 键盘上下箭头控制 - 触摸屏滑支持 - 滚节流防止过度触发 3. **视觉元素**: - 滚指示器画 - 当前屏幕高亮状态 - 响应式设计适配移设备 - 平滑的背景色过渡效果 4. **技术实现**: - 使用 Vue3 Composition API - 响应式数据管理当前屏幕索引 - 添加了生命周期钩子管理事件监听 - 使用 CSS 画增强用户体验 此实现完全符合"一次一屏"的需求,并提供了额外的交互方式和视觉反馈。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值