SlideShare a Scribd company logo
Make	
  your	
  own	
  Print	
  &	
  Play	
  card	
  
game	
  using	
  SVG	
  and	
  JavaScript	
  
Kevin	
  Hakanson	
  
5	
  April	
  2014	
  
Abstract	
  
Want	
  to	
  leverage	
  your	
  creaDvity,	
  love	
  of	
  board	
  games,	
  and	
  web	
  plaGorm	
  experience	
  to	
  do	
  
something	
  different?	
  	
  Turn	
  your	
  imaginaDon	
  into	
  a	
  Print	
  &	
  Play	
  card	
  game	
  using	
  only	
  a	
  modern	
  
web	
  browser,	
  color	
  printer	
  and	
  text	
  editor.	
  
	
  
This	
  session	
  will	
  use	
  the	
  Scalable	
  Vector	
  Graphics	
  (SVG)	
  image	
  format	
  and	
  JavaScript	
  
programming	
  language	
  to	
  make	
  a	
  deck	
  of	
  cards	
  for	
  a	
  simple	
  game.	
  	
  CreaDng	
  a	
  few	
  cards	
  in	
  
graphics	
  soSware	
  like	
  Inkscape	
  is	
  one	
  thing,	
  but	
  what	
  about	
  50	
  or	
  100	
  cards?	
  	
  What	
  happens	
  
when	
  you	
  need	
  to	
  update	
  them	
  all?	
  	
  That’s	
  the	
  value	
  of	
  generaDng	
  your	
  SVG	
  using	
  JavaScript.	
  
	
  
We	
  will	
  start	
  with	
  a	
  blank	
  screen,	
  adding	
  color	
  and	
  graphics	
  elements	
  like	
  lines,	
  shapes,	
  text	
  and	
  
images.	
  	
  Learn	
  about	
  container	
  elements	
  and	
  defining	
  content	
  for	
  re-­‐use.	
  	
  Understand	
  how	
  units	
  
in	
  the	
  SVG	
  coordinate	
  system	
  can	
  transform	
  our	
  on-­‐screen	
  creaDon	
  into	
  an	
  8.5	
  by	
  11	
  inch	
  printed	
  
page	
  (or	
  PDF).	
  	
  SVG	
  examples	
  will	
  be	
  both	
  in	
  their	
  naDve	
  XML	
  format	
  and	
  created	
  from	
  JavaScript	
  
using	
  Snap.svg,	
  an	
  open	
  source	
  library	
  from	
  Adobe	
  designed	
  for	
  modern	
  web	
  browsers.	
  
	
  
You	
  will	
  leave	
  this	
  session	
  with	
  a	
  basic	
  knowledge	
  of	
  SVG	
  concepts,	
  how	
  to	
  programmaDcally	
  
generate	
  SVG	
  using	
  JavaScript,	
  and	
  how	
  to	
  make	
  your	
  SVG	
  creaDon	
  printer	
  friendly.	
  
TL;DR	
  
•  Print	
  &	
  Play	
  Card	
  Game	
  
– Scalable	
  Vector	
  Graphics	
  (SVG)	
  
– JavaScript	
  
– Snap.svg	
  
– 8.5	
  by	
  11	
  PrinDng	
  
	
  
Kevin	
  Hakanson	
  
@hakanson	
  
#tccc16	
  
kevin.hakanson@gmail.com	
  
+KevinHakanson	
  
hep://stackoverflow.com/users/22514/kevin-­‐hakanson	
  
heps://github.com/hakanson	
  
Bio	
  
Kevin	
  Hakanson	
  is	
  an	
  applicaDon	
  architect	
  for	
  
Thomson	
  Reuters	
  where	
  he	
  is	
  focused	
  on	
  highly	
  
scalable	
  web	
  applicaDons,	
  especially	
  the	
  JavaScript	
  
and	
  security	
  aspects.	
  His	
  background	
  includes	
  
both	
  .NET	
  and	
  Java,	
  but	
  he	
  is	
  most	
  nostalgic	
  about	
  
Lotus	
  Notes.	
  He	
  has	
  been	
  developing	
  professionally	
  
since	
  1994	
  and	
  holds	
  a	
  Master’s	
  degree	
  in	
  SoSware	
  
Engineering.	
  When	
  not	
  staring	
  at	
  a	
  computer	
  
screen,	
  he	
  is	
  probably	
  staring	
  at	
  another	
  screen,	
  
either	
  watching	
  TV	
  or	
  playing	
  video	
  games	
  with	
  his	
  
family.	
  
Bio	
  
Kevin	
  Hakanson	
  is	
  an	
  applicaDon	
  architect	
  for	
  
Thomson	
  Reuters	
  where	
  he	
  is	
  focused	
  on	
  highly	
  
scalable	
  web	
  applicaDons,	
  especially	
  the	
  JavaScript	
  
and	
  security	
  aspects.	
  His	
  background	
  includes	
  
both	
  .NET	
  and	
  Java,	
  but	
  he	
  is	
  most	
  nostalgic	
  about	
  
Lotus	
  Notes.	
  He	
  has	
  been	
  developing	
  professionally	
  
since	
  1994	
  and	
  holds	
  a	
  Master’s	
  degree	
  in	
  SoSware	
  
Engineering.	
  When	
  not	
  staring	
  at	
  a	
  computer	
  
screen,	
  he	
  is	
  probably	
  staring	
  at	
  another	
  screen,	
  
either	
  watching	
  TV	
  or	
  playing	
  video	
  games	
  with	
  his	
  
family.	
  
Make your own Print & Play card game using SVG and JavaScript
Make your own Print & Play card game using SVG and JavaScript
Make your own Print & Play card game using SVG and JavaScript
Make your own Print & Play card game using SVG and JavaScript
Make your own Print & Play card game using SVG and JavaScript
Make your own Print & Play card game using SVG and JavaScript
Fluxx	
  Blanxx	
  
•  Add	
  your	
  own	
  zany	
  ideas	
  
•  Each	
  pack	
  contains	
  one	
  of	
  each	
  
of	
  the	
  five	
  card	
  types	
  
•  Cards	
  are	
  "halfway-­‐blank"	
  with	
  
standard-­‐issue	
  text	
  and	
  the	
  
stripe	
  of	
  color	
  
•  Just	
  grab	
  your	
  trusty	
  
permanent	
  marker	
  and	
  
customize	
  the	
  fun!	
  	
  
hep://store.looneylabs.com/Fluxx-­‐Blanxx	
  	
  
Print	
  &	
  Play	
  
•  “Print	
  &	
  Play	
  games	
  are	
  those	
  which	
  are	
  oSen	
  
free	
  to	
  any	
  player	
  who	
  wishes	
  to	
  print	
  them	
  
off	
  themselves.	
  Many	
  are	
  available	
  on	
  the	
  
Internet.”	
  
–  hep://boardgamegeek.com/boardgamecategory/1120/print-­‐play	
  	
  
	
  
•  Print	
  &	
  Play	
  games	
  Boardgamegeek	
  wiki	
  entry:	
  
–  hep://boardgamegeek.com/wiki/page/Print_and_Play_Games	
  	
  
Azure	
  Fluxx	
  
•  Version	
  of	
  Fluxx	
  based	
  in	
  the	
  Window	
  Azure	
  
“universe”:	
  
– SoSware	
  Development	
  
– MicrosoS	
  Products	
  
– Web	
  Technologies	
  
Fair	
  Use?	
  
•  Fluxx	
  Copyright	
  Looney	
  Labs	
  
•  Same	
  card	
  types	
  
•  Same	
  basic	
  gameplay	
  and	
  rules	
  wording	
  
•  Similar,	
  but	
  not	
  exact,	
  colors	
  and	
  artwork	
  
•  Different	
  fonts	
  
•  Different	
  physical	
  card	
  size	
  and	
  deck	
  count	
  
Azure	
  Fluxx	
  Cards	
  
Goals	
  and	
  Keepers	
  
•  Goals	
  
–  Old	
  School	
  
–  New	
  School	
  
–  Single	
  Page	
  App	
  
–  Polyglot	
  
–  Web	
  PlaGorm	
  
–  Tool	
  Master	
  
–  .NET	
  PlaGorm	
  
–  Entry	
  Level	
  
–  Mistaken	
  IdenDty	
  
–  Selectors	
  
–  Transpile	
  
–  Odd	
  Couple	
  
–  Double	
  MVC	
  
–  Intellisense	
  
–  Edge.js	
  
–  UI	
  Bootstrap	
  
•  Keepers	
  
Scalable	
  Vector	
  Graphics	
  (SVG)	
  
•  Text-­‐based	
  graphics	
  language	
  that	
  describes	
  
images	
  with	
  vector	
  shapes,	
  text,	
  and	
  
embedded	
  raster	
  graphics.	
  
•  SVG	
  files	
  provide	
  resoluDon	
  independent,	
  high	
  
resoluDon	
  dots	
  per	
  inch	
  (HiDPI)	
  graphics	
  on	
  
the	
  web,	
  in	
  print,	
  and	
  on	
  mobile	
  devices	
  in	
  a	
  
compact	
  format.	
  	
  
	
  
hep://www.adobe.com/devnet/svg.html	
  	
  
SVG	
  EssenDals	
  
“This	
  insighGul	
  book	
  takes	
  you	
  through	
  the	
  
ins	
  and	
  outs	
  of	
  SVG,	
  from	
  the	
  basics	
  to	
  
more	
  complicated	
  features.”	
  
	
  
hep://commons.oreilly.com/wiki/index.php/SVG_EssenDals	
  	
  
SVG	
  Primer	
  
“The	
  book	
  aeempts	
  to	
  discuss	
  SVG	
  in	
  
broader	
  terms,	
  but	
  at	
  the	
  same	
  Dme	
  to	
  
illustrate	
  how	
  one	
  can	
  write	
  JavaScript	
  
programs	
  that	
  use	
  and	
  manipulate	
  SVG.”	
  
	
  
hep://www.w3.org/Graphics/SVG/IG/resources/svgprimer.html	
  	
  
Snap.svg	
  
	
  
“the	
  JavaScript	
  SVG	
  library	
  for	
  the	
  modern	
  web”	
  
	
  
“makes	
  working	
  with	
  your	
  SVG	
  assets	
  as	
  easy	
  as	
  
jQuery	
  makes	
  working	
  with	
  the	
  DOM”	
  
	
  
	
  
	
  
hep://snapsvg.io/	
  	
  
The	
  svg	
  Element	
  
•  <svg>	
  is	
  both	
  root	
  element	
  and	
  used	
  to	
  nest	
  
standalone	
  SVG	
  fragments	
  
•  Each	
  standalone	
  fragment	
  has	
  its	
  own	
  
viewPort	
  and	
  coordinate	
  system	
  
<svg>	
  XML	
  Example	
  
<svg	
  
	
  	
  width="8.5in"	
  
	
  	
  height="11in"	
  
	
  	
  viewBox="0	
  0	
  215.9	
  279.4"	
  
	
  	
  version="1.1"	
  
	
  	
  xmlns="http://www.w3.org/2000/svg"	
  	
  
	
  	
  xmlns:xlink="http://www.w3.org/1999/xlink">	
  
</svg>	
  
<svg>	
  JavaScript	
  Example	
  
var	
  svg	
  =	
  Snap("8.5in",	
  (pageCount*11)+"in")	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  .attr({id:"SnapDeck",	
  style:"display:	
  block;"});	
  
	
  
var	
  pageAttr	
  =	
  {	
  width:"8.5in",	
  height:"11in",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "viewBox"	
  :	
  "0	
  0	
  215.9	
  279.4"};	
  
	
  
for	
  (pageIndex	
  =	
  1;	
  pageIndex<=pageCount;	
  pageIndex++)	
  {	
  
	
  
	
  	
  	
  	
  page	
  =	
  svg.el("svg",	
  pageAttr)	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  .attr({	
  id	
  :	
  "SnapDeckPage"+pageIndex,	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  y	
  :	
  ((pageIndex-­‐1)*11)+"in"	
  });	
  
}	
  
<svg>	
  XML	
  Example	
  
<svg	
  width="8.5in"	
  height="22in"	
  id="SnapDeck">	
  
	
  
	
  	
  <svg	
  width="8.5in"	
  height="11in"	
  y="0in"	
  
	
  	
  	
  viewBox="0	
  0	
  215.9	
  279.4"	
  id="SnapDeckPage1">	
  
	
  	
  </svg>	
  
	
  
	
  	
  <svg	
  width="8.5in"	
  height="11in"	
  y="11in"	
  
	
  	
  	
  viewBox="0	
  0	
  215.9	
  279.4"	
  id="SnapDeckPage2">	
  
	
  	
  </svg>	
  
	
  
</svg>	
  
Grouping	
  and	
  Reusing	
  
	
  
“The	
  <use>	
  (reuse)	
  and	
  <g>	
  (or	
  group)	
  
tags	
  bear	
  similarity	
  to	
  the	
  variables	
  and	
  
objects	
  encountered	
  in	
  programming	
  
languages.”	
  
	
  
	
  
hep://www.w3.org/Graphics/SVG/IG/resources/svgprimer.html#operaDons	
  	
  
The	
  g	
  Element	
  
•  Gathers	
  child	
  elements	
  into	
  a	
  group	
  
•  Uses	
  id	
  aeribute	
  to	
  give	
  a	
  unique	
  name	
  
•  Can	
  have	
  <title>	
  and	
  <desc>	
  
•  Styles	
  apply	
  to	
  child	
  elements	
  
•  Can	
  nest	
  groups	
  within	
  one	
  another	
  
<g>	
  XML	
  Example	
  
<g	
  id="plus"	
  	
  
	
  	
  	
  opacity=".4"	
  	
  
	
  	
  	
  stroke="black"	
  	
  
	
  	
  	
  stroke-­‐width="0.1">	
  
	
  
	
  	
  <path	
  d="M	
  -­‐3	
  0	
  H	
  3	
  M	
  0	
  -­‐3	
  V	
  3"	
  />	
  
	
  
</g>	
  
	
  
The	
  defs	
  Element	
  
•  Puxng	
  grouped	
  objects	
  inside	
  of	
  <defs>	
  tells	
  
SVG	
  to	
  define	
  them	
  without	
  displaying	
  them	
  
•  SVG	
  recommendaDon	
  is	
  to	
  put	
  all	
  objects	
  
intended	
  for	
  re-­‐use	
  inside	
  <defs>	
  
<defs>	
  JavaScript	
  Example	
  
var	
  plus	
  =	
  svg.g(	
  
	
  svg.path("M	
  -­‐3	
  0	
  H	
  3	
  M	
  0	
  -­‐3	
  V	
  3")	
  
);	
  
plus.attr({id:"plus",	
  	
  
	
  	
  opacity:"0.4",	
  
	
  	
  stroke:"black",	
  
	
  	
  "stroke-­‐width":"0.1"});	
  
plus.toDefs();	
  
The	
  symbol	
  Element	
  
•  <symbol>	
  element	
  provides	
  another	
  way	
  of	
  
grouping	
  elements	
  
•  Never	
  displayed,	
  so	
  don't	
  have	
  to	
  enclose	
  it	
  in	
  
<defs>	
  but	
  customary	
  to	
  do	
  so	
  
•  <symbol>	
  can	
  specify	
  viewBox	
  and	
  
preserveAspectRatio	
  aeributes	
  
The	
  use	
  Element	
  
•  “copy-­‐and-­‐paste”	
  of	
  a	
  defined	
  group	
  
•  Specify	
  with	
  an	
  xlink:href	
  aeribute	
  
•  Specify	
  the	
  x	
  and	
  y	
  locaDon	
  for	
  the	
  
group's	
  (0,	
  0)	
  point	
  
Chrome	
  Print	
  Dialog	
  
<g	
  id="pluses">	
  
	
  	
  	
  	
  <use	
  xlink:href="#plus"	
  x="12.7"	
  y="7.7"/>	
  
	
  	
  	
  	
  <use	
  xlink:href="#plus"	
  x="12.7"	
  y="95.7"/>	
  
	
  	
  	
  	
  <use	
  xlink:href="#plus"	
  x="12.7"	
  y="183.7"/>	
  
	
  	
  	
  	
  <use	
  xlink:href="#plus"	
  x="12.7"	
  y="271.7"/>	
  
	
  
	
  	
  	
  	
  <use	
  xlink:href="#plus"	
  x="76.2"	
  y="7.7"/>	
  
	
  	
  	
  	
  <use	
  xlink:href="#plus"	
  x="76.2"	
  y="95.7"/>	
  
	
  	
  	
  	
  <use	
  xlink:href="#plus"	
  x="76.2"	
  y="183.7"/>	
  
	
  	
  	
  	
  <use	
  xlink:href="#plus"	
  x="76.2"	
  y="271.7"/>	
  
	
  
	
  	
  	
  	
  <use	
  xlink:href="#plus"	
  x="139.7"	
  y="7.7"/>	
  
	
  	
  	
  	
  <use	
  xlink:href="#plus"	
  x="139.7"	
  y="95.7"/>	
  
	
  	
  	
  	
  <use	
  xlink:href="#plus"	
  x="139.7"	
  y="183.7"/>	
  
	
  	
  	
  	
  <use	
  xlink:href="#plus"	
  x="139.7"	
  y="271.7"/>	
  
	
  
	
  	
  	
  	
  <use	
  xlink:href="#plus"	
  x="203.2"	
  y="7.7"/>	
  
	
  	
  	
  	
  <use	
  xlink:href="#plus"	
  x="203.2"	
  y="95.7"/>	
  
	
  	
  	
  	
  <use	
  xlink:href="#plus"	
  x="203.2"	
  y="183.7"/>	
  
	
  	
  	
  	
  <use	
  xlink:href="#plus"	
  x="203.2"	
  y="271.7"/>	
  
</g>	
  
	
  
<use>	
  XML	
  Example	
  
<g	
  id="pluscolumn">	
  
	
  	
  	
  	
  <use	
  xlink:href="#plus"	
  y="7.7"	
  />	
  
	
  	
  	
  	
  <use	
  xlink:href="#plus"	
  y="95.7"	
  />	
  
	
  	
  	
  	
  <use	
  xlink:href="#plus"	
  y="183.7"	
  />	
  
	
  	
  	
  	
  <use	
  xlink:href="#plus"	
  y="271.7"	
  />	
  
</g>	
  
	
  
<g	
  id="pluses">	
  
	
  	
  	
  	
  <use	
  xlink:href="#pluscolumn"	
  x="12.7"	
  />	
  
	
  	
  	
  	
  <use	
  xlink:href="#pluscolumn"	
  x="76.2"	
  />	
  
	
  	
  	
  	
  <use	
  xlink:href="#pluscolumn"	
  x="139.7"	
  />	
  
	
  	
  	
  	
  <use	
  xlink:href="#pluscolumn"	
  x="203.2"	
  />	
  
</g>	
  
<use>	
  JavaScript	
  Example	
  
//	
  width:	
  63.5,	
  height:	
  88	
  
var	
  xstops	
  =	
  [12.7,	
  76.2,	
  139.7,	
  203.2];	
  
var	
  ystops	
  =	
  [7.7,	
  95.7,	
  183.7,	
  271.7];	
  
	
  
pages.forEach(function	
  (page)	
  {	
  
	
  	
  ystops.forEach(function	
  (y)	
  {	
  
	
  	
  	
  	
  xstops.forEach(function	
  (x)	
  {	
  
	
  	
  	
  	
  	
  	
  var	
  p	
  =	
  plus.use().attr({	
  x:	
  x,	
  y:	
  y	
  });	
  
	
  	
  	
  	
  	
  	
  page.append(p);	
  
	
  	
  	
  	
  });	
  
	
  	
  });	
  
});	
  
Why	
  63.5	
  x	
  88	
  mm	
  ?	
  
Make your own Print & Play card game using SVG and JavaScript
Paper	
  Cueer	
  
The	
  rect	
  Element	
  
•  Specify	
  x-­‐	
  and	
  y-­‐coordinates	
  of	
  the	
  upper	
  leS	
  
corner,	
  width,	
  and	
  height	
  
– 	
  x,	
  y,	
  width	
  and	
  height	
  aeributes	
  
•  Interior	
  is	
  filled	
  with	
  a	
  fill	
  color	
  (default	
  black)	
  
•  Outline	
  is	
  drawn	
  with	
  strokes	
  (default	
  none)	
  
<rect	
  x="0"	
  y="0"	
  	
  
	
  width="10"	
  height="10"	
  fill="black"/>	
  
The	
  circle	
  Element	
  
•  Specify	
  center	
  x-­‐coordinate,	
  center	
  y-­‐
coordinate,	
  and	
  radius	
  
– 	
  cx,	
  cy,	
  and	
  r	
  aeributes	
  
•  Interior	
  is	
  filled	
  with	
  a	
  fill	
  color	
  (default	
  black)	
  
•  Outline	
  is	
  drawn	
  with	
  strokes	
  (default	
  none)	
  
<circle	
  cx="5"	
  cy="5"	
  r="3.5"	
  
	
  fill="white"	
  stroke-­‐width="0"	
  />	
  
The	
  ellipse	
  Element	
  
•  Like	
  <circle>,	
  specify	
  center	
  x-­‐coordinate,	
  
center	
  y-­‐coordinate	
  
•  Also	
  needs	
  an	
  x-­‐radius	
  and	
  a	
  y-­‐radius	
  
– aeributes	
  for	
  these	
  radii	
  are	
  named	
  rx	
  and	
  ry	
  
<ellipse	
  cx="4"	
  cy="4"	
  	
  
	
  rx="0.25"	
  ry="0.5"	
  />	
  
The	
  line	
  Element	
  
•  Specify	
  the	
  x-­‐	
  and	
  y-­‐coordinates	
  of	
  the	
  line's	
  
endpoints	
  
– 	
  x1,	
  y1,	
  x2	
  and	
  x2	
  aeributes	
  
The	
  path	
  Element	
  
•  Draws	
  the	
  outline	
  of	
  any	
  arbitrary	
  shape	
  by	
  
specifying	
  a	
  series	
  of	
  connected	
  lines,	
  arcs,	
  and	
  
curves	
  
•  Must	
  begin	
  with	
  a	
  moveto	
  command	
  
•  Followed	
  by	
  one	
  or	
  more	
  lineto	
  commands	
  
•  Arc	
  draws	
  a	
  secDon	
  of	
  an	
  ellipse	
  that	
  connects	
  
two	
  points	
  
<path	
  fill="none"	
  stroke-­‐linecap="round"	
  
	
  	
  	
  	
  	
  	
  d="M	
  3.5	
  6.75	
  a	
  1.5,1.5	
  0	
  1	
  1	
  3	
  0"	
  />	
  
Fluxx	
  Card	
  Types	
  
<rect	
  x="0"	
  y="0"	
  width="10"	
  height="10"	
  fill="black"	
  />	
  
<g	
  id="frown"	
  stroke="black"	
  fill="black"	
  stroke-­‐width=".5">	
  
	
  	
  <circle	
  cx="5"	
  cy="5"	
  r="3.5"	
  fill="white"	
  stroke-­‐width="0"	
  />	
  
	
  
	
  	
  <circle	
  cx="4"	
  cy="4"	
  r="0.25"	
  />	
  
	
  	
  <circle	
  cx="6"	
  cy="4"	
  r="0.25"	
  />	
  
	
  
	
  	
  <path	
  fill="none"	
  
	
  	
  	
  	
  	
  	
  	
  	
  d="M	
  3.5	
  6.75	
  a	
  1.5,1.5	
  0	
  1	
  1	
  3	
  0"	
  />	
  
</g>	
  
<rect	
  x="0"	
  y="0"	
  width="10"	
  height="10"	
  fill="black"	
  />	
  
<g	
  id="frown"	
  stroke="black"	
  fill="black"	
  stroke-­‐width=".5">	
  
	
  	
  <circle	
  cx="5"	
  cy="5"	
  r="3.5"	
  fill="white"	
  stroke-­‐width="0"	
  />	
  
	
  
	
  	
  <ellipse	
  cx="4"	
  cy="4"	
  rx="0.25"	
  ry="0.5"	
  />	
  
	
  	
  <ellipse	
  cx="6"	
  cy="4"	
  rx="0.25"	
  ry="0.5"	
  />	
  
	
  
	
  	
  <path	
  fill="none"	
  stroke-­‐linecap="round"	
  
	
  	
  	
  	
  	
  	
  	
  	
  d="M	
  3.5	
  6.75	
  a	
  1.5,1.5	
  0	
  1	
  1	
  3	
  0"	
  />	
  
</g>	
  
<rect	
  x="0"	
  y="0"	
  width="10"	
  height="10"	
  fill="black"	
  />	
  
<g	
  id="frown"	
  stroke="black"	
  fill="black"	
  stroke-­‐width=".5">	
  
	
  	
  <circle	
  cx="5"	
  cy="5"	
  r="3.5"	
  fill="white"	
  stroke-­‐width="0"	
  />	
  
	
  
	
  	
  <ellipse	
  cx="4"	
  cy="4"	
  rx="0.25"	
  ry="0.5"	
  />	
  
	
  	
  <ellipse	
  cx="6"	
  cy="4"	
  rx="0.25"	
  ry="0.5"	
  />	
  
	
  
	
  	
  <path	
  fill="none"	
  stroke-­‐linecap="round"	
  
	
  	
  	
  	
  	
  	
  	
  	
  d="M	
  3.5	
  6.75	
  C	
  4	
  5	
  6	
  6	
  6.5	
  7"	
  />	
  
</g>	
  
svg.rect(0,	
  0,	
  10,	
  10);	
  
	
  
var	
  frown	
  =	
  svg.g()	
  
	
  	
  	
  	
  .attr({	
  id:	
  "frown",	
  stroke:	
  "black",	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  fill:	
  "black",	
  "stroke-­‐width":	
  0.5	
  });	
  
	
  
frown.append(svg.circle(5,	
  5,	
  3.5)	
  
	
  	
  	
  	
  .attr({	
  fill:	
  "white",	
  "stroke-­‐width":	
  0	
  }));	
  
frown.append(svg.ellipse(4,	
  4,	
  0.25,	
  0.5));	
  
frown.append(svg.ellipse(6,	
  4,	
  0.25,	
  0.5));	
  
	
  
frown.append(svg.path("M	
  3.5	
  6.75	
  C	
  4	
  5	
  6	
  6	
  6.5	
  7")	
  
	
  	
  	
  	
  .attr({	
  fill:	
  "none",	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "stroke-­‐linecap":	
  "round"	
  }));	
  
<rect	
  x="0"	
  y="0"	
  width="10"	
  height="10"	
  fill="yellow"/>	
  
	
  
<g	
  id="flowerpedal"	
  stroke="black"	
  stroke-­‐width="0">	
  
	
  	
  <path	
  fill="black"	
  	
  
	
   	
  d="M	
  5	
  5	
  l	
  -­‐0.75	
  3	
  a	
  0.75,0.75	
  0	
  1	
  0	
  1.5	
  0	
  Z"	
  />	
  
</g>	
  
The	
  transform	
  Aeribute	
  
•  matrix(<a>	
  <b>	
  <c>	
  <d>	
  <e>	
  <f>)	
  
•  translate(<x>	
  [<y>])	
  
•  scale(<x>	
  [<y>])	
  
•  rotate(<a>	
  [<x>	
  <y>])	
  
•  skewX(<a>)	
  
•  skewY(<a>)	
  
	
  
heps://developer.mozilla.org/en-­‐US/docs/Web/SVG/Aeribute/transform	
  	
  
<rect	
  x="0"	
  y="0"	
  width="10"	
  height="10"	
  fill="yellow"	
  />	
  
<g	
  id="flowerpedal"	
  stroke="black"	
  stroke-­‐width="0">	
  
	
  	
  <path	
  fill="black"	
  d="M	
  5	
  5	
  l	
  -­‐0.75	
  3	
  a	
  0.75,0.75	
  0	
  1	
  0	
  1.5	
  0	
  Z"	
  />	
  
</g>	
  
<use	
  xlink:href="#flowerpedal"	
  transform="rotate(	
  60,	
  5,	
  5)"	
  />	
  
<use	
  xlink:href="#flowerpedal"	
  transform="rotate(120,	
  5,	
  5)"	
  />	
  
<use	
  xlink:href="#flowerpedal"	
  transform="rotate(180,	
  5,	
  5)"	
  />	
  
<use	
  xlink:href="#flowerpedal"	
  transform="rotate(240,	
  5,	
  5)"	
  />	
  
<use	
  xlink:href="#flowerpedal"	
  transform="rotate(300,	
  5,	
  5)"	
  />	
  
<rect	
  x="0"	
  y="0"	
  width="10"	
  height="10"	
  fill="greenyellow"/>	
  
<g	
  id="check"	
  stroke="black"	
  stroke-­‐width="1">	
  
	
  	
  <polyline	
  stroke-­‐linejoin="round"	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  stroke-­‐linecap="round"	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  fill="none"	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  points="2	
  5,	
  3	
  8,	
  8	
  2"	
  />	
  
</g>	
  
<rect	
  x="0"	
  y="0"	
  width="10"	
  height="10"	
  fill="pink"	
  />	
  
<g	
  id="checkbox"	
  stroke="black">	
  
	
  	
  <rect	
  x="3"	
  y="3"	
  width="6"	
  height="6"	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  fill="black"	
  stroke-­‐width="0"	
  />	
  
	
  	
  <rect	
  x="2"	
  y="2"	
  width="6"	
  height="6"	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  fill="pink"	
  stroke-­‐width="0.5"	
  />	
  
</g>	
  
<rect	
  x="0"	
  y="0"	
  width="10"	
  height="10"	
  fill="skyblue"	
  />	
  
<g	
  id="arrow"	
  stroke="black"	
  stroke-­‐width="0.5">	
  
	
  	
  <path	
  fill="black"	
  d="M	
  5.5	
  2	
  l	
  .5	
  0	
  l	
  3	
  3	
  l	
  -­‐3	
  3	
  l	
  -­‐0.5	
  0	
  l	
  0	
  
-­‐1.5	
  l	
  -­‐4	
  0	
  l	
  0	
  -­‐3	
  l	
  4	
  0	
  Z"	
  />	
  
	
  	
  <path	
  stroke-­‐linejoin="round"	
  fill="skyblue"	
  d="M	
  6	
  2	
  l	
  3	
  3	
  l	
  
-­‐3	
  3	
  l	
  0	
  -­‐1.5	
  l	
  -­‐4	
  0	
  l	
  0	
  -­‐3	
  l	
  4	
  0	
  Z"	
  />	
  
</g>	
  
<rect	
  x="0"	
  y="0"	
  width="10"	
  height="10"	
  fill="mediumpurple"	
  />	
  
	
  
<g	
  id="bolt"	
  stroke="black"	
  stroke-­‐width="0.5">	
  
	
  	
  <path	
  fill="white"	
  d="M	
  5	
  1	
  l	
  -­‐3	
  3	
  l	
  2	
  0	
  l	
  -­‐2	
  2	
  l	
  2	
  0	
  l	
  -­‐2	
  3	
  l	
  
5	
  -­‐4	
  l	
  -­‐2	
  0	
  l	
  2	
  -­‐2	
  l	
  -­‐2	
  0	
  l	
  2	
  -­‐2	
  Z"	
  />	
  
</g>	
  
How-­‐To	
  Make	
  a	
  Keeper	
  
<symbol>	
  
How-­‐To	
  Make	
  a	
  Keeper	
  
<symbol>	
  
	
  
<text>	
  
How-­‐To	
  Make	
  a	
  Keeper	
  
<symbol>	
  
	
  
<text>	
  
	
  
<rect>	
  
	
  
How-­‐To	
  Make	
  a	
  Keeper	
  
<symbol>	
  
	
  
<text>	
  
	
  
<rect>	
  
	
  
<image>	
  
	
  
The	
  text	
  Element	
  
•  <text>	
  requires	
  only	
  two	
  aeributes,	
  x	
  and	
  y	
  
•  Default	
  style	
  is	
  to	
  have	
  a	
  fill	
  color	
  of	
  black	
  and	
  
no	
  outline	
  
•  font-­‐family,	
  font-­‐size,	
  font-­‐weight,	
  font-­‐style,	
  
text-­‐decoraDon,	
  word-­‐spacing,	
  leeer-­‐spacing	
  
•  “SVG	
  performs	
  no	
  automaDc	
  line	
  breaking	
  or	
  
word	
  wrapping”	
  
hep://www.w3.org/TR/SVG11/text.html#IntroducDon	
  	
  
<text>	
  XML	
  Example	
  
<g	
  text-­‐anchor="start"	
  	
  
	
  	
  	
  font-­‐size="3.5"	
  	
  
	
  	
  	
  letter-­‐spacing="-­‐0.05">	
  
	
  
	
  <text	
  x="15"	
  y="18">To	
  play	
  this	
  card,	
  place	
  it	
  face</text>	
  
	
  
	
  <text	
  x="15"	
  y="22.375">up	
  on	
  the	
  table	
  in	
  front	
  of	
  you.</text>	
  
	
  
</g>	
  
The	
  image	
  Element	
  
•  <image>	
  element	
  includes	
  an	
  enDre	
  SVG	
  or	
  
raster	
  file	
  (JPEG	
  or	
  PNG)	
  
•  x,	
  y,	
  width,	
  and	
  height	
  aeributes	
  
<image	
  xlink:href="images/JavaScript-­‐logo.png"	
  
preserveAspectRatio="meet"	
  x="22"	
  y="48"	
  width="30"	
  
height="30"	
  />	
  
<image>	
  XML	
  Example	
  
	
  <image	
  	
  
	
  xlink:href="images/JavaScript-­‐logo.png"	
  	
  
	
  x="22"	
  	
  
	
  y="48"	
  	
  
	
  width="30"	
  	
  
	
  height="30"	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  preserveAspectRatio	
  ="meet"	
  />	
  
<image>	
  JavaScript	
  Example	
  
s.image(	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "images/JavaScript-­‐logo.png",	
  	
  
	
  	
  	
  	
  22,	
  	
  
	
  	
  	
  	
  48,	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  30,	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  30)	
  
.attr({	
  "preserveAspectRatio":"meet"	
  })	
  
<svg	
  id="SnapDeckCard1"	
  	
  
	
  width="63.5"	
  height="88"	
  	
  
	
  xmlns="http://www.w3.org/2000/svg"	
  
	
  xmlns:xlink="http://www.w3.org/1999/xlink"	
  	
  
	
  font-­‐family="sans-­‐serif">	
  
	
  	
  	
  
	
  	
  <defs>	
  
	
  
	
  
	
  
	
  
	
  
	
  
	
  
	
  
	
  	
  	
  	
  <!-­‐-­‐	
  ...	
  -­‐-­‐>	
  
	
  	
  </defs>	
  
	
  <!-­‐-­‐	
  ...	
  -­‐-­‐>	
  
</svg>	
  
<svg	
  id="SnapDeckCard1"	
  	
  
	
  width="63.5"	
  height="88"	
  	
  
	
  xmlns="http://www.w3.org/2000/svg"	
  
	
  xmlns:xlink="http://www.w3.org/1999/xlink"	
  	
  
	
  font-­‐family="sans-­‐serif">	
  
	
  	
  	
  
	
  	
  <defs>	
  
	
  	
  	
  	
  <rect	
  id="sidebar"	
  x="3"	
  y="3"	
  width="10"	
  height="82"	
  />	
  
	
  
	
  
	
  
	
  
	
  
	
  
	
  
	
  	
  	
  	
  <!-­‐-­‐	
  ...	
  -­‐-­‐>	
  
	
  	
  </defs>	
  
	
  <!-­‐-­‐	
  ...	
  -­‐-­‐>	
  
</svg>	
  
<svg	
  id="SnapDeckCard1"	
  	
  
	
  width="63.5"	
  height="88"	
  	
  
	
  xmlns="http://www.w3.org/2000/svg"	
  
	
  xmlns:xlink="http://www.w3.org/1999/xlink"	
  	
  
	
  font-­‐family="sans-­‐serif">	
  
	
  	
  	
  
	
  	
  <defs>	
  
	
  	
  	
  	
  <rect	
  id="sidebar"	
  x="3"	
  y="3"	
  width="10"	
  height="82"	
  />	
  
	
  	
  	
  	
  <rect	
  id="hr"	
  x="15"	
  y="33"	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  width="45.5"	
  height="2"	
  fill="black"	
  />	
  
	
  
	
  
	
  
	
  
	
  
	
  	
  	
  	
  <!-­‐-­‐	
  ...	
  -­‐-­‐>	
  
	
  	
  </defs>	
  
	
  <!-­‐-­‐	
  ...	
  -­‐-­‐>	
  
</svg>	
  
<svg	
  id="SnapDeckCard1"	
  	
  
	
  width="63.5"	
  height="88"	
  	
  
	
  xmlns="http://www.w3.org/2000/svg"	
  
	
  xmlns:xlink="http://www.w3.org/1999/xlink"	
  	
  
	
  font-­‐family="sans-­‐serif">	
  
	
  	
  	
  
	
  	
  <defs>	
  
	
  	
  	
  	
  <rect	
  id="sidebar"	
  x="3"	
  y="3"	
  width="10"	
  height="82"	
  />	
  
	
  	
  	
  	
  <rect	
  id="hr"	
  x="15"	
  y="33"	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  width="45.5"	
  height="2"	
  fill="black"	
  />	
  
	
  
	
  	
  	
  	
  <symbol	
  id="check"	
  stroke="black"	
  stroke-­‐width="1">	
  
	
  	
  	
  	
  	
  	
  <polyline	
  points="5,8,6,11,11,5"	
  fill="none"	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  stroke-­‐linejoin="round"	
  stroke-­‐linecap="round"	
  />	
  
	
  	
  	
  	
  </symbol>	
  
	
  	
  	
  	
  <!-­‐-­‐	
  ...	
  -­‐-­‐>	
  
	
  	
  </defs>	
  
	
  <!-­‐-­‐	
  ...	
  -­‐-­‐>	
  
</svg>	
  
<svg>	
  	
  	
  
	
  	
  <defs>	
  
	
  	
  	
  	
  <!-­‐-­‐	
  ...	
  -­‐-­‐>	
  
	
  	
  	
  	
  <g	
  id="keeper">	
  
	
  	
  	
  	
  	
  	
  <use	
  xlink:href="#check"	
  />	
  
	
  	
  	
  	
  	
  	
  <use	
  xlink:href="#sidebar"	
  fill="#b3dd1a"	
  />	
  
	
  
	
  
	
  
	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  	
  	
  <use	
  xlink:href="#hr"	
  />	
  
	
  
	
  
	
  
	
  
	
  
	
  	
  	
  	
  </g>	
  
	
  	
  </defs>	
  
	
  <!-­‐-­‐	
  ...	
  -­‐-­‐>	
  
</svg>	
  
<svg>	
  	
  	
  
	
  	
  <defs>	
  
	
  	
  	
  	
  <!-­‐-­‐	
  ...	
  -­‐-­‐>	
  
	
  	
  	
  	
  <g	
  id="keeper">	
  
	
  	
  	
  	
  	
  	
  <use	
  xlink:href="#check"	
  />	
  
	
  	
  	
  	
  	
  	
  <use	
  xlink:href="#sidebar"	
  fill="#b3dd1a"	
  />	
  
	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  	
  	
  <text	
  text-­‐anchor="start"	
  x="14.5"	
  y="11"	
  font-­‐size="9"	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  letter-­‐spacing="-­‐.5"	
  font-­‐weight="bold">KEEPER</text>	
  
	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  	
  	
  <use	
  xlink:href="#hr"	
  />	
  
	
  
	
  
	
  
	
  
	
  
	
  	
  	
  	
  </g>	
  
	
  	
  </defs>	
  
	
  <!-­‐-­‐	
  ...	
  -­‐-­‐>	
  
</svg>	
  
<svg>	
  	
  	
  
	
  	
  <defs>	
  
	
  	
  	
  	
  <!-­‐-­‐	
  ...	
  -­‐-­‐>	
  
	
  	
  	
  	
  <g	
  id="keeper">	
  
	
  	
  	
  	
  	
  	
  <use	
  xlink:href="#check"	
  />	
  
	
  	
  	
  	
  	
  	
  <use	
  xlink:href="#sidebar"	
  fill="#b3dd1a"	
  />	
  
	
  
	
  	
  	
  	
  	
  	
  <text	
  text-­‐anchor="start"	
  x="14.5"	
  y="11"	
  font-­‐size="9"	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  letter-­‐spacing="-­‐.5"	
  font-­‐weight="bold">KEEPER</text>	
  
	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  	
  	
  <use	
  xlink:href="#hr"	
  />	
  
	
  
	
  	
  	
  	
  	
  	
  <g	
  text-­‐anchor="start"	
  font-­‐size="3.5"	
  letter-­‐spacing="-­‐0.05">	
  
	
  	
  	
  	
  	
  	
  	
  	
  <text	
  x="15"	
  y="18">To	
  play	
  this	
  card,	
  place	
  it	
  face</text>	
  
	
  	
  	
  	
  	
  	
  	
  	
  <text	
  x="15"	
  y="22.375">up	
  on	
  the	
  table	
  in	
  front	
  of	
  you.</text>	
  
	
  	
  	
  	
  	
  	
  </g>	
  
	
  	
  	
  	
  </g>	
  
	
  	
  </defs>	
  
	
  <!-­‐-­‐	
  ...	
  -­‐-­‐>	
  
</svg>	
  
<svg>	
  	
  	
  
	
  	
  <defs>	
  
	
  	
  	
  	
  <!-­‐-­‐	
  ...	
  -­‐-­‐>	
  
	
  	
  </defs>	
  
	
  
	
  	
  <use	
  xlink:href="#keeper"	
  />	
  
	
  
	
  	
  <g	
  text-­‐anchor="start"	
  font-­‐size="5.5"	
  	
  
	
  	
  	
  	
  	
  letter-­‐spacing="-­‐0.05"	
  font-­‐weight="bold">	
  
	
  	
  	
  	
  <text	
  x="15"	
  y="31">JavaScript</text>	
  
	
  	
  </g>	
  
	
  
	
  
	
  
	
  
	
  
	
  
	
  
</svg>	
  
<svg>	
  	
  	
  
	
  	
  <defs>	
  
	
  	
  	
  	
  <!-­‐-­‐	
  ...	
  -­‐-­‐>	
  
	
  	
  </defs>	
  
	
  
	
  	
  <use	
  xlink:href="#keeper"	
  />	
  
	
  
	
  	
  <g	
  text-­‐anchor="start"	
  font-­‐size="5.5"	
  
	
  	
  	
  	
  	
  letter-­‐spacing="-­‐0.05"	
  font-­‐weight="bold">	
  
	
  	
  	
  	
  <text	
  x="15"	
  y="31">JavaScript</text>	
  
	
  	
  </g>	
  
	
  
	
  	
  <text	
  x="10"	
  y="15"	
  transform="matrix(0,-­‐1,1,0,-­‐5,25)"	
  font-­‐size="6"	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  text-­‐anchor="end"	
  font-­‐weight="bold">JAVASCRIPT</text>	
  
	
  
	
  
	
  
	
  
</svg>	
  
<svg>	
  	
  	
  
	
  	
  <defs>	
  
	
  	
  	
  	
  <!-­‐-­‐	
  ...	
  -­‐-­‐>	
  
	
  	
  </defs>	
  
	
  
	
  	
  <use	
  xlink:href="#keeper"	
  />	
  
	
  
	
  	
  <g	
  line-­‐spacing="0"	
  paragraph-­‐spacing="0"	
  text-­‐anchor="start"	
  	
  
	
  	
  	
  	
  	
  font-­‐size="5.5"	
  letter-­‐spacing="-­‐0.05"	
  font-­‐weight="bold">	
  
	
  	
  	
  	
  <text	
  x="15"	
  y="31">JavaScript</text>	
  
	
  	
  </g>	
  
	
  
	
  	
  <text	
  x="10"	
  y="15"	
  transform="matrix(0,-­‐1,1,0,-­‐5,25)"	
  font-­‐size="6"	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  text-­‐anchor="end"	
  font-­‐weight="bold">JAVASCRIPT</text>	
  
	
  
	
  	
  <image	
  xlink:href="images/JavaScript-­‐logo.png"	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  preserveAspectRatio="meet"	
  x="22"	
  y="48"	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  width="30"	
  height="30"	
  />	
  
</svg>	
  
<svg	
  id="SnapDeckCard1"	
  width="460"	
  height="640"	
  viewBox="0	
  0	
  63.5	
  88"	
  xmlns="http://www.w3.org/2000/svg"	
  	
  
	
  	
  	
  	
  	
  xmlns:xlink="http://www.w3.org/1999/xlink"	
  font-­‐family="sans-­‐serif”>	
  	
  	
  
	
  	
  <defs>	
  
	
  	
  	
  	
  <rect	
  x="3"	
  y="3"	
  width="10"	
  height="82"	
  id="sidebar"	
  />	
  
	
  	
  	
  	
  <rect	
  x="15"	
  y="33"	
  width="45.5"	
  height="2"	
  id="hr"	
  fill="black"	
  />	
  
	
  
	
  	
  	
  	
  <symbol	
  id="check"	
  stroke="black"	
  stroke-­‐width="1">	
  
	
  	
  	
  	
  	
  	
  <polyline	
  points="5,8,6,11,11,5"	
  fill="none"	
  stroke-­‐linejoin="round"	
  stroke-­‐linecap="round"	
  />	
  
	
  	
  	
  	
  </symbol>	
  
	
  
	
  	
  	
  	
  <g	
  id="keeper">	
  
	
  	
  	
  	
  	
  	
  <use	
  xlink:href="#sidebar"	
  fill="#b3dd1a"	
  />	
  
	
  	
  	
  	
  	
  	
  <use	
  xlink:href="#check"	
  />	
  
	
  	
  	
  	
  	
  	
  <text	
  text-­‐anchor="start"	
  x="14.5"	
  y="11"	
  font-­‐size="9"	
  letter-­‐spacing="-­‐.5"	
  font-­‐weight="bold">KEEPER</text>	
  
	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  	
  	
  <use	
  xlink:href="#hr"	
  />	
  
	
  	
  	
  	
  	
  	
  <g	
  text-­‐anchor="start"	
  font-­‐size="3.5"	
  letter-­‐spacing="-­‐0.05">	
  
	
  	
  	
  	
  	
  	
  	
  	
  <text	
  x="15"	
  y="18">To	
  play	
  this	
  card,	
  place	
  it	
  face</text>	
  
	
  	
  	
  	
  	
  	
  	
  	
  <text	
  x="15"	
  y="22.375">up	
  on	
  the	
  table	
  in	
  front	
  of	
  you.</text>	
  
	
  	
  	
  	
  	
  	
  </g>	
  
	
  	
  	
  	
  </g>	
  
	
  	
  </defs>	
  
	
  	
  <use	
  xlink:href="#keeper"></use>	
  
	
  	
  <g	
  text-­‐anchor="start"	
  font-­‐size="5.5"	
  letter-­‐spacing="-­‐0.05"	
  font-­‐weight="bold">	
  
	
  	
  	
  	
  <text	
  x="15"	
  y="31">JavaScript</text>	
  
	
  	
  </g>	
  
	
  	
  <text	
  x="10"	
  y="15"	
  transform="matrix(0,-­‐1,1,0,-­‐5,25)"	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  font-­‐size="6"	
  text-­‐anchor="end"	
  font-­‐weight="bold">JAVASCRIPT</text>	
  
	
  	
  <image	
  xlink:href="images/JavaScript-­‐logo.png"	
  preserveAspectRatio="meet"	
  x="22"	
  y="48"	
  width="30"	
  height="30"	
  />	
  
</svg>	
  
Chrome	
  Print	
  Dialog	
  
SVG	
  1.1	
  Text	
  
Each	
  <text>	
  element	
  causes	
  a	
  single	
  string	
  of	
  
text	
  to	
  be	
  rendered.	
  SVG	
  performs	
  no	
  automaDc	
  
line	
  breaking	
  or	
  word	
  wrapping	
  
	
  
	
  hep://www.w3.org/TR/SVG11/text.html#IntroducDon	
  	
  
SVG	
  Tiny	
  1.2	
  	
  
•  The	
  <textArea>	
  element	
  allows	
  simplisDc	
  
wrapping	
  of	
  text	
  content	
  
	
  
•  The	
  <tbreak>	
  element	
  is	
  an	
  empty	
  element	
  
that	
  forcibly	
  breaks	
  the	
  current	
  line	
  of	
  text	
  
	
  
•  The	
  line-­‐increment	
  property	
  provides	
  
limited	
  control	
  over	
  the	
  size	
  of	
  each	
  line	
  
SVG	
  1.2	
  
•  Scalable	
  Vector	
  Graphics	
  (SVG)	
  Full	
  1.2	
  
SpecificaDon	
  
– W3C	
  Working	
  DraS	
  13	
  April	
  2005	
  
hep://www.w3.org/TR/SVG12/	
  	
  
•  “The	
  next	
  draS	
  of	
  SVG	
  1.2	
  Full	
  will	
  structured	
  
as	
  a	
  superset	
  of	
  the	
  SVG	
  1.2	
  Tiny	
  language”	
  
•  “At	
  this	
  Dme	
  the	
  refactored	
  SVG	
  1.2	
  Full	
  
specificaDon	
  is	
  not	
  ready	
  for	
  publicaDon.”	
  
snapdeck.textArea	
  =	
  function	
  (s,	
  x,	
  y,	
  width,	
  textToWrap,	
  attr)	
  {	
  
	
  	
  	
  	
  if	
  (!textToWrap)	
  return;	
  
	
  
	
  	
  	
  	
  attr	
  =	
  SnapDeck.defaultAttr(attr,	
  {	
  "text-­‐anchor":	
  "start",	
  "font-­‐size":	
  3.5,	
  "letter-­‐spacing":	
  -­‐.05,	
  "line-­‐spacing":	
  0,	
  "paragraph-­‐
spacing":	
  0	
  });	
  
	
  	
  	
  	
  var	
  fontSize	
  =	
  attr["font-­‐size"];	
  
	
  	
  	
  	
  width	
  =	
  width	
  *	
  (fontSize	
  /	
  3);	
  
	
  	
  	
  	
  var	
  yDelta	
  =	
  (fontSize	
  *	
  1.25)	
  +	
  attr["line-­‐spacing"];	
  
	
  	
  	
  	
  var	
  tmpSvg,	
  tmpRoot	
  =	
  deck.svg.g().attr(attr).toDefs();	
  
	
  	
  	
  	
  var	
  g	
  =	
  s.g().attr(attr);	
  
	
  	
  	
  	
  var	
  line	
  =	
  "",	
  tmpLine	
  =	
  "",	
  linecount	
  =	
  0;	
  
	
  	
  	
  	
  var	
  texts	
  =	
  textToWrap.split("n");	
  
	
  	
  	
  	
  texts.forEach(function	
  (text)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  var	
  words	
  =	
  text.split("	
  ");	
  
	
  	
  	
  	
  	
  	
  	
  	
  words.forEach(function	
  (word)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  if	
  (line)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  tmpLine	
  =	
  line	
  +	
  "	
  "	
  +	
  word;	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  tmpSvg	
  =	
  tmpRoot.text(0,	
  0,	
  tmpLine);	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  if	
  (tmpSvg.node.getBoundingClientRect().width	
  >	
  width)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  g.text(x,	
  y,	
  line);	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  y	
  =	
  y	
  +	
  yDelta;	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  linecount++;	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  line	
  =	
  tmpLine	
  =	
  word;	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  }	
  else	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  line	
  =	
  line	
  +	
  "	
  "	
  +	
  word;	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  tmpSvg.remove();	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  }	
  else	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  line	
  =	
  word;	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  	
  	
  	
  	
  });	
  
	
  
	
  	
  	
  	
  	
  	
  	
  	
  g.text(x,	
  y,	
  line);	
  
	
  	
  	
  	
  	
  	
  	
  	
  y	
  =	
  y	
  +	
  yDelta	
  +	
  attr["paragraph-­‐spacing"];	
  
	
  	
  	
  	
  	
  	
  	
  	
  linecount++;	
  
	
  	
  	
  	
  	
  	
  	
  	
  line	
  =	
  tmpLine	
  =	
  "";	
  
	
  	
  	
  	
  });	
  
	
  
	
  	
  	
  	
  tmpRoot.remove();	
  
	
  	
  	
  	
  return	
  g;	
  
};	
  
Chrome	
  Zoom	
  
100%	
   150%	
   200%	
  
snap.deck.js	
  
(function(window)	
  {	
  
	
  
	
  	
  	
  	
  function	
  Deck(cardCount)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  //	
  ...	
  
	
  	
  	
  	
  	
  	
  	
  	
  this.svg	
  =	
  Snap("8.5in",	
  (pageCount	
  *	
  11)	
  +	
  "in")	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  .attr({	
  id:	
  "SnapDeck",	
  style:	
  "display:	
  block;"	
  });	
  
	
  	
  	
  	
  	
  	
  	
  	
  this.pages	
  =	
  [];	
  
	
  	
  	
  	
  	
  	
  	
  	
  this.cards	
  =	
  [];	
  
	
  	
  	
  	
  	
  	
  	
  	
  //	
  ...	
  
	
  	
  	
  	
  }	
  
	
  
	
  	
  	
  	
  snapdeck.deck	
  =	
  function	
  (cards)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  return	
  new	
  Deck(cards);	
  
	
  	
  	
  	
  };	
  
	
  
	
  	
  	
  	
  window.SnapDeck	
  =	
  snapdeck;	
  
	
  
})(window);	
  
Make your own Print & Play card game using SVG and JavaScript
Make your own Print & Play card game using SVG and JavaScript
Len	
  Peralta’s	
  Geek	
  A	
  Week	
  
@hakanson	
  Card	
  
•  Mimic	
  look	
  from	
  the	
  
Geek	
  A	
  Week	
  series	
  
•  InformaDon	
  and	
  images	
  
from	
  Twieer	
  biography	
  
•  “More	
  cool”	
  than	
  a	
  
business	
  card	
  
var	
  s	
  =	
  Snap("460",	
  "640")	
  
	
  	
  	
  	
  	
  	
  	
  	
  .attr({	
  "viewBox":	
  "0	
  0	
  63.5	
  88",	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "font-­‐family":"sans-­‐serif"	
  });	
  
	
  
SnapDeck.pinwheel(s,	
  31.75,	
  44,	
  55,	
  120,	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "firebrick",	
  "maroon");	
  
	
  
	
  
	
  
Pinwheel	
  
•  120	
  rays	
  
•  firebrick	
  
•  maroon	
  
Unit	
  Circle	
  
snapdeck.pinwheel	
  =	
  function	
  (s,	
  cx,	
  cy,	
  cr,	
  count,	
  background,	
  foreground)	
  
{	
  
	
  	
  	
  	
  var	
  c	
  =	
  s.circle(cx,	
  cy,	
  cr);	
  
	
  	
  	
  	
  c.attr({	
  "stroke-­‐width":	
  0,	
  "fill":	
  background	
  });	
  
	
  
	
  	
  	
  	
  var	
  deg	
  =	
  360	
  /	
  count;	
  
	
  	
  	
  	
  var	
  offset	
  =	
  -­‐deg	
  /	
  2;	
  
	
  	
  	
  	
  for	
  (var	
  i	
  =	
  0;	
  i	
  <	
  count	
  /	
  2;	
  i++)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  var	
  start	
  =	
  "M	
  "	
  +	
  cx	
  +	
  "	
  "	
  +	
  cy;	
  
	
  
	
  	
  	
  	
  	
  	
  	
  	
  var	
  rad	
  =	
  (2	
  *	
  i	
  *	
  deg	
  +	
  offset)	
  *	
  (Math.PI	
  /	
  180);	
  
	
  	
  	
  	
  	
  	
  	
  	
  var	
  x	
  =	
  cx	
  +	
  (Math.cos(rad)	
  *	
  cr);	
  
	
  	
  	
  	
  	
  	
  	
  	
  var	
  y	
  =	
  cy	
  +	
  (Math.sin(rad)	
  *	
  cr);	
  
	
  
	
  	
  	
  	
  	
  	
  	
  	
  var	
  first	
  =	
  "	
  L	
  "	
  +	
  x	
  +	
  "	
  "	
  +	
  y;	
  
	
  
	
  	
  	
  	
  	
  	
  	
  	
  rad	
  =	
  (2	
  *	
  i	
  *	
  deg	
  +	
  deg	
  +	
  offset)	
  *	
  (Math.PI	
  /	
  180);	
  
	
  	
  	
  	
  	
  	
  	
  	
  x	
  =	
  cx	
  +	
  (Math.cos(rad)	
  *	
  cr);	
  
	
  	
  	
  	
  	
  	
  	
  	
  y	
  =	
  cy	
  +	
  (Math.sin(rad)	
  *	
  cr);	
  
	
  
	
  	
  	
  	
  	
  	
  	
  	
  var	
  second	
  =	
  "	
  A	
  "	
  +	
  cx	
  +	
  "	
  "	
  +	
  cy	
  +	
  "	
  0	
  0	
  1	
  "	
  +	
  x	
  +	
  "	
  "	
  +	
  y;	
  
	
  
	
  	
  	
  	
  	
  	
  	
  	
  s.path(start	
  +	
  first	
  +	
  second	
  +	
  "	
  Z").attr({	
  "fill":	
  foreground	
  });	
  
	
  	
  	
  	
  }	
  
	
  	
  	
  	
  return	
  s;	
  
};	
  
var	
  s	
  =	
  Snap("460",	
  "640")	
  
	
  	
  	
  	
  	
  	
  	
  	
  .attr({	
  "viewBox":	
  "0	
  0	
  63.5	
  88",	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "font-­‐family":"sans-­‐serif"	
  });	
  
	
  
SnapDeck.pinwheel(s,	
  31.75,	
  44,	
  55,	
  120,	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "firebrick",	
  "maroon");	
  
	
  
s.rect(3,	
  3,	
  57.5,	
  75,	
  0.5,	
  0.5)	
  
	
  .attr({	
  "fill":	
  "red"	
  });	
  
	
  
	
  
	
  
var	
  s	
  =	
  Snap("460",	
  "640")	
  
	
  	
  	
  	
  	
  	
  	
  	
  .attr({	
  "viewBox":	
  "0	
  0	
  63.5	
  88",	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "font-­‐family":"sans-­‐serif"	
  });	
  
	
  
SnapDeck.pinwheel(s,	
  31.75,	
  44,	
  55,	
  120,	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "firebrick",	
  "maroon");	
  
	
  
s.rect(3,	
  3,	
  57.5,	
  75,	
  0.5,	
  0.5)	
  
	
  .attr({	
  "fill":	
  "red"	
  });	
  
	
  
s.rect(4,	
  4,	
  55.5,	
  73,	
  0,	
  0)	
  
	
  .attr({	
  "fill":	
  "none",	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  "stroke-­‐width":	
  1,	
  "stroke":	
  "yellow",	
  });	
  
	
  
	
  
var	
  s	
  =	
  Snap("460",	
  "640")	
  
	
  	
  	
  	
  	
  	
  	
  	
  .attr({	
  "viewBox":	
  "0	
  0	
  63.5	
  88",	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "font-­‐family":"sans-­‐serif"	
  });	
  
	
  
SnapDeck.pinwheel(s,	
  31.75,	
  44,	
  55,	
  120,	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "firebrick",	
  "maroon");	
  
	
  
s.rect(3,	
  3,	
  57.5,	
  75,	
  0.5,	
  0.5)	
  
	
  .attr({	
  "fill":	
  "red"	
  });	
  
	
  
s.rect(4,	
  4,	
  55.5,	
  73,	
  0,	
  0)	
  
	
  .attr({	
  "fill":	
  "none",	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  "stroke-­‐width":	
  1,	
  "stroke":	
  "yellow",	
  });	
  
	
  
s.rect(5,	
  5,	
  53.5,	
  71)	
  
	
  .attr({	
  "fill":	
  "black"	
  });	
  
	
  
s.rect(56,	
  1.25,	
  6,	
  5.5,	
  0.5,	
  0.5)	
  
	
  .attr({	
  "fill":	
  "red"	
  });	
  
s.rect(56.5,	
  2,	
  5,	
  4.25,	
  0.25,	
  0.25)	
  
	
  .attr({	
  "fill":	
  "black",	
  "opacity":	
  0.85	
  });	
  
s.rect(56.5,	
  1.75,	
  4.75,	
  4.25,	
  0.25,	
  0.25)	
  
	
  .attr({	
  "fill":	
  "yellow",	
  "opacity":	
  0.9	
  });	
  
	
  
s.text(59,	
  5,	
  "#1").attr({	
  "text-­‐anchor":	
  "middle",	
  "font-­‐size":	
  
3.5,	
  "fill":	
  "black",	
  "font-­‐weight":	
  "bold"	
  });	
  
	
  
s.rect(56,	
  1.25,	
  6,	
  5.5,	
  0.5,	
  0.5)	
  
	
  .attr({	
  "fill":	
  "red"	
  });	
  
s.rect(56.5,	
  2,	
  5,	
  4.25,	
  0.25,	
  0.25)	
  
	
  .attr({	
  "fill":	
  "black",	
  "opacity":	
  0.85	
  });	
  
s.rect(56.5,	
  1.75,	
  4.75,	
  4.25,	
  0.25,	
  0.25)	
  
	
  .attr({	
  "fill":	
  "yellow",	
  "opacity":	
  0.9	
  });	
  
	
  
s.text(59,	
  5,	
  "#1").attr({	
  "text-­‐anchor":	
  "middle",	
  "font-­‐size":	
  
3.5,	
  "fill":	
  "black",	
  "font-­‐weight":	
  "bold"	
  });	
  
	
  
s.image("images/Twitter_logo_blue.png",	
  6,	
  71,	
  14,	
  14);	
  
	
  
s.rect(56,	
  1.25,	
  6,	
  5.5,	
  0.5,	
  0.5)	
  
	
  .attr({	
  "fill":	
  "red"	
  });	
  
s.rect(56.5,	
  2,	
  5,	
  4.25,	
  0.25,	
  0.25)	
  
	
  .attr({	
  "fill":	
  "black",	
  "opacity":	
  0.85	
  });	
  
s.rect(56.5,	
  1.75,	
  4.75,	
  4.25,	
  0.25,	
  0.25)	
  
	
  .attr({	
  "fill":	
  "yellow",	
  "opacity":	
  0.9	
  });	
  
	
  
s.text(59,	
  5,	
  "#1").attr({	
  "text-­‐anchor":	
  "middle",	
  "font-­‐size":	
  
3.5,	
  "fill":	
  "black",	
  "font-­‐weight":	
  "bold"	
  });	
  
	
  
s.image("images/Twitter_logo_blue.png",	
  6,	
  71,	
  14,	
  14);	
  
	
  
s.text(60,	
  82,	
  "Kevin	
  Hakanson").attr({	
  "text-­‐anchor":	
  "end",	
  
"font-­‐size":	
  4.5,	
  "fill":	
  "white",	
  "font-­‐weight":	
  "bold"	
  });	
  
s.text(60,	
  86,	
  "@hakanson")	
  
	
  .attr({	
  "text-­‐anchor":	
  "end",	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  "font-­‐size":	
  3.5,	
  "fill":	
  "white"	
  });	
  
s.rect(11.5,	
  7.5,	
  40,	
  40,	
  0.5,	
  0.5)	
  
	
  .attr({	
  "fill":	
  "white"	
  });	
  
s.image("images/hakanson.png",	
  12,	
  8,	
  39,	
  39);	
  
	
  
	
  
s.rect(11.5,	
  7.5,	
  40,	
  40,	
  0.5,	
  0.5)	
  
	
  .attr({	
  "fill":	
  "white"	
  });	
  
s.image("images/hakanson.png",	
  12,	
  8,	
  39,	
  39);	
  
	
  
var	
  bioAttr	
  =	
  {	
  "text-­‐anchor":	
  "middle",	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  "font-­‐size":	
  2.75,	
  "fill":	
  "white"	
  };	
  
