123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 |
- /*
- * ********************************************************************************************************************
- *
- * iFHS7.
- * ;BBMBMBMc rZMBMBR BMB
- * MBEr:;PBM, 7MBMMEOBB: BBB RBW
- * XK: BO SB. :SZ MBM. c;; ir BBM :FFr :SSF: ;xBMB:r iuGXv. i:. iF2;
- * DBBM0r. :D S7 ;XMBMB GMBMu. MBM: BMB MBMBBBMBMS WMBMBMBBK MBMBMBM BMBRBMBW .MBMBMBMBB
- * :JMRMMD .. , 1MMRM1; ;MBMBBR: MBM ;MB: BMB: MBM. RMBr sBMH BM0 UMB, BMB. KMBv
- * ;. XOW B1; :uM: 1RE, i .2BMBs rMB. MBO MBO JMB; MBB MBM BBS 7MBMBOBM: MBW :BMc
- * OBRJ.SEE MRDOWOR, 3DE:7OBM . ;BMB RMR7BM BMB MBB. BMB ,BMR .BBZ MMB rMB, BMM rMB7
- * :FBRO0D0 RKXSXPR. JOKOOMPi BMBSSWBMB; BMBB: MBMB0ZMBMS .BMBOXRBMB MBMDE RBM2;SMBM; MBB xBM2
- * iZGE O0SHSPO. uGZ7. sBMBMBDL :BMO OZu:BMBK, rRBMB0; ,EBMB xBMBr:ER. RDU :OO;
- * ,BZ, 1D0 RPSFHXR. xWZ .SMr . .BBB
- * :0BMRDG RESSSKR. 2WOMBW; BMBMR
- * i0BM: SWKHKGO MBDv
- * .UB OOGDM. MK, Copyright (c) 2015-2018. 斯伯坦机器人世界
- * , XMW ..
- * r All rights reserved.
- *
- * ********************************************************************************************************************
- */
- import './SCanvas'
- import SPoint from './types/SPoint'
- import SMouseEvent from './SMouseEvent'
- const bindEvent = Symbol('bindEvent')
- const toSceneMotionEvent = Symbol('toSceneMotionEvent')
- /**
- * Graphy图形引擎视图类
- *
- * @author Andy
- */
- export default class SGraphyView {
- /**
- * 构造函数
- *
- * @param id Canvas对象ID
- */
- constructor(id, scene) {
- this.canvasView = document.getElementById(id)
- this.canvas = this.canvasView.getContext('2d')
- this[bindEvent](this.canvasView)
- this.scene = scene
- this.pos = new SPoint(10, 0)
- this.scale = 1
- this.minScale = 0.004
- this.maxScale = 0.5
- this._midKeyX = 0
- this._midKeyY = 0
- this.wheelZoom = 1.05
- window.requestAnimationFrame(this.onDraw.bind(this))
- } // Function constructor()
- /**
- * 绑定canvas事件
- *
- * @param canvas canvas对象
- * @private
- */
- [bindEvent](canvasView) {
- canvasView.onclick = this.onClick.bind(this)
- canvasView.ondblclick = this.onDbClick.bind(this)
- canvasView.onmousedown = this.onMouseDown.bind(this)
- canvasView.onmousemove = this.onMouseMove.bind(this)
- canvasView.onmouseup = this.onMouseUp.bind(this)
- canvasView.onmousewheel = this.onMouseWheel.bind(this)
- canvasView.onresize = this.onResize.bind(this)
- } // Function [bindEvent]()
- /**
- * 获取canvas的宽度
- */
- get width() {
- return this.canvasView.width
- }
- get height() {
- return this.canvasView.height
- }
- /**
- * 将场景中的xy坐标转换成视图坐标。
- *
- * @param x 场景中的横坐标
- * @param y 场景中的纵坐标
- *
- * @return SPoint
- */
- mapFromScene(x, y = null) {
- if (typeof(x) === 'object') { // 如果传入的是SPoint对象
- return new SPoint(x.x * this.scale + this.pos.x, x.y * this.scale + this.pos.y)
- }
- return new SPoint(x * this.scale + this.pos.x, y * this.scale + this.pos.y)
- } // Function mapFromScene()
- /**
- * 将item中的xy坐标转换成场景坐标。
- *
- * @param x item中的横坐标
- * @param y item中的纵坐标
- * @return SPoint
- */
- mapToScene(x, y = null) {
- if (typeof(x) === 'object') { // 如果传入的是SPoint对象
- return new SPoint((x.x - this.pos.x) / this.scale, (x.y - this.pos.y) / this.scale)
- }
- return new SPoint((x - this.pos.x) / this.scale, (y - this.pos.y) / this.scale)
- } // Function mapToScene()
- /**
- * 缩放视图时计算视图的位置与缩放比例
- *
- * @param zoom 缩放比例
- * @param x0 缩放计算的中心点X坐标
- * @param y0 缩放计算的中心点Y坐标
- */
- scaleByPoint(zoom, x0, y0) {
- let z = zoom
- /**
- * 缩放比例在最小比例和最大比例范围内
- */
- if (this.scale * zoom >= this.maxScale) { // 大于最大缩放比例
- z = this.maxScale / this.scale
- this.scale = this.maxScale
- } else if (this.scale * zoom <= this.minScale) { // 小于最小绽放比例
- z = this.minScale / this.scale
- this.scale = this.minScale
- } else {
- this.scale *= zoom
- }
- this.pos.x = x0 - (x0 - this.pos.x) * z
- this.pos.y = y0 - (y0 - this.pos.y) * z
- // EventBus.getDefault().post(SGraphyViewZoomEvent(this, scale))
- // EventBus.getDefault().post(SGraphyViewMoveEvent(this, pos.x, pos.y))
- // return
- } // Function scaleByPoint()
- // ===================================================================================================================
- // 事件
- onDraw() {
- this.canvas.save()
- this.canvas.clearRect(0, 0, this.canvasView.width, this.canvasView.height)
- this.canvas.restore()
- if (this.scene != null) {
- // 绘制背景
- this.canvas.save()
- this.scene.drawBackground(this.canvas)
- this.canvas.restore()
- // 绘制场景
- this.canvas.save()
- this.canvas.translate(this.pos.x, this.pos.y)
- this.canvas.scale(this.scale, this.scale)
- this.scene.drawScene(this.canvas)
- this.canvas.restore()
- // 绘制前景
- this.canvas.save()
- this.scene.drawForeground(this.canvas)
- this.canvas.restore()
- }
- window.requestAnimationFrame(this.onDraw.bind(this))
- } // Function onDraw()
- /**
- * 鼠标单击事件
- *
- * @param e 保存事件参数
- */
- onClick(e) {
- if (this.scene != null) {
- let se = this[toSceneMotionEvent](e)
- this.scene.onClick(se)
- }
- } // Function onClick()
- /**
- * 鼠标双击事件
- *
- * @param e 保存事件参数
- */
- onDbClick(e) {
- if (this.scene != null) {
- let ce = this[toSceneMotionEvent](e)
- this.scene.onDbClick(ce)
- }
- } // Function onDbClick()
- /**
- * 鼠标按下事件
- *
- * @param e 保存事件参数
- */
- onMouseDown(e) {
- let se = new SMouseEvent(e)
- if (se.buttons & SMouseEvent.MIDDLE_BUTTON) { // 如果按下中键
- this._midKeyX = e.x
- this._midKeyY = e.y
- }
- if (this.scene != null) {
- let ce = this[toSceneMotionEvent](e)
- this.scene.onMouseDown(ce)
- }
- } // Function onMouseDown()
- /**
- * 鼠标移动事件
- *
- * @param e 保存事件参数
- */
- onMouseMove(e) {
- let se = new SMouseEvent(e)
- if (se.buttons & SMouseEvent.MIDDLE_BUTTON) { // 如果按下中键,则移动视图
- this.pos.x += e.x - this._midKeyX
- this.pos.y += e.y - this._midKeyY
- this._midKeyX = e.x
- this._midKeyY = e.y
- return
- }
- if (this.scene != null) {
- let ce = this[toSceneMotionEvent](e)
- this.scene.onMouseMove(ce)
- }
- } // Function onMouseMove()
- /**
- * 释放鼠标事件
- *
- * @param e 保存事件参数
- */
- onMouseUp(e) {
- if (this.scene != null) {
- let ce = this[toSceneMotionEvent](e)
- this.scene.onMouseUp(ce)
- }
- } // Function onMouseUp()
- /**
- * 鼠标滚轮事件
- *
- * @param e 保存事件参数
- */
- onMouseWheel(e) {
- let se = new SMouseEvent(e)
- if (e.wheelDelta < 0) {
- this.scaleByPoint(1 / this.wheelZoom, se.x, se.y)
- } else {
- this.scaleByPoint(this.wheelZoom, se.x, se.y)
- }
- } // Function onMouseWheel()
- /**
- * View大小发生变化事件
- *
- * @param e 保存事件参数
- */
- onResize(e) {} // Function onResize()
- /**
- * MotionEvent转场景对象MotionEvent
- *
- * @param e MotionEvent
- * @return 子对象MotionEvent
- */
- [toSceneMotionEvent](e) {
- let se = new SMouseEvent(e)
- se.x = (se.x - this.pos.x) / this.scale
- se.y = (se.y - this.pos.y) / this.scale
- return se
- } // Function toSceneMotionEvent()
- } // Class SGraphyView
|