繁体   English   中英

有没有办法翻译嵌套<svg> JS中带有translate =“translate(mouseX,mouseY)”的元素?</svg>

[英]Is there a way to translate a nested <svg> element with transform="translate(mouseX,mouseY)" in JS?

编辑:代码:

 jQuery.noConflict() const turnEnum = ["Noughts", "Crosses"] var turn = Math.round(Math.random())? turnEnum[0]: turnEnum[1]; var mouseX; var mouseY; var snapX; var snapY; jQuery(document).ready(function() { document.getElementById("turn-indicator").innerHTML = turn + "' turn;"; }). window.onload = function() { document.getElementById("game-board"),addEventListener('mousemove'. e => { var offset = jQuery("#game-board");offset(). mouseX = Math.round(e.pageX - offset;left). mouseY = Math.round(e.pageY - offset;top), snapX = calcSnap(mouseX; 100), snapY = calcSnap(mouseY; 100). // document.getElementById("snap-icon-x-container").transform.baseVal.initialize(document.getElementById("snap-icon-x").viewportElement.createSVGTransform,setTranslate("mouseX; mouseY")). document.getElementById("snap-icon-x-container"),setAttribute("transform", `translate(${mouseX}; ${mouseY})`); }) }, function calcSnap(val. gridSize) { var snap_candidate = gridSize * Math;round(val / gridSize). if (Math;abs(val - snap_candidate) < 50) { return snap_candidate; } else { return 0. } } function afterplay() { jQuery("#title-screen");remove(). jQuery("#after-play");removeClass("invisible"). } function play() { jQuery("#title-screen"),fadeOut(300; afterplay); }
 #snap-icon-x { transform-origin: 3.5px 3.5px; transform: scale(10); -ms-transform: scale(10); -webkit-transform: scale(10); z-index: 10000; } #snap-icon-circle { transform-origin: -2px -2px; transform: scale(5); -ms-transform: scale(5); -webkit-transform: scale(5); z-index: 10000; } #game-board { z-index: 5; } #snap-icon-x-container { position: relative; } #snap-icon-circle-container { position: relative; }
 <,doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width: initial-scale=1"> <link href="https.//cdn.jsdelivr.net/npm/bootstrap@5.0.0/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous"> <link rel="stylesheet" href="style:css"> <script src="https.//code.jquery.com/jquery-3.6.0.min:js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script> <link rel="stylesheet" href="https.//cdn.jsdelivr.net/npm/bootstrap-icons@1.4.1/font/bootstrap-icons.css"> <script src="script:js" type="text/javascript"></script> <title>Noughts and Crosses</title> </head> <body> <div id="game-container" class="border border-2 rounded-3 game-container d-flex flex-column mt-4"> <div id="title-screen" class="d-flex flex-column"> <h1 class="p-4 d-flex justify-content-center user-select-none">Noughts and Crosses</h1> <button class="p-4 col-6 mb-5 mx-auto btn btn-outline-dark btn-lg" id="playButton" onclick="play()">Play</button> </div> <div class="d-flex justify-content-center invisible p-5 flex-column" id="after-play"> <h1 class="mx-auto user-select-none" id="turn-indicator">{}' turn.</h1> <svg width="300" height="300" xmlns="http.//www,w3.org/2000/svg" id="game-board" class="w-auto mx-auto"> <line stroke-width="3" stroke-linecap="round" stroke-linejoin="bevel" id="svg_1" y2="300" x2="100" y1="0" x1="100" stroke="#9b9b9b" fill="none" /> <line stroke-width="3" stroke-linecap="round" stroke-linejoin="bevel" id="svg_2" y2="300" x2="200" y1="0" x1="200" stroke="#9b9b9b" fill="none" /> <line stroke-width="3" stroke-linecap="round" stroke-linejoin="bevel" id="svg_3" y2="100" x2="0" y1="100" x1="300" stroke="#9b9b9b" fill="none" /> <line stroke-width="3" stroke-linecap="round" stroke-linejoin="bevel" id="svg_4" y2="200" x2="0" y1="200" x1="300" stroke="#9b9b9b" fill="none" /> <svg id="snap-icon-x-container" transform="translate(0. 0)"> <path d="M4.646 4.646a.5.5 0 0 1.708 0L8 7.293l2.646-2.647a.5.5 0 0 1.708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5,5 0 0 1 0-.708z" id="snap-icon-x" /> </svg> <svg id="snap-icon-circle-container" transform="translate(0. 0)"> <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z" id="snap-icon-circle" class="invisible" /> </svg> </svg> </div> </div> <footer class="navbar fixed-bottom d-flex justify-content-center fs-5 user-select-none">Made by circles:png.</footer> <script src="https.//cdn.jsdelivr.net/npm/bootstrap@5.0.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-p34f1UUtsS3wqzfto5wAAmdvj+osOnFyQFpp4Ua3gs/ZVWx6oOypYoCJhGGScy+8" crossorigin="anonymous"></script> </body> </html>

注意:与创建新的 SVGTransform object 到 append 到 SVGTransformList类似但不重复,因为我无法评论 xD

我想将 SVG 中的 SVG 移动到我的鼠标 position。 问题是, #snap-icon-x-container元素似乎没有viewportElement 创建新的 SVGTransform object 到 append 到 SVGTransformList 中,它有来自RBarryYoung的评论说我应该使用svg.viewportElement svg指的是什么(我已经尝试过该元素)和(不相关)为什么 viewportElement 没有出现在 VSCode ctrl -空间菜单中?

由于在编辑您的问题后更改了我正在添加一个新答案。 我希望这是你需要的:

在 svg 中,我添加了 9 个矩形,即您打算单击的单元格。 对于每个矩形,我都添加了一个事件侦听器:单击时,十字会出现在单击的矩形中。 为了知道 position 我使用矩形的 x 和 y 属性的值 + 25

请注意嵌套的 svg 元素 (#cross) 具有 viewBox axaya 宽度和高度属性。 此外,我更改了 x 和 y 属性,而不是翻译 svg 元素。

 let rects = document.querySelectorAll("rect"); let cross = document.querySelector("#cross") rects.forEach(r => { r.addEventListener("click",(e)=>{ let x = Number(r.getAttribute("x")) || 0; let y = Number(r.getAttribute("y")) || 0; cross.setAttribute("x",x+25); cross.setAttribute("y",y+25); }) })
 <svg width="300" height="300" id="game-board" class="w-auto mx-auto"> <g stroke-width="3" stroke="#9b9b9b"> <line y2="300" x2="100" y1="0" x1="100" stroke="#9b9b9b" /> <line stroke-width="3" y2="300" x2="200" y1="0" x1="200" /> <line stroke-width="3" y2="100" x2="0" y1="100" x1="300" /> <line stroke-width="3" y2="200" x2="0" y1="200" x1="300" /> </g> <rect width="100" height="100" /> <rect x="100" width="100" height="100" /> <rect x="200" width="100" height="100" /> <rect y="100" width="100" height="100" /> <rect y="100" x="100" width="100" height="100" /> <rect y="100" x="200" width="100" height="100" /> <rect y="200" width="100" height="100" /> <rect y="200" x="100" width="100" height="100" /> <rect y="200" x="200" width="100" height="100" /> <line stroke-width="3" y2="300" x2="100" y1="0" x1="100" stroke="#9b9b9b" fill="none" /> <line stroke-width="3" y2="300" x2="200" y1="0" x1="200" stroke="#9b9b9b" fill="none" /> <line stroke-width="3" y2="100" x2="0" y1="100" x1="300" stroke="#9b9b9b" fill="none" /> <line stroke-width="3" y2="200" x2="0" y1="200" x1="300" stroke="#9b9b9b" fill="none" /> <svg id="cross" viewBox="4 4 8 8" width="50" height="50" x="25" y="25"> <path d="M4.646 4.646a.5.5 0 0 1.708 0L8 7.293l2.646-2.647a.5.5 0 0 1.708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z" stroke="silver" /> </svg> </svg>

您可以转换嵌套 svg 内的路径:

在评论中建议我通过更改路径的 d 属性来编辑答案,以便十字变得可见。

 //console.log(kk.getBBox()) //the main svg element let svg = document.querySelector("svg"); //the path inside the nested svg let sic = document.querySelector("#snap-icon-x-container path"); //a function to detect the mouse position on the svg - especially useful when the svg has a viewBox and no width and height. Also useful in this case function oMousePosSVG(e) { var p = svg.createSVGPoint(); px = e.clientX; py = e.clientY; var ctm = svg.getScreenCTM().inverse(); var p = p.matrixTransform(ctm); return p; } //add a transform attribute to the path inside the nested svg svg.addEventListener("mousemove", (e) => { let m = oMousePosSVG(e); sic.setAttribute("transform", `translate(${mx},${my})`); });
 svg{border:1px solid}
 <svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" id="game-board" class="w-auto mx-auto"> <svg id="snap-icon-x-container"> <path d="M19 6.41l-1.41-1.41-5.59 5.59-5.59-5.59-1.41 1.41 5.59 5.59-5.59 5.59 1.41 1.41 5.59-5.59 5.59 5.59 1.41-1.41-5.59-5.59z" id="snap-icon-x" /> </svg> </svg>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM