类似淘票票 选座功能(svg)

栏目: 后端 · 前端 · 发布时间: 7年前

内容简介:最近项目需要在移动端做一个可以选座订票的功能。上网搜了一下没找到一个现成的库可以解决需求,所以就自己写了一个粗糙的版本。详细效果可以去demo那体验一下座位分布图的SVG是UI画好后导出来,并且通过后端接口返回整个SVG标签以及里面的内容。 前端只要发请求获得SVG并且插入就好了。插入后需要将已订购的座位置黑,无法选择。

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

需求

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

技术栈

效果图

类似淘票票 选座功能(svg)
类似淘票票 选座功能(svg)

详细效果可以去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 / 4
    transform.maxX = transform.translateX + svgBox.clientWidth / 4
    transform.minY = transform.translateY - svgBox.clientHeight / 2.5
    transform.maxY = transform.translateY + svgBox.clientHeight / 2.5
    svgTarget.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 } = transform
        scale *= e.scale
        scale = scale >= maxScale ? maxScale : scale
        scale = scale <= minScale ? minScale : scale
        transform.scale = scale
        svgBox.style.transform = `scale(${scale})`
      })
复制代码

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

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

拖动事件

function checkXY(x, y) {
    let { minX, minY, maxX, maxY } = transform
    x = x > maxX ? maxX : x
    x = x < minX ? minX : x
    y = y > maxY ? maxY : y
    y = y < minY ? minY : y
    return {
        x,
        y
    }   
}

svgHam.on('panstart panmove', (e) => {
    let { scale, translateX, translateY, svgScale } = transform
    let y = translateY + e.deltaY / scale
    let x = translateX + e.deltaX / scale
    let validXY = checkXY(x, y)
    svgTarget.style.transform = `translate(${validXY.x}px, ${validXY.y}px) scale(${svgScale})`
})

svgHam.on('panend', (e) => {
    let { scale, translateX, translateY} = transform
    let y = translateY + e.deltaY / scale
    let x = translateX + e.deltaX / scale
    let validXY = checkXY(x, y)
    transform.translateY = validXY.y
    transform.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 false
  e.target.style.fill = e.target.style.fill === 'red' ? '#ccc' : 'red' // 选中的座位变成红色
  // do something...
}
复制代码

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

计算统计

计算统计

Geof H.Givens、Jennifer A.Hoeting / 王兆军、刘民千、邹长亮、杨建峰 / 人民邮电出版社 / 2009-09-01 / 59.00元

随着计算机的快速发展, 数理统计中许多涉及大计算量的有效方法也得到了广泛应用与迅猛发展, 可以说, 计算统计已是统计中一个很重要的研究方向. 本书既包含一些经典的统计计算方法, 如求解非线性方程组的牛顿方法、传统的随机模拟方法等, 又全面地介绍了近些年来发展起来的某些新方法, 如模拟退火算法、基因算法、EM算法、MCMC方法、Bootstrap方法等, 并通过某些实例, 对这些方法的应用进行......一起来看看 《计算统计》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具