简体   繁体   中英

Draw svg rect issues: infinity lenght and blink

I'm trying to draw a with the mouse. When the mouse is moving and pressed, it draws the area, but during it, the area blinks. In the console, when setAttribute adds width and height, sometimes appears "Infinity" and I think that it's the problem, but I don't understand why, because when I comment this line configRectSize(document.getElementById(rectId), width, height); , all numbers are correct.

I have other issue with drawing. When currentX or currentY coordinates are lower than initX or initY, I change x and y rect coordinates to be able to draw it in other direction (not only left to right and top to bottom) but sometimes the rect desappears or changes to other diferent coordinates.

Could you help me please? It's driving me crazy!

Thanks a lot!

https://jsfiddle.net/albaruz/scegfom8/23/

 var ns = "http://www.w3.org/2000/svg"; var svgId = "SvgId"; var image = document.getElementById("PlanImage"); function initSVG(SvgName, container) { svg = document.createElementNS(ns, "svg"); var svgId = SvgName; svg.setAttributeNS(null, "id", svgId); container.appendChild(svg); return svgId; } function calculateSVGSize(SvgName, container) { var imageWidth = container.clientWidth; var imageHeight = container.clientHeight; var aspectRatio = (imageHeight * 100) / imageWidth; document .getElementById(SvgName) .setAttributeNS(null, "viewBox", "0 0 100 " + aspectRatio); } function configRectSize(rect, width, height) { rect.setAttributeNS(null, "width", width); rect.setAttributeNS(null, "height", height); } function getY(rect, y) { rect.setAttributeNS(null, "y", y); } function getX(rect, x) { rect.setAttributeNS(null, "x", x); } function configRectCoords(rect, x, y) { getY(rect, y); getX(rect, x); } function configRect(name, width, height, x, y, isBooking) { var rect = document.getElementById(name); configRectSize(rect, width, height); configRectCoords(rect, x, y); rect.setAttributeNS( null, "fill", isBooking ? "rgba(0,265, 0, .3)" : "rgba(265, 0, 0, .3)" ); rect.onclick = function() { alert(name); }; } function createRect(SvgName, name) { var rect = document.createElementNS(ns, "rect"); rect.id = name; document.getElementById(SvgName).appendChild(rect); } function drawRect(SvgName, rectId) { var svg = document.getElementById(SvgName); var rect = document.getElementById(rectId); var isMouseDown = false; var isMouseMoving = true; var initX; var initY; var handleMouseMove = function(e, initX, initY) { var currentX = ((e.offsetX * 100) / e.target.clientWidth).toFixed(2); var currentY = ((e.offsetY * 100) / e.target.clientHeight).toFixed(2); var width = Math.sqrt(Math.pow(initX - (currentX), 2)).toFixed(2); var height = Math.sqrt(Math.pow(initY - (currentY), 2)).toFixed(2); console.log(`currentX: ${currentX}`); console.log(`currentY: ${currentY}`); console.log(`width: ${width}`); console.log(`height: ${height}`); if (currentY < initY && currentX < initX) { configRectCoords( document.getElementById(rectId), currentX, currentY ); } else if (currentX < initX) configRectCoords(document.getElementById(rectId), currentX, initY); else if (currentY < initY) configRectCoords(document.getElementById(rectId), initX, currentY); else configRectCoords(document.getElementById(rectId), initX, initY); configRectSize(document.getElementById(rectId), width, height); }; svg.addEventListener("mousedown", function(e) { isMouseDown = true; console.log("estoy apretando"); initX = ((e.offsetX * 100) / e.target.clientWidth).toFixed(2); initY = ((e.offsetY * 100) / e.target.clientHeight).toFixed(2); console.log(`initX: ${initX}`); console.log(`initY: ${initY}`); //Initialize RectCreation if (!document.getElementById(rectId)) { createRect(SvgName, rectId); } configRectCoords(document.getElementById(rectId), initX, initY); configRectSize(document.getElementById(rectId), 0, 0); }); svg.addEventListener("mousemove", function(e) { if (!isMouseDown) return; e.preventDefault(); e.stopPropagation(); console.log("me estoy moviendo"); handleMouseMove(e, initX, initY); }); svg.addEventListener("mouseup", function(e) { isMouseDown = false; }); } initSVG(svgId, DeskInteraction); image.onload = function() { calculateSVGSize(svgId, DeskInteraction); }; drawRect(svgId, DeskInteraction);
 .plan-wrapper { position: relative; max-width: 500px; } .plan-wrapper img { width: 100%; } .plan-wrapper .plan-interaction { position: absolute; top: 0; left: 0; right: 0; bottom: 0; width: 100%; z-index: 10; }
 <div data-container="" class="plan-wrapper" id="PlanContainer"> <img data-image="" class="plan-image" id="PlanImage" style="margin-left: auto" src="https://www.jcadg.com/2d-3d-floor-plan/images/mobile/gold.jpg" /> <div data-container="" class="plan-interaction" id="DeskInteraction"></div> </div>

The way you calculated the x and y coordinates is not correct, even if you are doing it for any DOM element. In the case of an svg element (which you are attaching the handle to), you would also need to take into account any transformation on the coordinates. This is simple with matrixTransform and getScreenCTM . I have added a function called getSVGCoords to your script and called it to calculate both the init and the current coordinates:

 var ns = "http://www.w3.org/2000/svg"; var svgId = "SvgId"; var image = document.getElementById("PlanImage"); function initSVG(SvgName, container) { svg = document.createElementNS(ns, "svg"); var svgId = SvgName; svg.setAttributeNS(null, "id", svgId); container.appendChild(svg); return svgId; } function calculateSVGSize(SvgName, container) { var imageWidth = container.clientWidth; var imageHeight = container.clientHeight; var aspectRatio = (imageHeight * 100) / imageWidth; document .getElementById(SvgName) .setAttributeNS(null, "viewBox", "0 0 100 " + aspectRatio); } function configRectSize(rect, width, height) { rect.setAttributeNS(null, "width", width); rect.setAttributeNS(null, "height", height); } function getY(rect, y) { rect.setAttributeNS(null, "y", y); } function getX(rect, x) { rect.setAttributeNS(null, "x", x); } function configRectCoords(rect, x, y) { getY(rect, y); getX(rect, x); } function configRect(name, width, height, x, y, isBooking) { var rect = document.getElementById(name); configRectSize(rect, width, height); configRectCoords(rect, x, y); rect.setAttributeNS( null, "fill", isBooking ? "rgba(0,265, 0, .3)" : "rgba(265, 0, 0, .3)" ); rect.onclick = function() { alert(name); }; } function createRect(SvgName, name) { var rect = document.createElementNS(ns, "rect"); rect.id = name; document.getElementById(SvgName).appendChild(rect); } function getSVGCoords(s, ev){ var pt = s.createSVGPoint(); pt.x = ev.clientX; pt.y = ev.clientY; var loc = pt.matrixTransform(svg.getScreenCTM().inverse()); return loc } function drawRect(SvgName, rectId) { var svg = document.getElementById(SvgName); var rect = document.getElementById(rectId); var isMouseDown = false; var isMouseMoving = true; var initX; var initY; var handleMouseMove = function(e, initX, initY) { // Insertion HERE var loc = getSVGCoords(svg, e); var currentX = loc.x; var currentY = loc.y; // var width = Math.sqrt(Math.pow(initX - (currentX), 2)).toFixed(2); var height = Math.sqrt(Math.pow(initY - (currentY), 2)).toFixed(2); console.log(`currentX: ${currentX}`); console.log(`currentY: ${currentY}`); console.log(`width: ${width}`); console.log(`height: ${height}`); if (currentY < initY && currentX < initX) { configRectCoords( document.getElementById(rectId), currentX, currentY ); } else if (currentX < initX) configRectCoords(document.getElementById(rectId), currentX, initY); else if (currentY < initY) configRectCoords(document.getElementById(rectId), initX, currentY); else configRectCoords(document.getElementById(rectId), initX, initY); configRectSize(document.getElementById(rectId), width, height); }; svg.addEventListener("mousedown", function(e) { isMouseDown = true; console.log("estoy apretando"); var loc = getSVGCoords(svg, e); initX = loc.x; initY = loc.y; console.log(`initX: ${initX}`); console.log(`initY: ${initY}`); //Initialize RectCreation if (!document.getElementById(rectId)) { createRect(SvgName, rectId); } configRectCoords(document.getElementById(rectId), initX, initY); configRectSize(document.getElementById(rectId), 0, 0); }); svg.addEventListener("mousemove", function(e) { if (!isMouseDown) return; e.preventDefault(); e.stopPropagation(); console.log("me estoy moviendo"); handleMouseMove(e, initX, initY); }); svg.addEventListener("mouseup", function(e) { isMouseDown = false; }); } initSVG(svgId, DeskInteraction); image.onload = function() { calculateSVGSize(svgId, DeskInteraction); }; drawRect(svgId, DeskInteraction);
 .plan-wrapper { position: relative; max-width: 500px; } .plan-wrapper img { width: 100%; } .plan-wrapper .plan-interaction { position: absolute; top: 0; left: 0; right: 0; bottom: 0; width: 100%; z-index: 10; }
 <div data-container="" class="plan-wrapper" id="PlanContainer"> <img data-image="" class="plan-image" id="PlanImage" style="margin-left: auto" src="https://www.jcadg.com/2d-3d-floor-plan/images/mobile/gold.jpg" /> <div data-container="" class="plan-interaction" id="DeskInteraction"></div> </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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