Skip to content
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

Get separated element by it's id. #106

Open
Audionysos opened this issue Aug 26, 2019 · 5 comments
Open

Get separated element by it's id. #106

Audionysos opened this issue Aug 26, 2019 · 5 comments
Assignees
Labels

Comments

@Audionysos
Copy link

Hi,
Is there a way I could get some portion of the drawing by it's "id" attribute? I'm currently loading the drawing via SvgViewBox but from what I see this only produces raw GeometryDrawing instances on drawing canvas that I cannot identify. Is there any way I can do this at the moment?

On top page you wrote "Interaction with the conversion process (by a visitor pattern) to allow for custom hyper-link implementations, font substitutions etc." by I'm not sure if this is what I need and can't find example of that.

Basically I have drawn some buttons in illustrator and would like modify some basic stuff at runtime - toggle visibility, maybe change some background, or size. Can I force converter to output WPF Grids for named elements?

@paulushub paulushub self-assigned this Aug 26, 2019
@paulushub
Copy link
Contributor

paulushub commented Aug 27, 2019

This issue is come up several times and we have resolved them but not settle it. Basically, you will need to perform hit-test or search through the DrawingGroup. All the codes you will need are already in SvgDrawingCanvas but are not used since these were designed for a particular need.
I commented some out so that I could solve all under interactivity task #10 and #11, in more general way.

For a start, any id attached to an SVG element is passed to the converted drawing. Any CSS class name is also attached to the converted drawing.
The codes in SvgDrawingCanvas shows to create hyperlink, show tool-tips and animation but as I said were designed for my own need at the beginning of this project. You can take a look.

On top page you wrote "Interaction with the conversion process (by a visitor pattern) to allow for
custom hyper-link implementations, font substitutions etc.

That is about participating in the conversion process itself not after. By the end of this weekend, I will try to make the necessary interfaces more accessible. Give me a little more time so that I could completely address this issue. Currently trying to complete the SVG font support task #9.

@Audionysos
Copy link
Author

Thanks, I will look up for it. It's just for little side project at the moment, so no hurry :)

paulushub added a commit that referenced this issue Sep 28, 2019
- Improved the WpfDrawingDrawing object implementation
- Added support for hit-testing by point and rectangle
- Added a sample, WpfTestSvgControl, for testing this feature
- Modified the codes to make the SetId value same as the SVG ID
- This is the first step in support for interactivities and resolve the issue #106
@paulushub
Copy link
Contributor

@Audionysos Hello! Sorry for the delay. I have started implementing a new class WpfDrawingDocument to make it easier to work with this issue.
The initial support for this issue of searching for and getting the drawing by ID was not complete. Basically, the ID of the SVG element is converted to x:Name property in the drawing. However, there were a few issues with this method:

  1. ID conversion to Name supports visitor pattern to allow the user to redefine it
  2. ID may be modified to qualify as C# variable name

Both of these could make the ID not compatible with the original ID defined in the SVG file.
The other problem is that, when you use async/await method to create the conversion, you have two options to make the drawing available to the GUI thread; either you freeze the drawing or save it to memory-stream as XAML and back to drawing object in the GUI.
The second approach, which is used in most of the demo samples, since that will preserve animations if any, means information kept about the drawing in the background thread must be discarded and recreated.

The WpfDrawingDocument is provided to help resolve these issues. This object is created by the FileSvgReader, since there is no need for other converters to support it. I have also extracted and moved the hit-testing methods in the SvgDrawingCanvas class to the WpfDrawingDocument with various improvements.

Finally, I have created a sample application WpfDrawingDocument for testing these features and will add the hit-testing demonstrations later. It is a modification of the current WpfTestSvgSample.

Now, please can you test this code and provide feedback for improvements? After these I will modify the SvgViewbox and SvgCanvas to support it.

WpfTestSvgControl

paulushub added a commit that referenced this issue Aug 29, 2020
- Hit-testing of the rendered drawing/geometry now works as expected.
- Issues: #106 #10
@Audionysos
Copy link
Author

Audionysos commented Dec 17, 2020

