如何为JavaScript实现的转盘添加空格键触发旋转功能?
Integrate Spacebar Trigger for D3.js Wheel Spinner
Got it, let's get that spacebar trigger working for your D3.js wheel spinner! The integration is straightforward—we'll hook up your key press snippet to call the existing spin() function, while making sure we don't allow multiple triggers during an active rotation.
Step-by-Step Implementation
Here's the modified code with the spacebar functionality added. I've marked key changes with comments:
Modified JavaScript Code
var padding = {top:20, right:40, bottom:0, left:0}, w = 500 - padding.left - padding.right, h = 500 - padding.top - padding.bottom, r = Math.min(w, h)/2, rotation = 0, oldrotation = 0, picked = 100000, oldpick = [], color = d3.scale.category20();//category20c() //randomNumbers = getRandomNumbers(); var data = [ {"label":"Dell LAPTOP", "value":1, "question":"What CSS property is used for specifying the area between the content and its border?"}, // 内边距 {"label":"IMAC PRO", "value":2, "question":"What CSS property is used for changing the font?"}, // 字体族 {"label":"SUZUKI", "value":3, "question":"What CSS property is used for changing the color of text?"}, // 文本颜色 {"label":"HONDA", "value":4, "question":"What CSS property is used for changing the boldness of text?"}, // 字体粗细 {"label":"FERRARI", "value":5, "question":"What CSS property is used for changing the size of text?"}, // 字体大小 {"label":"APARTMENT", "value":6, "question":"What CSS property is used for changing the background color of a box?"}, // 背景颜色 {"label":"IPAD PRO", "value":7, "question":"Which word is used for specifying an HTML tag that is inside another tag?"}, // 嵌套 {"label":"LAND", "value":8, "question":"Which side of the box is the third number in: margin:1px 1px 1px 1px; ?"}, // 底部 {"label":"MOTOROLLA", "value":9, "question":"What are the fonts that don't have serifs at the ends of letters called?"}, // 无衬线字体 {"label":"BMW", "value":10, "question":"With CSS selectors, what character prefix should one use to specify a class?"} // 类选择器前缀 ]; var svg = d3.select('#chart') .append("svg") .data([data]) .attr("width", w + padding.left + padding.right) .attr("height", h + padding.top + padding.bottom); var container = svg.append("g") .attr("class", "chartholder") .attr("transform", "translate(" + (w/2 + padding.left) + "," + (h/2 + padding.top) + ")"); var vis = container .append("g"); var pie = d3.layout.pie().sort(null).value(function(d){return 1;}); // 声明弧形生成器函数 var arc = d3.svg.arc().outerRadius(r); // 选择路径,使用弧形生成器绘制 var arcs = vis.selectAll("g.slice") .data(pie) .enter() .append("g") .attr("class", "slice"); arcs.append("path") .attr("fill", function(d, i){ return color(i); }) .attr("d", function (d) { return arc(d); }); // 添加文本 arcs.append("text").attr("transform", function(d){ d.innerRadius = 0; d.outerRadius = r; d.angle = (d.startAngle + d.endAngle)/2; return "rotate(" + (d.angle * 180 / Math.PI - 90) + ")translate(" + (d.outerRadius -10) +")"; }) .attr("text-anchor", "end") .text( function(d, i) { return data[i].label; }); container.on("click", spin); // ADDED: Spacebar trigger listener document.body.onkeyup = function(e){ // Check if spacebar is pressed AND spinner isn't already rotating if(e.keyCode === 32 && container.on("click") !== null){ spin(); } }; function spin(d){ // Disable both click and spacebar triggers during rotation container.on("click", null); // 所有扇区已被选中,结束操作 console.log("OldPick: " + oldpick.length, "Data length: " + data.length); if(oldpick.length == data.length){ console.log("完成"); container.on("click", null); return; } var ps = 360/data.length, pieslice = Math.round(1440/data.length), rng = Math.floor((Math.random() * 1440) + 360); rotation = (Math.round(rng / ps) * ps); picked = Math.round(data.length - (rotation % 360)/ps); picked = picked >= data.length ? (picked % data.length) : picked; if(oldpick.indexOf(picked) !== -1){ d3.select(this).call(spin); return; } else { oldpick.push(picked); } rotation += 90 - Math.round(ps/2); vis.transition() .duration(3000) .attrTween("transform", rotTween) .each("end", function(){ // 标记该问题已被选中 d3.select(".slice:nth-child(" + (picked + 1) + ") path") .attr("fill", "#111"); // 填充问题内容 d3.select("#question h1") .text(data[picked].question); oldrotation = rotation; /* 从data对象中获取结果值 */ console.log(data[picked].value) /* 取消以下注释可限制仅能旋转一次 */ // Re-enable click trigger (spacebar will automatically work again since we check this) container.on("click", spin); }); } // 绘制箭头 svg.append("g") .attr("transform", "translate(" + (w + padding.left + padding.right) + "," + ((h/2)+padding.top) + ")") .append("path") .attr("d", "M-" + (r*.15) + ",0L0," + (r*.05) + "L0,-" + (r*.05) + "Z") .style({"fill":"black"}); // 绘制旋转按钮圆圈 container.append("circle") .attr("cx", 0) .attr("cy", 0) .attr("r", 60) .style({"fill":"white","cursor":"pointer"}); // 旋转按钮文本 container.append("text") .attr("x", 0) .attr("y", 15) .attr("text-anchor", "middle") .text("SPIN") .style({"font-weight":"bold", "font-size":"30px"}); function rotTween(to) { var i = d3.interpolate(oldrotation % 360, rotation); return function(t) { return "rotate(" + i(t) + ")"; }; } function getRandomNumbers(){ var array = new Uint16Array(1000); var scale = d3.scale.linear().range([360, 1440]).domain([0, 100000]); if(window.hasOwnProperty("crypto") && typeof window.crypto.getRandomValues === "function"){ window.crypto.getRandomValues(array); console.log("随机数生成成功"); } else { // 不支持加密随机数,生成普通随机数 for(var i=0; i < 1000; i++){ array[i] = Math.floor(Math.random() * 100000) + 1; } } return array; }
CSS (Unchanged)
text{ font-family:Helvetica, Arial, sans-serif; font-size:11px; pointer-events:none; } #chart{ position:absolute; width:500px; height:500px; top:0; left:0; } #question{ position: absolute; width:400px; height:500px; top:0; left:520px; } #question h1{ font-size: 50px; font-weight: bold; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; position: absolute; padding: 0; margin: 0; top:50%; -webkit-transform:translate(0,-50%); transform:translate(0,-50%); }
HTML (Unchanged)
<div id="chart"></div> <div id="question"><h1></h1></div> <script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
Key Notes
- Locking Logic: The spacebar listener checks
container.on("click") !== nullto ensure we don't trigger a new spin while the wheel is already rotating. Your existingspin()function disables the click trigger at the start and re-enables it when the rotation finishes—this same check works for the spacebar. - Reusability: We're reusing your existing
spin()function instead of writing new rotation logic, so all the existing behavior (random selection, marking used slices, updating the question) stays intact. - KeyCode: We use
e.keyCode === 32which is the code for the spacebar—this is the snippet you provided, integrated directly into the listener.
内容的提问来源于stack exchange,提问作者user3332375
相关产品推荐
相关产品推荐

