An example of snapping elements to a grid on drag.
References:
| license: MIT |
An example of snapping elements to a grid on drag.
References:
| <!doctype html> | |
| <style> | |
| svg { | |
| box-sizing: border-box; | |
| border: 1px solid rgb(212, 212, 212); | |
| } | |
| circle { | |
| stroke: rgb(95, 176, 228); | |
| stroke-width: 2; | |
| fill: rgba(205, 246, 255, 0.3); | |
| } | |
| line { | |
| stroke: rgb(212, 212, 212); | |
| stroke-width: 1px; | |
| shape-rendering: crispEdges; | |
| } | |
| </style> | |
| <body> | |
| <script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script> | |
| <script> | |
| var width = 960, | |
| height = 500, | |
| resolution = 20, | |
| r = 15; | |
| var points = d3.range(10).map(function() { | |
| return { | |
| x: round(Math.random() * width, resolution), | |
| y: round(Math.random() * height, resolution) | |
| }; | |
| }); | |
| var drag = d3.behavior.drag() | |
| .origin(function(d) { return d; }) | |
| .on('drag', dragged); | |
| var svg = d3.select('body').append('svg') | |
| .attr('width', width) | |
| .attr('height', height); | |
| svg.selectAll('.vertical') | |
| .data(d3.range(1, width / resolution)) | |
| .enter().append('line') | |
| .attr('class', 'vertical') | |
| .attr('x1', function(d) { return d * resolution; }) | |
| .attr('y1', 0) | |
| .attr('x2', function(d) { return d * resolution; }) | |
| .attr('y2', height); | |
| svg.selectAll('.horizontal') | |
| .data(d3.range(1, height / resolution)) | |
| .enter().append('line') | |
| .attr('class', 'horizontal') | |
| .attr('x1', 0) | |
| .attr('y1', function(d) { return d * resolution; }) | |
| .attr('x2', width) | |
| .attr('y2', function(d) { return d * resolution; }); | |
| var circles = svg.selectAll('circle') | |
| .data(points) | |
| .enter().append('circle') | |
| .attr('cx', function(d) { return d.x; }) | |
| .attr('cy', function(d) { return d.y; }) | |
| .attr('r', r) | |
| .call(drag); | |
| function dragged(d) { | |
| var x = d3.event.x, | |
| y = d3.event.y, | |
| gridX = round(Math.max(r, Math.min(width - r, x)), resolution), | |
| gridY = round(Math.max(r, Math.min(height - r, y)), resolution); | |
| d3.select(this).attr('cx', d.x = gridX).attr('cy', d.y = gridY); | |
| } | |
| function round(p, n) { | |
| return p % n < n / 2 ? p - (p % n) : p + n - (p % n); | |
| } | |
| </script> | |
| </body> |