这是我一直想尝试的小功能。我终于实现了这个大家熟知的谷歌地图中的功能:拖动被称为Pegman的小人来切换到街景视图。
点击并拖动这个小图标到地图上。
HTML (超文本标记语言)简单来说,我有以下几点:
- 一个
#map
作为容器(带有背景图像)。 - 一个位于右下角的
#pegman-container
元素。 - 用于表示可拖动角色的
#pegman
元素。
<div id="map">
<div id="pegman-container">
<div id="pegman"> </div>
</div>
</div>
全屏显示 退出全屏
CSS样式表定位所有东西其实很简单,如你从源代码中可以看到,但其中最关键的部分是 rotate
属性。这个属性会通过 JavaScript 动态更改:
#pegman {
/* 其他样式代码 */
rotate: var(--r);
}
全屏, 退出
当用户进行操作时,rotate
的值会发生变化,我们接下来将进一步讨论。
这里的一切都与用户交互有关,JavaScript 负责:
- 监听鼠标事件。
- 根据鼠标操作动态更新Pegman的位置和旋转。
- 添加平滑动画以提高用户体验。
const pegman = document.querySelector('#pegman');
let isDragging = false;
let initialX = 0;
let initialY = 0;
let inactivityTimeout;
let lastX = 0;
const timeout = 25;
const maxDegrees = 50;
// 事件监听
pegman.addEventListener('mousedown', onMouseDown);
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
全屏模式,退出全屏
我们来拆解每个功能吧
onMouseDown
这通过记录鼠标位置并设置 isDragging
标志来开始拖动。
const onMouseDown = (e) => {
isDragging = true;
initialX = e.clientX;
initialY = e.clientY;
};
全屏切换 退出全屏
鼠标移动
这控制Pegman在拖拽期间的移动和旋转,确保一切正常。
- 旋转保持在一定范围之内,以避免像超人飞行时的极端角度。
- 通过
--r
参数动态更新rotate
值。
const onMouseMove = (e) => {
if (!isDragging) return;
const dy = e.clientY - initialY;
const dx = e.clientX - initialX;
// 限制旋转角度
let rx = Math.max(-maxDegrees, Math.min(maxDegrees, dx - lastX));
pegman.setAttribute('style', `--r: ${rx}deg`);
// 动画Pegman的位置变化
pegman.animate({ translate: `${dx}px ${dy}px` }, {
持续时间: 100,
填充: 'forwards',
});
// 在一段时间不活动后重置旋转
clearTimeout(inactivityTimeout);
inactivityTimeout = setTimeout(() => {
lastX = dx;
设置Pegman的旋转角度为0度;
}, timeout);
};
全屏,退出全屏
鼠标释放
这在用户停止拖拽后,重置Pegman的状态信息。
- 旋转重置为0度。
- Pegman会平滑地回到原来的位置。
const onMouseUp = () => {
isDragging = false;
// 瑞典小孩重置旋转角度
pegman.setAttribute('style', `--r: 0`);
// 将佩格曼动画恢复到初始位置
pegman.animate({ translate: `0px 0px` }, {
duration: 500,
fill: 'forwards',
easing: 'ease',
});
// 清除残留状态
inactivityTimeout = setTimeout(() => {
lastX = 0;
}, timeout);
};
进入全屏模式 退出全屏模式
最后的思考这段内容展示了如何通过简单的动画和互动来重现一个标志性的用户体验。关键要点如下:
-
比如,简单的动画和互动可以重现标志性的用户体验。
- 使用 CSS 自定义属性(如
--r
)可以让样式保持动态并易于管理。 - 旋转范围限制确保用户交互具有精致自然的感觉。
- 设置超时时间和缓动效果可以为动画增加真实感。
随意 Fork 这个 CodePen 代码,改一改,然后告诉我你的想法!🚀🗺️
顺便说一句...
我正在使用谷歌的原版精灵,你可以在这里看到并进行实验。
你知道吗?✨ 我在谷歌地图上用的位置就是真正的圣诞老人村!
趣味事实: 圣诞老人在芬兰的名字叫 Joulupukki,他其实是来自芬兰的 🎅🏻🎄