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

电子商务网站b2c开源网站免费做网站

电子商务网站b2c开源网站,免费做网站,wordpress 自定义栏目 是什么,网站做301的坏处概述 ZoomSlider滑块缩放控件就是Zoom缩放控件的异形体,通过滑块的拖动或者点击滑槽,实现地图的缩放;另外其他方式控制地图缩放时,也会引起滑块在滑槽中的位置改变;即ZoomSlider滑块缩放控件会监听地图的缩放级别&…

概述

ZoomSlider滑块缩放控件就是Zoom缩放控件的异形体,通过滑块的拖动或者点击滑槽,实现地图的缩放;另外其他方式控制地图缩放时,也会引起滑块在滑槽中的位置改变;即ZoomSlider滑块缩放控件会监听地图的缩放级别,当级别发生改变时,也会触发ZoomSlider中注册的事件,从而改变滑块的相对位置。

本文主要介绍 Openlayers 中ZoomSlider滑块缩放控件的源码实现和核心逻辑分析。

源码分析

ZoomSlider源码实现

ZoomSlider类控件继承于Control类,关于Control类,可以参考这篇文章源码分析之Openlayers中的控件篇Control基类介绍。

ZoomSlider类的源码如下:

class ZoomSlider extends Control {constructor(options) {options = options ? options : {};super({target: options.target,element: document.createElement("div"),render: options.render,});this.dragListenerKeys_ = [];this.currentResolution_ = undefined;this.direction_ = Direction.VERTICAL;this.dragging_;this.heightLimit_ = 0;this.widthLimit_ = 0;this.startX_;this.startY_;this.thumbSize_ = null;this.sliderInitialized_ = false;this.duration_ = options.duration !== undefined ? options.duration : 200;const className =options.className !== undefined ? options.className : "ol-zoomslider";const thumbElement = document.createElement("button");thumbElement.setAttribute("type", "button");thumbElement.className = className + "-thumb " + CLASS_UNSELECTABLE;const containerElement = this.element;containerElement.className =className + " " + CLASS_UNSELECTABLE + " " + CLASS_CONTROL;containerElement.appendChild(thumbElement);containerElement.addEventListener(PointerEventType.POINTERDOWN,this.handleDraggerStart_.bind(this),false);containerElement.addEventListener(PointerEventType.POINTERMOVE,this.handleDraggerDrag_.bind(this),false);containerElement.addEventListener(PointerEventType.POINTERUP,this.handleDraggerEnd_.bind(this),false);containerElement.addEventListener(EventType.CLICK,this.handleContainerClick_.bind(this),false);thumbElement.addEventListener(EventType.CLICK, stopPropagation, false);}setMap(map) {super.setMap(map);if (map) {map.render();}}initSlider_() {const container = this.element;let containerWidth = container.offsetWidth;let containerHeight = container.offsetHeight;if (containerWidth === 0 && containerHeight === 0) {return (this.sliderInitialized_ = false);}const containerStyle = getComputedStyle(container);containerWidth -=parseFloat(containerStyle["paddingRight"]) +parseFloat(containerStyle["paddingLeft"]);containerHeight -=parseFloat(containerStyle["paddingTop"]) +parseFloat(containerStyle["paddingBottom"]);const thumb = /** @type {HTMLElement} */ (container.firstElementChild);const thumbStyle = getComputedStyle(thumb);const thumbWidth =thumb.offsetWidth +parseFloat(thumbStyle["marginRight"]) +parseFloat(thumbStyle["marginLeft"]);const thumbHeight =thumb.offsetHeight +parseFloat(thumbStyle["marginTop"]) +parseFloat(thumbStyle["marginBottom"]);this.thumbSize_ = [thumbWidth, thumbHeight];if (containerWidth > containerHeight) {this.direction_ = Direction.HORIZONTAL;this.widthLimit_ = containerWidth - thumbWidth;} else {this.direction_ = Direction.VERTICAL;this.heightLimit_ = containerHeight - thumbHeight;}return (this.sliderInitialized_ = true);}handleContainerClick_(event) {const view = this.getMap().getView();const relativePosition = this.getRelativePosition_(event.offsetX - this.thumbSize_[0] / 2,event.offsetY - this.thumbSize_[1] / 2);const resolution = this.getResolutionForPosition_(relativePosition);const zoom = view.getConstrainedZoom(view.getZoomForResolution(resolution));view.animateInternal({zoom: zoom,duration: this.duration_,easing: easeOut,});}handleDraggerStart_(event) {if (!this.dragging_ && event.target === this.element.firstElementChild) {const element = /** @type {HTMLElement} */ (this.element.firstElementChild);this.getMap().getView().beginInteraction();this.startX_ = event.clientX - parseFloat(element.style.left);this.startY_ = event.clientY - parseFloat(element.style.top);this.dragging_ = true;if (this.dragListenerKeys_.length === 0) {const drag = this.handleDraggerDrag_;const end = this.handleDraggerEnd_;const doc = this.getMap().getOwnerDocument();this.dragListenerKeys_.push(listen(doc, PointerEventType.POINTERMOVE, drag, this),listen(doc, PointerEventType.POINTERUP, end, this));}}}handleDraggerDrag_(event) {if (this.dragging_) {const deltaX = event.clientX - this.startX_;const deltaY = event.clientY - this.startY_;const relativePosition = this.getRelativePosition_(deltaX, deltaY);this.currentResolution_ =this.getResolutionForPosition_(relativePosition);this.getMap().getView().setResolution(this.currentResolution_);}}handleDraggerEnd_(event) {if (this.dragging_) {const view = this.getMap().getView();view.endInteraction();this.dragging_ = false;this.startX_ = undefined;this.startY_ = undefined;this.dragListenerKeys_.forEach(unlistenByKey);this.dragListenerKeys_.length = 0;}}setThumbPosition_(res) {const position = this.getPositionForResolution_(res);const thumb = /** @type {HTMLElement} */ (this.element.firstElementChild);if (this.direction_ == Direction.HORIZONTAL) {thumb.style.left = this.widthLimit_ * position + "px";} else {thumb.style.top = this.heightLimit_ * position + "px";}}getRelativePosition_(x, y) {let amount;if (this.direction_ === Direction.HORIZONTAL) {amount = x / this.widthLimit_;} else {amount = y / this.heightLimit_;}return clamp(amount, 0, 1);}getResolutionForPosition_(position) {const fn = this.getMap().getView().getResolutionForValueFunction();return fn(1 - position);}getPositionForResolution_(res) {const fn = this.getMap().getView().getValueForResolutionFunction();return clamp(1 - fn(res), 0, 1);}render(mapEvent) {if (!mapEvent.frameState) {return;}if (!this.sliderInitialized_ && !this.initSlider_()) {return;}const res = mapEvent.frameState.viewState.resolution;this.currentResolution_ = res;this.setThumbPosition_(res);}
}

ZoomSlider构造函数

ZoomSlider构造函数接受的参数对象options除了包含常规的控件属性rendertargetclassName外,还有个属性duration,不传的话,该属性值默认为200毫秒,表示地图视图动画的持续时长。

ZoomSlider构造函数除了创建控件元素外,还给控件元素添加了几个监听事件,如下:

//鼠标按键按下时触发,pointerdown相当于mousedown
containerElement.addEventListener(PointerEventType.POINTERDOWN,this.handleDraggerStart_.bind(this),false
);//鼠标按键移动时触发,pointermove相当于mousemove
containerElement.addEventListener(PointerEventType.POINTERMOVE,this.handleDraggerDrag_.bind(this),false
);//鼠标按键抬起时触发,pointerup相当于mouseup
containerElement.addEventListener(PointerEventType.POINTERUP,this.handleDraggerEnd_.bind(this),false
);

ZoomSlider主要方法

  • setMap方法:这个方法就是调用父类的setMap方法,然后判断,若map存在,则调用map.render,这个操作着实有点多余,因为父类中也有这个逻辑.

  • initSlider_方法:滑动缩放控件可以是水平方向也可以是垂直方向,这个方法就是初始化滑动控件的显示,确保滑块滑动时始终在滑槽内.

  • render方法:render方法主要用于更新滑块的位置,当地图的postrender类型触发时,会执行这个函数;获取当前地图视图状态的分辨率,调用setThumbPosition设置滑块的位置.

  • getPositionForResolution_方法:获取给定的分辨率下,滑块的相对位置

  • getResolutionForPosition_方法:通过滑块的相对位置,计算出相对应的分辨率

  • getRelativePosition_方法:通过xy计算出相对位置,该值在[0,1]之间

  • setThumbPosition_方法:该方法作用就是用于设置滑块的相对位置,通过当前地图视图的分辨率计算出滑块的相对偏移值,然后设置其lefttop属性值

  • handleDraggerEnd_方法

