d3.js - 在 d3.js 中将对象拖放到 SVG 元素上
问题描述
我有一个对象(图像上的滑雪者),我希望能够将其拖放到直线(斜坡)上。我的目标是把滑雪者拖上斜坡,计算滑雪者在那个点的能量,当我放下他时,他从斜坡上下来,然后我根据他掉下的地方的能量计算他的速度。
我已经设法生成了线路路径,但我不知道如何将拖放区域限制为我生成的线路路径。我试图找到相关的 d3.drag()但我找不到我在找的东西。一些想法我如何能做到这一点?
这是我的所有代码:
const skierIconSvg = "skier.svg";
const margin = {top: 20, right: 20, bottom: 30, left: 50},
width = 600 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
const svg = d3.select('body').append('svg')
.attr("width", width)
.attr("height", height)
const data = [
{"x": 1, "y": 100},
{"x": 2, "y": 99},
{"x": 3, "y": 98},
{"x": 4, "y": 97},
{"x": 5, "y": 96},
{"x": 6, "y": 95},
{"x": 7, "y": 94},
{"x": 8, "y": 93},
{"x": 9, "y": 92},
{"x": 10, "y": 91},
{"x": 11, "y": 90},
{"x": 12, "y": 89},
{"x": 13, "y": 88},
{"x": 14, "y": 87},
{"x": 15, "y": 86},
{"x": 16, "y": 85},
{"x": 17, "y": 84},
{"x": 18, "y": 83},
{"x": 19, "y": 82},
{"x": 20, "y": 81},
{"x": 21, "y": 80},
{"x": 22, "y": 79},
{"x": 23, "y": 78},
{"x": 24, "y": 77},
{"x": 25, "y": 76},
{"x": 26, "y": 75},
{"x": 27, "y": 74},
{"x": 28, "y": 73},
{"x": 29, "y": 72},
{"x": 30, "y": 71},
{"x": 31, "y": 70},
{"x": 32, "y": 69},
{"x": 33, "y": 68},
{"x": 34, "y": 67},
{"x": 35, "y": 66},
{"x": 36, "y": 65},
{"x": 37, "y": 64},
{"x": 38, "y": 63},
{"x": 39, "y": 62},
{"x": 40, "y": 61},
{"x": 41, "y": 60},
{"x": 42, "y": 59},
{"x": 43, "y": 58},
{"x": 44, "y": 57},
{"x": 45, "y": 56},
{"x": 46, "y": 55},
{"x": 47, "y": 54},
{"x": 48, "y": 53},
{"x": 49, "y": 52},
{"x": 50, "y": 51},
{"x": 51, "y": 50},
{"x": 52, "y": 49},
{"x": 53, "y": 48},
{"x": 54, "y": 47},
{"x": 55, "y": 46},
{"x": 56, "y": 45},
{"x": 57, "y": 44},
{"x": 58, "y": 43},
{"x": 59, "y": 42},
{"x": 60, "y": 41},
{"x": 61, "y": 40},
{"x": 62, "y": 39},
{"x": 63, "y": 38},
{"x": 64, "y": 37},
{"x": 65, "y": 36},
{"x": 66, "y": 35},
{"x": 67, "y": 34},
{"x": 68, "y": 33},
{"x": 69, "y": 32},
{"x": 70, "y": 31},
{"x": 71, "y": 30},
{"x": 72, "y": 29},
{"x": 73, "y": 28},
{"x": 74, "y": 27},
{"x": 75, "y": 26},
{"x": 76, "y": 25},
{"x": 77, "y": 24},
{"x": 78, "y": 23},
{"x": 79, "y": 22},
{"x": 80, "y": 21},
{"x": 81, "y": 20},
{"x": 82, "y": 19},
{"x": 83, "y": 18},
{"x": 84, "y": 17},
{"x": 85, "y": 16},
{"x": 86, "y": 15},
{"x": 87, "y": 14},
{"x": 88, "y": 13},
{"x": 89, "y": 12},
{"x": 90, "y": 11},
{"x": 91, "y": 10},
{"x": 92, "y": 9},
{"x": 93, "y": 8},
{"x": 94, "y": 7},
{"x": 95, "y": 6},
{"x": 96, "y": 5},
{"x": 97, "y": 4},
{"x": 98, "y": 3},
{"x": 99, "y": 2},
{"x": 100, "y": 1},
];
const xScale = d3.scaleLinear()
.domain([d3.min(data, function(d) { return d.x; }), d3.max(data, function(d) { return d.x; }) ])
.range([0, width]);
const yScale = d3.scaleLinear()
.domain([0, d3.max(data, function(d) { return d.y; }) ])
.range([height, 0]);
const linje = d3.line()
.x(d => xScale(d.x))
.y(d => yScale(d.y))
const gLinje = svg.append("g")
const loypegenerator = gLinje.append("path")
.attr("d", linje(data))
.attr("stroke", "blue")
.attr("stroke-width", 1)
.attr("class", "loypeprofil")
.attr("fill", "none")
const newG = svg.append("g")
const nyLoypegenerator = newG.append("path")
.attr("d", linje(data))
.attr("stroke", "none")
.attr("stroke-width", 1)
.attr("class", "loypeprofil")
.attr("fill", "none")
// This finds the x coordinate on the G element using d3.mouse
nyLoypegenerator.append("rect")
.attr("height", height)
.attr("width", width)
.attr("fill", "none")
.attr("pointer-events", "all")
.on("mousemove", () => {
const x = d3.mouse(g.node())[1];
const hoveredX = yScale.invert(x)
console.log(hoveredX)
});
// Here I append the skier object
const skier = newG.append("image")
.attr("id", "skier")
.attr("href", skierIconSvg)
.attr("x", 130)
.attr("y", 150)
.attr("width", 100)
.attr("height", 100)
.call(d3
.drag()
.on('start', start)
.on('drag', dragged));
function start() {
let current = d3.select(this)
deltaX = current.attr("x") - d3.event.x;
deltaY = current.attr("y") - d3.event.y;
};
function dragged() {
d3.select(this)
.attr("x", d3.mouse(newG.node())[0])
.attr("y", d3.mouse(newG.node())[1])
};
解决方案
推荐阅读
- database - 无法从 PostgreSQL 中的一个函数调用多个函数
- c# - C# EF Core 引用不同的表
- python - 从网络电报硒抓取中获取群组短信数据
- azure-web-app-service - 配置 Azure 应用服务以允许下载 *.config 文件
- realex-payments-api - HPP 不正确的哈希
- c# - SQLite 错误 19:'NOT NULL 约束失败:ef_temp_Posts.UserId
- wordpress - 如何在我们的 woocommerce 上应用自定义小计并影响购物车总数
- azure-databricks - 如何解决 Azure Databricks Autoloader cloudfiles 源中的偏移不匹配错误?
- reactjs - reactJs中的useContext导入问题和props
- google-chrome-os - 如何在 Chrome OS 上静默安装证书