Hello, I actually didn't expect from you to be that quick :) I've only find out that you responded about half a year ago and I played around with this but I didn't finish what I wanted, then I couldn't find the project I made and now I just moved back to in yesterday and made some progress.

So this seem to work. I made a little explorer class based on the WpfDrawingDocument to manipulate the image easier. It may not fit your programming style but it works nice for me, and the ids do work.

public MainWindow() {
	InitializeComponent();
	var d = new SVGExplorer("data/test.svg");
	Content = d.view;
	d["star"].look.fill = Brushes.Black;
	d["star"].events.mouse.DOWN += (s, e) => {
		var r = d["rect815"];
		r.look.toggleVisibility();
	};
	d["path821"].transform.pivot.toMassCenter();
	d["rect815"].events.mouse.DOWN += (s, e) => {
		var o = d["path821"];
		o.transform.x += 30;
		if (o.transform.x > 300) o.transform.x = 0;

		o.transform.scale *= 1.5;
		if (o.transform.scale > 3) o.transform.scale = 1;
		o.transform.rotation += 20;
	};
}

sharpvectors

Now, I still didn't figure out few things.

  1. Initially I added this project to my local repo of SharpVectors and it works from there. However when I extracted this to separate solution and installed latest SharpVectors nuget package the WpfDrawingDocument.DrawingNames don't sore any name. Do I need to specify some additional configuration for the properties. Here is the link for this solution.

  2. I would like to be able to change text of the <text> element. But I'm not sure how to do this. I tried to set Characters property of GlyphRunDrawing, but this gives me an exception. I'm also not sure if a new text would be properly placed. Can you give me some hints? How you set up these glyph runs?

  3. I concerned about object's transform's center. Inkscape exports path with absolute coordinates or relative to layer and produced WPF drawings seem to reflect that. However this is not ideal when I rotate or scale an object. I can set pivot point relative to AABB of the drawing and this works ok in most scenarios. However there are some object for which this is not desirable. For example the AABB of a star may not be in it's center. For star I can calculate center of a mass to rote it in place, however there are still some other scenarios where it would be nice to specify pivot in a drawing software. For example if I would like to animate pointer of a gauge, it's practically impossible to figure out the point in code:

gaugeRotation

When I move the point in Inkscape, I see Inkscape saves this as inkscape:transform-center-x/y. This suggest that defining such point is not native for SVG, so you probably will not support it. Perhaps maybe there is a way I can access whole original svg element that is associated with the drawing similar to how I access WpfDrawingDocument.DrawingNames?

@paulushub
Copy link
Contributor

Really nice work you are doing with this stuff, highly impressive.

installed latest SharpVectors nuget package the WpfDrawingDocument.DrawingNames don't store any name.

True, the initial release was experimental and the updated version even add more information to the drawings that are
not needed except when you need the features in WpfDrawingDocument. So, I made it optional, you have to set the a new property, InteractiveMode to either SvgInteractiveModes.Standard or SvgInteractiveModes.Advanced. For now there is no difference between the Standard and Advanced modes.
For the advanced mode, I am thinking about something in line with your work but by rendering each individual drawing to DrawingVisual, which is still lighter object but supports interactivities unlike the Drawing objects.

I have posted a pull request to your repository, so you can take a look at the updates to make it work.

I would like to be able to change text of the element.

It is one of the puzzle I have still not resolved yet. At the WPF low-level, that flexibility of simple changing characters is not there, so you may need to recreate the GlyphRunDrawing or set both GlyphRun.Characters and GlyphRun.GlyphIndices, I have not tried it.

The main problem is when the text is rendered as PathGeometry, there you cannot even tell the original character contents.

I concerned about object's transform's center.

WpfDrawingDocument contains the SVG DOM or SvgDocument object instance WpfDrawingDocument.Document , which is an extension of the .NET XmlDocument class, so you can query it for all other contents.
If necessary, we can support the Inkscape contents like the metadata contents element, SvgMetadataElement; say SvgInkscapeElement with specialized properties to make things easier.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants