Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for Geeking-out on SVG Graphics part-three
Tracy Gilmore
Tracy Gilmore

Posted on • Edited on

     

Geeking-out on SVG Graphics part-three

Reprise

My project is to create an SVG-based backdrop in the style of a cutting mat for software engineers (well me, not really anyone else, apologies for being selfish).

As covered in theprevious post, I have a grid 4000px by 2500px with cells of 250px square and bounded with a slightly thicker rectangle. Also, as stated in the previous post, I have chosen a background colour based on engineer's marking fluid (#191662) and a grey (#777) for the grid lines and the by-line.

In this third post I will be representing a small number of screen resolutions using actual screen dimensions. We will also show ratio projection lines and labels. See theinitial post for more details.

I will release the cutting-mat SVG image at the end of each stage via myGitHub repo.

Screen Resolutions

As the technology behind computer displays has progressed we have seen a significant increase in the number of pixels that can be used to present graphical information on screen. We have also seen displays getting wider but in general the width and height a screen presents (in pixels) conforms to an industry standard and align to a common ratio.

Display units (known as Cathode Ray Tube (CRT) displays) of the 1980's and 90's typically assumed a ratio of 4:3, for every four pixels of width there would be three pixels in height.

Examples includes:

Screen ResolutionsWidthHeight
VGA640480
SVGA800600
XGA1024768
UXGA16001200

More recently people will be familiar with flat-panel High Definition (HD) screens, which assume a 16:9 resolution ratio.

Screen ResolutionsWidthHeight
HD 720p1280720
Full HD 1080p19201080
UHD 2K/QHD 1440p25601440
UHD 4K38402160

Wikipedia has an excellent page on this topic.

In this step of the project I want to represent each screen resolution using actual pixel dimensions. The rectangles will be anchored to the top-left corner of the grid with a label to indicate the standard and resolution attached to the bottom-right corner. Two projection lines from the origin will pass through the diagonal for each rectangle to link the common resolutions.

Let's get coding

We will update the project in three stages, first we establish a containingsvg element with threegroup elements within it.

Stage One - SVG and group containers

There will be one group for the ratio projection lines, a second for the rectangles and labels, and a third for the title text and an anchor point. The order is significant as the graphics will be plotted on top of each other ingroup element order.

<svgx="20"y="20"width="1360"height="880"id="resolution"viewBox="-125 -125 4250 2750"><gclass="ratios"></g><gclass="rectangles"></g><gclass="labels"><textx="25"y="-25"class="title">Screen Resolutions</text><circlecx="0"cy="0"r="15"></circle></g></svg>
Enter fullscreen modeExit fullscreen mode

Things to notice in the above code include:

  • See how the dimensions of thesvg element (1360 x 880) is considerably smaller than the largest screen resolution I want to plot (3840 x 2160).
  • We have an attribute ofviewBox that offsets whatever is presented insidesvg element#resolution by 125px up and to the left. We have also remapped the 1360x880 actual pixels to 4250x2750 'virtual' pixels.
  • The first and second groups are currently empty but the third contains hard-coded SVG elements for the title text and the origin circle.

The projection lines will start at the same origin as the screen resolution rectangles and extend to the edge of the grid. As the grid itself has an aspect ratio of 16:10 neither projection line will pass through the bottom-right corner of the grid. The 16:9 line will pass trough the right-side edge and the 4:3 line will go through the bottom edge.

Stage two - update the styling

First we add a custom property to provide a common colour.

--resolution-colour:#fcc;
Enter fullscreen modeExit fullscreen mode

Next we add styling for the content.

#resolutionline,#resolutionrect{stroke:var(--resolution-colour);stroke-width:3;fill:transparent;}#resolutioncircle{stroke:var(--resolution-colour);stroke-width:2;fill:var(--background-colour);}#resolution.labelscircle,#resolutiontext{fill:var(--resolution-colour);}#resolution.ratiostext{font-size:3rem;text-anchor:middle;}#resolution.labelstext{font-size:2.5rem;text-anchor:end;}#resolution.labels.title{font-size:4rem;text-anchor:start;}
Enter fullscreen modeExit fullscreen mode