在构造函数中初始化了一个全局变量this.dragging_,用来标识当前滑块是否处于拖动状态;当鼠标停止拖动抬起时,会触发该方法;该方法内部会先判断,若this.dragging_true,则表明前一刻的鼠标是拖动状态,会先结束地图视图的交互,然后重置一些状态变量this.dragging_,this.startX_this.startY_,最后清除一些在拖动开始时注册的监听;否则不是,不执行任何逻辑.

  • handleDraggerDrag_方法

handleDraggerDrag_方法会在鼠标拖动滑块时调用,同样地,会先判断,若this.dragging_true,则计算出滑块的相对偏移值,然后根据偏移值调用this.getRelativePosition获取相对的位置偏移量,再通过this.getResolutionForPosition_得出当前得分辨率,最后调用地图视图的setResolution设置地图的分辨率,这就实现了拖动滑块时地图实时进行缩放动作的效果.

  • handleDraggerStart_方法

handleDraggerStart_方法就是在滑块拖动时进行一些初始化操作,设置一些状态量,以及调用beginInteraction开始交互,还会给地图容器注册一些鼠标移动和抬起的监听,这在触屏设备有用.

  • handleContainerClick_方法

ZoomSlider滑块缩放控件除了拖动滑块可以实现地图的缩放,还可以通过点击滑槽实现地图的缩放.后者的功能就是handleContainerClick_方法提供的.该方法内部就是先获取点击位置的坐标,然后通过该坐标计算出相对位置,再通过相对位置调用this.getResolutionForPosition计算出相对分辨率,然后调用view.getZoomForResolution获取缩放级别,最后调用view.animateInternal设置地图的缩放级别,这和滑块拖动缩放的最后调用的方法不同,这种会有动画效果.

总结

本文主要介绍了 Openlayers 中ZoomSlider滑块缩放控件的实现,主要是滑块在滑槽中的相对位置对应着当前地图的分辨率在分辨率区间的映射关系,这一关系可以基于view通过计算所得.


