fix drawing example. Add drawing hook for y-xml
This commit is contained in:
		
							parent
							
								
									02253f9a8d
								
							
						
					
					
						commit
						85492ad2e0
					
				@ -13,7 +13,7 @@
 | 
				
			|||||||
  <button type="button" id="clearDrawingCanvas">Clear Drawing</button>
 | 
					  <button type="button" id="clearDrawingCanvas">Clear Drawing</button>
 | 
				
			||||||
  <svg id="drawingCanvas" viewbox="0 0 100 100" width="100%"></svg>
 | 
					  <svg id="drawingCanvas" viewbox="0 0 100 100" width="100%"></svg>
 | 
				
			||||||
  <script src="../yjs-dist.js"></script>
 | 
					  <script src="../yjs-dist.js"></script>
 | 
				
			||||||
  <script src="./canvasjs.min.js"></script>
 | 
					  <script src="../bower_components/d3/d3.min.js"></script>
 | 
				
			||||||
  <script src="./index.js"></script>
 | 
					  <script src="./index.js"></script>
 | 
				
			||||||
</body>
 | 
					</body>
 | 
				
			||||||
</html>
 | 
					</html>
 | 
				
			||||||
 | 
				
			|||||||
@ -10,11 +10,11 @@ let y = new Y({
 | 
				
			|||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
window.yDrawing = y
 | 
					window.yDrawing = y
 | 
				
			||||||
var drawing = y.share.drawing
 | 
					var drawing = y.define('drawing', Y.Array)
 | 
				
			||||||
var renderPath = d3.svg.line()
 | 
					var renderPath = d3.svg.line()
 | 
				
			||||||
  .x(function (d) { return d[0] })
 | 
					  .x(function (d) { return d[0] })
 | 
				
			||||||
  .y(function (d) { return d[1] })
 | 
					  .y(function (d) { return d[1] })
 | 
				
			||||||
  .interpolate('basis')
 | 
					  .interpolate('basic')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var svg = d3.select('#drawingCanvas')
 | 
					var svg = d3.select('#drawingCanvas')
 | 
				
			||||||
  .call(d3.behavior.drag()
 | 
					  .call(d3.behavior.drag()
 | 
				
			||||||
@ -33,14 +33,13 @@ function drawLine (yarray) {
 | 
				
			|||||||
  })
 | 
					  })
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
// call drawLine every time an array is appended
 | 
					// call drawLine every time an array is appended
 | 
				
			||||||
y.share.drawing.observe(function (event) {
 | 
					drawing.observe(function (event) {
 | 
				
			||||||
  event.changedKeys.forEach(function (key) {
 | 
					  event.removedElements.forEach(function () {
 | 
				
			||||||
    let path = y.share.drawing.get(key)
 | 
					    // if one is deleted, all will be deleted!!
 | 
				
			||||||
    if (path === undefined) {
 | 
					    svg.selectAll('path').remove()
 | 
				
			||||||
      svg.selectAll('path').remove()
 | 
					  })
 | 
				
			||||||
    } else {
 | 
					  event.addedElements.forEach(function (path) {
 | 
				
			||||||
      drawLine(path)
 | 
					    drawLine(path)
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
// draw all existing content
 | 
					// draw all existing content
 | 
				
			||||||
@ -65,7 +64,7 @@ function drag () {
 | 
				
			|||||||
  if (sharedLine != null && ignoreDrag == null) {
 | 
					  if (sharedLine != null && ignoreDrag == null) {
 | 
				
			||||||
    ignoreDrag = window.setTimeout(function () {
 | 
					    ignoreDrag = window.setTimeout(function () {
 | 
				
			||||||
      ignoreDrag = null
 | 
					      ignoreDrag = null
 | 
				
			||||||
    }, 33)
 | 
					    }, 10)
 | 
				
			||||||
    sharedLine.push([d3.mouse(this)])
 | 
					    sharedLine.push([d3.mouse(this)])
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										35
									
								
								examples/html-editor-drawing-hook/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								examples/html-editor-drawing-hook/index.html
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,35 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					  <script src="../yjs-dist.js"></script>
 | 
				
			||||||
 | 
					  <script src="../bower_components/d3/d3.min.js"></script>
 | 
				
			||||||
 | 
					  <script src="./index.js"></script>
 | 
				
			||||||
 | 
					  <style>
 | 
				
			||||||
 | 
					    magic-drawing .drawingCanvas path {
 | 
				
			||||||
 | 
					      fill: none;
 | 
				
			||||||
 | 
					      stroke: blue;
 | 
				
			||||||
 | 
					      stroke-width: 2px;
 | 
				
			||||||
 | 
					      stroke-linejoin: round;
 | 
				
			||||||
 | 
					      stroke-linecap: round;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    magic-drawing .drawingCanvas {
 | 
				
			||||||
 | 
					      width: 500px;
 | 
				
			||||||
 | 
					      height: 500px;
 | 
				
			||||||
 | 
					      cursor: default;
 | 
				
			||||||
 | 
					      padding:1px;
 | 
				
			||||||
 | 
					      border:1px solid #021a40;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    magic-drawing .clearDrawingButton {
 | 
				
			||||||
 | 
					      position: absolute;
 | 
				
			||||||
 | 
					      top: 0;
 | 
				
			||||||
 | 
					      left: 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    magic-drawing {
 | 
				
			||||||
 | 
					      position: relative;
 | 
				
			||||||
 | 
					      display: block;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  </style>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body contenteditable="true">
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										134
									
								
								examples/html-editor-drawing-hook/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								examples/html-editor-drawing-hook/index.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,134 @@
 | 
				
			|||||||
 | 
					/* global Y, d3 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					window.onload = function () {
 | 
				
			||||||
 | 
					  window.yXmlType.bindToDom(document.body)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					window.addMagicDrawing = function addMagicDrawing () {
 | 
				
			||||||
 | 
					  let mt = document.createElement('magic-drawing')
 | 
				
			||||||
 | 
					  mt.dataset.yjsHook = 'magic-drawing'
 | 
				
			||||||
 | 
					  document.body.append(mt)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var renderPath = d3.svg.line()
 | 
				
			||||||
 | 
					  .x(function (d) { return d[0] })
 | 
				
			||||||
 | 
					  .y(function (d) { return d[1] })
 | 
				
			||||||
 | 
					  .interpolate('basic')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function initDrawingBindings (type, dom) {
 | 
				
			||||||
 | 
					  dom.contentEditable = 'false'
 | 
				
			||||||
 | 
					  dom.dataset.yjsHook = 'magic-drawing'
 | 
				
			||||||
 | 
					  var drawing = type.get('drawing')
 | 
				
			||||||
 | 
					  if (drawing === undefined) {
 | 
				
			||||||
 | 
					    drawing = type.set('drawing', new Y.Array())
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  var canvas = dom.querySelector('.drawingCanvas')
 | 
				
			||||||
 | 
					  if (canvas == null) {
 | 
				
			||||||
 | 
					    canvas = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
 | 
				
			||||||
 | 
					    canvas.setAttribute('class', 'drawingCanvas')
 | 
				
			||||||
 | 
					    canvas.setAttribute('viewbox', '0 0 100 100')
 | 
				
			||||||
 | 
					    dom.insertBefore(canvas, null)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  var clearDrawingButton = dom.querySelector('.clearDrawingButton')
 | 
				
			||||||
 | 
					  if (clearDrawingButton == null) {
 | 
				
			||||||
 | 
					    clearDrawingButton = document.createElement('button')
 | 
				
			||||||
 | 
					    clearDrawingButton.setAttribute('type', 'button')
 | 
				
			||||||
 | 
					    clearDrawingButton.setAttribute('class', 'clearDrawingButton')
 | 
				
			||||||
 | 
					    clearDrawingButton.innerText = 'Clear Drawing'
 | 
				
			||||||
 | 
					    dom.insertBefore(clearDrawingButton, null)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  var svg = d3.select(canvas)
 | 
				
			||||||
 | 
					    .call(d3.behavior.drag()
 | 
				
			||||||
 | 
					      .on('dragstart', dragstart)
 | 
				
			||||||
 | 
					      .on('drag', drag)
 | 
				
			||||||
 | 
					      .on('dragend', dragend))
 | 
				
			||||||
 | 
					  // create line from a shared array object and update the line when the array changes
 | 
				
			||||||
 | 
					  function drawLine (yarray, svg) {
 | 
				
			||||||
 | 
					    var line = svg.append('path').datum(yarray.toArray())
 | 
				
			||||||
 | 
					    line.attr('d', renderPath)
 | 
				
			||||||
 | 
					    yarray.observe(function (event) {
 | 
				
			||||||
 | 
					      line.remove()
 | 
				
			||||||
 | 
					      line = svg.append('path').datum(yarray.toArray())
 | 
				
			||||||
 | 
					      line.attr('d', renderPath)
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // call drawLine every time an array is appended
 | 
				
			||||||
 | 
					  drawing.observe(function (event) {
 | 
				
			||||||
 | 
					    event.removedElements.forEach(function () {
 | 
				
			||||||
 | 
					      // if one is deleted, all will be deleted!!
 | 
				
			||||||
 | 
					      svg.selectAll('path').remove()
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    event.addedElements.forEach(function (path) {
 | 
				
			||||||
 | 
					      drawLine(path, svg)
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					  // draw all existing content
 | 
				
			||||||
 | 
					  for (var i = 0; i < drawing.length; i++) {
 | 
				
			||||||
 | 
					    drawLine(drawing.get(i), svg)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // clear canvas on request
 | 
				
			||||||
 | 
					  clearDrawingButton.onclick = function () {
 | 
				
			||||||
 | 
					    drawing.delete(0, drawing.length)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  var sharedLine = null
 | 
				
			||||||
 | 
					  function dragstart () {
 | 
				
			||||||
 | 
					    drawing.insert(drawing.length, [Y.Array])
 | 
				
			||||||
 | 
					    sharedLine = drawing.get(drawing.length - 1)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // After one dragged event is recognized, we ignore them for 33ms.
 | 
				
			||||||
 | 
					  var ignoreDrag = null
 | 
				
			||||||
 | 
					  function drag () {
 | 
				
			||||||
 | 
					    if (sharedLine != null && ignoreDrag == null) {
 | 
				
			||||||
 | 
					      ignoreDrag = window.setTimeout(function () {
 | 
				
			||||||
 | 
					        ignoreDrag = null
 | 
				
			||||||
 | 
					      }, 10)
 | 
				
			||||||
 | 
					      sharedLine.push([d3.mouse(this)])
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function dragend () {
 | 
				
			||||||
 | 
					    sharedLine = null
 | 
				
			||||||
 | 
					    window.clearTimeout(ignoreDrag)
 | 
				
			||||||
 | 
					    ignoreDrag = null
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Y.XmlHook.addHook('magic-drawing', {
 | 
				
			||||||
 | 
					  fillType: function (dom, type) {
 | 
				
			||||||
 | 
					    initDrawingBindings(type, dom)
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  createDom: function (type) {
 | 
				
			||||||
 | 
					    const dom = document.createElement('magic-drawing')
 | 
				
			||||||
 | 
					    initDrawingBindings(type, dom)
 | 
				
			||||||
 | 
					    return dom
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// initialize a shared object. This function call returns a promise!
 | 
				
			||||||
 | 
					let y = new Y({
 | 
				
			||||||
 | 
					  connector: {
 | 
				
			||||||
 | 
					    name: 'websockets-client',
 | 
				
			||||||
 | 
					    url: 'http://127.0.0.1:1234',
 | 
				
			||||||
 | 
					    room: 'html-editor-example6'
 | 
				
			||||||
 | 
					    // maxBufferLength: 100
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					window.yXml = y
 | 
				
			||||||
 | 
					window.yXmlType = y.define('xml', Y.XmlFragment)
 | 
				
			||||||
 | 
					window.undoManager = new Y.utils.UndoManager(window.yXmlType, {
 | 
				
			||||||
 | 
					  captureTimeout: 500
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					document.onkeydown = function interceptUndoRedo (e) {
 | 
				
			||||||
 | 
					  if (e.keyCode === 90 && e.metaKey) {
 | 
				
			||||||
 | 
					    if (!e.shiftKey) {
 | 
				
			||||||
 | 
					      window.undoManager.undo()
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      window.undoManager.redo()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    e.preventDefault()
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -5,15 +5,38 @@ import { logID } from '../MessageHandler/messageToString.js'
 | 
				
			|||||||
import YEvent from '../Util/YEvent.js'
 | 
					import YEvent from '../Util/YEvent.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class YArrayEvent extends YEvent {
 | 
					class YArrayEvent extends YEvent {
 | 
				
			||||||
  constructor (yarray, remote) {
 | 
					  constructor (yarray, remote, transaction) {
 | 
				
			||||||
    super(yarray)
 | 
					    super(yarray)
 | 
				
			||||||
    this.remote = remote
 | 
					    this.remote = remote
 | 
				
			||||||
 | 
					    this._transaction = transaction
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  get addedElements () {
 | 
				
			||||||
 | 
					    const target = this.target
 | 
				
			||||||
 | 
					    const transaction = this._transaction
 | 
				
			||||||
 | 
					    const addedElements = new Set()
 | 
				
			||||||
 | 
					    transaction.newTypes.forEach(function (type) {
 | 
				
			||||||
 | 
					      if (type._parent === target && !transaction.deletedStructs.has(type)) {
 | 
				
			||||||
 | 
					        addedElements.add(type)
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    return addedElements
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  get removedElements () {
 | 
				
			||||||
 | 
					    const target = this.target
 | 
				
			||||||
 | 
					    const transaction = this._transaction
 | 
				
			||||||
 | 
					    const removedElements = new Set()
 | 
				
			||||||
 | 
					    transaction.deletedStructs.forEach(function (struct) {
 | 
				
			||||||
 | 
					      if (struct._parent === target && !transaction.newTypes.has(struct)) {
 | 
				
			||||||
 | 
					        removedElements.add(struct)
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    return removedElements
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class YArray extends Type {
 | 
					export default class YArray extends Type {
 | 
				
			||||||
  _callObserver (transaction, parentSubs, remote) {
 | 
					  _callObserver (transaction, parentSubs, remote) {
 | 
				
			||||||
    this._callEventHandler(transaction, new YArrayEvent(this, remote))
 | 
					    this._callEventHandler(transaction, new YArrayEvent(this, remote, transaction))
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  get (pos) {
 | 
					  get (pos) {
 | 
				
			||||||
    let n = this._start
 | 
					    let n = this._start
 | 
				
			||||||
@ -214,6 +237,17 @@ export default class YArray extends Type {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    this.insertAfter(left, content)
 | 
					    this.insertAfter(left, content)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  push (content) {
 | 
				
			||||||
 | 
					    let n = this._start
 | 
				
			||||||
 | 
					    let lastUndeleted = null
 | 
				
			||||||
 | 
					    while (n !== null) {
 | 
				
			||||||
 | 
					      if (!n._deleted) {
 | 
				
			||||||
 | 
					        lastUndeleted = n
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      n = n._right
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    this.insertAfter(lastUndeleted, content)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  _logString () {
 | 
					  _logString () {
 | 
				
			||||||
    const left = this._left !== null ? this._left._lastId : null
 | 
					    const left = this._left !== null ? this._left._lastId : null
 | 
				
			||||||
    const origin = this._origin !== null ? this._origin._lastId : null
 | 
					    const origin = this._origin !== null ? this._origin._lastId : null
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user