निम्नलिखित उदाहरण में मेरे पास सोने में 3 आकृतियों का प्रतिच्छेदन है (इस मामले में मैं मंडलियों का उपयोग कर रहा हूं लेकिन वे 3 आकार कुछ भी हो सकते हैं) सुनहरा चौराहा क्लिप-पथ के साथ क्लिपिंग का परिणाम है।

मैं चौराहे को एक प्रतीक के रूप में उपयोग करना चाहता हूं और इसके लिए मुझे चौराहे के बाउंडिंग बॉक्स, यानी लाल स्ट्रोक वाले आयत को जानना होगा।

अगर मैं चौराहे का उपयोग कर रहा हूं। getBBox() मुझे क्लिपिंग से पहले बाउंडिंग बॉक्स मिल रहा है।

मैं चौराहे का बाउंडिंग बॉक्स कैसे प्राप्त कर सकता हूं?

console.log(intersection.getBBox())
svg{border:solid}

.circles{fill:none;stroke:black}
<svg id="svg" viewBox="-150 -150 300 300" width="300">
  <defs>
  <circle id="c1" cx="0" cy="-50" r="80"></circle>
  <circle id="c2" cx="43.3" cy="25" r="80"></circle>
  <circle id="c3" cx="-43.3" cy="25" r="80"></circle>
  
  <clipPath id="clipC2"><use xlink:href="#c2"/></clipPath>
  <clipPath id="clipC3"><use xlink:href="#c3"/></clipPath>
  </defs>
  
  <g class="circles">
  <use xlink:href="#c1"/>
  <use xlink:href="#c2"/>
  <use xlink:href="#c3"/>
  </g>
  
  
<g id="intersection">
  <g clip-path="url(#clipC3)">
  <use fill="gold" xlink:href="#c1" clip-path="url(#clipC2)"/>
  </g>
</g>
  
  <rect x="-38" y="-42" width="75" height="74" stroke="red" fill="none"/>
</svg>
2
enxaneta 7 जुलाई 2020, 19:34

2 जवाब

सबसे बढ़िया उत्तर

मुख्य विचार यह है:

  1. मैं svg तत्व ले रहा हूं, इसे बेस 64 बनाएं और इसे किसी छवि की src विशेषता के रूप में उपयोग करें।
  2. मैं svg तत्व को canvas पर svg तत्व के समान आकार के साथ चित्रित कर रहा हूं।
  3. मुझे कैनवास से छवि डेटा मिलता है
  4. छवि डेटा के माध्यम से लूप करें और प्राप्त करें:
  • एक काले पिक्सेल का सबसे छोटा x मान
  • काले पिक्सेल का सबसे छोटा y मान
  • एक काले पिक्सेल का सबसे बड़ा x मान
  • एक काले पिक्सेल का सबसे बड़ा y मान
  1. मैं चौराहे के लिए नया व्यूबॉक्स मान बनाने के लिए उन मानों का उपयोग कर रहा हूं।
//the svg's viewBox
let vB = { x: -100, y: -100, w: 200, h: 200 };

//canvas
let ctx = c.getContext("2d");
//set the size of the canvas equal to the size of the svg element
c.width = vB.w;
c.height = vB.h;

// draw the svg element on the canvas
let xml = new XMLSerializer().serializeToString(svg);
// make it base64 and use it as the src attribute of the image
let img=new Image()
img.src = "data:image/svg+xml;base64," + btoa(xml);
img.onload = function() {
  //paint the image on the canvas
    ctx.drawImage(this, 0, 0);
  
//get the image data from the canvas
let imgData = ctx.getImageData(0, 0, vB.w, vB.h).data;

// x the smallest x value of a black pixel
// y the smallest y value of a black pixel
// X the biggest x value of a black pixel
// Y the biggest y value of a black pixel
let x = vB.w,
  y = vB.h,
  X = 0,
  Y = 0;
let n = 0;

for (let i = 0; i < imgData.length; i += 4) {
  n++
  if (imgData[i + 3] != 0) {
    //if the alpha (i+3) value of the pixel is not 0
    let _y = Math.ceil(i / (4 * vB.w));
    let _x = (i / 4) % vB.w;
    if (_x < x) { x = _x; }
    if (_y < y) { y = _y; }
    if (_x > X) { X = _x; }
    if (_y > Y) { Y = _y; }
  } 
  
  if(n==imgData.length/4){
    let newViewBox = `${x + vB.x} ${y + vB.y} ${X - x + 1} ${Y - y}`;
    reuleaux.setAttribute("viewBox", newViewBox);
    console.log(`viewBox="${newViewBox}"`);
  }
}
}
svg,
canvas {
  outline: 1px solid;
}
<svg id="svg" viewBox="-100 -100 200 200" width="200">
  <defs>
  <circle id="c1" cx="0" cy="-50" r="80"></circle>
  <circle id="c2" cx="43.3" cy="25" r="80"></circle>
  <circle id="c3" cx="-43.3" cy="25" r="80"></circle>  
  <clipPath id="clipC2"><use xlink:href="#c2"/></clipPath>
  <clipPath id="clipC3"><use xlink:href="#c3"/></clipPath>
  </defs>    
<g id="intersection">
  <g clip-path="url(#clipC3)">
  <use xlink:href="#c1" clip-path="url(#clipC2)"/>
  </g>
</g>
</svg>
<!--<img id="img" width="200" height="200"/>-->

<canvas id="c"></canvas>

<svg id="reuleaux" viewBox="-100 -100 200 200" width="200" style="background:#dfdfdf">
  <use xlink:href="#intersection"/>
</svg>
1
enxaneta 1 अगस्त 2020, 13:01

सुनिश्चित नहीं है कि यह उस प्रकार की चीज थी जिसके बाद आप थे।

let myBB = {
    x: c2.getBBox().x,
    get y() {
        return c1.getBBox().y + this.width
    },
    get width() {
        // return (posNum(c3.getBBox().x))  - (posNum(myBB.x));
        let leftPointOfWidth = c2.getBBox().x;
        let rightPointofWidth = c3.getBBox().x + c3.getBBox().width;
        // 10000 to guarantee both positive numbers. very hacky
        let mywidth = (rightPointofWidth + 10000) - (leftPointOfWidth + 10000);
        return mywidth;
    },
    get height() {
        return this.width;
    }
}

मुझे पूरा यकीन है कि इसे लगाने का एक बेहतर तरीका है। और गेटर्स को कॉल करने की आवश्यकता है; वे console.log(myBB) में दिखाई नहीं देंगे

प्राप्त निर्देशांक और चौड़ाई को इनपुट करने से रेक्ट पीले रंग में आता है। (गुलाबी रेक्टस सर्कल के शोइंग सेंटर हैं) यहां छवि विवरण दर्ज करें

0
Owain Evans 8 जुलाई 2020, 15:24