@ -0,0 +1,2 @@
|
||||
*.png |
||||
!card_00_expected.png |
||||
@ -0,0 +1,29 @@
|
||||
require 'squib' |
||||
|
||||
# Here's an example of being able to scale a font |
||||
# based on the length of individual string. |
||||
# Handy for making minor font scales to fill text boxes. |
||||
def autoscale(str_array) |
||||
str_array.map do | str | |
||||
case str.length |
||||
when 0..15 |
||||
32 |
||||
when 16..20 |
||||
18 |
||||
else |
||||
12 |
||||
end |
||||
end |
||||
end |
||||
|
||||
Squib::Deck.new(width: 300, height: 100, cards: 3) do |
||||
background color: :white |
||||
rect |
||||
title = ['Short & Big', |
||||
'Medium Length & Size', |
||||
'Super duper long string here, therefore a smaller font.'] |
||||
text str: title, font: 'Arial', font_size: autoscale(title), |
||||
x: 10, y:10, align: :center, width: 280, ellipsize: false, hint: :red |
||||
|
||||
save_sheet dir: '.', columns: 3 |
||||
end |
||||
|
After Width: | Height: | Size: 5.2 KiB |
@ -0,0 +1,5 @@
|
||||
# To configure for using SVG as our backend, we need to set this option |
||||
# This will create a series of SVG files that get updated with Squib command |
||||
backend: svg |
||||
# They are auto-saved with this background |
||||
prefix: backend_vectors_ |
||||
@ -0,0 +1,33 @@
|
||||
require 'squib' |
||||
|
||||
# Our SVGs are auto-saved after each step using the configuration parameters |
||||
Squib::Deck.new(cards: 2, config: '_backend-config.yml') do |
||||
|
||||
# These are all supported by the SVG backend |
||||
background color: :gray |
||||
text str: 'Hello, world!', y: 500, width: 825, font: 'Sans bold 72', align: :center |
||||
rect x: 38, y: 38, width: 750, height: 1050, x_radius: 38, y_radius: 38 |
||||
circle x: 100, y: 400, radius: 25 |
||||
triangle x1: 100, y1: 425, x2: 125, y2: 475, x3: 75, y3: 475 |
||||
line x1: 100, y1: 620, x2: 720, y2: 620, stroke_width: 15.0 |
||||
svg file: 'spanner.svg', x: 100, y: 75 |
||||
png file: 'shiny-purse.png', x: 250, y: 75 # raster can still be used too |
||||
png file: 'shiny-purse.png', x: 250, y: 250, mask: :red # still renders as raster |
||||
# We can still rasterize whenever we want |
||||
save_png prefix: 'backend_' |
||||
|
||||
# And our PDFs will be vectorized . |
||||
save_pdf file: 'backend_vectorized.pdf', gap: 5 |
||||
|
||||
# This one is a known issue. Masking an SVG onto an SVG backend is still buggy. |
||||
# svg file: 'glass-heart.svg', x: 100, y: 200, width: 100, height: 100, mask: :sangria |
||||
|
||||
# This one is, unfortunately, not possible with svg back ends |
||||
# Cairo lacks a perspective transform (currently), so we have to |
||||
# use a striping method, which assumes raster. Fortunately, Cairo |
||||
# has perspective transforms on its roadmap, |
||||
# so perhaps this can be done someday with all vectors. |
||||
# |
||||
# showcase file: 'showcase.png', fill_color: 'white' |
||||
|
||||
end |
||||
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
@ -0,0 +1,37 @@
|
||||
require 'squib' |
||||
|
||||
Squib::Deck.new(width: 825, height: 1125, cards: 1) do |
||||
background color: :white |
||||
|
||||
y = 0 |
||||
text color: '#f00', str: '3-hex', x: 50, y: y += 50 |
||||
text color: '#f00', str: '3-hex (alpha)', x: 50, y: y += 50 |
||||
text color: '#ff0000', str: '6-hex', x: 50, y: y += 50 |
||||
text color: '#ff000099', str: '8-hex(alpha)', x: 50, y: y += 50 |
||||
text color: '#ffff00000000', str: '12-hex', x: 50, y: y += 50 |
||||
text color: '#ffff000000009999', str: '12-hex (alpha)', x: 50, y: y += 50 |
||||
text color: :burnt_orange, str: 'Symbols of constants too', x: 50, y: y += 50 |
||||
text color: '(0,0)(400,0) blue@0.0 red@1.0', str: 'Linear gradients!', x: 50, y: y += 50 |
||||
text color: '(200,500,10)(200,500,100) blue@0.0 red@1.0', str: 'Radial gradients!', x: 50, y: y += 50 |
||||
# see gradients.rb sample for more on gradients |
||||
|
||||
save_png prefix: 'colors_' |
||||
end |
||||
|
||||
# This script generates a table of the built-in constants |
||||
Squib::Deck.new(width: 3000, height: 1500) do |
||||
colors = (Cairo::Color.constants - %i(HEX_RE Base RGB CMYK HSV X11)) |
||||
colors.sort_by! {|c| Cairo::Color.parse(c).to_s} |
||||
x, y, w, h = 0, 0, 300, 50 |
||||
colors.each_with_index do |color, i| |
||||
rect x: x, y: y, width: w, height: h, fill_color: color |
||||
text str: color.to_s, x: x + 5, y: y + 13, font: 'Sans Bold 16', |
||||
color: (Cairo::Color.parse(color).to_hsv.v > 0.9) ? '#000' : '#fff' |
||||
y += h |
||||
if y > @height |
||||
x += w |
||||
y = 0 |
||||
end |
||||
end |
||||
save_png prefix: 'color_constants_' |
||||
end |
||||
@ -0,0 +1,34 @@
|
||||
require 'squib' |
||||
|
||||
Squib::Deck.new do |
||||
# Just about anywhere Squib takes in a color it can also take in a gradient too |
||||
# The x-y coordinates on the card itself, |
||||
# and then color stops are defined between 0 and 1 |
||||
background color: '(0,0)(0,1125) #ccc@0.0 #111@1.0' |
||||
line stroke_color: '(0,0)(825,0) #111@1.0 #ccc@0.0', |
||||
x1: 0, y1: 600, x2: 825, y2: 600, |
||||
stroke_width: 15 |
||||
|
||||
# Radial gradients look like this |
||||
circle fill_color: '(425,400,2)(425,400,120) #ccc@0.0 #111@1.0', |
||||
x: 415, y: 415, radius: 100, stroke_color: '#0000' |
||||
triangle fill_color: '(650,400,2)(650,400,120) #ccc@0.0 #111@1.0', |
||||
stroke_color: '#0000', |
||||
x1: 650, y1: 360, |
||||
x2: 550, y2: 500, |
||||
x3: 750, y3: 500 |
||||
|
||||
# Gradients are also good for beveling effects: |
||||
rect fill_color: '(0,200)(0,600) #111@0.0 #ccc@1.0', |
||||
x: 30, y: 350, width: 150, height: 150, |
||||
radius: 15, stroke_color: '#0000' |
||||
rect fill_color: '(0,200)(0,600) #111@1.0 #ccc@0.0', |
||||
x: 40, y: 360, width: 130, height: 130, |
||||
radius: 15, stroke_color: '#0000' |
||||
|
||||
# Alpha transparency can be used too |
||||
text str: 'Hello, world!', x: 75, y: 700, font: 'Sans Bold 72', |
||||
color: '(0,0)(825,0) #000f@0.0 #0000@1.0' |
||||
|
||||
save_png prefix: 'gradient_' |
||||
end |
||||
|
After Width: | Height: | Size: 346 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 30 KiB |
@ -0,0 +1,33 @@
|
||||
require 'squib' |
||||
|
||||
Squib::Deck.new(cards: 2) do |
||||
background color: :white |
||||
|
||||
# Outputs a hash of arrays with the header names as keys |
||||
data = csv file: 'sample.csv' |
||||
text str: data['Type'], x: 250, y: 55, font: 'Arial 54' |
||||
text str: data['Level'], x: 65, y: 65, font: 'Arial 72' |
||||
|
||||
save format: :png, prefix: 'sample_csv_' |
||||
|
||||
# You can also specify the sheet, starting at 0 |
||||
data = xlsx file: 'sample.xlsx', sheet: 2 |
||||
end |
||||
|
||||
# CSV is also a Squib-module-level function, so this also works: |
||||
data = Squib.csv file: 'quantity_explosion.csv' # 2 rows... |
||||
num_cards = data['Name'].size # ...but 4 cards! |
||||
|
||||
Squib::Deck.new(cards: num_cards) do |
||||
background color: :white |
||||
rect # card border |
||||
text str: data['Name'], font: 'Arial 54' |
||||
save_sheet prefix: 'sample_csv_qty_', columns: 4 |
||||
end |
||||
|
||||
# Additionally, CSV supports inline data specifically |
||||
data = Squib.csv data: <<-EOCSV |
||||
Name,Cost |
||||
Knight,3 |
||||
Orc,1 |
||||
EOCSV |
||||
@ -0,0 +1,55 @@
|
||||
require 'squib' |
||||
|
||||
Squib::Deck.new(cards: 3) do |
||||
background color: :white |
||||
|
||||
# Reads the first sheet by default (sheet 0) |
||||
# Outputs a hash of arrays with the header names as keys |
||||
data = xlsx file: 'sample.xlsx' |
||||
|
||||
text str: data['Name'], x: 250, y: 55, font: 'Arial 54' |
||||
text str: data['Level'], x: 65, y: 65, font: 'Arial 72' |
||||
text str: data['Description'], x: 65, y: 600, font: 'Arial 36' |
||||
|
||||
save format: :png, prefix: 'sample_excel_' # save to individual pngs |
||||
end |
||||
|
||||
# xlsx is also a Squib-module-level function, so this also works: |
||||
data = Squib.xlsx file: 'explode_quantities.xlsx' # 2 rows... |
||||
num_cards = data['Name'].size # ...but 4 cards! |
||||
|
||||
Squib::Deck.new(cards: num_cards) do |
||||
background color: :white |
||||
rect # card border |
||||
text str: data['Name'], font: 'Arial 54' |
||||
save_sheet prefix: 'sample_xlsx_qty_', columns: 4 |
||||
end |
||||
|
||||
|
||||
# Here's another example, a bit more realistic. Here's what's going on: |
||||
# * We call xlsx from Squib directly - BEFORE Squib::Deck creation. This |
||||
# allows us to infer the number of cards based on the size of the "Name" |
||||
# field |
||||
# * We make use of quantity explosion. Fields named "Qty" or "Quantity" |
||||
# (any capitalization), or any other in the "qty_header" get expanded by the |
||||
# number given |
||||
# * We also make sure that trailing and leading whitespace is stripped |
||||
# from each value. This is the default behavior in Squib, but the options |
||||
# are here just to make sure. |
||||
|
||||
resource_data = Squib.xlsx(file: 'sample.xlsx', sheet: 2, strip: true) do |header, value| |
||||
case header |
||||
when 'Cost' |
||||
"$#{value}k" # e.g. "3" becomes "$3k" |
||||
else |
||||
value # always return the original value if you didn't do anything to it |
||||
end |
||||
end |
||||
|
||||
Squib::Deck.new(cards: resource_data['Name'].size) do |
||||
background color: :white |
||||
rect width: :deck, height: :deck |
||||
text str: resource_data['Name'], align: :center, width: :deck, hint: 'red' |
||||
text str: resource_data['Cost'], align: :right, width: :deck, hint: 'red' |
||||
save_sheet prefix: 'sample_excel_resources_' # save to a whole sheet |
||||
end |
||||
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 8.5 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 9.4 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 18 KiB |
@ -0,0 +1,7 @@
|
||||
*.png |
||||
!ball.png |
||||
!grit.png |
||||
!sprites.png |
||||
!with-alpha.png |
||||
!_images_00_expected.png |
||||
!shiny-purse.png |
||||
@ -0,0 +1,104 @@
|
||||
require 'squib' |
||||
require 'squib/sample_helpers' |
||||
|
||||
Squib::Deck.new(width: 1000, height: 3000) do |
||||
draw_graph_paper width, height |
||||
|
||||
sample "This a PNG.\nNo scaling is done by default." do |x, y| |
||||
png file: 'angler-fish.png', x: x, y: y |
||||
end |
||||
|
||||
sample 'PNGs can be upscaled, but they will emit an antialias warning (unless you turn it off in the config.yml)' do |x,y| |
||||
png file: 'angler-fish.png', x: x, y: y, width: 150, height: 150 |
||||
end |
||||
|
||||
sample 'SVGs can be loaded from a file (left) or from straight XML (right). They can also be scaled to any size.' do |x,y| |
||||
svg file: 'robot-golem.svg', x: x, y: y, width: 100, height: 100 |
||||
svg data: File.read('robot-golem.svg'), width: 100, height: 100, |
||||
x: x + 200, y: y |
||||
end |
||||
|
||||
sample 'PNG and SVG can be auto-scaled by one side and setting the other to :scale' do |x,y| |
||||
svg file: 'robot-golem.svg', x: x, y: y, width: 50, height: :scale |
||||
svg file: 'robot-golem.svg', x: x + 50, y: y, width: :scale, height: 50 |
||||
|
||||
png file: 'angler-fish.png', x: x + 200, y: y, width: 50, height: :scale |
||||
png file: 'angler-fish.png', x: x + 250, y: y, width: :scale, height: 50 |
||||
end |
||||
|
||||
sample 'PNGs can be cropped. To work from sprite sheets, you can set crop coordinates to PNG images. Rounded corners supported too.' do |x,y| |
||||
png file: 'sprites.png', x: x - 50, y: y - 50 # entire sprite sheet |
||||
rect x: x - 50, y: y - 50, width: 100, height: 100, # draw the crop line |
||||
radius: 15, dash: '3 3', stroke_color: 'red', stroke_width: 3 |
||||
text str: '➜', font: 'Sans Bold 36', x: x + 150, y: y - 35 |
||||
png file: 'sprites.png', x: x + 200, y: y - 50, # just the robot golem image |
||||
crop_x: 0, crop_y: 0, crop_corner_radius: 15, |
||||
crop_width: 100, crop_height: 100 |
||||
|
||||
png file: 'sprites.png', x: x - 50, y: y + 50 # entire sprite sheet again |
||||
rect x: x + 14, y: y + 50, width: 65, height: 65, # highlight the crop |
||||
radius: 25, dash: '3 3', stroke_color: 'red', stroke_width: 3 |
||||
text str: '➜', font: 'Sans Bold 36', x: x + 150, y: y + 50 |
||||
png file: 'sprites.png', x: x + 225, y: y + 50, # just the drakkar ship image, rotated |
||||
crop_x: 64, crop_y: 0, crop_corner_x_radius: 25, crop_corner_y_radius: 25, |
||||
crop_width: 64, crop_height: 64, angle: Math::PI / 6 |
||||
end |
||||
|
||||
sample 'SVGs can be cropped too.' do |x,y| |
||||
svg file: 'robot-golem.svg', x: x, y: y, width: 100, height: 100, |
||||
crop_x: 40, crop_y: 0, crop_width: 50, crop_height: 50 |
||||
end |
||||
|
||||
sample 'Images can be flipped about their center.' do |x,y| |
||||
png file: 'angler-fish.png', x: x, y: y, flip_vertical: true, flip_horizontal: true |
||||
svg file: 'robot-golem.svg', x: x + 200, y: y, width: 100, height: 100, |
||||
flip_horizontal: true |
||||
end |
||||
|
||||
sample 'SVG can be limited to rendering to a single object if the SVG ID is set. If you look in this SVG file, the black backdrop has ID #backdrop.' do |x,y| |
||||
svg file: 'robot-golem.svg', id: 'backdrop', x: x, y: y, width: 100, height: 100 |
||||
end |
||||
|
||||
sample "The SVG force_id option allows use of an ID only when specified, and render nothing if empty. Useful for multiple icons in one SVG file.\nThis should show nothing." do |x,y| |
||||
svg file: 'robot-golem.svg', x: x, y: y, |
||||
force_id: true, id: '' # <-- the important parts |
||||
end |
||||
|
||||
sample 'NOTE! If you render a single object in an SVG, its placement is still relative to the SVG document.' do |x,y| |
||||
svg file: 'offset.svg', x: x, y: y |
||||
rect x: x, y: y, width: 100, height: 100, dash: '3 1', stroke_color: 'red', stroke_width: 3 |
||||
|
||||
svg file: 'offset.svg', id: 'thing', x: x + 200, y: y, width: 100, height: 100 |
||||
rect x: x + 200, y: y, width: 100, height: 100, dash: '3 1', stroke_color: 'red', stroke_width: 3 |
||||
end |
||||
|
||||
sample 'PNGs can be blended onto each other with 15 different blending operators. Alpha transparency supported too. See http://cairographics.org/operators' do |x,y| |
||||
png file: 'ball.png', x: x, y: y |
||||
png file: 'grit.png', x: x + 20, y: y + 20, blend: :color_burn, alpha: 0.75 |
||||
end |
||||
|
||||
sample 'Rotation is around the upper-left corner of the image. Unit is radians.' do |x,y| |
||||
rect x: x, y: y, width: 100, height: 100, stroke_width: 3, dash: '3 3', stroke_color: :red |
||||
png x: x, y: y, width: 100, height: 100, angle: Math::PI / 4, file: 'angler-fish.png' |
||||
|
||||
rect x: x + 250, y: y, width: 100, height: 100, stroke_width: 3, dash: '3 3', stroke_color: :red |
||||
svg x: x + 250, y: y, width: 100, height: 100, file: 'robot-golem.svg', |
||||
angle: Math::PI / 2 - 0.2 |
||||
end |
||||
|
||||
sample 'SVGs and PNGs can be used as masks for colors instead of being directly rendered.' do |x,y| |
||||
svg mask: '#00ff00', file: 'glass-heart.svg', x: x - 50, y: y - 50, width: 200, height: 200 |
||||
svg mask: '(0,0)(500,0) #eee@0.0 #111@1.0', file: 'glass-heart.svg', x: x + 150, y: y - 50, width: 200, height: 200 |
||||
end |
||||
|
||||
sample 'PNG masks are based on the alpha channel. Gradient coordinates are relative to the card.' do |x,y| |
||||
png file: 'with-alpha.png', x: x - 50, y: y |
||||
png file: 'with-alpha.png', mask: :magenta, x: x + 50, y: y |
||||
|
||||
mask = "(#{x+150+75}, #{y+75}, 0)(#{x+150+75}, #{y+75}, 100) #f00@0.0 #000@1.0" |
||||
png file: 'with-alpha.png', mask: mask, x: x + 150, y: y, width: 150, height: :scale |
||||
end |
||||
|
||||
|
||||
save_png prefix: '_images_', dir: '.' |
||||
end |
||||
|
After Width: | Height: | Size: 312 KiB |
@ -0,0 +1,99 @@
|
||||
require 'squib' |
||||
|
||||
Squib::Deck.new(width: 825, height: 1125, cards: 1, config: 'load_images_config.yml') do |
||||
background color: '#0b7c8e' |
||||
rect x: 38, y: 38, width: 750, height: 1050, x_radius: 38, y_radius: 38 |
||||
|
||||
png file: 'shiny-purse.png', x: 620, y: 75 # no scaling is done by default |
||||
svg file: 'spanner.svg', x: 620, y: 218 |
||||
|
||||
# Can be scaled if width and height are set |
||||
svg file: 'spanner.svg', x: 50, y: 50, width: 250, height: 250 |
||||
png file: 'shiny-purse.png', x: 305, y: 50, width: 250, height: 250 |
||||
# ...but PNGs will warn if it's an upscale, unless you disable them in config.yml |
||||
|
||||
# Can be scaled using just width or height, if one of them is set to :scale |
||||
svg file: 'spanner.svg', x: 200, y: 350, width: 35, height: :scale |
||||
svg file: 'spanner.svg', x: 200, y: 390, width: :scale, height: 35 |
||||
png file: 'shiny-purse.png', x: 240, y: 350, width: 35, height: :scale |
||||
png file: 'shiny-purse.png', x: 240, y: 390, width: :scale, height: 35 |
||||
|
||||
# You can also crop the loaded images, so you can work from a sprite sheet |
||||
png file: 'sprites.png', x: 300, y: 350 # entire sprite sheet |
||||
png file: 'sprites.png', x: 300, y: 425, # just the robot golem image |
||||
crop_x: 0, crop_y: 0, crop_corner_radius: 10, |
||||
crop_width: 64, crop_height: 64 |
||||
png file: 'sprites.png', x: 400, y: 425, # just the drakkar ship image |
||||
crop_x: 64, crop_y: 0, crop_corner_x_radius: 25, crop_corner_y_radius: 25, |
||||
crop_width: 64, crop_height: 64 |
||||
png file: 'sprites.png', x: 500, y: 415, # just the drakkar ship image, rotated |
||||
crop_x: 64, crop_y: 0, crop_corner_x_radius: 25, crop_corner_y_radius: 25, |
||||
crop_width: 64, crop_height: 64, angle: Math::PI / 6 |
||||
|
||||
# Cropping also works on SVGs too |
||||
svg file: 'spanner.svg', x: 300, y: 500, width: 64, height: 64, |
||||
crop_x: 32, crop_y: 32, crop_width: 32, crop_height:32 |
||||
|
||||
# We can flip our images too |
||||
png file: 'sprites.png', x: 300, y: 535, flip_vertical: true, flip_horizontal: true |
||||
svg file: 'spanner.svg', x: 300, y: 615, width: 64, height: 64, |
||||
flip_vertical: true, flip_horizontal: true |
||||
|
||||
# We can also limit our rendering to a single object, if the SVG ID is set |
||||
svg file: 'spanner.svg', id: '#backdrop', x: 50, y: 350, width: 75, height: 75 |
||||
# Squib prepends a #-sign if one is not specified |
||||
svg file: 'spanner.svg', id: 'backdrop', x: 50, y: 450, width: 125, height: 125 |
||||
|
||||
# We can also load SVGs as a string of XML |
||||
svg data: File.read('spanner.svg'), x: 50, y: 600, width: 75, height: 75 |
||||
|
||||
# The svg data field works nicely with modifying the SVG XML on-the-fly. |
||||
# To run this one, do `gem install game_icons` and uncomment the following |
||||
# |
||||
# require 'game_icons' |
||||
# svg data: GameIcons.get('angler-fish').recolor(fg: '#ccc', bg: '#333').string, |
||||
# x: 150, y: 600, width: 75, height: 75 |
||||
# |
||||
# More examples at https://github.com/andymeneely/game_icons |
||||
# (or `gem install game_icons`) to get & manipulate art from game-icons.net |
||||
# Nokogiri (already included in Squib) is also great for XML manipulation. |
||||
|
||||
# WARNING! If you choose to use the SVG ID, the x-y coordinates are still |
||||
# relative to the SVG page. See this example in an SVG editor |
||||
svg file: 'offset.svg', id: 'thing', x: 0, y: 0, width: 600, height: 600 |
||||
|
||||
# Over 15 different blending operators are supported. |
||||
# See http://cairographics.org/operators |
||||
# Alpha transparency too |
||||
png file: 'ball.png', x: 50, y: 700 |
||||
png file: 'grit.png', x: 70, y: 750, blend: :color_burn, alpha: 0.75 |
||||
|
||||
# Images can be rotated around their upper-left corner |
||||
png file: 'shiny-purse.png', x: 300, y: 700, angle: 0.0 # default (no rotate) |
||||
png file: 'shiny-purse.png', x: 300, y: 800, angle: Math::PI / 4 |
||||
svg file: 'spanner.svg', x: 300, y: 900, angle: Math::PI / 2 - 0.1 |
||||
|
||||
# Images can also be used as masks instead of being directly painted. |
||||
# This is particularly useful for switching directly over to black-and-white for printing |
||||
# Or, if you want the same image to be used but with different colors/gradients |
||||
svg mask: '#00ff00', |
||||
file: 'glass-heart.svg', |
||||
x: 500, y: 600, width: 200, height: 200 |
||||
svg mask: '(0,0)(0,500) #ccc@0.0 #333@1.0', |
||||
file: 'glass-heart.svg', |
||||
x: 500, y: 800, width: 200, height: 200 |
||||
|
||||
# Masks are based on the alpha channel, so this is just a magenta square |
||||
png mask: :magenta, file: 'shiny-purse.png', |
||||
x: 650, y: 950 |
||||
|
||||
# Note that this method does nothing, even though it would normally fill up |
||||
# the card. force_id: true looks to the id field to be non-empty to render. |
||||
# This is useful if you have multiple different icons in one SVG file, |
||||
# but sometimes want to use none. |
||||
# e.g. id: [:attack, :defend, nil] |
||||
svg file: 'spanner.svg', width: :deck, height: :deck, |
||||
force_id: true, id: '' # <-- the important part |
||||
|
||||
save prefix: 'load_images_', format: :png |
||||
end |
||||
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 9.9 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
@ -0,0 +1,9 @@
|
||||
require 'squib' |
||||
|
||||
Squib::Deck.new cards: 1 do |
||||
background color: 'pink' |
||||
rect |
||||
text str: 'Draw two cards.' |
||||
save_png prefix: 'part1_', dir: '.' |
||||
end |
||||
|
||||
@ -0,0 +1,15 @@
|
||||
require 'squib' |
||||
|
||||
Squib::Deck.new cards: 1 do |
||||
background color: '#252322' |
||||
rect fill_color: '#0B3736', |
||||
x: 38, y: 38, width: 750, height: 1050, radius: 38 |
||||
text str: 'Robot Golem', font: 'True Crimes, Sans 72', |
||||
align: :center, x: 75, width: :deck, color: '#DFDFE1', y: 90 |
||||
svg file: 'auto-repair.svg', x: 75, y: 75, width: 100, height: :scale |
||||
svg file: 'robot-golem.svg', x: 75, y: 300, width: 675, height: :scale |
||||
text str: 'Draw two cards', font: 'Serif 36', |
||||
align: :center, width: :deck, color: '#DFDFE1', y: 1000 |
||||
save_png prefix: 'part2_', dir: '.' |
||||
end |
||||
|
||||
@ -0,0 +1,12 @@
|
||||
require 'squib' |
||||
|
||||
Squib::Deck.new cards: 1, layout: 'part3_layout.yml' do |
||||
background color: '#252322' |
||||
rect layout: 'backdrop' |
||||
text str: 'Robot Golem', layout: 'title' |
||||
svg layout: 'drone' |
||||
svg file: 'robot-golem.svg', layout: 'art' |
||||
text str: 'Draw two cards.', layout: 'power' |
||||
save_png prefix: 'part3_', dir: '.' |
||||
end |
||||
|
||||
@ -0,0 +1,16 @@
|
||||
require 'squib' |
||||
|
||||
Squib::Deck.new cards: 2, layout: 'part3_layout.yml' do |
||||
background color: '#252322' |
||||
rect layout: 'backdrop' |
||||
text str: ['Robot Golem', 'Ninja'], |
||||
layout: 'title' |
||||
svg layout: ['drone', 'human'] |
||||
svg file: ['robot-golem.svg','ninja-mask.svg'], |
||||
layout: 'art' |
||||
text str: ['Draw two cards', |
||||
'Use the power of another player'], |
||||
layout: 'power' |
||||
save_png prefix: 'part4_', dir: '.' |
||||
end |
||||
|
||||
@ -0,0 +1,15 @@
|
||||
require 'squib' |
||||
|
||||
Squib::Deck.new cards: 4, layout: 'part3_layout.yml' do |
||||
background color: '#252322' |
||||
rect layout: 'backdrop' |
||||
data = xlsx file: 'data.xlsx' |
||||
text str: data['name'], layout: 'title' |
||||
svg layout: data['class'] |
||||
svg file: data['art'], layout: 'art' |
||||
text str: data['power'], layout: 'power' |
||||
save_png prefix: 'part5_', dir: '.' |
||||
hand file: 'part5_hand.png', dir: '.', trim_radius: 38 |
||||
showcase file: 'part5_showcase.png', dir: '.' |
||||
end |
||||
|
||||
|
After Width: | Height: | Size: 8.5 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 61 KiB |
@ -0,0 +1,34 @@
|
||||
backdrop: |
||||
fill_color: '#0B3736' |
||||
x: 38 |
||||
y: 38 |
||||
radius: 38 |
||||
width: 750 |
||||
height: 1050 |
||||
title: |
||||
font: 'True Crimes, Sans 72' |
||||
align: center |
||||
color: '#DFDFE1' |
||||
x: 75 |
||||
y: 90 |
||||
width: 825 |
||||
drone: |
||||
file: auto-repair.svg |
||||
x: 75 |
||||
y: 75 |
||||
width: 100 |
||||
height: 100 |
||||
human: |
||||
extends: drone |
||||
file: humans.svg |
||||
art: |
||||
x: 75 |
||||
y: 300 |
||||
width: 675 |
||||
height: 675 |
||||
power: |
||||
font: 'Serif 36' |
||||
align: center |
||||
width: 825 |
||||
color: '#DFDFE1' |
||||
y: 1000 |
||||
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 306 KiB |
|
After Width: | Height: | Size: 548 KiB |
@ -0,0 +1,54 @@
|
||||
require 'squib' |
||||
|
||||
Squib::Deck.new do |
||||
background color: :white |
||||
|
||||
grid x: 10, y: 10, width: 50, height: 50, stroke_color: '#0066FF', stroke_width: 1.5, angle: 0.1 |
||||
grid x: 10, y: 10, width: 200, height: 200, stroke_color: '#0066FF', stroke_width: 3, angle: 0.1 |
||||
|
||||
rect x: 305, y: 105, width: 200, height: 50, dash: '4 2' |
||||
|
||||
rect x: 300, y: 300, width: 400, height: 400, |
||||
fill_color: :blue, stroke_color: :red, stroke_width: 50.0, |
||||
join: 'bevel' |
||||
|
||||
rect x: 550, y: 105, width: 100, height: 100, |
||||
stroke_width: 5, stroke_color: :orange, angle: -0.2 |
||||
|
||||
ellipse x: 675, y: 105, width: 65, height: 100, |
||||
stroke_width: 5, stroke_color: :orange, angle: -0.2 |
||||
|
||||
circle x: 600, y: 600, radius: 75, |
||||
fill_color: :gray, stroke_color: :green, stroke_width: 8.0 |
||||
|
||||
triangle x1: 50, y1: 50, |
||||
x2: 150, y2: 150, |
||||
x3: 75, y3: 250, |
||||
fill_color: :gray, stroke_color: :green, stroke_width: 3.0 |
||||
|
||||
line x1: 50, y1: 550, |
||||
x2: 150, y2: 650, |
||||
stroke_width: 25.0 |
||||
|
||||
curve x1: 50, y1: 850, cx1: 150, cy1: 700, |
||||
x2: 625, y2: 900, cx2: 150, cy2: 700, |
||||
stroke_width: 12.0, stroke_color: :cyan, |
||||
fill_color: :burgundy, cap: 'round' |
||||
|
||||
ellipse x: 50, y: 925, width: 200, height: 100, |
||||
stroke_width: 5.0, stroke_color: :cyan, |
||||
fill_color: :burgundy |
||||
|
||||
star x: 300, y: 1000, n: 5, inner_radius: 15, outer_radius: 40, |
||||
fill_color: :cyan, stroke_color: :burgundy, stroke_width: 5 |
||||
|
||||
# default draw is fill-then-stroke. Can be changed to stroke-then-fill |
||||
star x: 375, y: 1000, n: 5, inner_radius: 15, outer_radius: 40, |
||||
fill_color: :cyan, stroke_color: :burgundy, |
||||
stroke_width: 5, stroke_strategy: :stroke_first |
||||
|
||||
polygon x: 500, y: 1000, n: 5, radius: 25, angle: Math::PI / 2, |
||||
fill_color: :cyan, stroke_color: :burgundy, stroke_width: 2 |
||||
|
||||
save_png prefix: 'shape_' |
||||
end |
||||
|
After Width: | Height: | Size: 39 KiB |
@ -0,0 +1,47 @@
|
||||
require 'squib' |
||||
require 'squib/sample_helpers' |
||||
|
||||
Squib::Deck.new(width: 1000, height: 1250) do |
||||
draw_graph_paper width, height |
||||
|
||||
sample 'Font strings are quite expressive. Specify family, modifiers, then size. Font names with spaces in them should end with a comma to help with parsing.' do |x, y| |
||||
text font: 'Arial bold italic 32', str: 'Bold and italic!', x: x, y: y - 50 |
||||
text font: 'Arial weight=300 32', str: 'Light bold!', x: x, y: y |
||||
text font: 'Times New Roman, 32', str: 'Times New Roman', x: x, y: y + 50 |
||||
text font: 'NoSuchFont,Arial 32', str: 'Arial Backup', x: x, y: y + 100 |
||||
end |
||||
|
||||
sample 'Specify width and height to see a text box. Also: set "hint" to see the extents of your text box' do |x, y| |
||||
text str: 'This has fixed width and height.', x: x, y: y, |
||||
hint: :red, width: 300, height: 100, font: 'Serif bold 24' |
||||
end |
||||
|
||||
sample 'If you specify the width only, the text will ellipsize.' do |x, y| |
||||
text str: 'The meaning of life is 42', x: x - 50, y: y, |
||||
hint: :red, width: 350, font: 'Serif bold 22' |
||||
end |
||||
|
||||
sample 'If you specify the width only, and turn off ellipsize, the height will auto-stretch.' do |x, y| |
||||
text str: 'This has fixed width, but not fixed height.', x: x, y: y, |
||||
hint: :red, width: 300, ellipsize: false, font: 'Serif bold 24' |
||||
end |
||||
|
||||
sample 'The text method returns the ink extents of each card\'s rendered text. So you can custom-fit a shape around it.' do |x, y| |
||||
['Auto fit!', 'Auto fit!!!!' ].each.with_index do |str, i| |
||||
text_y = y + i * 50 |
||||
extents = text str: str, x: x, y: text_y, font: 'Sans Bold 24' |
||||
|
||||
# Extents come back as an array of hashes, which can get split out like this |
||||
text_width = extents[0][:width] |
||||
text_height = extents[0][:height] |
||||
rect x: x, y: text_y, width: text_width, height: text_height, radius: 10, |
||||
stroke_color: :purple, stroke_width: 3 |
||||
end |
||||
end |
||||
|
||||
sample 'Text can be rotated about the upper-left corner of the text box. Unit is in radians.' do |x, y| |
||||
text str: 'Rotated', hint: :red, x: x, y: y, angle: Math::PI / 6 |
||||
end |
||||
|
||||
save_png prefix: '_text_', dir: '.' |
||||
end |
||||
|
After Width: | Height: | Size: 92 KiB |