dynamic-sprites 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/dynamic-sprites +54 -0
- data/dynamic-sprites.sass +42 -0
- data/lib/dynamic-sprites.rb +31 -0
- data/lib/dynamic-sprites/generator.rb +73 -0
- data/lib/dynamic-sprites/interface.rb +64 -0
- data/lib/dynamic-sprites/runner.rb +76 -0
- metadata +51 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4e66fb4237da83f5be891b1d055a33a7db84ed1e
|
4
|
+
data.tar.gz: accd4811e105cffdd89760e68b256fbd1e2e192c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6578afb03c296b402be255ce957df3fe68efe74e8bcd8a7e624279b6df5e69aef27fdaf28d549da7b12c15e16b5e257c530b591422c768f11083055e0fad32a0
|
7
|
+
data.tar.gz: 4bf1e72083d3b38223cc21b0877ff85c6d8dce45bf6809dd9a5d510817d4d3acd576c359f6aff14e556d9717fb5efe210496a5cdf0625831de4c86a19d1209a4
|
data/bin/dynamic-sprites
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$LOAD_PATH.push File.expand_path("../lib", File.dirname(__FILE__)) # add sprite factory library to load path
|
4
|
+
|
5
|
+
require 'dynamic-sprites'
|
6
|
+
require 'optparse'
|
7
|
+
|
8
|
+
options = { layout: 'vertical', selector: 'img.sprite' }
|
9
|
+
op = OptionParser.new
|
10
|
+
op.banner = <<-eos
|
11
|
+
#{DynamicSprites::DESCRIPTION}
|
12
|
+
|
13
|
+
Usage: dynamic-sprites <command> [PATH] [options]
|
14
|
+
|
15
|
+
Available commands:
|
16
|
+
init: generates sass mixin, you can pass your own path as an option
|
17
|
+
generate: generates sprite, you must enter relative or absolute path to source images
|
18
|
+
|
19
|
+
eos
|
20
|
+
|
21
|
+
op.on("-h", "--help") do
|
22
|
+
puts op.to_s
|
23
|
+
exit!
|
24
|
+
end
|
25
|
+
|
26
|
+
op.on("-v", "--version") do
|
27
|
+
puts DynamicSprites::VERSION
|
28
|
+
exit!
|
29
|
+
end
|
30
|
+
|
31
|
+
layout_help = "specify layout orientation ( horizontal, vertical, packed )"
|
32
|
+
selector_help = "specify custom selector to use ( default: 'img.sprite' )"
|
33
|
+
output_help = "specify output location for generated image ( default: <sources folder>.png )"
|
34
|
+
|
35
|
+
op.on("--layout [ORIENTATION]", layout_help) {|value| options[:layout] = value }
|
36
|
+
op.on("--selector [SELECTOR]", selector_help) {|value| options[:selector] = value }
|
37
|
+
op.on("--output [PATH]", output_help) {|value| options[:output] = value }
|
38
|
+
op.on("--layout [ORIENTATION]", layout_help) {|value| options[:layout] = value }
|
39
|
+
|
40
|
+
begin
|
41
|
+
op.parse!(ARGV)
|
42
|
+
command = ARGV[0]
|
43
|
+
path = ARGV[1]
|
44
|
+
if command.nil?
|
45
|
+
raise "You must pass command (init, generate)\nUsage: dynamic-sprites <command> [PATH] [options]"
|
46
|
+
elsif command == 'generate' and path.nil?
|
47
|
+
raise "Generate command requires path to source images\nUsage: dynamic-sprites generate <PATH> [options]"
|
48
|
+
end
|
49
|
+
ARGV.clear
|
50
|
+
DynamicSprites.run!(command, path, options)
|
51
|
+
rescue Exception => ex
|
52
|
+
puts ex.message
|
53
|
+
exit!
|
54
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
// Generates sass code for responsive sprites.
|
2
|
+
//
|
3
|
+
// sprite_url - String containing url to sprite image.
|
4
|
+
// images - Collection of strings, which represents images from sprites, each of them will generate separate class. Order must be preserved as in sprite
|
5
|
+
// image_height - Percentage height of image within sprite, (100% / ($number_of_images - 1))
|
6
|
+
// width - Element width
|
7
|
+
// padding_bottom - Padding bottom replaces height in its functionality.
|
8
|
+
//
|
9
|
+
// Examples
|
10
|
+
//
|
11
|
+
// .social img
|
12
|
+
// dynamic-sprite('/images/social.png', ('facebook', 'linkedin'))
|
13
|
+
//
|
14
|
+
// Returns sass for element and it's subclasses, for each image in sprite respectively.
|
15
|
+
@mixin dynamic-sprite($sprite_url, $images: (), $image_height : 100%, $width: 100%, $padding_bottom: 100%)
|
16
|
+
padding-bottom: $padding_bottom
|
17
|
+
width: $width
|
18
|
+
height: 0
|
19
|
+
background-repeat: no-repeat
|
20
|
+
background-image: url($sprite_url)
|
21
|
+
background-size: 100%
|
22
|
+
|
23
|
+
@for $i from 1 through length($images)
|
24
|
+
$image: nth($images, $i)
|
25
|
+
|
26
|
+
&.#{$image}
|
27
|
+
background-position: 0 $image_height * ($i - 1)
|
28
|
+
|
29
|
+
// Generates sass code for horizontal responsive sprites, everything works similar to vertical version.
|
30
|
+
@mixin dynamic-sprite-horizontal($sprite_url, $images: (), $image_width : 100%, $width: 100%, $padding_bottom: 100%)
|
31
|
+
padding-bottom: $padding_bottom
|
32
|
+
width: $width
|
33
|
+
height: 0
|
34
|
+
background-repeat: no-repeat
|
35
|
+
background-image: url($sprite_url)
|
36
|
+
background-size: 100% * length($images)
|
37
|
+
|
38
|
+
@for $i from 1 through length($images)
|
39
|
+
$image: nth($images, $i)
|
40
|
+
|
41
|
+
&.#{$image}
|
42
|
+
background-position: $image_width * ($i - 1) 0
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module DynamicSprites
|
2
|
+
|
3
|
+
#----------------------------------------------------------------------------
|
4
|
+
|
5
|
+
VERSION = "0.0.2"
|
6
|
+
SUMMARY = "Dynamic sprites mixin in SASS with sprite generator"
|
7
|
+
DESCRIPTION = "Generates sass mixin and combines directory of images into one sprite"
|
8
|
+
|
9
|
+
require 'find'
|
10
|
+
require 'rmagick'
|
11
|
+
|
12
|
+
require_relative 'dynamic-sprites/runner' # Controller of this module
|
13
|
+
require_relative 'dynamic-sprites/interface' # User interaction methods
|
14
|
+
require_relative 'dynamic-sprites/generator' # Sprite generator
|
15
|
+
|
16
|
+
# Initilizes Runner which controls all the magic stuff.
|
17
|
+
#
|
18
|
+
def self.run!(command, path, options = {})
|
19
|
+
Runner.new(command, path, options).run!
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def self.gem_root
|
25
|
+
File.expand_path '../..', __FILE__
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.mixin_source_path
|
29
|
+
File.join gem_root, 'dynamic-sprites.sass'
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module DynamicSprites
|
2
|
+
# Generates sprites
|
3
|
+
class Generator
|
4
|
+
|
5
|
+
# Array of file extensions used for creating sprites.
|
6
|
+
#
|
7
|
+
VALID_EXTENSIONS = %w(.png .jpg .jpeg .gif .ico)
|
8
|
+
|
9
|
+
attr :filename
|
10
|
+
attr :layout
|
11
|
+
attr :files
|
12
|
+
|
13
|
+
# Initializer
|
14
|
+
#
|
15
|
+
# filename - Pathname where generated file should be placed to.
|
16
|
+
# path - Pathname of directory containing source images.
|
17
|
+
# layout - sprite layout name as a String
|
18
|
+
#
|
19
|
+
def initialize(filename, path, layout)
|
20
|
+
@filename = filename
|
21
|
+
@layout = layout
|
22
|
+
@files = Dir.glob(File.join(path, '*')).select { |e| VALID_EXTENSIONS.include?(File.extname(e)) }
|
23
|
+
end
|
24
|
+
|
25
|
+
# Main method for sprites generation
|
26
|
+
#
|
27
|
+
def run!
|
28
|
+
create(filename, load(files), layout)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# Converts Array of Filenames into an Array of Magic::Image objects
|
34
|
+
#
|
35
|
+
def load(files)
|
36
|
+
files.map do |filename|
|
37
|
+
image = Magick::Image.read(filename)[0]
|
38
|
+
{
|
39
|
+
:image => image,
|
40
|
+
:width => image.columns,
|
41
|
+
:height => image.rows
|
42
|
+
}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Generates sprite
|
47
|
+
#
|
48
|
+
def create(filename, images, layout)
|
49
|
+
images_width = images.map{ |i| i[:width] }
|
50
|
+
images_height = images.map{ |i| i[:height] }
|
51
|
+
if layout == 'horizontal'
|
52
|
+
width = images_width.reduce(:+)
|
53
|
+
height = images_height.max
|
54
|
+
else
|
55
|
+
height = images_height.reduce(:+)
|
56
|
+
width = images_width.max
|
57
|
+
end
|
58
|
+
target = Magick::Image.new(width, height)
|
59
|
+
target.opacity = Magick::MaxRGB
|
60
|
+
offset_x = 0
|
61
|
+
offset_y = 0
|
62
|
+
images.each do |image|
|
63
|
+
target.composite!(image[:image], offset_x, offset_y, Magick::SrcOverCompositeOp)
|
64
|
+
if layout == 'horizontal'
|
65
|
+
offset_x += image[:width]
|
66
|
+
else
|
67
|
+
offset_y += image[:height]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
target.write(filename)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module DynamicSprites
|
2
|
+
# User Interaction class
|
3
|
+
#
|
4
|
+
class Interface
|
5
|
+
|
6
|
+
def prompt_directory
|
7
|
+
puts "Where should sass mixin be placed? (e.g. '/home/User/project/app/assets/stylesheets')"
|
8
|
+
prompt
|
9
|
+
end
|
10
|
+
|
11
|
+
def choose_directory(directories)
|
12
|
+
puts "Found more than one possible sass directory. To which one you want to insert sass mixin?"
|
13
|
+
option_number = 1
|
14
|
+
directories.each do |directory|
|
15
|
+
puts "#{option_number}. #{directory}"
|
16
|
+
option_number += 1
|
17
|
+
end
|
18
|
+
puts "#{option_number}. Other"
|
19
|
+
choice = choose(option_number)
|
20
|
+
if choice == option_number
|
21
|
+
puts "Enter directory path: (e.g. '/home/User/project/app/assets/stylesheets')"
|
22
|
+
prompt
|
23
|
+
else
|
24
|
+
directories[choice.to_i - 1]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def generate_mixin_summary(path)
|
29
|
+
puts "Mixin generated in #{path}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def generate_sprite_summary(path)
|
33
|
+
puts "Sprite generated in #{path}"
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
# Choose option by it's index
|
39
|
+
#
|
40
|
+
def choose(limit)
|
41
|
+
puts "Select an option (1-#{limit}):"
|
42
|
+
choice = gets.to_i
|
43
|
+
raise RangeError unless choice.between?(1, limit)
|
44
|
+
choice
|
45
|
+
rescue RangeError
|
46
|
+
puts "Choose correct option (e.g. 1):"
|
47
|
+
retry
|
48
|
+
end
|
49
|
+
|
50
|
+
# Prompt user for specific Pathname
|
51
|
+
#
|
52
|
+
def prompt
|
53
|
+
path = gets
|
54
|
+
raise FileNotFoundError unless File.exist?(path)
|
55
|
+
Pathname.new(path)
|
56
|
+
rescue FileNotFoundError
|
57
|
+
puts "This path does not exist, try again:"
|
58
|
+
retry
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class FileNotFoundError < StandardError
|
64
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module DynamicSprites
|
2
|
+
class Runner
|
3
|
+
|
4
|
+
attr :command
|
5
|
+
attr :path
|
6
|
+
attr :options
|
7
|
+
attr :interface
|
8
|
+
|
9
|
+
def initialize(command, path, options = {})
|
10
|
+
@interface = Interface.new
|
11
|
+
@command = command
|
12
|
+
@path = Pathname.new(path) unless path.nil?
|
13
|
+
@path ||= File.join(sass_directory, 'dynamic-sprites.sass') unless command.nil?
|
14
|
+
@options = options
|
15
|
+
@options[:output] ||= "#{@path}.png"
|
16
|
+
end
|
17
|
+
|
18
|
+
# Runs dynamic-sprites command.
|
19
|
+
#
|
20
|
+
def run!
|
21
|
+
case command
|
22
|
+
when 'init'
|
23
|
+
generate_mixin!
|
24
|
+
when 'generate'
|
25
|
+
generate_sprite!
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
# Generates mixin in provided path or initializes user interface to determine it otherwise.
|
32
|
+
#
|
33
|
+
def generate_mixin!
|
34
|
+
FileUtils.copy DynamicSprites.mixin_source_path, path
|
35
|
+
interface.generate_mixin_summary(path)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Generates sprite using provided options.
|
39
|
+
#
|
40
|
+
def generate_sprite!
|
41
|
+
Generator.new(options[:output], path, options[:layout]).run!
|
42
|
+
interface.generate_sprite_summary(@options[:output])
|
43
|
+
end
|
44
|
+
|
45
|
+
# Chooses one of possible options of defining sass directory path.
|
46
|
+
#
|
47
|
+
def sass_directory
|
48
|
+
case sass_directories.size
|
49
|
+
when 0
|
50
|
+
interface.prompt_directory
|
51
|
+
when 1
|
52
|
+
sass_directories.first
|
53
|
+
else
|
54
|
+
interface.choose_directory(sass_directories)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Returns an Array of possible paths to directories of project .sass files.
|
59
|
+
#
|
60
|
+
def sass_directories
|
61
|
+
style_directories = []
|
62
|
+
|
63
|
+
Find.find(Dir.pwd) do |path|
|
64
|
+
next unless FileTest.directory?(path)
|
65
|
+
if File.basename(path).match /sass|style/
|
66
|
+
style_directories << Pathname.new(path)
|
67
|
+
elsif File.basename(path)[0] == ?.
|
68
|
+
Find.prune
|
69
|
+
else
|
70
|
+
next
|
71
|
+
end
|
72
|
+
end
|
73
|
+
style_directories
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
metadata
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dynamic-sprites
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Maciej Walusiak
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-09-05 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Dynamic sprites mixin in SASS with sprite generator.
|
14
|
+
email: rabsztok@gmail.com
|
15
|
+
executables:
|
16
|
+
- dynamic-sprites
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/dynamic-sprites.rb
|
21
|
+
- lib/dynamic-sprites/runner.rb
|
22
|
+
- lib/dynamic-sprites/generator.rb
|
23
|
+
- lib/dynamic-sprites/interface.rb
|
24
|
+
- dynamic-sprites.sass
|
25
|
+
- bin/dynamic-sprites
|
26
|
+
homepage: https://github.com/Rabsztok/dynamic-sprites
|
27
|
+
licenses:
|
28
|
+
- GPL
|
29
|
+
metadata: {}
|
30
|
+
post_install_message:
|
31
|
+
rdoc_options: []
|
32
|
+
require_paths:
|
33
|
+
- lib
|
34
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - '>='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
requirements: []
|
45
|
+
rubyforge_project:
|
46
|
+
rubygems_version: 2.0.7
|
47
|
+
signing_key:
|
48
|
+
specification_version: 4
|
49
|
+
summary: Dynamic sprites
|
50
|
+
test_files: []
|
51
|
+
has_rdoc:
|