This VisConnect example is adapted from this block. The only changes are adding the PeerJS and VisConnect script tags, adding the collaboration attribute to the HTML body, and replacing d3.drag with vc.drag.
-
-
Save dsaffo/432feae93ee2af995a427ad459afd454 to your computer and use it in GitHub Desktop.
Freehand drawing adapted with VisConnect
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<title>Freehand drawing</title> | |
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css"> | |
<script src="https://d3js.org/d3.v5.js"></script> | |
<script src="https://unpkg.com/peerjs@1.0.4/dist/peerjs.min.js"></script> | |
<script src="https://unpkg.com/visconnect@latest/visconnect-bundle.js"></script> | |
</head> | |
<style> | |
#canvas { | |
/*background: oldlace;*/ | |
} | |
#ui { | |
position: absolute; | |
top: 0; | |
left: 0; | |
pointer-events: none; | |
} | |
.swatch { | |
pointer-events: all; | |
} | |
.swatch.active { | |
stroke-width: 2px; | |
stroke: black; | |
} | |
.swatch { | |
cursor: pointer; | |
} | |
.btn { | |
pointer-events: all; | |
font-family: FontAwesome; | |
fill: #333; | |
font-size: 32px; | |
text-anchor: middle; | |
-webkit-touch-callout: none; | |
-webkit-user-select: none; | |
-khtml-user-select: none; | |
-moz-user-select: none; | |
-ms-user-select: none; | |
user-select: none; | |
} | |
.btn:hover { | |
fill: black; | |
cursor: pointer; | |
} | |
.line { | |
fill: none; | |
stroke-width: 2px; | |
stroke-linejoin: round; | |
stroke-linecap: round; | |
} | |
</style> | |
<body collaboration="live"> | |
<svg id="canvas" width="960px" height="500px"></svg> | |
<svg id="ui" width="960px" height="500px"></svg> | |
<script src="index.js"></script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function () { | |
var SWATCH_D, active_color, active_line, canvas, drag, drawing_data, lines_layer, palette, redraw, render_line, | |
swatches, trash_btn, ui; | |
SWATCH_D = 22; | |
render_line = d3.line().x((d) => d[0]).y((d) => d[1]).curve(d3.curveBasis); | |
drawing_data = { | |
lines: [] | |
}; | |
active_line = {}; | |
active_color = {}; | |
const default_color = '#333333'; | |
let active_local_color = default_color; | |
canvas = d3.select('#canvas'); | |
lines_layer = canvas.append('g'); | |
ui = d3.select('#ui'); | |
palette = ui.append('g').attr('transform', "translate(" + (4 + SWATCH_D / 2) + "," + (4 + SWATCH_D / 2) + ")"); | |
swatches = palette.selectAll('.swatch').data(["#333333", "#ffffff", "#1b9e77", "#d95f02", "#7570b3", "#e7298a", "#66a61e", "#e6ab02", "#a6761d", "#666666"]); | |
trash_btn = ui.append('text').html('') | |
.attr("class", 'btn') | |
.attr("dy", '0.35em') | |
.attr("transform", 'translate(940,20)') | |
.on('click', function () { | |
drawing_data.lines = []; | |
return redraw(); | |
}); | |
const swatchEnter = swatches.enter().append('circle'); | |
swatchEnter | |
.attr("class", 'swatch') | |
.attr('cx', function (d, i) { | |
return i * (SWATCH_D + 4) / 2; | |
}) | |
.attr('cy', function (d, i) { | |
if (i % 2) { | |
return SWATCH_D; | |
} else { | |
return 0; | |
} | |
}) | |
.attr('r', SWATCH_D / 2) | |
.attr('fill', d => d) | |
.on('click', function (d) { | |
active_color[d3.event.collaboratorId] = d; | |
if (d3.event.isLocalEvent) { | |
active_local_color = d; | |
palette.selectAll('.swatch').classed('active', false); | |
return d3.select(this).classed('active', true); | |
} | |
}); | |
swatchEnter.each(function (d) { | |
if (d === active_local_color) { | |
return d3.select(this).classed('active', true); | |
} | |
}); | |
drag = vc.drag(); // = d3.drag(); | |
var rafRequest = 0; | |
drag.on('start', function () { | |
active_line[d3.event.sourceEvent.collaboratorId] = { | |
points: [], | |
color: active_color[d3.event.sourceEvent.collaboratorId] || default_color | |
}; | |
drawing_data.lines.push(active_line[d3.event.sourceEvent.collaboratorId]); | |
redraw(); | |
}); | |
drag.on('drag', function () { | |
if (active_line[d3.event.sourceEvent.collaboratorId]) { | |
active_line[d3.event.sourceEvent.collaboratorId].points.push(d3.mouse(this)); | |
if(!rafRequest) { | |
rafRequest = requestAnimationFrame(redraw.bind(this)); | |
} | |
} | |
}); | |
drag.on('end', function () { | |
if (active_line[d3.event.sourceEvent.collaboratorId] && | |
active_line[d3.event.sourceEvent.collaboratorId].points.length === 0) { | |
drawing_data.lines.pop(); | |
} | |
active_line[d3.event.sourceEvent.collaboratorId] = null; | |
}); | |
canvas.call(drag); | |
redraw = function () { | |
rafRequest = 0; | |
const lines = lines_layer.selectAll('.line').data(drawing_data.lines); | |
const enter = lines.enter(); | |
enter.append('path') | |
.attr("class", 'line') | |
.attr('stroke', function (d) { | |
return d.color; | |
}).each(function (d) { | |
return d.elem = d3.select(this); | |
}); | |
lines.attr('d', function (d) { | |
return render_line(d.points); | |
}); | |
lines.exit().remove(); | |
}; | |
redraw(); | |
}).call(this); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment