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

Feature Request: support scalable (i.e. 9 slice) SVGs elements #29

Open
Emasoft opened this issue Jul 26, 2015 · 12 comments
Open

Feature Request: support scalable (i.e. 9 slice) SVGs elements #29

Emasoft opened this issue Jul 26, 2015 · 12 comments

Comments

@Emasoft
Copy link

Emasoft commented Jul 26, 2015

Please add scalable (i.e. 9 slice) SVGs elements to NGraphics.

Let me explain what I mean by that. As you know SVG are already scalable, being vector based. For example for gradients I just use an SVG image. A simple rectangle drawn in Inkscape, where I can edit and preview all gradients colors, steps, orientation, etc. This is the svg file content:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="600" width="600" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 600 600">
 <defs>
  <linearGradient id="linearGradient4297" y2="600" gradientUnits="userSpaceOnUse" x2="300" x1="300">
   <stop stop-color="#e66aff" offset="0"/>
   <stop stop-color="#fef8ff" offset="1"/>
  </linearGradient>
 </defs>
 <rect style="color:#000000" height="600" width="600" y="0" x="0" fill="url(#linearGradient4297)"/>
</svg>

Then I use the Xamarin Forms SVG plugin with NGraphics to display it and resize it from the default size (viewBox of 600x600 pixels) to fit any Windows, iOS or Android app frame or button background.
In this way artists in my team can change all graphic elements and color themes without my intervention, just editing the SVG files in Inkscape.

A 9-slice element is something different and more complex. Is the composition of both a regular svg image, and a 3x3 grid definition associated with it. Each sub element of the 3x3 grid is flagged with one of the following tags:

  • "resizable horizontally"
  • "resizable vertically"
  • "resizable in both directions"
  • "not resizable".

The renderer of the app should be aware of this and be able to render the svg image scaled according to the grid. Usually this is used to create frame border, setting the corners of the 3x3 grid as "not resizable", the left and right elements as "resizable vertically", and the top and bottom elements as "resizable horizontally". The central element must be set to "resizable in both directions".
The Android SDK already implements this, Windows Mobile doesn't, while on iOS there is a very limited implementation (see: http://macoscope.com/blog/stretchable-images-using-interface-builder/ ).

A true cross platform implementation of this would be very useful for using 9-tiles on Xamarin.Forms.
The Xamarin.Forms plugin for SVG uses NGraphics, and then we would need to add this feature to NGraphics library. We need to add a method to associate the 3x3 grid matrix to the current loaded svg image. It would be useful to load the 3x3 grid data from the SVG image itself, using some metadata.

Currently SVG already supports 9-slice resizing, because SVG format specification includes many CSS 3 style attributes. And that is by using the CSS style attribute BORDER-IMAGE-SLICE:

https://developer.mozilla.org/en-US/docs/Web/CSS/border-image-slice

border-image-slice

schermata 2015-07-26 alle 23 06 01

Here is an interactive example I've made on codepen of an SVG button resized with the border-image-slice attribute:

http://codepen.io/Emasoft/pen/qEsFr

It would be great to have this functionality supported by NGraphics.

@BlueRaja
Copy link

I don't mean to be a pessimist, but I think if you want this functionality implemented you're most likely going to have to implement it yourself.

But if you do, please send a pull-request to share with the rest of us!

@chrfalch
Copy link
Contributor

This is in my opinion a little bit too specialized for a generic library like NGraphics, since the library is trying to provide developers with generic functionality to do cross platform drawing.

I suggest that you build this as a separate control that you can publish as a Nuget package.

@Emasoft
Copy link
Author

Emasoft commented Jul 27, 2015

Unfortunately it is not possible to add the 9-slice as a separate control. The 9-slice feature should be integrated right into the NGraphics rendering pipeline, to make use of the specific and optimized rendering methods of the various platforms. It must also apply the slices transformations on its vector rappresentation of the image internally, to let the user of the library still operates on the original, untrasformed and unsliced, elements. In this way the geometric data is always consistent, while the 9-slice processing is something invisible to the user. An external component would add additional burden to this process, having to render the graphic element in an intermediate 9-slice geometric rappresentation before passing it to the NGraphics rendering pipe again. If the process will be managed internally by NGraphics, you'll be able to render directly the 9-sliced version of the element on the device canvas, using the specific features of the platform to speed up the task. No need to rerender the element to an intermediate geometric rappresentation.

Also: a 9-slice element it is a very common element in UI design. I'd say that this is not specialized at all. There is nothing more broad and useful. Supporting 9-slice would make this library very popular among developers.

@ansuria
Copy link

ansuria commented Jul 27, 2015

I second the notion that 9-slice graphics are a common, accepted way of
skinning UI elements. 9-slice PNG files were the only thing used on
projects that I worked on back in my Adobe Flash/Flex days. They're very
handy for UI elements like buttons, frames, panels etc.

