-
-
Notifications
You must be signed in to change notification settings - Fork 112
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
accessing the internal objects #98
Comments
We are looking for SVG rendering library for our icons and we also need modify some object properties such as color, opacity, or stroke width. It is possible with NanoSVG. |
@jry2 Are you still searching? |
Yes. We also need to hide group with specified id. |
@jry2 I'll let you know when it's ready. |
Maybe classes as well? It will help mass manipulation based on the class |
@rossanoparis @kariem2k @jry2 Added with this commit 760e7e8 |
Example: auto document = Document::loadFromData("<svg viewBox='0 0 200 200'><circle id='a' cx='50' cy='50' r='40' fill='green'/></svg>");
auto element = document->getElementById("a");
element.setAttribute("cx", "100");
element.setAttribute("cy", "100");
element.setAttribute("r", "100");
element.setAttribute("fill", "red");
document->updateLayout(); @rossanoparis Reminder: Don't forget to call |
@sammycage it sounds great! Thank you for starting this kind of implementation I couldn't wait to test it ... what about gradients Is there a chance to operate with gradients handled by using urls instead of constant colours |
@rossanoparis Hello! You have the flexibility to modify any attribute using the versatile std::string content = R"SVG(
<svg width="200" height="200">
<defs>
<!-- Gradient -->
<linearGradient id="myGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color: #ff0000;"/>
<stop offset="100%" style="stop-color: #0000ff;"/>
</linearGradient>
<!-- Pattern -->
<pattern id="myPattern" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
<circle cx="10" cy="10" r="8" fill="#00ff00"/>
</pattern>
</defs>
<circle id="myCircle" cx="100" cy="100" r="50" fill="red"/>
</svg>)SVG";
auto document = Document::loadFromData(content);
writeToPng(*document, "circle-with-solid-color.png");
auto circle = document->getElementById("myCircle");
circle.setAttribute("fill", "url(#myGradient)");
document->updateLayout();
writeToPng(*document, "circle-with-gradient.png");
circle.setAttribute("fill", "url(#myPattern)");
document->updateLayout();
writeToPng(*document, "circle-with-pattern.png"); |
Yes, It's clear, but my question was different. |
@rossanoparis Yes, I understand now. To modify the attributes of a gradient or a pattern, you can use a similar approach with the // To modify gradient attributes
auto gradient = document->getElementById("yourGradientId");
gradient.setAttribute("x1", "newX1Value");
gradient.setAttribute("y1", "newY1Value");
// Add more attributes as needed
// To modify pattern attributes
auto pattern = document->getElementById("yourPatternId");
pattern.setAttribute("x", "newXValue");
pattern.setAttribute("y", "newYValue");
// Add more attributes as needed Feel free to adapt this code based on the specific attributes you want to modify. Let me know if you have any further questions or if there's anything else I can assist you with. But it seems like you've got the method now! |
Thank you @sammycage, it is clear Regarding attributes I'd like to introduce two new requests/discussions. 1) Groups or single object "transformations"
It would be very useful, using the same approach as attributes, to apply transformations to all objects contained in a group or even to a single object. I imagine something like:
2) Groups or single object "references" It would be very useful, using the same approach as attributes, to get such information. I imagine something like:
Transformations and references features would be very powerful to "animate" a SVG document ... what do you think about them. |
@rossanoparis I appreciate your detailed suggestions and the illustrative diagrams you provided. I'm confident that incorporating the This code snippet illustrates the usage of std::string content = R"SVG(
<svg width="200" height="200">
<g id="myGroup">
<rect width="50" height="50" fill="blue"/>
</g>
</svg>)SVG";
auto document = Document::loadFromData(content);
writeToPng(*document, "original.png");
// Get the SVG element and its bounding box
auto element = document->getElementById("myGroup");
auto bbox = element.getBBox();
// Calculate the new position (e.g., move 150 units to the right and 30 units down)
auto newX = 150;
auto newY = 30;
// Calculate the translation values
auto deltaX = newX - bbox.x;
auto deltaY = newY - bbox.y;
// Apply the transform attribute to move the SVG group
element.setAttribute("transform", "translate(" + std::to_string(deltaX) + " " + std::to_string(deltaY) + ")");
document->updateLayout();
writeToPng(*document, "translated.png");
|
Kind @sammycage thank you for aving accepted my proposal and ... wow! how fast you are :) I don't have time in this week to test the latest commits. Again thank you, regards |
@rossanoparis You can adjust SVG transformations with the following code. Feel free to ask any further questions! void writeToPng(Document& document, const char* filename)
{
auto bitmap = document.renderToBitmap();
stbi_write_png(filename, bitmap.width(), bitmap.height(), 4, bitmap.data(), 0);
std::cout << "Generated PNG file : " << filename << std::endl;
}
void setTransformAttribute(DomElement& element, const Matrix& matrix)
{
std::string transform("matrix(");
transform += std::to_string(matrix.a);
transform += ' ';
transform += std::to_string(matrix.b);
transform += ' ';
transform += std::to_string(matrix.c);
transform += ' ';
transform += std::to_string(matrix.d);
transform += ' ';
transform += std::to_string(matrix.e);
transform += ' ';
transform += std::to_string(matrix.f);
transform += ')';
element.setAttribute("transform", transform);
}
int main(int argc, char** argv)
{
std::string content = R"SVG(
<svg width="200" height="200">
<g id="myGroup">
<rect width="50" height="50" fill="blue"/>
</g>
</svg>)SVG";
auto document = Document::loadFromData(content);
writeToPng(*document, "original.png");
// Retrieve the SVG element and its transformation matrix.
auto element = document->getElementById("myGroup");
auto transform = element.getLocalTransform();
// Modify the transformation matrix.
transform.translate(50, 50);
transform.rotate(45);
// Apply the modified transformation to the SVG element.
setTransformAttribute(element, transform);
document->updateLayout();
writeToPng(*document, "transformed.png");
return 0;
}
|
Thank you @sammycage There are some points I don't understand their behaviour, perhaps because of my lack of knowledge ... I'm debugging this feature, and I'm going to open different issues for each test I'm doing related to: scale, rotate, translate ... |
Hi @sammycage
This point probably requires a deep discussion, below I try to explain my needs.
It would be useful to identify an object inside SVG code in order to change some properties after the SVG file has been loaded in memory.
Perhaps the attribute ID ( https://www.w3.org/TR/SVG2/struct.html#IDAttribute ) is the right one to identify objects.
Mainly the purpose is for being able to change colours, lines width, visibility, etc …
It would be very useful to get the position and size occupied by every addressable SVG objects
LunaSVG library should keep a list of SVG objects and expose it in some way
The user should inform the library about the object ID and the attribute to change with the new value.
Regads
Rossano
The text was updated successfully, but these errors were encountered: