最近项目需要在移动端做一个可以选座订票的功能。上网搜了一下没找到一个现成的库可以解决需求,所以就自己写了一个粗糙的版本。

需求

  • 前端展示座位分布
  • 可拖动 放大缩小 点击选座

技术栈

  • svg
  • hammerjs

效果图

详细效果可以去demo那体验一下,建议用手机端体验。

svg

座位分布图的SVG是UI画好后导出来,并且通过后端接口返回整个SVG标签以及里面的内容。 前端只要发请求获得SVG并且插入就好了。插入后需要将已订购的座位置黑,无法选择。

hammerjs

hammerjs是一个手势库,提供了tap, doubletap, press, pan, swipe, pinch以及 rotate等多种手势事件,同时也提供丰富的自定义配置可以让你完成产品各(nao)种(dong)各(da)样(kai)的需求。

用法

let hammertime = new Hammer(myElement, myOptions);
hammertime.on('pan', function(ev) {console.log(ev)
})
复制代码

html 结构

箱子svg-box用以捏放(缩放)

svg用以偏移

<div class="ticket-map"><div class=svg-box><svg>.....</svg></div>
</div>
复制代码

初始化

设置一个变量用以记录手势操作后的属性变化

// 记录位移变量
let transform = {svgScale: 0.5, // svg 默认缩放scale: 1, // svg-box 缩放maxScale: 7, // svg-box 最大缩放minScale: 1,  // svg-box 最小缩放translateX: 0, // svg X轴偏移translateY: 0, // svg Y轴偏移minX: 0, // svg 最小X轴偏移maxX: 0, // svg 最大X轴偏移minY: 0, // svg 最小Y轴偏移maxY: 0  // svg 最大Y轴偏移
}
复制代码

因为UI提供的SVG是1000*715 略大,为了适应屏幕 作了svgScale: 0.5的缩放。

获取到SVG后需要进行居中 并且 计算出拖动边界(minX/Y maxX/Y)

    let svgTarget = document.querySelector('svg')let svgBox = document.querySelector('.svg-box')transform.translateX = Math.round((svgBox.clientWidth - svgTarget.clientWidth) / 2) // 垂直居中时的X偏移transform.translateY = Math.round((svgBox.clientHeight - svgTarget.clientHeight) / 2) // 垂直居中时的Y偏移transform.minX = transform.translateX - svgBox.clientWidth / 4transform.maxX = transform.translateX + svgBox.clientWidth / 4transform.minY = transform.translateY - svgBox.clientHeight / 2.5transform.maxY = transform.translateY + svgBox.clientHeight / 2.5svgTarget.style.transform = `translate(${transform.translateX}px, ${transform.translateY}px) scale(${transform.svgScale})`复制代码

以svg-box的width的4分之一,以及height的2.5分之一作为svg的X Y轴偏移量的极限,以免svg被拖动出屏幕之外。可以根据实际SVG调整分数。

手势配置

  //  初始化 hammer对象var svgHam = new Hammer(svgBox)svgHam.get('pinch').set({ enable: true })  // 返回pinch识别器 设置 可捏放 (放大缩小手势) 默认不监听svgHam.get('pan').set({ direction: Hammer.DIRECTION_ALL }) // 返回pan识别器 设置拖动方向为 所有方向
复制代码

监听svg-box,以免svg移动后手指点击不到触发不了事件

捏放事件

svgHam.on('pinchstart pinchmove', (e) => {let { scale, maxScale, minScale } = transformscale *= e.scalescale = scale >= maxScale ? maxScale : scalescale = scale <= minScale ? minScale : scaletransform.scale = scalesvgBox.style.transform = `scale(${scale})`})
复制代码

设置maxScale,minScale以免无限大或者无限小

· 注意这里缩放的是box而不是svg本身,否则拖动后再缩放就会发现整个SVG都跑偏了

拖动事件

function checkXY(x, y) {let { minX, minY, maxX, maxY } = transformx = x > maxX ? maxX : xx = x < minX ? minX : xy = y > maxY ? maxY : yy = y < minY ? minY : yreturn {x,y}
}svgHam.on('panstart panmove', (e) => {let { scale, translateX, translateY, svgScale } = transformlet y = translateY + e.deltaY / scalelet x = translateX + e.deltaX / scalelet validXY = checkXY(x, y)svgTarget.style.transform = `translate(${validXY.x}px, ${validXY.y}px) scale(${svgScale})`
})svgHam.on('panend', (e) => {let { scale, translateX, translateY} = transformlet y = translateY + e.deltaY / scalelet x = translateX + e.deltaX / scalelet validXY = checkXY(x, y)transform.translateY = validXY.ytransform.translateX = validXY.x
})
复制代码

偏移结束后更新偏移值,因为hammer提供的event事件的偏差值deltaY/deltaX是你手指点击初始位置以及移动后的差值。

偏移量 / scale 可以有效的控制放大后的拖动速度,否则放大后一拖动,整个SVG就跑走了。

选座

做好了上述效果,选座就简单了 直接一个点击事件就好了

document.querySelector('.svg-box').addEventListener('click', selectSeat)
// svg 点击事件 选座
function selectSeat (e) {if (e.target.tagName !== 'circle') return falsee.target.style.fill = e.target.style.fill === 'red' ? '#ccc' : 'red' // 选中的座位变成红色// do something...
}
复制代码

完整代码


写在最后

不是十分完美,不过也满足现在的需求,希望能给大家带来一点启发。不足的地方,也望各位大神指点迷津。

类似淘票票 选座功能(svg)相关推荐

  1. andriod 打造炫酷的电影票在线选座控件,1比1还原淘宝电影在线选座功能

    本篇文章已经授权微信公共账号 guolin_blog(郭霖)独家发布 不知道大家有没有跟我一样的感觉,看了那么多的介绍自定义控件原理.事件分发机制的书籍,文章,教程,依然还是不能随心所欲的自定义控件. ...

  2. 为12306点赞!高铁动车买票正式上线选座功能

    今天,12306在官网悄然放出一则公告, 宣布正式上线选座功能和接续换乘功能. 选座方面,目前12306支持C.D.G字头的动车组列车选座, 此功能仅提供相邻座位关系选择,如果剩余车票不能满足需求,系 ...

  3. 选座php,ticketbooking 电影院在线售票系统,可以 选座功能和 订票 ,分为前台管理和后 WEB(ASP,PHP,...) 246万源代码下载- www.pudn.com...

    文件名称: ticketbooking下载  收藏√  [ 5  4  3  2  1 ] 开发工具: ASP 文件大小: 783 KB 上传时间: 2015-04-17 下载次数: 4 提 供 者: ...

  4. Axure电影购票服务产品需求文档+Axure体育球赛购票服务产品需求文档+Axure演唱会购票服务原型+在线购票系统+在线买票+在线选座+移动端票务系统+Axure电影购票服务prd文档

    Axure原型作品介绍:Axure电影购票服务产品需求文档+Axure体育球赛购票服务产品需求文档+Axure演唱会购票服务原型+在线购票系统+在线买票+在线选座+移动端票务系统+Axure电影购票服 ...

  5. 火车票能不能选座_12306选座功能上线 选座位的方法是什么?

    12306选座功能上线 据@上铁资讯消息,2017年春运火车票开售在即,12306铁路官网售票再次优化.12月1日起,铁路客票系统启用部分新功能,期待已久的网上购票"选座功能"终于 ...

  6. java电影票选座_Android自定义view实现电影票在线选座功能

    先看看电影票在线选座功能实现的效果图: 界面比较粗糙,主要看原理. 这个界面主要包括以下几部分 1.座位 2.左边的排数 3.左上方的缩略图 4.缩略图中的红色区域 5.手指移动时跟随移动 6.两个手 ...

  7. 视频教程-react电影院在线选座功能-ReactJS

    react电影院在线选座功能 北京八维研修学院技术工程师,5年大型项目实战开发经验,3年授课经验. 孟宪杰 ¥29.00 立即订阅 扫码下载「CSDN程序员学院APP」,1000+技术好课免费看 AP ...

  8. 教你敲代码实现在线电影票选座功能

    网上购票如此的方便,那么我们能用HTML5+JavaScript实现一款在线电影票的选票功能吗? 答案是肯定的,今天我们就来借助jQuery的jQuery-Seat-Charts插件来实现在线电影票选 ...

  9. Vue 实现移动端在线选座功能(支持miniMap,支持缩放)

    Vue 实现在线选座功能(支持miniMap,支持缩放) 前言 一.功能介绍 二.选座页面效果 三.实现原理 布局设计方面 交互实现方面 四.在线例子 总结 前言 前段时间写了一个在线选座功能,现在分 ...

  10. php 影院选座js代码,在react中用canvas做一个电影院选座功能

    又到了每日分享了.这次分享的是:在react中用canvas做一个电影院选座功能. 前言:项目采用create-react-app脚手架,就是做了一个效果所以只有一个页面但是也用了react-rout ...

最新文章

  1. Dockerfile springboot项目拿走即用,将yml配置文件从外部挂入容器
  2. 201621123037 《Java程序设计》第10周学习总结
  3. 容器生态系统 (续) - 每天5分钟玩转容器技术(3)
  4. 【bzoj2324】[ZJOI2011]营救皮卡丘 最短路-Floyd+有上下界费用流
  5. 生信多组学整合工具的比较研究
  6. HDU 6030 Happy Necklace
  7. 多个for语句嵌套执行顺序_阿里真实面试题解析之实现多个线程顺序执行的几种方式...
  8. 单片机c语言 oxfe,AVR单片机入门及C语言高效设计实践(五)
  9. as3 php,[AS3]as3.0与PHP程序通信源代码示例
  10. 真香无疑了!新iPhone抢断货,国内最受欢迎的颜色是它
  11. Windows Embedded Standard 7 帮零售业快速抢占市场
  12. 面向云数据库,超低延迟文件系统PolarFS诞生了 1
  13. (十) 一起学 Unix 环境高级编程 (APUE) 之 线程控制
  14. 12、箱形图和小提琴图的绘制
  15. 车牌号识别 OpenCV
  16. 群晖DS218+部署kafka
  17. 又出新玩法?微软公式编辑器系列漏洞新利用方式
  18. 自考 02333 软件工程 思维导图 结构化方法
  19. iOS之悬浮视图:按钮/图片/轮播图/gif图/视频/音频/自定义view
  20. val什么意思vb中的属性值_VB语言中的val()函数是什么意思?如何使用?

热门文章

  1. python 流水作业调度,流水作业调度完整代码
  2. ios Symbol(s) not found for architecture arm64
  3. 修炼系列(八),你真的会写注释吗
  4. 音视频编解码流程与如何使用 FFMPEG 命令进行音视频处理
  5. 网络通信详解-深入浅出
  6. ECCV 2022开奖!清华、浙大校友斩获最佳论文奖
  7. 当地特色旅游系统 计算机毕业设计 微信小程序开发
  8. mac idea Tomcat 内网映射解决方案
  9. Wallpaper Engine壁纸提取
  10. LTE连接态读取系统消息SIB24疑问