Creating 9-slice graphics is supported in the Adobe tools, including
Illustrator and Fireworks. See these Adobe videos for examples:
http://tv.adobe.com/videos/9-slice-scaling/

Having an equivalent for the SVG format would be super groovy!

On Mon, Jul 27, 2015 at 10:38 AM, Emasoft notifications@github.com wrote:

Unfortunately it is not possible to add the 9-slice as a separate control.
The 9-slice feature should be integrated right into the NGraphics rendering
pipeline, to make use of the specific and optimized rendering methods of
the various platforms. It must also apply the slices transformations on its
vector rappresentation of the image internally, to let the user of the
library still operates on the original, untrasformed and unsliced,
elements. In this way the geometric data is always consistent, while the
9-slice processing is something invisible to the user. An external
component would add additional burden to this process, having to render the
graphic element in an intermediate 9-slice geometric rappresentation before
passing it to the NGraphics rendering pipe again. If the process will be
managed internally by NGraphics, you'll be able to render directly the
9-sliced version of the element on the device canvas, using the specific
features of the platform to speed up the task. N o need to rerender the
element to an intermediate geometric rappresentation.

Also: a 9-slice element it is a very common element in UI design. I'd say
that this is not specialized at all. There is nothing more broad and
useful. Supporting 9-slice would make this library very popular among
developers.


Reply to this email directly or view it on GitHub
#29 (comment)
.

@patridge
Copy link

While it probably wouldn't end up back here in core NGraphics code, I'm working on a 9-slice-capable SVG control built on NControl (the NGraphics-wrapping control library). While this post deals with an implementation based on the SvgImage library, I wrote about the same naïve 9-slice implementation used in the NControl version in this blog post.

@Emasoft
Copy link
Author

Emasoft commented Feb 24, 2016

@patridge That experiment is amazing, and it is truly a great progress toward a true 9-slice SVG. Maybe you should team with @praeclarum Frank Kruger to do this directly inside NGraphics!

P.S.
I've also proposed to the SVG working group to define a standard attribute for the 9-slice matrix in the SVG file format,so that we can store that information in a standard and exchangeable way, from artists to developers.

@chrfalch
Copy link
Contributor

NControl just got built-in support for svg's (https://github.com/chrfalch/NControl.Controls/blob/develop/NControl.Controls/SvgImage.cs), maybe this could be something to build upon? NControl.Controls is a library with controls built on NControl.

@patridge
Copy link

Thank you so much for adding it. I just found it yesterday. I spent some time yesterday trying to figure out how to incorporate the NControl-based 9-slice SVG efforts I rigged up back in January into that SvgImage control and hit a snag. It probably isn't going to be impossible to reconcile them, I just didn't see it immediately. Your SvgImage is much cleaner since it doesn't use custom renderers, but I'm not quite sure yet how to allow re-drawing the image with your approach when width/height/insets change during runtime.

On that note, NGraphics appears to be heading toward using a cross-platform Platforms.Current soon (post v0.4.0) that could allow my variant to eliminate most of the custom renderers code (maybe entirely, if I'm lucky).

@Emasoft
Copy link
Author

Emasoft commented Feb 24, 2016

Not many people I know are using NControl, because the main advantage of NGraphics and SVG is that they allow an easy developement of custom controls. (just draw them in Inkscape, one SVG for each control state, and you get them ready to use). Everybody is jumping on the NGraphics train because today mobile apps need to have an unique look (and unique controls) to stand out and sell. If Platforms.Current is going to happen I think NGraphics will become hugely popular, probably becoming the jQuery of the mobile world.

@chrfalch
Copy link
Contributor

@patridge: I'd be happy to take a look and see what I can do about redrawing after changing insets etc. Redrawing should be simple and easy to fix.

I can take a look and see if it is possible to merge your code into the existing SvgImage control in NControl.Controls or if we should create it as a separate control.

@Emasoft: Thanks for making a point about usage adoption; NControl has approximately the same number of downloads on NuGet as NGraphics (https://www.nuget.org/packages?q=ngraphics) so I would assume that the work done by @patridge would be appreciated among these developers.

@patridge
Copy link

@chrfalch First off, thank you so much for your work on NControl. I absolutely love what it enables. I wish I had started using it sooner.

I would be happy to contribute everything I can back to NControl.Controls if we can make it work. And I would definitely appreciate a second set of eyes and any direction you might be able to suggest in reworking what I have. I am fairly new the NControl and ideal control coding practices, so I won't be surprised if I went the wrong direction coming from the version I built based on paulpatarinski's SvgImage control.

Would it be useful for me to start a PR and/or issue thread on NControl.Controls for this effort instead of stretching this thread on further?

@chrfalch
Copy link
Contributor

@patridge Thanks for the feedback, really appreciate it. Yes, a PR/Issue would be great.

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

No branches or pull requests

5 participants