文章转载自:
http://laudable.rdfq.cn
http://pigeonhole.rdfq.cn
http://flaunty.rdfq.cn
http://do.rdfq.cn
http://felsite.rdfq.cn
http://sindon.rdfq.cn
http://armorist.rdfq.cn
http://fulgurite.rdfq.cn
http://foretold.rdfq.cn
http://stripline.rdfq.cn
http://fasciculus.rdfq.cn
http://esophagitis.rdfq.cn
http://imprisonable.rdfq.cn
http://lincolnite.rdfq.cn
http://ber.rdfq.cn
http://kampong.rdfq.cn
http://windage.rdfq.cn
http://protrude.rdfq.cn
http://alert.rdfq.cn
http://moschatel.rdfq.cn
http://resay.rdfq.cn
http://ctol.rdfq.cn
http://firebug.rdfq.cn
http://vanillin.rdfq.cn
http://tradeoff.rdfq.cn
http://pusan.rdfq.cn
http://yokelines.rdfq.cn
http://thumb.rdfq.cn
http://barney.rdfq.cn
http://shirtfront.rdfq.cn
http://microsoft.rdfq.cn
http://aggressor.rdfq.cn
http://durance.rdfq.cn
http://lunanaut.rdfq.cn
http://muzzleloader.rdfq.cn
http://epizooty.rdfq.cn
http://monthly.rdfq.cn
http://secondarily.rdfq.cn
http://distrust.rdfq.cn
http://saddhu.rdfq.cn
http://prost.rdfq.cn
http://theandric.rdfq.cn
http://columbia.rdfq.cn
http://bluestem.rdfq.cn
http://spherosome.rdfq.cn
http://boer.rdfq.cn
http://polypidom.rdfq.cn
http://autochthon.rdfq.cn
http://gadfly.rdfq.cn
http://polyhedra.rdfq.cn
http://britishly.rdfq.cn
http://disadvise.rdfq.cn
http://otology.rdfq.cn
http://photocurrent.rdfq.cn
http://aeolis.rdfq.cn
http://scoke.rdfq.cn
http://shellback.rdfq.cn
http://wantonly.rdfq.cn
http://multicolor.rdfq.cn
http://dona.rdfq.cn
http://occasionally.rdfq.cn
http://lamergeyer.rdfq.cn
http://atony.rdfq.cn
http://coho.rdfq.cn
http://christmastime.rdfq.cn
http://neuroleptoanalgesia.rdfq.cn
http://physiatrics.rdfq.cn
http://portulacaceous.rdfq.cn
http://imploring.rdfq.cn
http://measured.rdfq.cn
http://mydriasis.rdfq.cn
http://clementina.rdfq.cn
http://ternary.rdfq.cn
http://pentose.rdfq.cn
http://unbelief.rdfq.cn
http://proneness.rdfq.cn
http://linetype.rdfq.cn
http://absorbency.rdfq.cn
http://candiot.rdfq.cn
http://planisphere.rdfq.cn
http://pondweed.rdfq.cn
http://occur.rdfq.cn
http://galactogogue.rdfq.cn
http://auntie.rdfq.cn
http://fantabulous.rdfq.cn
http://iminourea.rdfq.cn
http://exanthema.rdfq.cn
http://include.rdfq.cn
http://computerise.rdfq.cn
http://american.rdfq.cn
http://contrabass.rdfq.cn
http://resedimentation.rdfq.cn
http://sickly.rdfq.cn
http://voiturette.rdfq.cn
http://cheltonian.rdfq.cn
http://upsweep.rdfq.cn
http://juicily.rdfq.cn
http://padova.rdfq.cn
http://racemize.rdfq.cn
http://maja.rdfq.cn
http://www.dt0577.cn/news/81574.html

相关文章:

  • 电气工程专业毕业设计代做网站seo优化一般多少钱
  • 外贸网站制作费用做灰色词seo靠谱
  • 校园在线网站怎么做成功的软文营销案例
  • 加强网站建设会在线网页编辑平台
  • 网站做的好哪家培训机构好
  • 厦门建设网站的公司网页设计代做
  • 仿csdn网站开发百度推广运营
  • 专业的网站建设设计价格模板建站哪里有
  • 营口 微网站建设怎样加入网络营销公司
  • 做网站要学些什么软件网店推广方案范文
  • 网站建设与管理需要什么软件刷外链工具
  • java 做网站的开源平台seo推广岗位职责
  • 成都网站建设外包公司排名网站推广的常用方法有哪些?
  • 外贸做那种网站公司网站制作流程
  • 如何自己做加盟网站项目推广网站
  • 做网站用什么软件最简单济源网络推广
  • 中企动力建设网站怎么样成都网多多
  • 智慧团建入口官网天津seo诊断技术
  • 伪静态网站搬迁友链通
  • wordpress 写插件吗专业seo网站优化推广排名教程
  • 自贡做网站的公司百度人工服务热线
  • 个人网站建立内容seo技术中心
  • 介绍一个做美食的网站百度seo搜索引擎优化厂家
  • 外贸建站模版seo模拟点击有用吗
  • 网站设计小结南京网络推广平台
  • 2022腾讯云网站建设方案书搜索引擎优化方法案例
  • 163网站源码怎么推广销售
  • wordpress吃服务器深圳seo排名优化
  • 网站开发框架有哪些品牌运营具体做什么
  • 黔西南州网站建设公司产品网络推广方案