s.text(31.75,	
  52,	
  	
  
	
  	
  	
  "Software	
  Architect	
  at	
  Thomson	
  Reuters.")	
  
	
  .attr(bioAttr);	
  
s.text(31.75,	
  56,	
  	
  
	
  	
  	
  "WestlawNext.	
  Web	
  Platform.	
  JavaScript.")	
  
	
  .attr(bioAttr);	
  
s.text(31.75,	
  60,	
  	
  
	
  	
  	
  "Agile	
  Software	
  Development.").attr(bioAttr);	
  
s.text(31.75,	
  64,	
  	
  
	
  	
  	
  "Information	
  Security.	
  Speaker.").attr(bioAttr);	
  
s.text(31.75,	
  68,	
  "Creator	
  @LicPlateZone").attr(bioAttr);	
  
	
  
s.rect(11.5,	
  7.5,	
  40,	
  40,	
  0.5,	
  0.5)	
  
	
  .attr({	
  "fill":	
  "white"	
  });	
  
s.image("images/hakanson.png",	
  12,	
  8,	
  39,	
  39);	
  
	
  
var	
  bioAttr	
  =	
  {	
  "text-­‐anchor":	
  "middle",	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  "font-­‐size":	
  2.75,	
  "fill":	
  "white"	
  };	
  
s.text(31.75,	
  52,	
  	
  
	
  	
  	
  "Software	
  Architect	
  at	
  Thomson	
  Reuters.")	
  
	
  .attr(bioAttr);	
  
s.text(31.75,	
  56,	
  	
  
	
  	
  	
  "WestlawNext.	
  Web	
  Platform.	
  JavaScript.")	
  
	
  .attr(bioAttr);	
  
s.text(31.75,	
  60,	
  	
  
	
  	
  	
  "Agile	
  Software	
  Development.").attr(bioAttr);	
  
s.text(31.75,	
  64,	
  	
  
	
  	
  	
  "Information	
  Security.	
  Speaker.").attr(bioAttr);	
  
s.text(31.75,	
  68,	
  "Creator	
  @LicPlateZone").attr(bioAttr);	
  
	
  
s.text(56,	
  74,	
  "http://about.me/kevin.hakanson")	
  
	
  .attr({	
  "font-­‐size":	
  2.5,	
  "text-­‐anchor":	
  "end",	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  "fill":	
  "lightskyblue"	
  });	
  
var	
  s	
  =	
  Snap("460",	
  "640")	
  
	
  	
  	
  	
  	
  	
  	
  	
  .attr({	
  "viewBox":	
  "0	
  0	
  63.5	
  88",	
  style:	
  "display:	
  block;",	
  "font-­‐family":"sans-­‐serif"	
  });	
  
var	
  cx	
  =	
  31.75,	
  cy	
  =	
  44,	
  cr	
  =	
  55;	
  
	
  
SnapDeck.pinwheel(s,	
  cx,	
  cy,	
  cr,	
  120,	
  "firebrick",	
  "maroon");	
  
	
  
s.rect(3,	
  3,	
  57.5,	
  75,	
  0.5,	
  0.5).attr({	
  "fill":	
  "red"	
  });	
  
s.rect(4,	
  4,	
  55.5,	
  73,	
  0,	
  0).attr({	
  "stroke-­‐width":	
  1,	
  "stroke":	
  "yellow",	
  "fill":	
  "none"	
  });	
  
s.rect(5,	
  5,	
  53.5,	
  71).attr({	
  "fill":	
  "black"	
  });	
  
	
  	
  	
  	
  	
  
s.rect(56,	
  1.25,	
  6,	
  5.5,	
  0.5,	
  0.5).attr({	
  "fill":	
  "red"	
  });	
  
s.rect(56.5,	
  2,	
  5,	
  4.25,	
  0.25,	
  0.25).attr({	
  "fill":	
  "black",	
  "opacity":	
  0.85	
  });	
  
s.rect(56.5,	
  1.75,	
  4.75,	
  4.25,	
  0.25,	
  0.25).attr({	
  "fill":	
  "yellow",	
  "opacity":	
  0.9	
  });	
  
	
  
s.text(59,	
  5,	
  "#1").attr({	
  "text-­‐anchor":	
  "middle",	
  "font-­‐size":	
  3.5,	
  "fill":	
  "black",	
  "font-­‐weight":	
  "bold"	
  });	
  
	
  	
  	
  	
  	
  	
  	
  	
  
s.rect(11.5,	
  7.5,	
  40,	
  40,	
  0.5,	
  0.5).attr({	
  "fill":	
  "white"	
  });	
  
s.image("images/hakanson.png",	
  12,	
  8,	
  39,	
  39);	
  
	
  	
  	
  	
  
var	
  bioAttr	
  =	
  {	
  "text-­‐anchor":	
  "middle",	
  "font-­‐size":	
  2.75,	
  "fill":	
  "white"	
  };	
  
s.text(cx,	
  52,	
  "Software	
  Architect	
  at	
  Thomson	
  Reuters.").attr(bioAttr);	
  
s.text(cx,	
  56,	
  "WestlawNext.	
  Web	
  Platform.	
  JavaScript.").attr(bioAttr);	
  
s.text(cx,	
  60,	
  "Agile	
  Software	
  Development.").attr(bioAttr);	
  
s.text(cx,	
  64,	
  "Information	
  Security.	
  Speaker.").attr(bioAttr);	
  
s.text(cx,	
  68,	
  "Creator	
  @LicPlateZone").attr(bioAttr);	
  
s.text(56,	
  74,	
  "http://about.me/kevin.hakanson")	
  
	
  .attr({	
  "font-­‐size":	
  2.5,	
  "text-­‐anchor":	
  "end",	
  "fill":	
  "lightskyblue"	
  });	
  
	
  
//	
  https://about.twitter.com/press/brand-­‐assets	
  
s.image("images/Twitter_logo_blue.png",	
  6,	
  71,	
  14,	
  14);	
  
	
  
s.text(60,	
  82,	
  "Kevin	
  Hakanson")	
  
	
  .attr({	
  "text-­‐anchor":	
  "end",	
  "font-­‐size":	
  4.5,	
  "fill":	
  "white",	
  "font-­‐weight":	
  "bold"	
  });	
  
s.text(60,	
  86,	
  "@hakanson").attr({	
  "text-­‐anchor":	
  "end",	
  "font-­‐size":	
  3.5,	
  "fill":	
  "white"	
  });	
  
Evil	
  Twins?	
  
QuesDons?	
  
Ad

More Related Content

What's hot (14)

Drawing in HTML5 Open House
Drawing in HTML5 Open HouseDrawing in HTML5 Open House
Drawing in HTML5 Open House
Noam Kfir
 
Using Web Standards to create Interactive Data Visualizations for the Web
Using Web Standards to create Interactive Data Visualizations for the WebUsing Web Standards to create Interactive Data Visualizations for the Web
Using Web Standards to create Interactive Data Visualizations for the Web
philogb
 
Learn svg
Learn svgLearn svg
Learn svg
FitBlar Mit
 
Top 10 HTML5 features
Top 10 HTML5 featuresTop 10 HTML5 features
Top 10 HTML5 features
Gill Cleeren
 
Html5
Html5Html5
Html5
Mehdi Jalal
 
Web Development using Ruby on Rails
Web Development using Ruby on RailsWeb Development using Ruby on Rails
Web Development using Ruby on Rails
Avi Kedar
 
Html5 more than just html5 v final
Html5  more than just html5 v finalHtml5  more than just html5 v final
Html5 more than just html5 v final
Lohith Goudagere Nagaraj
 
HTML5 and CSS3: does now really mean now?
HTML5 and CSS3: does now really mean now?HTML5 and CSS3: does now really mean now?
HTML5 and CSS3: does now really mean now?
Chris Mills
 
Polyglot Adventures for the Modern Java Developer
Polyglot Adventures for the Modern Java DeveloperPolyglot Adventures for the Modern Java Developer
Polyglot Adventures for the Modern Java Developer
QAware GmbH
 
Responsive Web Design
Responsive Web DesignResponsive Web Design
Responsive Web Design
Debra Shapiro
 
Everything-as-code – Polyglotte Entwicklung in der Praxis
Everything-as-code – Polyglotte Entwicklung in der PraxisEverything-as-code – Polyglotte Entwicklung in der Praxis
Everything-as-code – Polyglotte Entwicklung in der Praxis
QAware GmbH
 
Windows Phone 7 and Windows Azure – A Match Made in the Cloud
Windows Phone 7 and Windows Azure – A Match Made in the CloudWindows Phone 7 and Windows Azure – A Match Made in the Cloud
Windows Phone 7 and Windows Azure – A Match Made in the Cloud
Michael Collier
 
Responsive Web Design: Clever Tips and Techniques
Responsive Web Design: Clever Tips and TechniquesResponsive Web Design: Clever Tips and Techniques
Responsive Web Design: Clever Tips and Techniques
Vitaly Friedman
 
Drupal Backbone.js in the Frontend
Drupal Backbone.js in the FrontendDrupal Backbone.js in the Frontend
Drupal Backbone.js in the Frontend
David Corbacho Román
 
Drawing in HTML5 Open House
Drawing in HTML5 Open HouseDrawing in HTML5 Open House
Drawing in HTML5 Open House
Noam Kfir
 
Using Web Standards to create Interactive Data Visualizations for the Web
Using Web Standards to create Interactive Data Visualizations for the WebUsing Web Standards to create Interactive Data Visualizations for the Web
Using Web Standards to create Interactive Data Visualizations for the Web
philogb
 
Top 10 HTML5 features
Top 10 HTML5 featuresTop 10 HTML5 features
Top 10 HTML5 features
Gill Cleeren
 
Web Development using Ruby on Rails
Web Development using Ruby on RailsWeb Development using Ruby on Rails
Web Development using Ruby on Rails
Avi Kedar
 
HTML5 and CSS3: does now really mean now?
HTML5 and CSS3: does now really mean now?HTML5 and CSS3: does now really mean now?
HTML5 and CSS3: does now really mean now?
Chris Mills
 
Polyglot Adventures for the Modern Java Developer
Polyglot Adventures for the Modern Java DeveloperPolyglot Adventures for the Modern Java Developer
Polyglot Adventures for the Modern Java Developer
QAware GmbH
 
Responsive Web Design
Responsive Web DesignResponsive Web Design
Responsive Web Design
Debra Shapiro
 
Everything-as-code – Polyglotte Entwicklung in der Praxis
Everything-as-code – Polyglotte Entwicklung in der PraxisEverything-as-code – Polyglotte Entwicklung in der Praxis
Everything-as-code – Polyglotte Entwicklung in der Praxis
QAware GmbH
 
Windows Phone 7 and Windows Azure – A Match Made in the Cloud
Windows Phone 7 and Windows Azure – A Match Made in the CloudWindows Phone 7 and Windows Azure – A Match Made in the Cloud
Windows Phone 7 and Windows Azure – A Match Made in the Cloud
Michael Collier
 
Responsive Web Design: Clever Tips and Techniques
Responsive Web Design: Clever Tips and TechniquesResponsive Web Design: Clever Tips and Techniques
Responsive Web Design: Clever Tips and Techniques
Vitaly Friedman
 

Similar to Make your own Print & Play card game using SVG and JavaScript (20)

W3C HTML5 KIG-The complete guide to building html5 games
W3C HTML5 KIG-The complete guide to building html5 gamesW3C HTML5 KIG-The complete guide to building html5 games
W3C HTML5 KIG-The complete guide to building html5 games
Changhwan Yi
 
SVG Strikes Back
SVG Strikes BackSVG Strikes Back
SVG Strikes Back
Matt Baxter
 
Html5 Canvas and Mobile Graphics
Html5 Canvas and Mobile GraphicsHtml5 Canvas and Mobile Graphics
Html5 Canvas and Mobile Graphics
Engin Hatay
 
Vector Graphics on the Web: SVG, Canvas, CSS3
Vector Graphics on the Web: SVG, Canvas, CSS3Vector Graphics on the Web: SVG, Canvas, CSS3
Vector Graphics on the Web: SVG, Canvas, CSS3
Pascal Rettig
 
D3.js and SVG
D3.js and SVGD3.js and SVG
D3.js and SVG
Karol Depka Pradzinski
 
Easy charting with
Easy charting withEasy charting with
Easy charting with
Major Ye
 
Thats Not Flash?
Thats Not Flash?Thats Not Flash?
Thats Not Flash?
Mike Wilcox
 
CANVAS vs SVG @ FrontInRio 2011
CANVAS vs SVG @ FrontInRio 2011CANVAS vs SVG @ FrontInRio 2011
CANVAS vs SVG @ FrontInRio 2011
Davidson Fellipe
 
HTML5DevConf 2013 (October): WebGL is a game changer!
HTML5DevConf 2013 (October): WebGL is a game changer!HTML5DevConf 2013 (October): WebGL is a game changer!
HTML5DevConf 2013 (October): WebGL is a game changer!
Iker Jamardo
 
The Image that called me - Active Content Injection with SVG Files
The Image that called me - Active Content Injection with SVG FilesThe Image that called me - Active Content Injection with SVG Files
The Image that called me - Active Content Injection with SVG Files
Mario Heiderich
 
Universal Applications with Universal JavaScript
Universal Applications with Universal JavaScriptUniversal Applications with Universal JavaScript
Universal Applications with Universal JavaScript
Thomas Joseph
 
HTML5 - A Whirlwind tour
HTML5 - A Whirlwind tourHTML5 - A Whirlwind tour
HTML5 - A Whirlwind tour
Lohith Goudagere Nagaraj
 
DojoX GFX Keynote Eugene Lazutkin SVG Open 2007
DojoX GFX Keynote Eugene Lazutkin SVG Open 2007DojoX GFX Keynote Eugene Lazutkin SVG Open 2007
DojoX GFX Keynote Eugene Lazutkin SVG Open 2007
Eugene Lazutkin
 
Academy PRO: HTML5 API graphics
Academy PRO: HTML5 API graphicsAcademy PRO: HTML5 API graphics
Academy PRO: HTML5 API graphics
Binary Studio
 
NativeScript: Cross-Platform Mobile Apps with JavaScript and Angular
NativeScript: Cross-Platform Mobile Apps with JavaScript and AngularNativeScript: Cross-Platform Mobile Apps with JavaScript and Angular
NativeScript: Cross-Platform Mobile Apps with JavaScript and Angular
Todd Anglin
 
Svghtml5 Meetup
Svghtml5 MeetupSvghtml5 Meetup
Svghtml5 Meetup
Oswald Campesato
 
Rich Media Advertising with SVG and JavaScript
Rich Media Advertising with SVG and JavaScriptRich Media Advertising with SVG and JavaScript
Rich Media Advertising with SVG and JavaScript
Gjokica Zafirovski
 
SVG Icons and Screen Reader Accessibility
SVG Icons and Screen Reader AccessibilitySVG Icons and Screen Reader Accessibility
SVG Icons and Screen Reader Accessibility
Dennis Lembree
 
Uni Tour Germany 11.2009
Uni Tour Germany 11.2009Uni Tour Germany 11.2009
Uni Tour Germany 11.2009
Patrick Lauke
 
Polyglot Adventures for the Modern Java Developer #javaone2017
Polyglot Adventures for the Modern Java Developer #javaone2017Polyglot Adventures for the Modern Java Developer #javaone2017
Polyglot Adventures for the Modern Java Developer #javaone2017
Mario-Leander Reimer
 
W3C HTML5 KIG-The complete guide to building html5 games
W3C HTML5 KIG-The complete guide to building html5 gamesW3C HTML5 KIG-The complete guide to building html5 games
W3C HTML5 KIG-The complete guide to building html5 games
Changhwan Yi
 
SVG Strikes Back
SVG Strikes BackSVG Strikes Back
SVG Strikes Back
Matt Baxter
 
Html5 Canvas and Mobile Graphics
Html5 Canvas and Mobile GraphicsHtml5 Canvas and Mobile Graphics
Html5 Canvas and Mobile Graphics
Engin Hatay
 
Vector Graphics on the Web: SVG, Canvas, CSS3
Vector Graphics on the Web: SVG, Canvas, CSS3Vector Graphics on the Web: SVG, Canvas, CSS3
Vector Graphics on the Web: SVG, Canvas, CSS3
Pascal Rettig
 
Easy charting with
Easy charting withEasy charting with
Easy charting with
Major Ye
 
Thats Not Flash?
Thats Not Flash?Thats Not Flash?
Thats Not Flash?
Mike Wilcox
 
CANVAS vs SVG @ FrontInRio 2011
CANVAS vs SVG @ FrontInRio 2011CANVAS vs SVG @ FrontInRio 2011
CANVAS vs SVG @ FrontInRio 2011
Davidson Fellipe
 
HTML5DevConf 2013 (October): WebGL is a game changer!
HTML5DevConf 2013 (October): WebGL is a game changer!HTML5DevConf 2013 (October): WebGL is a game changer!
HTML5DevConf 2013 (October): WebGL is a game changer!
Iker Jamardo
 
The Image that called me - Active Content Injection with SVG Files
The Image that called me - Active Content Injection with SVG FilesThe Image that called me - Active Content Injection with SVG Files
The Image that called me - Active Content Injection with SVG Files
Mario Heiderich
 
Universal Applications with Universal JavaScript
Universal Applications with Universal JavaScriptUniversal Applications with Universal JavaScript
Universal Applications with Universal JavaScript
Thomas Joseph
 
DojoX GFX Keynote Eugene Lazutkin SVG Open 2007
DojoX GFX Keynote Eugene Lazutkin SVG Open 2007DojoX GFX Keynote Eugene Lazutkin SVG Open 2007
DojoX GFX Keynote Eugene Lazutkin SVG Open 2007
Eugene Lazutkin
 
Academy PRO: HTML5 API graphics
Academy PRO: HTML5 API graphicsAcademy PRO: HTML5 API graphics
Academy PRO: HTML5 API graphics
Binary Studio
 
NativeScript: Cross-Platform Mobile Apps with JavaScript and Angular
NativeScript: Cross-Platform Mobile Apps with JavaScript and AngularNativeScript: Cross-Platform Mobile Apps with JavaScript and Angular
NativeScript: Cross-Platform Mobile Apps with JavaScript and Angular
Todd Anglin
 
Rich Media Advertising with SVG and JavaScript
Rich Media Advertising with SVG and JavaScriptRich Media Advertising with SVG and JavaScript
Rich Media Advertising with SVG and JavaScript
Gjokica Zafirovski
 
SVG Icons and Screen Reader Accessibility
SVG Icons and Screen Reader AccessibilitySVG Icons and Screen Reader Accessibility
SVG Icons and Screen Reader Accessibility
Dennis Lembree
 
Uni Tour Germany 11.2009
Uni Tour Germany 11.2009Uni Tour Germany 11.2009
Uni Tour Germany 11.2009
Patrick Lauke
 
Polyglot Adventures for the Modern Java Developer #javaone2017
Polyglot Adventures for the Modern Java Developer #javaone2017Polyglot Adventures for the Modern Java Developer #javaone2017
Polyglot Adventures for the Modern Java Developer #javaone2017
Mario-Leander Reimer
 
Ad

More from Kevin Hakanson (11)

Sharpen your "Architectural Documentation" Saw
Sharpen your "Architectural Documentation" SawSharpen your "Architectural Documentation" Saw
Sharpen your "Architectural Documentation" Saw
Kevin Hakanson
 
Who's in your Cloud? Cloud State Monitoring
Who's in your Cloud? Cloud State MonitoringWho's in your Cloud? Cloud State Monitoring
Who's in your Cloud? Cloud State Monitoring
Kevin Hakanson
 
Adopting Multi-Cloud Services with Confidence
Adopting Multi-Cloud Services with ConfidenceAdopting Multi-Cloud Services with Confidence
Adopting Multi-Cloud Services with Confidence
Kevin Hakanson
 
Introduction to Speech Interfaces for Web Applications
Introduction to Speech Interfaces for Web ApplicationsIntroduction to Speech Interfaces for Web Applications
Introduction to Speech Interfaces for Web Applications
Kevin Hakanson
 
Learning to Mod Minecraft: A Father/Daughter Retrospective
Learning to Mod Minecraft: A Father/Daughter RetrospectiveLearning to Mod Minecraft: A Father/Daughter Retrospective
Learning to Mod Minecraft: A Father/Daughter Retrospective
Kevin Hakanson
 
ng-owasp: OWASP Top 10 for AngularJS Applications
ng-owasp: OWASP Top 10 for AngularJS Applicationsng-owasp: OWASP Top 10 for AngularJS Applications
ng-owasp: OWASP Top 10 for AngularJS Applications
Kevin Hakanson
 
Securing TodoMVC Using the Web Cryptography API
Securing TodoMVC Using the Web Cryptography APISecuring TodoMVC Using the Web Cryptography API
Securing TodoMVC Using the Web Cryptography API
Kevin Hakanson
 
HTTP Potpourri
HTTP PotpourriHTTP Potpourri
HTTP Potpourri
Kevin Hakanson
 
Implementing Messaging Patterns in JavaScript using the OpenAjax Hub
Implementing Messaging Patterns in JavaScript using the OpenAjax HubImplementing Messaging Patterns in JavaScript using the OpenAjax Hub
Implementing Messaging Patterns in JavaScript using the OpenAjax Hub
Kevin Hakanson
 
Internationalize your JavaScript Application: Prepare for "the next billion" ...
Internationalize your JavaScript Application: Prepare for "the next billion" ...Internationalize your JavaScript Application: Prepare for "the next billion" ...
Internationalize your JavaScript Application: Prepare for "the next billion" ...
Kevin Hakanson
 
Developer's Guide to JavaScript and Web Cryptography
Developer's Guide to JavaScript and Web CryptographyDeveloper's Guide to JavaScript and Web Cryptography
Developer's Guide to JavaScript and Web Cryptography
Kevin Hakanson
 
Sharpen your "Architectural Documentation" Saw
Sharpen your "Architectural Documentation" SawSharpen your "Architectural Documentation" Saw
Sharpen your "Architectural Documentation" Saw
Kevin Hakanson
 
Who's in your Cloud? Cloud State Monitoring
Who's in your Cloud? Cloud State MonitoringWho's in your Cloud? Cloud State Monitoring
Who's in your Cloud? Cloud State Monitoring
Kevin Hakanson
 
Adopting Multi-Cloud Services with Confidence
Adopting Multi-Cloud Services with ConfidenceAdopting Multi-Cloud Services with Confidence
Adopting Multi-Cloud Services with Confidence
Kevin Hakanson
 
Introduction to Speech Interfaces for Web Applications
Introduction to Speech Interfaces for Web ApplicationsIntroduction to Speech Interfaces for Web Applications
Introduction to Speech Interfaces for Web Applications
Kevin Hakanson
 
Learning to Mod Minecraft: A Father/Daughter Retrospective
Learning to Mod Minecraft: A Father/Daughter RetrospectiveLearning to Mod Minecraft: A Father/Daughter Retrospective
Learning to Mod Minecraft: A Father/Daughter Retrospective
Kevin Hakanson
 
ng-owasp: OWASP Top 10 for AngularJS Applications
ng-owasp: OWASP Top 10 for AngularJS Applicationsng-owasp: OWASP Top 10 for AngularJS Applications
ng-owasp: OWASP Top 10 for AngularJS Applications
Kevin Hakanson
 
Securing TodoMVC Using the Web Cryptography API
Securing TodoMVC Using the Web Cryptography APISecuring TodoMVC Using the Web Cryptography API
Securing TodoMVC Using the Web Cryptography API
Kevin Hakanson
 
Implementing Messaging Patterns in JavaScript using the OpenAjax Hub
Implementing Messaging Patterns in JavaScript using the OpenAjax HubImplementing Messaging Patterns in JavaScript using the OpenAjax Hub
Implementing Messaging Patterns in JavaScript using the OpenAjax Hub
Kevin Hakanson
 
Internationalize your JavaScript Application: Prepare for "the next billion" ...
Internationalize your JavaScript Application: Prepare for "the next billion" ...Internationalize your JavaScript Application: Prepare for "the next billion" ...
Internationalize your JavaScript Application: Prepare for "the next billion" ...
Kevin Hakanson
 
Developer's Guide to JavaScript and Web Cryptography
Developer's Guide to JavaScript and Web CryptographyDeveloper's Guide to JavaScript and Web Cryptography
Developer's Guide to JavaScript and Web Cryptography
Kevin Hakanson
 
Ad

Recently uploaded (20)

SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdfSAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
Precisely
 
How Can I use the AI Hype in my Business Context?
How Can I use the AI Hype in my Business Context?How Can I use the AI Hype in my Business Context?
How Can I use the AI Hype in my Business Context?
Daniel Lehner
 
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
BookNet Canada
 
Into The Box Conference Keynote Day 1 (ITB2025)
Into The Box Conference Keynote Day 1 (ITB2025)Into The Box Conference Keynote Day 1 (ITB2025)
Into The Box Conference Keynote Day 1 (ITB2025)
Ortus Solutions, Corp
 
Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...
Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...
Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...
Noah Loul
 
Big Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur MorganBig Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur Morgan
Arthur Morgan
 
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdfThe Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
Abi john
 
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In France
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In FranceManifest Pre-Seed Update | A Humanoid OEM Deeptech In France
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In France
chb3
 
Semantic Cultivators : The Critical Future Role to Enable AI
Semantic Cultivators : The Critical Future Role to Enable AISemantic Cultivators : The Critical Future Role to Enable AI
Semantic Cultivators : The Critical Future Role to Enable AI
artmondano
 
Technology Trends in 2025: AI and Big Data Analytics
Technology Trends in 2025: AI and Big Data AnalyticsTechnology Trends in 2025: AI and Big Data Analytics
Technology Trends in 2025: AI and Big Data Analytics
InData Labs
 
Mobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi ArabiaMobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi Arabia
Steve Jonas
 
Linux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdfLinux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdf
RHCSA Guru
 
AI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global TrendsAI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global Trends
InData Labs
 
What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...
Vishnu Singh Chundawat
 
Rusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond SparkRusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond Spark
carlyakerly1
 
Role of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered ManufacturingRole of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered Manufacturing
Andrew Leo
 
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-UmgebungenHCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
panagenda
 
Drupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy ConsumptionDrupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy Consumption
Exove
 
Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025
Splunk
 
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Impelsys Inc.
 
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdfSAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
Precisely
 
How Can I use the AI Hype in my Business Context?
How Can I use the AI Hype in my Business Context?How Can I use the AI Hype in my Business Context?
How Can I use the AI Hype in my Business Context?
Daniel Lehner
 
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
BookNet Canada
 
Into The Box Conference Keynote Day 1 (ITB2025)
Into The Box Conference Keynote Day 1 (ITB2025)Into The Box Conference Keynote Day 1 (ITB2025)
Into The Box Conference Keynote Day 1 (ITB2025)
Ortus Solutions, Corp
 
Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...
Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...
Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...
Noah Loul
 
Big Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur MorganBig Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur Morgan
Arthur Morgan
 
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdfThe Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
Abi john
 
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In France
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In FranceManifest Pre-Seed Update | A Humanoid OEM Deeptech In France
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In France
chb3
 
Semantic Cultivators : The Critical Future Role to Enable AI
Semantic Cultivators : The Critical Future Role to Enable AISemantic Cultivators : The Critical Future Role to Enable AI
Semantic Cultivators : The Critical Future Role to Enable AI
artmondano
 
Technology Trends in 2025: AI and Big Data Analytics
Technology Trends in 2025: AI and Big Data AnalyticsTechnology Trends in 2025: AI and Big Data Analytics
Technology Trends in 2025: AI and Big Data Analytics
InData Labs
 
Mobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi ArabiaMobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi Arabia
Steve Jonas
 
Linux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdfLinux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdf
RHCSA Guru
 
AI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global TrendsAI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global Trends
InData Labs
 
What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...
Vishnu Singh Chundawat
 
Rusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond SparkRusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond Spark
carlyakerly1
 
Role of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered ManufacturingRole of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered Manufacturing
Andrew Leo
 
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-UmgebungenHCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
panagenda
 
Drupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy ConsumptionDrupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy Consumption
Exove
 
Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025
Splunk
 
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Impelsys Inc.
 

Make your own Print & Play card game using SVG and JavaScript

  • 1. Make  your  own  Print  &  Play  card   game  using  SVG  and  JavaScript   Kevin  Hakanson   5  April  2014  
  • 2. Abstract   Want  to  leverage  your  creaDvity,  love  of  board  games,  and  web  plaGorm  experience  to  do   something  different?    Turn  your  imaginaDon  into  a  Print  &  Play  card  game  using  only  a  modern   web  browser,  color  printer  and  text  editor.     This  session  will  use  the  Scalable  Vector  Graphics  (SVG)  image  format  and  JavaScript   programming  language  to  make  a  deck  of  cards  for  a  simple  game.    CreaDng  a  few  cards  in   graphics  soSware  like  Inkscape  is  one  thing,  but  what  about  50  or  100  cards?    What  happens   when  you  need  to  update  them  all?    That’s  the  value  of  generaDng  your  SVG  using  JavaScript.     We  will  start  with  a  blank  screen,  adding  color  and  graphics  elements  like  lines,  shapes,  text  and   images.    Learn  about  container  elements  and  defining  content  for  re-­‐use.    Understand  how  units   in  the  SVG  coordinate  system  can  transform  our  on-­‐screen  creaDon  into  an  8.5  by  11  inch  printed   page  (or  PDF).    SVG  examples  will  be  both  in  their  naDve  XML  format  and  created  from  JavaScript   using  Snap.svg,  an  open  source  library  from  Adobe  designed  for  modern  web  browsers.     You  will  leave  this  session  with  a  basic  knowledge  of  SVG  concepts,  how  to  programmaDcally   generate  SVG  using  JavaScript,  and  how  to  make  your  SVG  creaDon  printer  friendly.  
  • 3. TL;DR   •  Print  &  Play  Card  Game   – Scalable  Vector  Graphics  (SVG)   – JavaScript   – Snap.svg   – 8.5  by  11  PrinDng    
  • 4. Kevin  Hakanson   @hakanson   #tccc16   [email protected]   +KevinHakanson   hep://stackoverflow.com/users/22514/kevin-­‐hakanson   heps://github.com/hakanson  
  • 5. Bio   Kevin  Hakanson  is  an  applicaDon  architect  for   Thomson  Reuters  where  he  is  focused  on  highly   scalable  web  applicaDons,  especially  the  JavaScript   and  security  aspects.  His  background  includes   both  .NET  and  Java,  but  he  is  most  nostalgic  about   Lotus  Notes.  He  has  been  developing  professionally   since  1994  and  holds  a  Master’s  degree  in  SoSware   Engineering.  When  not  staring  at  a  computer   screen,  he  is  probably  staring  at  another  screen,   either  watching  TV  or  playing  video  games  with  his   family.  
  • 6. Bio   Kevin  Hakanson  is  an  applicaDon  architect  for   Thomson  Reuters  where  he  is  focused  on  highly   scalable  web  applicaDons,  especially  the  JavaScript   and  security  aspects.  His  background  includes   both  .NET  and  Java,  but  he  is  most  nostalgic  about   Lotus  Notes.  He  has  been  developing  professionally   since  1994  and  holds  a  Master’s  degree  in  SoSware   Engineering.  When  not  staring  at  a  computer   screen,  he  is  probably  staring  at  another  screen,   either  watching  TV  or  playing  video  games  with  his   family.  
  • 13. Fluxx  Blanxx   •  Add  your  own  zany  ideas   •  Each  pack  contains  one  of  each   of  the  five  card  types   •  Cards  are  "halfway-­‐blank"  with   standard-­‐issue  text  and  the   stripe  of  color   •  Just  grab  your  trusty   permanent  marker  and   customize  the  fun!     hep://store.looneylabs.com/Fluxx-­‐Blanxx    
  • 14. Print  &  Play   •  “Print  &  Play  games  are  those  which  are  oSen   free  to  any  player  who  wishes  to  print  them   off  themselves.  Many  are  available  on  the   Internet.”   –  hep://boardgamegeek.com/boardgamecategory/1120/print-­‐play       •  Print  &  Play  games  Boardgamegeek  wiki  entry:   –  hep://boardgamegeek.com/wiki/page/Print_and_Play_Games    
  • 15. Azure  Fluxx   •  Version  of  Fluxx  based  in  the  Window  Azure   “universe”:   – SoSware  Development   – MicrosoS  Products   – Web  Technologies  
  • 16. Fair  Use?   •  Fluxx  Copyright  Looney  Labs   •  Same  card  types   •  Same  basic  gameplay  and  rules  wording   •  Similar,  but  not  exact,  colors  and  artwork   •  Different  fonts   •  Different  physical  card  size  and  deck  count  
  • 18. Goals  and  Keepers   •  Goals   –  Old  School   –  New  School   –  Single  Page  App   –  Polyglot   –  Web  PlaGorm   –  Tool  Master   –  .NET  PlaGorm   –  Entry  Level   –  Mistaken  IdenDty   –  Selectors   –  Transpile   –  Odd  Couple   –  Double  MVC   –  Intellisense   –  Edge.js   –  UI  Bootstrap   •  Keepers  
  • 19. Scalable  Vector  Graphics  (SVG)   •  Text-­‐based  graphics  language  that  describes   images  with  vector  shapes,  text,  and   embedded  raster  graphics.   •  SVG  files  provide  resoluDon  independent,  high   resoluDon  dots  per  inch  (HiDPI)  graphics  on   the  web,  in  print,  and  on  mobile  devices  in  a   compact  format.       hep://www.adobe.com/devnet/svg.html    
  • 20. SVG  EssenDals   “This  insighGul  book  takes  you  through  the   ins  and  outs  of  SVG,  from  the  basics  to   more  complicated  features.”     hep://commons.oreilly.com/wiki/index.php/SVG_EssenDals    
  • 21. SVG  Primer   “The  book  aeempts  to  discuss  SVG  in   broader  terms,  but  at  the  same  Dme  to   illustrate  how  one  can  write  JavaScript   programs  that  use  and  manipulate  SVG.”     hep://www.w3.org/Graphics/SVG/IG/resources/svgprimer.html    
  • 22. Snap.svg     “the  JavaScript  SVG  library  for  the  modern  web”     “makes  working  with  your  SVG  assets  as  easy  as   jQuery  makes  working  with  the  DOM”         hep://snapsvg.io/    
  • 23. The  svg  Element   •  <svg>  is  both  root  element  and  used  to  nest   standalone  SVG  fragments   •  Each  standalone  fragment  has  its  own   viewPort  and  coordinate  system  
  • 24. <svg>  XML  Example   <svg      width="8.5in"      height="11in"      viewBox="0  0  215.9  279.4"      version="1.1"      xmlns="http://www.w3.org/2000/svg"        xmlns:xlink="http://www.w3.org/1999/xlink">   </svg>  
  • 25. <svg>  JavaScript  Example   var  svg  =  Snap("8.5in",  (pageCount*11)+"in")                    .attr({id:"SnapDeck",  style:"display:  block;"});     var  pageAttr  =  {  width:"8.5in",  height:"11in",                                    "viewBox"  :  "0  0  215.9  279.4"};     for  (pageIndex  =  1;  pageIndex<=pageCount;  pageIndex++)  {            page  =  svg.el("svg",  pageAttr)                        .attr({  id  :  "SnapDeckPage"+pageIndex,                                        y  :  ((pageIndex-­‐1)*11)+"in"  });   }  
  • 26. <svg>  XML  Example   <svg  width="8.5in"  height="22in"  id="SnapDeck">        <svg  width="8.5in"  height="11in"  y="0in"        viewBox="0  0  215.9  279.4"  id="SnapDeckPage1">      </svg>        <svg  width="8.5in"  height="11in"  y="11in"        viewBox="0  0  215.9  279.4"  id="SnapDeckPage2">      </svg>     </svg>  
  • 27. Grouping  and  Reusing     “The  <use>  (reuse)  and  <g>  (or  group)   tags  bear  similarity  to  the  variables  and   objects  encountered  in  programming   languages.”       hep://www.w3.org/Graphics/SVG/IG/resources/svgprimer.html#operaDons    
  • 28. The  g  Element   •  Gathers  child  elements  into  a  group   •  Uses  id  aeribute  to  give  a  unique  name   •  Can  have  <title>  and  <desc>   •  Styles  apply  to  child  elements   •  Can  nest  groups  within  one  another  
  • 29. <g>  XML  Example   <g  id="plus"          opacity=".4"          stroke="black"          stroke-­‐width="0.1">        <path  d="M  -­‐3  0  H  3  M  0  -­‐3  V  3"  />     </g>    
  • 30. The  defs  Element   •  Puxng  grouped  objects  inside  of  <defs>  tells   SVG  to  define  them  without  displaying  them   •  SVG  recommendaDon  is  to  put  all  objects   intended  for  re-­‐use  inside  <defs>  
  • 31. <defs>  JavaScript  Example   var  plus  =  svg.g(    svg.path("M  -­‐3  0  H  3  M  0  -­‐3  V  3")   );   plus.attr({id:"plus",        opacity:"0.4",      stroke:"black",      "stroke-­‐width":"0.1"});   plus.toDefs();  
  • 32. The  symbol  Element   •  <symbol>  element  provides  another  way  of   grouping  elements   •  Never  displayed,  so  don't  have  to  enclose  it  in   <defs>  but  customary  to  do  so   •  <symbol>  can  specify  viewBox  and   preserveAspectRatio  aeributes  
  • 33. The  use  Element   •  “copy-­‐and-­‐paste”  of  a  defined  group   •  Specify  with  an  xlink:href  aeribute   •  Specify  the  x  and  y  locaDon  for  the   group's  (0,  0)  point  
  • 35. <g  id="pluses">          <use  xlink:href="#plus"  x="12.7"  y="7.7"/>          <use  xlink:href="#plus"  x="12.7"  y="95.7"/>          <use  xlink:href="#plus"  x="12.7"  y="183.7"/>          <use  xlink:href="#plus"  x="12.7"  y="271.7"/>            <use  xlink:href="#plus"  x="76.2"  y="7.7"/>          <use  xlink:href="#plus"  x="76.2"  y="95.7"/>          <use  xlink:href="#plus"  x="76.2"  y="183.7"/>          <use  xlink:href="#plus"  x="76.2"  y="271.7"/>            <use  xlink:href="#plus"  x="139.7"  y="7.7"/>          <use  xlink:href="#plus"  x="139.7"  y="95.7"/>          <use  xlink:href="#plus"  x="139.7"  y="183.7"/>          <use  xlink:href="#plus"  x="139.7"  y="271.7"/>            <use  xlink:href="#plus"  x="203.2"  y="7.7"/>          <use  xlink:href="#plus"  x="203.2"  y="95.7"/>          <use  xlink:href="#plus"  x="203.2"  y="183.7"/>          <use  xlink:href="#plus"  x="203.2"  y="271.7"/>   </g>    
  • 36. <use>  XML  Example   <g  id="pluscolumn">          <use  xlink:href="#plus"  y="7.7"  />          <use  xlink:href="#plus"  y="95.7"  />          <use  xlink:href="#plus"  y="183.7"  />          <use  xlink:href="#plus"  y="271.7"  />   </g>     <g  id="pluses">          <use  xlink:href="#pluscolumn"  x="12.7"  />          <use  xlink:href="#pluscolumn"  x="76.2"  />          <use  xlink:href="#pluscolumn"  x="139.7"  />          <use  xlink:href="#pluscolumn"  x="203.2"  />   </g>  
  • 37. <use>  JavaScript  Example   //  width:  63.5,  height:  88   var  xstops  =  [12.7,  76.2,  139.7,  203.2];   var  ystops  =  [7.7,  95.7,  183.7,  271.7];     pages.forEach(function  (page)  {      ystops.forEach(function  (y)  {          xstops.forEach(function  (x)  {              var  p  =  plus.use().attr({  x:  x,  y:  y  });              page.append(p);          });      });   });  
  • 38. Why  63.5  x  88  mm  ?  
  • 41. The  rect  Element   •  Specify  x-­‐  and  y-­‐coordinates  of  the  upper  leS   corner,  width,  and  height   –   x,  y,  width  and  height  aeributes   •  Interior  is  filled  with  a  fill  color  (default  black)   •  Outline  is  drawn  with  strokes  (default  none)   <rect  x="0"  y="0"      width="10"  height="10"  fill="black"/>  
  • 42. The  circle  Element   •  Specify  center  x-­‐coordinate,  center  y-­‐ coordinate,  and  radius   –   cx,  cy,  and  r  aeributes   •  Interior  is  filled  with  a  fill  color  (default  black)   •  Outline  is  drawn  with  strokes  (default  none)   <circle  cx="5"  cy="5"  r="3.5"    fill="white"  stroke-­‐width="0"  />  
  • 43. The  ellipse  Element   •  Like  <circle>,  specify  center  x-­‐coordinate,   center  y-­‐coordinate   •  Also  needs  an  x-­‐radius  and  a  y-­‐radius   – aeributes  for  these  radii  are  named  rx  and  ry   <ellipse  cx="4"  cy="4"      rx="0.25"  ry="0.5"  />  
  • 44. The  line  Element   •  Specify  the  x-­‐  and  y-­‐coordinates  of  the  line's   endpoints   –   x1,  y1,  x2  and  x2  aeributes  
  • 45. The  path  Element   •  Draws  the  outline  of  any  arbitrary  shape  by   specifying  a  series  of  connected  lines,  arcs,  and   curves   •  Must  begin  with  a  moveto  command   •  Followed  by  one  or  more  lineto  commands   •  Arc  draws  a  secDon  of  an  ellipse  that  connects   two  points   <path  fill="none"  stroke-­‐linecap="round"              d="M  3.5  6.75  a  1.5,1.5  0  1  1  3  0"  />  
  • 47. <rect  x="0"  y="0"  width="10"  height="10"  fill="black"  />   <g  id="frown"  stroke="black"  fill="black"  stroke-­‐width=".5">      <circle  cx="5"  cy="5"  r="3.5"  fill="white"  stroke-­‐width="0"  />        <circle  cx="4"  cy="4"  r="0.25"  />      <circle  cx="6"  cy="4"  r="0.25"  />        <path  fill="none"                  d="M  3.5  6.75  a  1.5,1.5  0  1  1  3  0"  />   </g>  
  • 48. <rect  x="0"  y="0"  width="10"  height="10"  fill="black"  />   <g  id="frown"  stroke="black"  fill="black"  stroke-­‐width=".5">      <circle  cx="5"  cy="5"  r="3.5"  fill="white"  stroke-­‐width="0"  />        <ellipse  cx="4"  cy="4"  rx="0.25"  ry="0.5"  />      <ellipse  cx="6"  cy="4"  rx="0.25"  ry="0.5"  />        <path  fill="none"  stroke-­‐linecap="round"                  d="M  3.5  6.75  a  1.5,1.5  0  1  1  3  0"  />   </g>  
  • 49. <rect  x="0"  y="0"  width="10"  height="10"  fill="black"  />   <g  id="frown"  stroke="black"  fill="black"  stroke-­‐width=".5">      <circle  cx="5"  cy="5"  r="3.5"  fill="white"  stroke-­‐width="0"  />        <ellipse  cx="4"  cy="4"  rx="0.25"  ry="0.5"  />      <ellipse  cx="6"  cy="4"  rx="0.25"  ry="0.5"  />        <path  fill="none"  stroke-­‐linecap="round"                  d="M  3.5  6.75  C  4  5  6  6  6.5  7"  />   </g>  
  • 50. svg.rect(0,  0,  10,  10);     var  frown  =  svg.g()          .attr({  id:  "frown",  stroke:  "black",                            fill:  "black",  "stroke-­‐width":  0.5  });     frown.append(svg.circle(5,  5,  3.5)          .attr({  fill:  "white",  "stroke-­‐width":  0  }));   frown.append(svg.ellipse(4,  4,  0.25,  0.5));   frown.append(svg.ellipse(6,  4,  0.25,  0.5));     frown.append(svg.path("M  3.5  6.75  C  4  5  6  6  6.5  7")          .attr({  fill:  "none",                            "stroke-­‐linecap":  "round"  }));  
  • 51. <rect  x="0"  y="0"  width="10"  height="10"  fill="yellow"/>     <g  id="flowerpedal"  stroke="black"  stroke-­‐width="0">      <path  fill="black"        d="M  5  5  l  -­‐0.75  3  a  0.75,0.75  0  1  0  1.5  0  Z"  />   </g>  
  • 52. The  transform  Aeribute   •  matrix(<a>  <b>  <c>  <d>  <e>  <f>)   •  translate(<x>  [<y>])   •  scale(<x>  [<y>])   •  rotate(<a>  [<x>  <y>])   •  skewX(<a>)   •  skewY(<a>)     heps://developer.mozilla.org/en-­‐US/docs/Web/SVG/Aeribute/transform    
  • 53. <rect  x="0"  y="0"  width="10"  height="10"  fill="yellow"  />   <g  id="flowerpedal"  stroke="black"  stroke-­‐width="0">      <path  fill="black"  d="M  5  5  l  -­‐0.75  3  a  0.75,0.75  0  1  0  1.5  0  Z"  />   </g>   <use  xlink:href="#flowerpedal"  transform="rotate(  60,  5,  5)"  />   <use  xlink:href="#flowerpedal"  transform="rotate(120,  5,  5)"  />   <use  xlink:href="#flowerpedal"  transform="rotate(180,  5,  5)"  />   <use  xlink:href="#flowerpedal"  transform="rotate(240,  5,  5)"  />   <use  xlink:href="#flowerpedal"  transform="rotate(300,  5,  5)"  />  
  • 54. <rect  x="0"  y="0"  width="10"  height="10"  fill="greenyellow"/>   <g  id="check"  stroke="black"  stroke-­‐width="1">      <polyline  stroke-­‐linejoin="round"                            stroke-­‐linecap="round"                            fill="none"                            points="2  5,  3  8,  8  2"  />   </g>  
  • 55. <rect  x="0"  y="0"  width="10"  height="10"  fill="pink"  />   <g  id="checkbox"  stroke="black">      <rect  x="3"  y="3"  width="6"  height="6"                    fill="black"  stroke-­‐width="0"  />      <rect  x="2"  y="2"  width="6"  height="6"                    fill="pink"  stroke-­‐width="0.5"  />   </g>  
  • 56. <rect  x="0"  y="0"  width="10"  height="10"  fill="skyblue"  />   <g  id="arrow"  stroke="black"  stroke-­‐width="0.5">      <path  fill="black"  d="M  5.5  2  l  .5  0  l  3  3  l  -­‐3  3  l  -­‐0.5  0  l  0   -­‐1.5  l  -­‐4  0  l  0  -­‐3  l  4  0  Z"  />      <path  stroke-­‐linejoin="round"  fill="skyblue"  d="M  6  2  l  3  3  l   -­‐3  3  l  0  -­‐1.5  l  -­‐4  0  l  0  -­‐3  l  4  0  Z"  />   </g>  
  • 57. <rect  x="0"  y="0"  width="10"  height="10"  fill="mediumpurple"  />     <g  id="bolt"  stroke="black"  stroke-­‐width="0.5">      <path  fill="white"  d="M  5  1  l  -­‐3  3  l  2  0  l  -­‐2  2  l  2  0  l  -­‐2  3  l   5  -­‐4  l  -­‐2  0  l  2  -­‐2  l  -­‐2  0  l  2  -­‐2  Z"  />   </g>  
  • 58. How-­‐To  Make  a  Keeper   <symbol>  
  • 59. How-­‐To  Make  a  Keeper   <symbol>     <text>  
  • 60. How-­‐To  Make  a  Keeper   <symbol>     <text>     <rect>    
  • 61. How-­‐To  Make  a  Keeper   <symbol>     <text>     <rect>     <image>    
  • 62. The  text  Element   •  <text>  requires  only  two  aeributes,  x  and  y   •  Default  style  is  to  have  a  fill  color  of  black  and   no  outline   •  font-­‐family,  font-­‐size,  font-­‐weight,  font-­‐style,   text-­‐decoraDon,  word-­‐spacing,  leeer-­‐spacing   •  “SVG  performs  no  automaDc  line  breaking  or   word  wrapping”   hep://www.w3.org/TR/SVG11/text.html#IntroducDon    
  • 63. <text>  XML  Example   <g  text-­‐anchor="start"          font-­‐size="3.5"          letter-­‐spacing="-­‐0.05">      <text  x="15"  y="18">To  play  this  card,  place  it  face</text>      <text  x="15"  y="22.375">up  on  the  table  in  front  of  you.</text>     </g>  
  • 64. The  image  Element   •  <image>  element  includes  an  enDre  SVG  or   raster  file  (JPEG  or  PNG)   •  x,  y,  width,  and  height  aeributes   <image  xlink:href="images/JavaScript-­‐logo.png"   preserveAspectRatio="meet"  x="22"  y="48"  width="30"   height="30"  />  
  • 65. <image>  XML  Example    <image      xlink:href="images/JavaScript-­‐logo.png"      x="22"      y="48"      width="30"      height="30"                    preserveAspectRatio  ="meet"  />  
  • 66. <image>  JavaScript  Example   s.image(                          "images/JavaScript-­‐logo.png",            22,            48,                    30,                    30)   .attr({  "preserveAspectRatio":"meet"  })  
  • 67. <svg  id="SnapDeckCard1"      width="63.5"  height="88"      xmlns="http://www.w3.org/2000/svg"    xmlns:xlink="http://www.w3.org/1999/xlink"      font-­‐family="sans-­‐serif">            <defs>                          <!-­‐-­‐  ...  -­‐-­‐>      </defs>    <!-­‐-­‐  ...  -­‐-­‐>   </svg>  
  • 68. <svg  id="SnapDeckCard1"      width="63.5"  height="88"      xmlns="http://www.w3.org/2000/svg"    xmlns:xlink="http://www.w3.org/1999/xlink"      font-­‐family="sans-­‐serif">            <defs>          <rect  id="sidebar"  x="3"  y="3"  width="10"  height="82"  />                        <!-­‐-­‐  ...  -­‐-­‐>      </defs>    <!-­‐-­‐  ...  -­‐-­‐>   </svg>  
  • 69. <svg  id="SnapDeckCard1"      width="63.5"  height="88"      xmlns="http://www.w3.org/2000/svg"    xmlns:xlink="http://www.w3.org/1999/xlink"      font-­‐family="sans-­‐serif">            <defs>          <rect  id="sidebar"  x="3"  y="3"  width="10"  height="82"  />          <rect  id="hr"  x="15"  y="33"                        width="45.5"  height="2"  fill="black"  />                    <!-­‐-­‐  ...  -­‐-­‐>      </defs>    <!-­‐-­‐  ...  -­‐-­‐>   </svg>  
  • 70. <svg  id="SnapDeckCard1"      width="63.5"  height="88"      xmlns="http://www.w3.org/2000/svg"    xmlns:xlink="http://www.w3.org/1999/xlink"      font-­‐family="sans-­‐serif">            <defs>          <rect  id="sidebar"  x="3"  y="3"  width="10"  height="82"  />          <rect  id="hr"  x="15"  y="33"                        width="45.5"  height="2"  fill="black"  />            <symbol  id="check"  stroke="black"  stroke-­‐width="1">              <polyline  points="5,8,6,11,11,5"  fill="none"                                    stroke-­‐linejoin="round"  stroke-­‐linecap="round"  />          </symbol>          <!-­‐-­‐  ...  -­‐-­‐>      </defs>    <!-­‐-­‐  ...  -­‐-­‐>   </svg>  
  • 71. <svg>          <defs>          <!-­‐-­‐  ...  -­‐-­‐>          <g  id="keeper">              <use  xlink:href="#check"  />              <use  xlink:href="#sidebar"  fill="#b3dd1a"  />                                <use  xlink:href="#hr"  />                    </g>      </defs>    <!-­‐-­‐  ...  -­‐-­‐>   </svg>  
  • 72. <svg>          <defs>          <!-­‐-­‐  ...  -­‐-­‐>          <g  id="keeper">              <use  xlink:href="#check"  />              <use  xlink:href="#sidebar"  fill="#b3dd1a"  />                            <text  text-­‐anchor="start"  x="14.5"  y="11"  font-­‐size="9"                            letter-­‐spacing="-­‐.5"  font-­‐weight="bold">KEEPER</text>                          <use  xlink:href="#hr"  />                    </g>      </defs>    <!-­‐-­‐  ...  -­‐-­‐>   </svg>  
  • 73. <svg>          <defs>          <!-­‐-­‐  ...  -­‐-­‐>          <g  id="keeper">              <use  xlink:href="#check"  />              <use  xlink:href="#sidebar"  fill="#b3dd1a"  />                <text  text-­‐anchor="start"  x="14.5"  y="11"  font-­‐size="9"                            letter-­‐spacing="-­‐.5"  font-­‐weight="bold">KEEPER</text>                          <use  xlink:href="#hr"  />                <g  text-­‐anchor="start"  font-­‐size="3.5"  letter-­‐spacing="-­‐0.05">                  <text  x="15"  y="18">To  play  this  card,  place  it  face</text>                  <text  x="15"  y="22.375">up  on  the  table  in  front  of  you.</text>              </g>          </g>      </defs>    <!-­‐-­‐  ...  -­‐-­‐>   </svg>  
  • 74. <svg>          <defs>          <!-­‐-­‐  ...  -­‐-­‐>      </defs>        <use  xlink:href="#keeper"  />        <g  text-­‐anchor="start"  font-­‐size="5.5"              letter-­‐spacing="-­‐0.05"  font-­‐weight="bold">          <text  x="15"  y="31">JavaScript</text>      </g>                 </svg>  
  • 75. <svg>          <defs>          <!-­‐-­‐  ...  -­‐-­‐>      </defs>        <use  xlink:href="#keeper"  />        <g  text-­‐anchor="start"  font-­‐size="5.5"            letter-­‐spacing="-­‐0.05"  font-­‐weight="bold">          <text  x="15"  y="31">JavaScript</text>      </g>        <text  x="10"  y="15"  transform="matrix(0,-­‐1,1,0,-­‐5,25)"  font-­‐size="6"                    text-­‐anchor="end"  font-­‐weight="bold">JAVASCRIPT</text>           </svg>  
  • 76. <svg>          <defs>          <!-­‐-­‐  ...  -­‐-­‐>      </defs>        <use  xlink:href="#keeper"  />        <g  line-­‐spacing="0"  paragraph-­‐spacing="0"  text-­‐anchor="start"              font-­‐size="5.5"  letter-­‐spacing="-­‐0.05"  font-­‐weight="bold">          <text  x="15"  y="31">JavaScript</text>      </g>        <text  x="10"  y="15"  transform="matrix(0,-­‐1,1,0,-­‐5,25)"  font-­‐size="6"                    text-­‐anchor="end"  font-­‐weight="bold">JAVASCRIPT</text>        <image  xlink:href="images/JavaScript-­‐logo.png"                      preserveAspectRatio="meet"  x="22"  y="48"                      width="30"  height="30"  />   </svg>  
  • 77. <svg  id="SnapDeckCard1"  width="460"  height="640"  viewBox="0  0  63.5  88"  xmlns="http://www.w3.org/2000/svg"              xmlns:xlink="http://www.w3.org/1999/xlink"  font-­‐family="sans-­‐serif”>          <defs>          <rect  x="3"  y="3"  width="10"  height="82"  id="sidebar"  />          <rect  x="15"  y="33"  width="45.5"  height="2"  id="hr"  fill="black"  />            <symbol  id="check"  stroke="black"  stroke-­‐width="1">              <polyline  points="5,8,6,11,11,5"  fill="none"  stroke-­‐linejoin="round"  stroke-­‐linecap="round"  />          </symbol>            <g  id="keeper">              <use  xlink:href="#sidebar"  fill="#b3dd1a"  />              <use  xlink:href="#check"  />              <text  text-­‐anchor="start"  x="14.5"  y="11"  font-­‐size="9"  letter-­‐spacing="-­‐.5"  font-­‐weight="bold">KEEPER</text>                          <use  xlink:href="#hr"  />              <g  text-­‐anchor="start"  font-­‐size="3.5"  letter-­‐spacing="-­‐0.05">                  <text  x="15"  y="18">To  play  this  card,  place  it  face</text>                  <text  x="15"  y="22.375">up  on  the  table  in  front  of  you.</text>              </g>          </g>      </defs>      <use  xlink:href="#keeper"></use>      <g  text-­‐anchor="start"  font-­‐size="5.5"  letter-­‐spacing="-­‐0.05"  font-­‐weight="bold">          <text  x="15"  y="31">JavaScript</text>      </g>      <text  x="10"  y="15"  transform="matrix(0,-­‐1,1,0,-­‐5,25)"                    font-­‐size="6"  text-­‐anchor="end"  font-­‐weight="bold">JAVASCRIPT</text>      <image  xlink:href="images/JavaScript-­‐logo.png"  preserveAspectRatio="meet"  x="22"  y="48"  width="30"  height="30"  />   </svg>  
  • 79. SVG  1.1  Text   Each  <text>  element  causes  a  single  string  of   text  to  be  rendered.  SVG  performs  no  automaDc   line  breaking  or  word  wrapping      hep://www.w3.org/TR/SVG11/text.html#IntroducDon    
  • 80. SVG  Tiny  1.2     •  The  <textArea>  element  allows  simplisDc   wrapping  of  text  content     •  The  <tbreak>  element  is  an  empty  element   that  forcibly  breaks  the  current  line  of  text     •  The  line-­‐increment  property  provides   limited  control  over  the  size  of  each  line  
  • 81. SVG  1.2   •  Scalable  Vector  Graphics  (SVG)  Full  1.2   SpecificaDon   – W3C  Working  DraS  13  April  2005   hep://www.w3.org/TR/SVG12/     •  “The  next  draS  of  SVG  1.2  Full  will  structured   as  a  superset  of  the  SVG  1.2  Tiny  language”   •  “At  this  Dme  the  refactored  SVG  1.2  Full   specificaDon  is  not  ready  for  publicaDon.”  
  • 82. snapdeck.textArea  =  function  (s,  x,  y,  width,  textToWrap,  attr)  {          if  (!textToWrap)  return;            attr  =  SnapDeck.defaultAttr(attr,  {  "text-­‐anchor":  "start",  "font-­‐size":  3.5,  "letter-­‐spacing":  -­‐.05,  "line-­‐spacing":  0,  "paragraph-­‐ spacing":  0  });          var  fontSize  =  attr["font-­‐size"];          width  =  width  *  (fontSize  /  3);          var  yDelta  =  (fontSize  *  1.25)  +  attr["line-­‐spacing"];          var  tmpSvg,  tmpRoot  =  deck.svg.g().attr(attr).toDefs();          var  g  =  s.g().attr(attr);          var  line  =  "",  tmpLine  =  "",  linecount  =  0;          var  texts  =  textToWrap.split("n");          texts.forEach(function  (text)  {                  var  words  =  text.split("  ");                  words.forEach(function  (word)  {                          if  (line)  {                                  tmpLine  =  line  +  "  "  +  word;                                  tmpSvg  =  tmpRoot.text(0,  0,  tmpLine);                                  if  (tmpSvg.node.getBoundingClientRect().width  >  width)  {                                          g.text(x,  y,  line);                                          y  =  y  +  yDelta;                                          linecount++;                                          line  =  tmpLine  =  word;                                  }  else  {                                          line  =  line  +  "  "  +  word;                                  }                                  tmpSvg.remove();                          }  else  {                                  line  =  word;                          }                  });                    g.text(x,  y,  line);                  y  =  y  +  yDelta  +  attr["paragraph-­‐spacing"];                  linecount++;                  line  =  tmpLine  =  "";          });            tmpRoot.remove();          return  g;   };  
  • 83. Chrome  Zoom   100%   150%   200%  
  • 84. snap.deck.js   (function(window)  {            function  Deck(cardCount)  {                  //  ...                  this.svg  =  Snap("8.5in",  (pageCount  *  11)  +  "in")                          .attr({  id:  "SnapDeck",  style:  "display:  block;"  });                  this.pages  =  [];                  this.cards  =  [];                  //  ...          }            snapdeck.deck  =  function  (cards)  {                  return  new  Deck(cards);          };            window.SnapDeck  =  snapdeck;     })(window);  
  • 87. Len  Peralta’s  Geek  A  Week  
  • 88. @hakanson  Card   •  Mimic  look  from  the   Geek  A  Week  series   •  InformaDon  and  images   from  Twieer  biography   •  “More  cool”  than  a   business  card  
  • 89. var  s  =  Snap("460",  "640")                  .attr({  "viewBox":  "0  0  63.5  88",                                    "font-­‐family":"sans-­‐serif"  });     SnapDeck.pinwheel(s,  31.75,  44,  55,  120,                                        "firebrick",  "maroon");        
  • 90. Pinwheel   •  120  rays   •  firebrick   •  maroon  
  • 92. snapdeck.pinwheel  =  function  (s,  cx,  cy,  cr,  count,  background,  foreground)   {          var  c  =  s.circle(cx,  cy,  cr);          c.attr({  "stroke-­‐width":  0,  "fill":  background  });            var  deg  =  360  /  count;          var  offset  =  -­‐deg  /  2;          for  (var  i  =  0;  i  <  count  /  2;  i++)  {                  var  start  =  "M  "  +  cx  +  "  "  +  cy;                    var  rad  =  (2  *  i  *  deg  +  offset)  *  (Math.PI  /  180);                  var  x  =  cx  +  (Math.cos(rad)  *  cr);                  var  y  =  cy  +  (Math.sin(rad)  *  cr);                    var  first  =  "  L  "  +  x  +  "  "  +  y;                    rad  =  (2  *  i  *  deg  +  deg  +  offset)  *  (Math.PI  /  180);                  x  =  cx  +  (Math.cos(rad)  *  cr);                  y  =  cy  +  (Math.sin(rad)  *  cr);                    var  second  =  "  A  "  +  cx  +  "  "  +  cy  +  "  0  0  1  "  +  x  +  "  "  +  y;                    s.path(start  +  first  +  second  +  "  Z").attr({  "fill":  foreground  });          }          return  s;   };  
  • 93. var  s  =  Snap("460",  "640")                  .attr({  "viewBox":  "0  0  63.5  88",                                    "font-­‐family":"sans-­‐serif"  });     SnapDeck.pinwheel(s,  31.75,  44,  55,  120,                                        "firebrick",  "maroon");     s.rect(3,  3,  57.5,  75,  0.5,  0.5)    .attr({  "fill":  "red"  });        
  • 94. var  s  =  Snap("460",  "640")                  .attr({  "viewBox":  "0  0  63.5  88",                                    "font-­‐family":"sans-­‐serif"  });     SnapDeck.pinwheel(s,  31.75,  44,  55,  120,                                        "firebrick",  "maroon");     s.rect(3,  3,  57.5,  75,  0.5,  0.5)    .attr({  "fill":  "red"  });     s.rect(4,  4,  55.5,  73,  0,  0)    .attr({  "fill":  "none",                      "stroke-­‐width":  1,  "stroke":  "yellow",  });      
  • 95. var  s  =  Snap("460",  "640")                  .attr({  "viewBox":  "0  0  63.5  88",                                    "font-­‐family":"sans-­‐serif"  });     SnapDeck.pinwheel(s,  31.75,  44,  55,  120,                                        "firebrick",  "maroon");     s.rect(3,  3,  57.5,  75,  0.5,  0.5)    .attr({  "fill":  "red"  });     s.rect(4,  4,  55.5,  73,  0,  0)    .attr({  "fill":  "none",                      "stroke-­‐width":  1,  "stroke":  "yellow",  });     s.rect(5,  5,  53.5,  71)    .attr({  "fill":  "black"  });    
  • 96. s.rect(56,  1.25,  6,  5.5,  0.5,  0.5)    .attr({  "fill":  "red"  });   s.rect(56.5,  2,  5,  4.25,  0.25,  0.25)    .attr({  "fill":  "black",  "opacity":  0.85  });   s.rect(56.5,  1.75,  4.75,  4.25,  0.25,  0.25)    .attr({  "fill":  "yellow",  "opacity":  0.9  });     s.text(59,  5,  "#1").attr({  "text-­‐anchor":  "middle",  "font-­‐size":   3.5,  "fill":  "black",  "font-­‐weight":  "bold"  });    
  • 97. s.rect(56,  1.25,  6,  5.5,  0.5,  0.5)    .attr({  "fill":  "red"  });   s.rect(56.5,  2,  5,  4.25,  0.25,  0.25)    .attr({  "fill":  "black",  "opacity":  0.85  });   s.rect(56.5,  1.75,  4.75,  4.25,  0.25,  0.25)    .attr({  "fill":  "yellow",  "opacity":  0.9  });     s.text(59,  5,  "#1").attr({  "text-­‐anchor":  "middle",  "font-­‐size":   3.5,  "fill":  "black",  "font-­‐weight":  "bold"  });     s.image("images/Twitter_logo_blue.png",  6,  71,  14,  14);    
  • 98. s.rect(56,  1.25,  6,  5.5,  0.5,  0.5)    .attr({  "fill":  "red"  });   s.rect(56.5,  2,  5,  4.25,  0.25,  0.25)    .attr({  "fill":  "black",  "opacity":  0.85  });   s.rect(56.5,  1.75,  4.75,  4.25,  0.25,  0.25)    .attr({  "fill":  "yellow",  "opacity":  0.9  });     s.text(59,  5,  "#1").attr({  "text-­‐anchor":  "middle",  "font-­‐size":   3.5,  "fill":  "black",  "font-­‐weight":  "bold"  });     s.image("images/Twitter_logo_blue.png",  6,  71,  14,  14);     s.text(60,  82,  "Kevin  Hakanson").attr({  "text-­‐anchor":  "end",   "font-­‐size":  4.5,  "fill":  "white",  "font-­‐weight":  "bold"  });   s.text(60,  86,  "@hakanson")    .attr({  "text-­‐anchor":  "end",                      "font-­‐size":  3.5,  "fill":  "white"  });  
  • 99. s.rect(11.5,  7.5,  40,  40,  0.5,  0.5)    .attr({  "fill":  "white"  });   s.image("images/hakanson.png",  12,  8,  39,  39);      
  • 100. s.rect(11.5,  7.5,  40,  40,  0.5,  0.5)    .attr({  "fill":  "white"  });   s.image("images/hakanson.png",  12,  8,  39,  39);     var  bioAttr  =  {  "text-­‐anchor":  "middle",                      "font-­‐size":  2.75,  "fill":  "white"  };   s.text(31.75,  52,          "Software  Architect  at  Thomson  Reuters.")    .attr(bioAttr);   s.text(31.75,  56,          "WestlawNext.  Web  Platform.  JavaScript.")    .attr(bioAttr);   s.text(31.75,  60,          "Agile  Software  Development.").attr(bioAttr);   s.text(31.75,  64,          "Information  Security.  Speaker.").attr(bioAttr);   s.text(31.75,  68,  "Creator  @LicPlateZone").attr(bioAttr);    
  • 101. s.rect(11.5,  7.5,  40,  40,  0.5,  0.5)    .attr({  "fill":  "white"  });   s.image("images/hakanson.png",  12,  8,  39,  39);     var  bioAttr  =  {  "text-­‐anchor":  "middle",                      "font-­‐size":  2.75,  "fill":  "white"  };   s.text(31.75,  52,          "Software  Architect  at  Thomson  Reuters.")    .attr(bioAttr);   s.text(31.75,  56,          "WestlawNext.  Web  Platform.  JavaScript.")    .attr(bioAttr);   s.text(31.75,  60,          "Agile  Software  Development.").attr(bioAttr);   s.text(31.75,  64,          "Information  Security.  Speaker.").attr(bioAttr);   s.text(31.75,  68,  "Creator  @LicPlateZone").attr(bioAttr);     s.text(56,  74,  "http://about.me/kevin.hakanson")    .attr({  "font-­‐size":  2.5,  "text-­‐anchor":  "end",                      "fill":  "lightskyblue"  });  
  • 102. var  s  =  Snap("460",  "640")                  .attr({  "viewBox":  "0  0  63.5  88",  style:  "display:  block;",  "font-­‐family":"sans-­‐serif"  });   var  cx  =  31.75,  cy  =  44,  cr  =  55;     SnapDeck.pinwheel(s,  cx,  cy,  cr,  120,  "firebrick",  "maroon");     s.rect(3,  3,  57.5,  75,  0.5,  0.5).attr({  "fill":  "red"  });   s.rect(4,  4,  55.5,  73,  0,  0).attr({  "stroke-­‐width":  1,  "stroke":  "yellow",  "fill":  "none"  });   s.rect(5,  5,  53.5,  71).attr({  "fill":  "black"  });             s.rect(56,  1.25,  6,  5.5,  0.5,  0.5).attr({  "fill":  "red"  });   s.rect(56.5,  2,  5,  4.25,  0.25,  0.25).attr({  "fill":  "black",  "opacity":  0.85  });   s.rect(56.5,  1.75,  4.75,  4.25,  0.25,  0.25).attr({  "fill":  "yellow",  "opacity":  0.9  });     s.text(59,  5,  "#1").attr({  "text-­‐anchor":  "middle",  "font-­‐size":  3.5,  "fill":  "black",  "font-­‐weight":  "bold"  });                   s.rect(11.5,  7.5,  40,  40,  0.5,  0.5).attr({  "fill":  "white"  });   s.image("images/hakanson.png",  12,  8,  39,  39);           var  bioAttr  =  {  "text-­‐anchor":  "middle",  "font-­‐size":  2.75,  "fill":  "white"  };   s.text(cx,  52,  "Software  Architect  at  Thomson  Reuters.").attr(bioAttr);   s.text(cx,  56,  "WestlawNext.  Web  Platform.  JavaScript.").attr(bioAttr);   s.text(cx,  60,  "Agile  Software  Development.").attr(bioAttr);   s.text(cx,  64,  "Information  Security.  Speaker.").attr(bioAttr);   s.text(cx,  68,  "Creator  @LicPlateZone").attr(bioAttr);   s.text(56,  74,  "http://about.me/kevin.hakanson")    .attr({  "font-­‐size":  2.5,  "text-­‐anchor":  "end",  "fill":  "lightskyblue"  });     //  https://about.twitter.com/press/brand-­‐assets   s.image("images/Twitter_logo_blue.png",  6,  71,  14,  14);     s.text(60,  82,  "Kevin  Hakanson")    .attr({  "text-­‐anchor":  "end",  "font-­‐size":  4.5,  "fill":  "white",  "font-­‐weight":  "bold"  });   s.text(60,  86,  "@hakanson").attr({  "text-­‐anchor":  "end",  "font-­‐size":  3.5,  "fill":  "white"  });