We are referencing theid attribute of theSVG element to target the text, lines, circles and rectangles it contains to apply styling.

Finally - We have the JavaScript required to populate the empty group elements

We start by updating the main function to calldrawResolutions that callsdrawProjectionLines for the first group anddrawScreenResultions for the second group, as follows.

(function(){drawGrid();drawResolutions();})();// :functiondrawResolutions(){drawProjectionLines();drawScreenResultions();}
Enter fullscreen modeExit fullscreen mode

The following functions follow a similar pattern:

  1. Locate the DOM entry point (group element) using thedocument.querySelector('#resolution ... method.
  2. Prepare the data to be rendered.
  3. Traverse the data and for each item generate the SVG instruction(s) required to represent the data.

drawProjectionLines

functiondrawProjectionLines(){constresolutionRatios=document.querySelector('#resolution .ratios');constratioLines=[{w:3333,h:2500,t:'4:3'},{w:4000,h:2250,t:'16:9'},];ratioLines.forEach(r=>(resolutionRatios.innerHTML+=`      <line x1="0" y1="0" x2="${r.w}" y2="${r.h}"        stroke-dasharray="8,8"></line>      <circle cx="${r.w}" cy="${r.h}" r="60"></circle>      <text x="${r.w}" y="${r.h+20}">${r.t}</text>    `));}
Enter fullscreen modeExit fullscreen mode

So, we locate the group in the resolutionSVG element with a class ofratios. We prepare an array contain the data for the two projection lines including the width (w), height (h) and text (t) label.

For each item in the array we create the SVG instructions for a projection line using a template literal (string) and inject it into the DOM using theinnerHTML attribute. This might not be the most performant approach but it works and performance is not a major concern, especially for two data items.

The string consists of three SVG elements;

  • the line running from the origin to the 'w' and 'h' coordinates. We will use a dashed line for the projection lines via thestroke-dasharray attribute.
  • a large filled circle is drawn on top of the end of the projection line where is intersects with the edge of the grid.
  • within the boundary of the circle we add atext element stating the ratio the projection line represents. The vertical location of the text is 20px lower than the centre of the circle.

drawScreenResultions

So, I cheated but for good reason. ThedrawScreenResultions function is actually split in two further function calls:

  • ThedrawScreenResultionsRectangles function draws the rectangles representing the screen resolutions.
  • ThedrawScreenResultionsLabels function adds the labels, which uses a different resolution otherwise the text would be too tinu to read.Both functions use the same data set that is created in thedrawScreenResultions function and passed as an attribute to the sub functions. The data consists of an array of objects, one for each screen resolution, and containing the following properties:
  • width
  • height
  • spec: the name of the standard the resolution applies
  • xOffset: the number of pixels left/right to shift the text so it aligns with the rectangle.
  • yOffset: similar to xOffset, it is used to position the text relative to the rectangle representing the screen resolution.I will not present the data in this post as it is quite lengthy but ask you check out the repo if you are interested.

With the data already defined the sub functions just have to locate the entry point in the DOM and render the appropriate graphics.

drawScreenResultionsRectangles

The entry point is the group with the class ofrectangles and the rendering is rectangle that starts at the origin and uses the prescribed width and height, which is also used to locate a small filled circle.

drawScreenResultionsLabels

Using the entry point in the DOM of the group with the 'labels' class, this function injects the text at the prescribed location.

There we have it. We have a cutting-mat with a grid, by-line, Creative-commons link and presenting a selection of the (arguably) most common screen resolutions along with their ratio projection lines.

Cutting-mat with screen resultions

In thenext instalment I will be adding some 'standard angles' and using thepath element to draw some arcs, which is harder than is sounds so stay tuned.

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

After my first contact with a computer in the 1980's, I taught myself to program in BASIC and Z80 assembler. I went on to study Computer Science and have enjoyed a long career in Software Engineering.
  • Location
    Somerset, UK
  • Education
    BSc (Hons) Computer Science
  • Work
    Software Engineer specialising in web technologies, frontend and full stack (Node & xAMPP)
  • Joined

More fromTracy Gilmore

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp