Sunday, August 31, 2014

Downside of SVG - Fonts

My third attempt at conversion to SVG is a logo with text. I spent about 4 hours doing it, because it's got 16 different SVG elements without counting the linear gradients (which are creating using elements instead of CSS it turns out). In the end, it looks really great, and the text resizes smoothly in a way that you normally requires javascript:

SVG:

Original PNG:




Here's the thing. If you are reading this post via a Windows or OSX -based PC, then the two should look almost identical. If you are using Firefox on Android the same will apply. However, Chrome, Dolphin, and the Android browser itself, will all render this incorrectly. See the comparison below. The top is Firefox for Android, the bottom is Chrome on Android:



The problem is that the font I'm using is Palatino Linotype, which ships default with Windows and OSX (and somehow Firefox for Android??). Chrome doesn't have it though, and so pulls in the default Chrome serif font. It's thicker and so looks too big.

All of which leads me to a fundamental problem of SVG, which is that it's not prerendered, and because of that it relies on the browser having all rendering resources. If you notice in the comparison, there's another problem. The first letter of each word isn't a large size in Chrome. This is because Chrome doesn't support the CSS rule "first-letter" for SVG text elements. As I take SVG into more complex situations, I'm becoming less sure it is really read for primetime. Which is sad, because when I compare the SVG and PNG versions of this logo on my phone, the clarity difference is striking. I just have to find workarounds to all the things that Chrome is screwing up.

In regards to the font-face, I just need to embed the font or have the SVG pull from a hosted source. If one is using a commercial font, however, one runs into issues. Palatino Linoype costs 150 bucks, so for this particular logo I'm out of luck (unless someone knows a free alternative that looks close enough that most people won't tell the difference??). It can be mitigated by using open-source fonts. As to the first-letter issue, the alternative is to split the text elements into more text elements and apply the large size via classes.

EDIT:


I've started a StackOverflow question about workarounds to the first-letter issue. Hopefully someone will have a clever idea.

Monday, August 18, 2014

CodePen.io SVG Feature Request Update

Less than two weeks ago I submitted a feature request to CodePen.io, for the ability to embed a 'pen as an SVG image. Not only did they respond within a few days saying that they'd add it to their list, they actually got it working .... in less than two weeks. Take a look at the logo I converted to SVG a few days ago, emdedded below from CodePen. It looks and acts like a simple image. This is how I'd be calling it in a production site, as an image. It's really easy now to compare the difference between the two image types:

SVG:




PNG:

(Displayed at native resolution)





Now, if CodePen could add the ability to take snapshots and version history like JSFiddle does, I'd have everything I need in one service and wouldn't have to use both.

Sunday, August 17, 2014

Shift In Focus

Over the years, this blog has been somewhat of a scattershot of topics. Initially, it had a very political/civil liberties focus, but that branched into more theoretical topics, such as ethics and philosophy. As I moved into web development, and WordPress, those became topics of greater frequency. And scattered throughout have been posts on music, humor, and even poetry I've written.

You may have noticed that I haven't posted much about politics for some time, and the reason is that politics has become increasingly depressing to me. We live in a society which increasingly embraces constant surveillance, in which we daren't videotape a police officer out of fear of retribution. A society in which we can be sent to prison for shooting a home intruder who invades without a warrant or even warning, just because they happen to have a badge and made a mistake on the address. There are some bright spots. Marriage equality has won. The falling tree may not have hit the ground, but gravity took over years ago and the conclusion is foregone. But in almost all areas, the world has become a scarier and more depressing place.

I also don't write about civil liberties as much, because I have grown increasingly disillusioned and fed up with all sides. It is absolutely wrong to judge someone for the color of their skin, or for the person they love. But that cuts both ways, and as someone who has been judged for being a white male by my supposed allies, my willingness to get involved has decreased over time. Yes, I understand that I have white privilege, and any automatic judgement I get for my skin is nothing compared to the judgement that a transgender person of color gets. But time and time again I see a level of automatic hate coming from the non-cisgendered community that almost approaches the level of hate (that I've fought against) from the fundamentalist religious faction.

Which brings me to my final point. What I HAVE been writing more about recently is code. The beauty of PHP, of HTML, of CSS ... is that they are languages of utter and complete honesty, and logic. If you write something, it's either correct or incorrect. There's no debate, there's no hatred. Certainly people might have differences of opinion on best practices, or what browser to use, but in general it's a much more pleasant area to spend my time in. Additionally, the communities are some of the least judgmental communities that exist. No one cares about who you are or what you look like. If you can write good code, or design great UX, or even just come up with good ideas ... that is all that matters. WordPress contributors are from all around the world, and almost no one brings their societal/cultural baggage with them. Code is king, and I like code.

Saturday, August 16, 2014

SVG: A More Complex Logo

My logo is extreme simple. It has two shapes and is all straight lines. Because of this simplicity, I had no trouble converting it to SVG, and the entire file ended up being four lines of code. My next challenge, then, is to convert a more complex logo, one which involves more shapes, and shapes which involve curves. My partner at Catstache has a logo which fits the bill. It's complex, has many layers, and is more than one color. So can it be done well in SVG? Lets take a look at the logo in PNG first:



As you can see there is a pen (which also is two letters), plus an ink drop, and a curved line. And this is all on a double circle. We'll need 6six different shapes to create the entire thing. Lets get started!



We first need to create the SVG wrapper code. I'm going to give it dimensions of 250 by 250. These will scale when it's displayed, but it's large enough that we won't have to use partial numbers much:

<svg version="1.1" baseProfile="full" width="250" height="250" xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink">
</svg>




Inside that code, we'll add all of our shapes. SVG does layering in order of code. The first element that you type will be on the bottom, and the last one will be on the top. So we'll start with a gray circle. To create this, I'm going to use , and put it in the center by saying that the center's y and x coordinates at both 125, and the radius is 125:

<circle cx="125" cy="125" r="125" fill="rgb(24,24,24)" />

This gives us: (JSFiddle)





Next up is the white border. Since this isn't on the outside, we need another circle, slightly smaller. It needs a white border, and transparent fill.

<circle cx="125" cy="125" r="115" fill="transparent" stroke="white" stroke-width="4" />

Adding this gives us: (JSFiddle)





Now that we have the background done, we need to start on the shapes. I'm going to do the pen first. I'm going to create a line using , and it will have two segments, all straight. The way this is created is really odd. You basically use letters as commands, inside the "d" attribute. "M" with coordinates is where the line starts, then "L" with coordinates means it moves to those new coordinates. A line with 2 segments has 3 points. So we'll use an "M" and two "L"s.

<path d="M192 50 L170 111 L186 117" stroke-width="4" stroke="white" fill="transparent" />

Adding this gives us: (JSFiddle)





The bottom portion of the pen shape consists of 4 segments, which means five coordinates. We'll use another , this time with an "M" and four "L"s.

<path d="M183 125 L167 170 L163 161 L146 175 L166 117" stroke-width="4" stroke="white" fill="transparent" />

Adding this gives us: (JSFiddle)





Next up, we need the ink drop. When I researched the shape, I found out that it is possible to make an ink drop. It's extremely complex though, so we are going to simply slightly and use an ellipsis. At most resolutions, it will be a negligible difference anyway. I'm also going to rotate it, to get the long radius angled towards the pen tip. This shape is similar to the circle, in that we declare the coordinates of the center. The difference is that there is an x radius and a y radius. Also, we are rotating 15 degrees, which is another attribute.

<ellipse transform="rotate(15)" cx="183" cy="150" rx="3" ry="5" fill="white" />

Adding this gives us: (JSFiddle)





Finally, we need to create the curving trail that the pen has already left. This is the most complex part. SVG has several ways to do curves, and to be honest I don't really fully understand them all. But the easiest is a method in which you define 4 points to make a single arc. We still use the , and still use the "d" attribute. Instead of an "L" command, we use a "Q" to create the curve. For this specific shape, we'll need to combine several arcs. After playing around for about a half hour, I got a long that looks very similar to the goal.

<path d="M130,193 C81,208 132,153 71,170 Q32,181 49,158" stroke-width="2" stroke="white" fill="transparent" />

Adding this gives us: (JSFiddle)





Success! The final code ends up being:

<svg version="1.1" baseProfile="full" width="250" height="250" xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink">
<circle cx="125" cy="125" r="125" fill="rgb(24,24,24)" />
<circle cx="125" cy="125" r="115" fill="transparent" stroke="white" stroke-width="4" />
<path d="M192 50 L170 111 L186 117" stroke-width="4" stroke="white" fill="transparent" />
<path d="M183 125 L167 170 L163 161 L146 175 L166 117" stroke-width="4" stroke="white" fill="transparent" />
<ellipse transform="rotate(15)" cx="183" cy="150" rx="3" ry="5" fill="white" />
<path d="M130,193 C81,208 132,153 71,170 Q32,181 49,158" stroke-width="2" stroke="white" fill="transparent" />
</svg>


Wednesday, August 6, 2014

Creating SVG with CodePen.io

Over the past few days, I've been exploring the SVG image format, and I converted my own logo, with great results. I decided to try my hand at a more complex logo, and I decided that instead of typing, saving, and refreshing the browser, I'd use Codepen.io. I chose this testbed over my normal JSFiddle.net testbed due to it's live updating capability.

I'll go into detail another time about the new logo, but suffice to say I got it working. To test in a webpage, I really wanted to just take the codepen that I'd created and embed it. They have a nifty feature where you can write JS or CSS in one 'pen, and embed the whole 'pen into another. Turns out this wonderful recursion doesn't work with inline SVGs though. It would be a great feature to have, though, I think. Apparently the creators of CodePen agree (and are also VERY timely with feature request responses. The ability to embed inline SVG 'pens into another 'pen is now on the feature shortlist!

Monday, August 4, 2014

SVG vs PNG Logo Results

Earlier today I wrote about the method I used to convert my website logo from a scalar PNG to a vector SVG file. I wanted to share the results with you.I opened the site up in Firefox, and then CTRL+ zoomed in as far as possible. Then I screenshot'd a before and after:

Scalar PNG Logo:




Scalar PNG Logo:




Another nice feature is a size reduction of the image file. I went from 604B to 294B, which is a better than 50% reduction! Granted, both files are incredible tiny, but I've tested with a more complex logo and the reduction is even better, down from 2340B to 704B.

Converting Logo to Scalable SVG

Background


When coming up with a logo, I took inspiration from the first letter of my name: A. I played around with many variations, and eventually came up with a symbol which resembles an A but isn't exactly the same.



I took my sketches out ideas, and went into Paint.net to come up with a sharp looking PNG icon. I started out large, at 500px by 500px, and then resized down to come up with an icon which looks decently sharp (I've played a gray background under it to make it easier to see):


I plugged it into my website (my WIP website which has been sitting on my localhost for 6 months now, awaiting the availability of andymercer.net), and left it there.

Recently I built a site for my partner at Catstache, and when I tested it on a high-res screen, her logo looked terrible. I realized the problem was that it was the only thing on the site that wasn't vector. I immediately remembered my own logo, and sure enough when I tested, it too looked blurry when zoomed in. I set out to rebuild it in a vector format.



Solution


I chose SVG as my format because it's the mist widely support vector format. Every web browser will correctly render an SVG image, and it'll look sharp at any size. The issue is that one has to either build the image with a vector program (which I don't have) or code it manually, which sounds complex. Given my lack of Photoshop, I looked into coding it by hand.

To my surprise, I found that it's actually incredibly simple. You basically imagine a grid, starting from the top-left, and moving down. You define shapes, and give them an X and Y coordinate (higher being further right and down). That's it. I broke my logo into two polygon shapes, and defined each breakpoint.

<svg version="1.1" baseProfile="full" width="50" height="50" >
    <polygon points="15 5, 11 20, 39 20, 35 5" fill="white"/>
    <polygon points="10 25, 5 45, 15 45, 16.5 39, 33.5 39, 35 45, 45 45, 40 25" fill="white"/>
</svg>


This ends up appearing as:


You should be able to see it, and if you zoom this page, it should stay super sharp. And only 4 lines of code. Success!

EDIT: I just viewed this post on my Galaxy S4, and the difference between the PNG and the SVG is enormous. The SVG is far sharper.