Published
Edited
Jun 8, 2021
1 fork
Insert cell
Insert cell
Insert cell
{
const draw = new Draw()
console.log('s ==>', draw.s)
return draw.s;
}
Insert cell
class Draw {
constructor () {
this.mouseDown = false;
this.startX = 0;
this.startY = 0;
this.placeholderX = 0;
this.placeholderY = 0;
this.endX = 0;
this.endY = 0;
this.target = null;
this.createSvgViewBox()
this.drawGridBg()
this.registerEvent()
}
createSvgViewBox () {
const w = width
const h = w * .6
this.s = DOM.svg(w, h);
}
drawGridBg () {
const w = width
const h = w * .6
const mx = w/2 * margin
const my = h/2 * margin;
const path = `M${mx},${my}${gridPath(w - mx * 2, h - my * 2, false)}`;
this.s.appendChild(svg`<path stroke=#ccc d="${path}">`)
}

registerEvent () {
if (this.s) {
this.s.onmousedown = this.startHandler.bind(this)
this.s.onmousemove = this.moveHandler.bind(this)
this.s.onmouseup = this.endHandler.bind(this)

this.s.addEventListener('touchstart', this.startHandler.bind(this), false)
this.s.addEventListener('touchmove', this.moveHandler.bind(this), false)
this.s.addEventListener('touchend', this.endHandler.bind(this), false)
}
}

startHandler (e) {
e.preventDefault()
console.log(e, e.offsetX, e.offsetY)
this.mouseDown = true
this.startX = this.getOffsetX(e)
this.startY = this.getOffsetY(e)
}

moveHandler (e) {
e.preventDefault()
if(this.mouseDown) {
console.log(e.type, e)
this.placeholderX = this.getOffsetX(e)
this.placeholderY = this.getOffsetY(e)
if (this.startX !== this.endX || this.startY !== this.endY) {
if (!this.target) {
this.target = this.s.appendChild(svg`<path stroke=#666 d="M${this.startX} ${this.startY} L${this.placeholderX} ${this.placeholderY}">`)
} else {
d3.select(this.target).attr('d', `M${this.startX} ${this.startY} L${this.placeholderX} ${this.placeholderY}`)
}
}
}
}

endHandler (e) {
e.preventDefault()
console.log(e.type , e)
if(this.mouseDown) {
this.mouseDown = false
this.endX = this.getOffsetX(e)
this.endY = this.getOffsetY(e)
if (!this.target) {
this.target = this.s.appendChild(svg`<path stroke=#666 d="M${this.startX} ${this.startY} L${this.endX} ${this.endY}">`)
} else {
d3.select(this.target).attr('d', `M${this.startX} ${this.startY} L${this.endX} ${this.endY}`)
}
this.placeholderX = 0
this.placeholderY = 0
this.target = null
}
}
getOffsetX(e) {
if(e.touches) {
if (e.touches[0]) {
const offset = getDomOffset(this.s)
return e.touches[0].pageX - offset.offsetLeft
} else { // touchend
return this.placeholderX
}
} else {
return e.offsetX || e.pageX
}
}
getOffsetY(e) {
if(e.touches) {
if (e.touches[0]) {
return e.touches[0].pageY - getDomOffset(this.s).offsetTop
} else { // touchend
return this.placeholderY
}
} else {
return e.offsetY || e.pageY
}
}
}
Insert cell
function getDomOffset(dom) {
// console.log('offset dom', dom)
if (dom) {
if (dom.offsetTop === undefined) {
return getDomOffset(dom.parentNode)
} else {
return {
offsetTop: dom.offsetTop,
offsetRight: dom.offsetRight,
offsetBottom: dom.offsetBottom,
offsetLeft: dom.offsetLeft,
}
}
} else {
return {
offsetTop: 0,
offsetRight: 0,
offsetBottom: 0,
offsetLeft: 0
}
}
}
Insert cell
function gridPath(width = 1, height = 1, initPosition = true) {
// Line distances.
// const sx = width / cols, sy = height / rows;
// Horizontal and vertical path segments, joined by relative move commands.
const px = Array(Math.ceil(height / cellWidth)).fill(`h${width}`).join(`m${-width},${cellWidth}`);
const py = Array(Math.ceil(width / cellWidth)).fill(`v${height}`).join(`m${cellWidth},${-height}`);
// Paths require an initial move command. It can be set either by this function
// or appended to the returned path.
console.log('px, py', px)
return `${initPosition ? 'M0,0' : ''}${px}m${-width}${-height}${py}`;
}
Insert cell
cellWidth = 10
Insert cell
cellHeight = 10
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more