]>
iEval git - svg-spritemaker.git/blob - lib/SVG/SpriteMaker.pm
47d566ceba541159a7769ffa970a56b138ab8547
1 package SVG
::SpriteMaker
;
7 our $VERSION = '0.002';
8 our @EXPORT = qw
/make_sprite/;
9 our @EXPORT_OK = @EXPORT;
11 use parent qw
/Exporter/;
17 use SVG
-indent
=> '', -elsep
=> '';
21 my ($prefix, @images) = @_;
22 my $sub = ref $prefix eq 'CODE' ?
$prefix : sub {
23 my $base = scalar fileparse
$_[0], qr/[.].*/;
26 my $sprite = SVG
->new(-inline
=> 1);
27 my $parser = SVG
::Parser
->new;
28 @images = map {[ $sub->($_) => $parser->parse_file($_) ]} @images;
29 my ($x, $mh) = (0, 0);
30 my %ids = map { $_->[0] => 1 } @images; # start with image names
33 my ($img, $doc) = @
$_;
34 my $svg = $doc->getFirstChild;
35 my ($w) = $svg->attr('width') =~ /([0-9.]*)/ or carp
"Image $img has no width";
36 my ($h) = $svg->attr('height') =~ /([0-9.]*)/ or carp
"Image $img has no height";
39 $svg->attr(version
=> undef);
40 my $view = $sprite->view(id
=> $img, viewBox
=> "$x 0 $w $h");
43 my @all_elems = $svg->getElements;
45 for my $elem (@all_elems) {
46 my $id = $elem->attr('id');
49 push @duplicate_ids, $id;
55 warn <<"EOF" if @duplicate_ids && !$ENV{SVG_SPRITEMAKER_NO_DUPLICATE_WARNINGS};
56 Some IDs (@duplicate_ids) in $img also exist in previous images.
57 Trying to fix automatically, but this might produce a broken SVG.
58 Fix IDs manually to avoid incorrect output.
61 for my $oid (@duplicate_ids) {
63 $nid .= '_' while $ids{$nid};
64 $svg->getElementByID($oid)->attr(id
=> $nid);
65 for my $elem (@all_elems) {
66 my %attribs = %{$elem->getAttributes};
67 for my $key (keys %attribs) {
68 if ($attribs{$key} =~ /#$oid\b/) {
69 $attribs{$key} =~ s/#$oid\b/#$nid/g;
70 $elem->attr($key => $attribs{$key});
73 if ($elem->cdata =~ /#$oid\b/) {
74 $elem->cdata($elem->cdata =~ s/#$oid\b/#$nid/gr);
79 $view->getParent->insertAfter($svg, $view);
82 # Keep a reference to the documents to prevent garbage collection
83 $sprite->{'--images'} = \
@images;
84 $sprite->getFirstChild->attr(viewBox
=> "0 0 $x $mh");
95 SVG::SpriteMaker - Combine several SVG images into a single SVG sprite
99 use File::Slurp qw/write_file/;
100 use SVG::SpriteMaker;
101 my $sprite = make_sprite img => '1.svg', '2.svg', '3.svg';
102 write_file 'sprite.svg', $sprite->xmlify;
103 # You can now use <img src="sprite.svg#img-1" alt="...">
105 my @images = <dir/*>; # dir/ImageA.svg dir/ImageB.svg
106 $sprite = make_sprite sub {
107 my ($name) = $_[0] =~ m,/([^/.]*),;
109 }, @images; # Sprite will have identifiers #IMAGEA #IMAGEB
113 A SVG sprite is a SVG image that contains several smaller images that
114 can be referred to using fragment identifiers. For example, this HTML
117 <img src="/img/cat.svg" alt="A cat">
118 <img src="/img/dog.svg" alt="A dog">
119 <img src="/img/horse.svg" alt="A horse">
123 <img src="/img/sprite.svg#cat" alt="A cat">
124 <img src="/img/sprite.svg#dog" alt="A dog">
125 <img src="/img/sprite.svg#horse" alt="A horse">
127 This module exports a single function:
129 =head2 B<make_sprite>(I<$prefix>|I<$coderef>, I<@files>)
131 Takes a list of filenames, combines them and returns the resulting
132 sprite as a L<SVG> object. Each SVG must have width and height
133 attributes whose values are in pixels.
135 If the first argument is a coderef, it will be called with each
136 filename as a single argument and it should return the desired
139 If the first argument is not a coderef, the following coderef will be
143 my $base = scalar fileparse $_[0], qr/\..*/s;
147 where I<$prefix> is the value of the first argument.
149 If an ID is shared between two or more input files, this module will
150 try to rename each occurence except for the first one. This operation
151 might have false positives (attributes/cdatas that are mistakenly
152 identified to contain the ID-to-be-renamed) and false negatives
153 (attributes/cdatas that actually contain the ID-to-be-renamed but this
154 is missed by the module), and as such SVG::SpriteMaker will warn if
155 duplicate IDs are detected. You can suppress this warning by setting
156 the C<SVG_SPRITEMAKER_NO_DUPLICATE_WARNINGS> environment variable to a
161 L<svg-spritemaker>, L<https://css-tricks.com/svg-fragment-identifiers-work/>
165 Marius Gavrilescu, E<lt>marius@ieval.roE<gt>
167 =head1 COPYRIGHT AND LICENSE
169 Copyright (C) 2015-2017 by Marius Gavrilescu
171 This library is free software; you can redistribute it and/or modify
172 it under the same terms as Perl itself, either Perl version 5.20.2 or,
173 at your option, any later version of Perl 5 you may have available.
This page took 0.059945 seconds and 5 git commands to generate.