POPSブログ

SVG.js viewbox() bbox()とIconの表示

389

  Category:  javascript2016/07/20 pops 

SVG.js SVG.js viewbox()とbbox()、SVG Iconの表示について調べてみます。当方独自の方法をも取りますが、一応正常に可動します。何も知らない者が「SVG」を触るのですから大変無謀なことです。

 

SVG.js viewbox()とbbox() Iconの表示のテスト

 

ご注意、Chrome.Firefox.IE11(一部機能しません)などSVGに対応したブラウザでご覧ください。Chromeを推奨します。

 

SVG.js 使用の基本的な説明


基本的な説明下記ページ参照ください。
【参照】当方の記事: SVG.js を使用してsvgコンテンツを作り表示します
このページとデモページにサンプルと共にJSを記載しています。余り説明などしていませんので、感覚的に違いなど理解ください。
Chrome.Firefox.IE11で確認しながら進めますが、その他のブラウザは未確認です。

 

SVG.jsのDropShadowはエラーで機能しません。カスタムDropShadowは独自のもので、4個をdropshadow-custom.jsで設定している。
【参照】当方の記事: SVG.js DropShadowの自作とBlur


 

SVG.js viewbox()とbbox()


zuzu

 

viewbox は「描画の領域」を表します。左上の座標(x, y)からどれくらい横と縦に移動して右下の座標かと言う概念です。
「svg」の width height属性はHtmlにどれ位の大きさで表示するかの「表示範囲」です。svgはベクターですから「表示範囲」により伸縮します。


● SVG.jsではviewBox属性を viewbox() で操作設定します。
● グラフイック、パスなどの大きさ(描画範囲)を bbox() で取得できます。


簡単な書式をマニュアルから抜粋しますと、


viewbox()

SVGインスタンス.viewbox(0,0,640,100)
または
SVGインスタンス.viewbox({x:0,y:0,width:640,height:100})


var box_size=インスタンス.bbox()

次の10項目のサイズが取得できます、w h はショートカット
.width
.height
.w
.h
.x
.y
.cx
.cy
.x2
.y2

viewboxの設定と変更

SVG.jsでは通常はviewbox()を使用せずとも構築できますが、他人のグラフイック、パスなどを利用したい場合にサイズなどを合わせるために、パスを書き換えるのは大変困難です。アイコンなどインラインで取り込む場合にviewbox()を利用すれば便利です。


viewbox設定された「svg」は、表示先の大きさに合わせて拡大縮小します。


1. 外部「svg」の読み込みは「img」タグなどで簡単に表示できますが、中の要素に対し JavaScript CSS の操作は出来ません。つまりグラフイックの色を変えるなど簡単な操作も出来ません。
2. SVG.jsではsvg()で取り込めば、簡単に「svg」を表示出来ます。インラインですから中の操作は可能になります。
3. 取り込み先の「svg」にviewBox属性があれば、自動で拡大縮小され収まります。ここがviewboxの便利なところ。
4. SVGアイコン等は事前にviewboxが設定されています。
(下段で説明のsvg()でアイコンを取り込み表示するサンプルを参照ください)


SVG.jsでの通常の「svg」構成

下記の様に width height はHTML上に表示する描画の大きさ viewPort です。SVG.jsでは通常、viewbox()を実行しませんので、viewBox属性は表記されません。
rootにあたるsvgには通常SVG.jsではviewBox属性を設定することは稀でしょう。
もし必要なら通常「同じ大きさ」の設定になる。



通常SVG.jsでviewBox属性は設定しない

<svg id="SvgjsSvg..." width="160" height="160">
...
</svg>

設定するなら同じ大きさで

draw.viewbox(0,0,160,160)
viewBoxが設定されます
<svg id="SvgjsSvg..." width="160" height="160" viewBox="0,0,160,160">

viewbox は表示する範囲を規定します。SVG.jsではviewbox()を実行することで、viewBox属性が表記されます。
通常は、中にネストしたインラインのsvgにはその時々の事情でviewBox属性を設定することは有り得えます。

但し、無意味にviewBox属性を変更はしないでください。混乱するだけの結果になります。


nested()ではviewBox属性の設定は時として便利な事もある

<svg id="SvgjsSvg..." width="160" height="160">
...
<svg id="SvgjsSvg..." width="50" height="50" viewBox="0,0,50,50">
...
</svg>
...
</svg>

● nested()で作る「svg」には、初期状態でスタイルが overflow:visible に設定されています。
つまり、中の要素が「svg」より食み出しても表示する。


<svg id="SvgjsSvg..." style="overflow:visible;">

viewbox bboxのサンプル


● 同じ大きさでdraw層を表示
640x100のステージに対し viewbox(0,0,640,100) は何ら変化は無い。

通常、SVG.jsでは意図的に viewbox() を実行しなければ、viewBox属性は設定されません。(必ずしも必要ではない)


もし、この出来上がったSVGを他のSVGに取り込み(または読み込み)表示するなら、viewbox(0,0,640,100)設定があったほうが良い。表示先のSVGの大きさにあわせ自動的に伸縮させ表示出来る。


● draw層を縮小して表示 (実際に設定することは無いと思います、一応テストです)
640x100のステージに対し viewbox(0,0,640,200) は縮小50%と同じになる、X方向が同じ大きさのためcenterがX方向のみ機能している。(draw層をscale()では変更できない)

以下で、縮尺率を算出出来る。viewboxに変更が無ければzoomは1である。


//縮尺率算出
var box1=draw.viewbox()
var zoom=box1.zoom

このような設定は通常ありえない。混乱するだけの結果になります。


サンプルJS


	//対象エレメントID
	var draw=SVG('geometry-1a').size(640,100)
	draw.viewbox(0,0,640,100)

	//TEXT
	var text=draw.text('center').font({leading:0.8})

	//文字
	var title_text=draw.text('POPSWEB KOUBOU')
	.font({
		family:'Arial'
		,size:50
		,'font-weight':'bolder'
		,anchor:'left'
		,leading:1
	})

	//大きさ取得
	//var txdata=title_text.bbox()
	//var mv_x=(640-txdata.width)/2
	//var mv_y=(100-txdata.height)/2

	title_text.center(320,50)

	//-----------

	//対象エレメントID
	var draw=SVG('geometry-1b').size(640,100)
	draw.viewbox(0,0,640,200)

	//縮尺率算出
	var box1=draw.viewbox()
	var zoom=box1.zoom

	//TEXT
	var text=draw.text('viewbox/zoom ' + zoom).font({leading:1})

	//文字2
	var title_text2=draw.text('POPSWEB KOUBOU')
	.font({
		family:'Arial'
		,size:50
		,'font-weight':'bolder'
		,anchor:'left'
		,leading:1
	})

	title_text2.center(320,50)


● Nestした「svg」にviewboxを処理 (nestはsvg要素です)
注意、中の構成要素は、Nestした「svg」の境界で切れない。(調べるとスタイルがoverflow:visibleです)
1. Nestの「viewbox設定」が無い場合、中の要素の位置決めは「ステージ(root)基準」であり、「svg」の相対では無い。

2. Nestの「viewbox設定」がrootと違う場合は、中の要素の位置決めは「Nest基準」になります。
構成には注意が必要で結構面倒と思います。何回か作りこみクセを覚えこまねばならないようです。

3. 陰影なしならはみ出しても表示しますが、陰影の種類によっては「上と左」が切れます。形式の違う「別陰影」ではサンプルの様に表示する。(新しい陰影は中段で説明しています)
中の構造、移動する場合の方法、陰影の種類、文字、グラフィックなどの条件で変わって来る様ですので、テストを重ねて振る舞いを知りましょう。最大の原因は陰影の作り方にある様です。(大変ですね... 余り利用したくない...)


もし構成するなら、下の「サンプル6番」、のような場合と思う。しいて言えば、部分的に「スケール」を違わせると言う事でしょうか。



サンプルJS


	//対象エレメントID
	var draw=SVG('geometry-1c').size(640,100)

	//TEXT
	var text=draw.text('Nest viewbox設定、食み出し表示').font({leading:0.8})

	//文字3
	var title_text3=draw.text('POPSWEB KOUBOU')
	.font({
		family:'Arial'
		,size:50
		,'font-weight':'bolder'
		,anchor:'left'
		,leading:1
	})
	title_text3.attr({'fill':'#CCC'})

	//viewbox設定の違うsvgです
	//Nestは大きさ指定
	var nest1=draw.nested().size(320,50)
	nest1.viewbox(0,0,320,50)
	.x(0).y(50)//svg移動

	//svg範囲を図示
	var rect=nest1.rect(320,50).attr({'fill':'none','stroke':'#F00','stroke-width':1}).x(0).y(0)//nest1基準の位置

	//中にサークル描画TEST
	var circle=nest1.circle(30).attr({'fill':'#FFD700'}).center(40,10)//上にずらして表示
	.attr({'filter':'url(#drop-shadow2)'})//別陰影
	//陰影なし
	var circle2=nest1.circle(30).attr({'fill':'#DAA520'}).center(80,10)//上にずらして表示
	//通常陰影
	var circle3=nest1.circle(30).attr({'fill':'#B8860B'}).center(120,10)//上にずらして表示
	.attr({'filter':'url(#dropShadow2)'})//通常陰影

	//文字4
	var title_text4=nest1.text('POPSWEB KOUBOU')
	.font({
		family:'Arial'
		,size:24
		,'font-weight':'bolder'
		,anchor:'left'
		,leading:1
	})
	.attr({'fill':'#00F'}).x(200).y(10)//食み出しても表示する、通常の陰影で上左移動はきれる
	//.translate(200,-10)//文字は、通常の陰影で上左に移動しても切れない
	.attr({'filter':'url(#dropShadow2)'})//通常の陰影


● bbox()の取得
下記はFONTの場合であるが、解釈の違いなどで「ブラウザ」によって取得値に少しの差異があります。
FONT以外の取得値は同じになります。(全て確認はしていませんが...)


取得例、Chrome w 491.6875 h 56 / Firefox w 493 h 59 / IE11 w 491.6999816894531 h 57.5


サンプルJS


	//対象エレメントID
	var draw=SVG('geometry-2a').size(640,100)

	//TEXT
	var text2a=draw.text('bbox').font({leading:0.8})

	//文字
	var title_text2a=draw.text('POPSWEB KOUBOU')
	.font({
		family:'Arial'
		,size:50
		,'font-weight':'bolder'
		,anchor:'left'
		,leading:1
	})
	.attr({fill:'#00CED1'})
	.attr({'filter':'url(#dropShadow2)'})//陰影
	//center中央表示
	//title_text2a.center(320,50)
	//bbox
	var bbox_v=title_text2a.bbox()
	//move中央表示
	title_text2a.move((640-bbox_v.w)/2,(100-bbox_v.h)/2)

	//テキストの大きさのレクト描画
	var rect=draw.rect(bbox_v.w,bbox_v.h).attr({'fill':'none','stroke':'#F00','stroke-width':1}).center(320,50)

 	text2a.text(' w ' + bbox_v.w + ' h ' + bbox_v.h)


 

svg読み込み表示とsvg()処理のサンプル

svg構造の中に新たな「svg」構造を挿入するには、とりあえず3つの方法がある様です。


1. imageで読み込む。中の要素に対し JavaScript CSS の操作は出来ません。
(グループは陰影が切れるので、要素の配置方法に注意ください、修正可能)
2. svg()で書き込む。他人のパスをそのまま利用出来るのでスコブル簡単です。
インラインで在るゆえ、処理方法を考慮すれば、JavaScript CSS の操作は可能です。
(原則、グループでラップしなければなりません、都合のよい様に書き換えて処理することも可能)
3. nested()で「svg」構造を作り、そこに要素を記載する。通常のSVG.js処理ですから問題は有りませんが、新たにSVG.jsで構成しなおす作業な為、再現が面倒になります。


● 表示に使用している、rss-icon.svg


<?xml version="1.0" encoding="UTF-8" ?>
<svg id="svg_icon1" xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48">
  <defs></defs>
  <rect id="rect_1" fill="#ff7c01" width="48" height="48" rx="7" ry="7"/>
  <path id="shape_1" fill="#fff" d="M40.953,41H34.367A26.88,26.88,0,0,0,26.917,22.2C18.684,13.264,7,13.734,7,13.734V7s15.761-.313,25.485,11.049S40.953,41,40.953,41ZM24.094,25.958C30.211,33.637,29.5,40.924,29.5,40.924H22.918s-0.078-7.209-4.783-11.519A18.193,18.193,0,0,0,7,25.1V18.357S17.978,18.279,24.094,25.958ZM11.783,31.835A4.466,4.466,0,1,1,7.314,36.3,4.468,4.468,0,0,1,11.783,31.835Z"/>
</svg>

外部svgの読み込み表示(SVG Icon)

● imageで外部「svg」を読み込み表示。画像と同じ扱いになる。陰影は処理できますが、場合によっては補正が必要です。
1番、draw層の場合は陰影はOKです。3番、グループは注意


1. 大きさの変更と、陰影処理は出来ます。
2. stroke、色の変更は出来ません。


グループにaddするのが正式ですが、imageを先に移動させないと「g」が邪魔して陰影がキレル場合がある(ややこしいですね)。
但し、後で説明する「新しい陰影drop-shadow2」を使用すれば、陰影はキレル無い。


//add形式が正式
image_svg2=draw.image('/main/js/rss-icon.svg').size(48,48).center(80,80)
.attr({'filter':'url(#dropShadow2)'})//陰影
//グループにadd
var svgicon=draw.group()
svgicon.add(image_svg2)

-----------------------------------

//OK/グループ陰影もOK
var svgicon=draw.group()
var icon2=svgicon.image('/main/js/rss-icon.svg').size(48,48).center(80,80)
.attr({'filter':'url(#dropShadow2)'})//陰影

読み込み「svg」内部の JavaScript CSS の操作は一切出来ない。仮に操作しても反応しません。

1番、svg読込表示 / 2番、svg読込表示 / 3番、グループは陰影補正


サンプルJS


	//対象エレメントID
	var draw=SVG('geometry-3a').size(160,160)

	//TEXT
	var text=draw.text('svg()表示rotate 30').font({leading:0.8})

	//案内用
	var rect=draw.rect(80,80).attr({'fill':'none','stroke':'#CCC','stroke-width':1}).center(80,80)

	//SVG表示
	var svg_image=draw.image('/main/js/rss-icon.svg').size(48,48).center(80,80)
	svg_image.rotate(30)
	.attr({'filter':'url(#dropShadow2)'})//陰影

	//-------------

	//対象エレメントID
	var draw=SVG('geometry-3b').size(160,160)

	//TEXT
	var text=draw.text('svg() loaded サイズ変更').font({leading:0.8})
	//SVG表示/id=svg_icon1
	var image_svg=draw.image('').size(0,0).center(80,80)

	image_svg=draw.image('/main/js/rss-icon.svg').loaded(function(loader) {
		this.size(96,96).center(80,80)
		.attr({'filter':'url(#dropShadow2)'})//陰影
	})

	//-------------

	//対象エレメントID
	var draw=SVG('geometry-3c').size(160,160)

	//TEXT
	var text=draw.text('グループ').font({leading:0.8})

	//OK/グループ陰影もOK
	var svgicon=draw.group()
	var icon2=svgicon.image('/main/js/rss-icon.svg').size(48,48).center(80,80)
	.attr({'filter':'url(#dropShadow2)'})//陰影


svg構成で表示

● svg() nested()などで「svg」を書き込み、内部の色などを操作する。svg()が便利です。
svg()で取り込む場合、中の要素より「svg」が余裕を持って大きい場合を除き、viewbox で調整しなければならない時は注意が必要です。下図の様に外周に余裕のある作りは少ないでしょう。


zu

 

1. 外周に余裕がある作りは問題は有りません。(サンプル9番、参照)
2. 余裕が無い作りは、陰影、stroke処理が困難です。修正するには2つの方法があります。
3. 図1番の様に、「svg」を overflow:visible にして、陰影も修正したもので処理します。
4. 図2番の様に、外周に余裕が出来る様にviewboxを変更し、中の要素を移動します。
5. fill色変更のみならば、上記修正などは不要です。
6. 取り込み先きの「svg」の構成で多少作業が違ってきます。


外周に余裕が無いと、一般的に、修正が面倒に成ります。


svg()を利用してsvg記述

「svg」をimageで表示は出来ますが、中の操作は出来ません。しかし、svg()を利用して「アイコンなどを取り込み」インライン要素として「svg」を表示出来ます。簡単に取り込め(手書きでをSVG書き込みます)、中の要素にアクセスできるのが特徴です。


注意、svg()処理の場合、中の要素をグループでラップしなければ移動できない。マニュアルより...

svg()の中は、改行、インデントなど付けず、必ず一行で記述します。(サンプル4 5番を参照ください)


書式
draw.svg('<g>.....</g>')
この場合の「g」の制御には限界があるようです、回転が上手くできない

実際にはグループを作り実行、ラップ同様です、これは問題なし
var group=draw.group()
group.svg('.....')

注意、add形式の使用はエラーです
group.add(......)//ダメ

svg要素をSVG.jsのインスタンスにする。ID名は重複しないように付ければよい。
(svg rect circle line path text 等のsvg要素)


書式
var element=SVG.get('ID名')

以後、SVG.jsのメソッド等実行出来ます
element.attr({fill:'#F00'})//fill
.attr({'filter':'url(#dropShadow2)'})//陰影

新しい陰影

● 構造によっては陰影がキレルため次の様に新しい陰影を追加しました。(ほぼ問題が解決するようですが...)

新しい「陰影#drop-shadow2」の設定。filterUnits属性を削除して、下記の様に「%」設定に変更しました。
「%」設定のため10x10サイズ以上の大きさならば問題は無い。余り小さすぎるとダメ。

line()の水平または垂直の単線は表示が消えます(斜線はOK)。他にも影響を受けるものもあるかも知れないので確認ください。
このような場合は従来の陰影 #dropShadow2 を使用して下さい。


5x5位の大きさでも切れない
<filter id="drop-shadow2" x="-100%" y="-100%" width="400%" height="400%">

-------------------------------------

Nestでも問題の出ない様に、filterUnits属性は削除したほうがよい様です
これでもいける、widthが広いのはIE対策です
<filter id="drop-shadow2" x="-100" y="-100" width="1000" height="500">

filterUnits属性についての詳細が余り詳しくないので、問題があれば自己解決ください。


1. viewBoxの変更無しでsvg()処理するサンプル

余裕の無いアイコンをsvg()処理します。そのまま表示しますが、


1. viewBox、大きさを変更せず、取り込み「svg」の overflow:visible でstroke等の切れを防止します。
(中の要素が「svg」範囲外にあっても表示します、一種のゴマカシです)
2. 「g」が邪魔して陰影を切りますので、新たな「陰影drop-shadow2」を利用します。(新しい陰影)
3. viewBoxが同じですから、大きさ変更で伸縮を簡単に行えます。
4. 詳細は、サンプル4 5番を参照ください。


6番、nested()はSVG.js方式に完全書き換えですから再現するのが大変です。時には上手く行かない場合もあるかも...
中の要素をずらせば、従来の陰影処理でよい。グループ構成にすれば回転できる。

svg()を利用する方が簡単なことが実感できます。


4番、overflow:visibleで表示pointer / 5番、stroke変更 / 6番、nested()処理、キレルので別陰影


サンプルJS


	//対象エレメントID
	var draw=SVG('geometry-4a').size(160,160)

	//TEXT
	var text=draw.text('「svg」overflow:visible表示').font({leading:0.8})

	//SVGをグループでラップ
	var rawSvg4='<svg id="svg_icon4" width="48" height="48" viewBox="0 0 48 48"><rect id="rect_4" fill="#ff7c01" width="48" height="48" rx="7" ry="7"/><path id="shape_4" fill="#fff" d="M40.953,41H34.367A26.88,26.88,0,0,0,26.917,22.2C18.684,13.264,7,13.734,7,13.734V7s15.761-.313,25.485,11.049S40.953,41,40.953,41ZM24.094,25.958C30.211,33.637,29.5,40.924,29.5,40.924H22.918s-0.078-7.209-4.783-11.519A18.193,18.193,0,0,0,7,25.1V18.357S17.978,18.279,24.094,25.958ZM11.783,31.835A4.466,4.466,0,1,1,7.314,36.3,4.468,4.468,0,0,1,11.783,31.835Z"/></svg>'
	var svg_group4=draw.group()
	.style({'cursor':'pointer'})//pathが邪魔なのでグループに
	//svg挿入/要素移動無し
	svg_group4.svg(rawSvg4)

	//svg変更
	var svg_icon4=SVG.get('svg_icon4')
	//大きさを変更するならば
	//.attr({width:48,height:48})
	.center(80,80)//中央に移動
	.style({'overflow':'visible'})//stroke切れ防止

	//rect変更、移動はしない
	var element4=SVG.get('rect_4')
	element4.attr({fill:'#F00'})//fill変更
	//strokeが必要ならば
	//.attr({'stroke':'#FFF','stroke-width':4,'vector-effect':'non-scaling-stroke'})//stroke

	//drop-shadow2の実行
	.attr({'filter':'url(#drop-shadow2)'})//切れ防止用

	//グループを回転させる、動作します
	//svg_group4.transform({'rotation':30})

	//-------------

	//対象エレメントID
	var draw=SVG('geometry-4b').size(160,160)

	//TEXT
	var text=draw.text('svg() 80x80 stroke 回転').font({leading:0.8})

	//SVGをグループでラップ
	var rawSvg5='<svg id="svg_icon5" width="48" height="48" viewBox="0 0 48 48"><rect id="rect_5" fill="#ff7c01" width="48" height="48" rx="7" ry="7"/><path id="shape_5" fill="#fff" d="M40.953,41H34.367A26.88,26.88,0,0,0,26.917,22.2C18.684,13.264,7,13.734,7,13.734V7s15.761-.313,25.485,11.049S40.953,41,40.953,41ZM24.094,25.958C30.211,33.637,29.5,40.924,29.5,40.924H22.918s-0.078-7.209-4.783-11.519A18.193,18.193,0,0,0,7,25.1V18.357S17.978,18.279,24.094,25.958ZM11.783,31.835A4.466,4.466,0,1,1,7.314,36.3,4.468,4.468,0,0,1,11.783,31.835Z"/></svg>'
	var svg_group5=draw.group()
	//svg挿入/要素移動無し
	svg_group5.svg(rawSvg5)

	//svg変更
	var svg_icon5=SVG.get('svg_icon5')
	//大きさを変更
	.attr({width:80,height:80})
	.center(80,80)//中央に移動
	.style({'overflow':'visible'})//stroke切れ防止

	//rect変更、移動はしない
	var element5=SVG.get('rect_5')
	element5.attr({fill:'#00F','stroke':'#FFF','stroke-width':2,'vector-effect':'non-scaling-stroke'})//fill stroke変更
	//drop-shadow2の実行
	.attr({'filter':'url(#drop-shadow2)'})//切れ防止用

	//グループを回転させる、動作します
	svg_group5.transform({'rotation':30})

	//-------------

	//対象エレメントID
	var draw=SVG('geometry-4c').size(160,160)

	//TEXT
	var text=draw.text('nested()').font({leading:0.8})

	//svg/Nestをcenter移動
	var nest_svg=draw.nested()
	//表示の大きさを変えれば伸縮する
	.attr({'width':48,'height':48}).viewbox(0,0,48,48)
	.center(80,80)

	//グループ構成では無い
	//rect
	nest_svg.rect(48,48).radius(7).attr({'fill':'#00CED1','stroke':'#FFF','stroke-width':2,'vector-effect':'non-scaling-stroke'})
	//drop-shadow2の実行
	.attr({'filter':'url(#drop-shadow2)'})//切れ防止用
	//path
	var d="M40.953,41H34.367A26.88,26.88,0,0,0,26.917,22.2C18.684,13.264,7,13.734,7,13.734V7s15.761-.313,25.485,11.049S40.953,41,40.953,41ZM24.094,25.958C30.211,33.637,29.5,40.924,29.5,40.924H22.918s-0.078-7.209-4.783-11.519A18.193,18.193,0,0,0,7,25.1V18.357S17.978,18.279,24.094,25.958ZM11.783,31.835A4.466,4.466,0,1,1,7.314,36.3,4.468,4.468,0,0,1,11.783,31.835Z"
	nest_svg.path(d).attr({'fill':'#FFF'}).move(7,7)


なるべく、rss-icon.svg の構造通りに再現してみました。


4番5番、svg()処理サンプルの説明

「svg」をスタイルで、overflow:visibleすれば、陰影とstroke切れを防止しますが、「g」要素でラップしているために、処理方法によっては陰影が切れます。その修正のために、新たな「陰影#drop-shadow2」で処理します。


● 4番の処理例、IDは競合しないテキトウな名前で作ります。


//SVGをグループでラップ
var rawSvg4='取り込むsvgを記載、ID名はテキトウに'
var svg_group4=draw.group()
.style({'cursor':'pointer'})//pathが邪魔なのでグループに
//svg挿入/要素移動無し
svg_group4.svg(rawSvg4)

//svg変更
var svg_icon4=SVG.get('svg_icon4')
//大きさを変更するならば
//.attr({width:48,height:48})
.center(80,80)//中央に移動
.style({'overflow':'visible'})//stroke切れ防止

//rect変更、移動はしない
var element4=SVG.get('rect_4')
element4.attr({fill:'#F00'})//fill変更
//strokeが必要ならば
//.attr({'stroke':'#FFF','stroke-width':4,'vector-effect':'non-scaling-stroke'})//stroke

//drop-shadow2の実行
.attr({'filter':'url(#drop-shadow2)'})//切れ防止用

//グループを回転させる、動作します
//svg_group4.transform({'rotation':30})

●「svg」をはみ出しても表示出来るように overflow:visible を設定しています。
center()表示はviewBoxを変更していないので、移動可能です。


//svgをインスタンス化
var svg_icon4=SVG.get('svg_icon4')
.style({'overflow':'visible'})//stroke切れ防止
.center(80,80)//中央に移動

-------------------------------------

同じ
.style('overflow','visible')

● 陰影は「g」の影響でキレル為別途「新規の陰影」で処理、色、ストロークの変更も可能です。


//rectをインスタンス化
var element4=SVG.get('rect_4')
.attr({'filter':'url(#drop-shadow2)'})//切れ防止用

2. viewBoxを変更、中の要素を移動して処理するサンプル、他

上記のアイコンの外側にviewBoxを変更で余裕を作り表示する方法です。表示がずれるので、中の要素を移動します。9番は余裕のあるアイコンの表示です。

viewBoxを大きく変更して余裕を作ります

サンプルのアイコン、そのままでは外側に余裕がないので、陰影、ストローク変更などの処理などを行えません。外側に余裕を作る方法です。上記、4 5番、の方法が簡単ならばそれでも構わないでショウ。

何らかの参考になるかも知れませんので、テストしてみます。


1. viewBoxを変更、表示大きさを上下左右10ピクセル分広げます。center()は正確に成りません。
2. 中の要素をXY方向とも10ピクセル移動します。
3. 外側に余裕が出来ますので、陰影処理など自由になります。
4. 9番、viewPort(width heigh)指定無しのSVGを表示します。指定する大きさに伸縮します。
(7番、8番とは構造が違います、大きさ指定はこちらが簡単です)
5. 実際表示の要素は指定サイズより小さくなります。


7番、大幅な書き換え / 8番、大幅な書き換え / 9番、viewPort指定無しのSVG


Twitterは「ツブヤク」ですが、KOKEKOKKOUは「ウルサク ホエル」です。

7番、8番、サンプルJS


	//対象エレメントID
	var draw=SVG('geometry-5a').size(160,160)

	//TEXT
	var text=draw.text('svg()改造 原寸で表示').font({leading:0.8})

	//SVGグループ/viewBox大きさ変更
	var rawSvg7='<svg id="svg_icon7" width="68" height="68" viewBox="0 0 68 68"><rect id="rect_7" fill="#ff7c01" width="48" height="48" rx="7" ry="7"/><path id="shape_7" fill="#fff" d="M40.953,41H34.367A26.88,26.88,0,0,0,26.917,22.2C18.684,13.264,7,13.734,7,13.734V7s15.761-.313,25.485,11.049S40.953,41,40.953,41ZM24.094,25.958C30.211,33.637,29.5,40.924,29.5,40.924H22.918s-0.078-7.209-4.783-11.519A18.193,18.193,0,0,0,7,25.1V18.357S17.978,18.279,24.094,25.958ZM11.783,31.835A4.466,4.466,0,1,1,7.314,36.3,4.468,4.468,0,0,1,11.783,31.835Z"/></svg>'
	var svg_group7=draw.group()
	svg_group7.svg(rawSvg7).x(80-34).y(80-34)//中央に移動

	//RECT
	var element7=SVG.get('rect_7')
	.move(10,10)//移動
	.attr({fill:'#F00'})//色変更
	.attr({'filter':'url(#dropShadow2)'})//陰影
	//PATH
	var shape7=SVG.get('shape_7')
	.transform({'x':10}).transform({'y':10})//移動
	.attr({'filter':'url(#dropShadow2)'})

	//グループを回転させる、動作します
	//svg_group7.transform({'rotation':30})

	//-------------

	//対象エレメントID
	var draw=SVG('geometry-5b').size(160,160)

	//TEXT
	var text=draw.text('svg()改造 拡大とstroke').font({leading:0.8})

	//SVGグループ/viewBox大きさ変更
	var rawSvg8='<svg id="svg_icon8" width="100" height="100" viewBox="0 0 68 68"><rect id="rect_8" fill="#ff7c01" width="48" height="48" rx="7" ry="7"/><path id="shape_8" fill="#fff" d="M40.953,41H34.367A26.88,26.88,0,0,0,26.917,22.2C18.684,13.264,7,13.734,7,13.734V7s15.761-.313,25.485,11.049S40.953,41,40.953,41ZM24.094,25.958C30.211,33.637,29.5,40.924,29.5,40.924H22.918s-0.078-7.209-4.783-11.519A18.193,18.193,0,0,0,7,25.1V18.357S17.978,18.279,24.094,25.958ZM11.783,31.835A4.466,4.466,0,1,1,7.314,36.3,4.468,4.468,0,0,1,11.783,31.835Z"/></svg>'
	var svg_group8=draw.group()
	svg_group8.svg(rawSvg8).x(80-50).y(80-50)//中央に移動

	//RECT
	var element8=SVG.get('rect_8')
	.move(10,10)//移動
	.attr({fill:'#00F','stroke':'#FFF','stroke-width':2,'stroke-width':2,'vector-effect':'non-scaling-stroke'})//色stroke変更
	.attr({'filter':'url(#dropShadow2)'})//陰影
	//PATH
	var shape8=SVG.get('shape_8')
	.transform({'x':10}).transform({'y':10})//移動

	//グループを回転させる、動作します
	svg_group8.transform({'rotation':30})


7番8番、svg()処理サンプルの説明

● 「svg」の大きさとviewBoxを上下左右に10px広げて書き換えます。IDは競合しないテキトウな名前で作ります。直接手書きで修正していますが、attr() viewbbox()でも修正は可能です。


<svg id="svg_icon7" width="68" height="68" viewBox="0 0 68 68">

attr() viewbbox()の場合は


//インスタンス化
var svg_icon7=SVG.get('svg_icon7')
//大きさviewBox変更
.attr({width:68,height:68}).viewbox(0,0,68,68)

● 7 8番、は「svg」の大きさとviewBoxを変更しています。48x48 を 68x68 に変更して、内部の要素を10ピクセル移動して、陰影などの処理を行えるようにしています。
rectをtransformで移動すると「陰影」がキレルので注意ください。「g」が邪魔している(ややこしいですね)。


rectは x y 値で移動します
<rect id="rect_7" fill="#ff7c01" width="48" height="48" x="10" y="10" rx="7" ry="7"/>

-------------------------------------

pathはtransformで移動します
transform="translate(10,10)"
または
transform="matrix(1,0,0,1,10,10)"

● rect path をインスタンス化して操作する場合は下記の通りです。注意、pathはmove()では動きません。


//RECT
var element7=SVG.get('rect_7')
.move(10,10)//移動
.attr({fill:'#F00'})//色変更
.attr({'filter':'url(#dropShadow2)'})//陰影
//PATH
var shape7=SVG.get('shape_7')
.transform({'x':10}).transform({'y':10})//移動
.attr({'filter':'url(#dropShadow2)'})

-------------------------------------

PATHをtranslate()で動かす時は
.translate(10,10)

● 7番、はグループの中にありますので。回転させる場合は、transform() を設定します。


//グループを回転させる、動作します
svg_group7.transform({'rotation':30})

pointerが必要なら、pathが邪魔なのでグループに設定します。


var svg_group7=draw.group()
.style({'cursor':'pointer'})//pathが邪魔なのでグループに

● 7番、「svg」の大きさを変えれば拡大縮小します。例では100x100サイズで表示。8番も同様です。
大きさは外側のサイズであり中の要素のサイズではありませんので注意ください。


インスタンスにして変更
var svg_element=SVG.get('svg_icon7')
svg_element.attr({'width':100,'height':100})

直接変更
<svg id="svg_icon7" width="100" height="100" viewBox="0 0 68 68">

-------------------------------------

中の要素表示サイズの計算(stroke幅は考慮していません)
アイコンサイズ48x48、表示するサイズ100x100、viewBoxサイズ68x68とすると

48*100/68=約70

● 7番、中央表示のcenter()は中の要素の大きさを取得しますので正確にはなりません。修正が面倒です。


//68x68のcenter()表示は10pxずれるので下記で出来るが、他サイズはダメ
svg_group7.svg(rawSvg7).center(80-10,80-10)

-------------------------------------

//表示の大きさで修正するのが良い、計算し易い
svg_group7.svg(rawSvg7).x(80-34).y(80-34)//68x68
svg_group7.svg(rawSvg7).x(80-50).y(80-50)//100x100
svg_group7.svg(rawSvg7).x(80-17).y(80-17)//34x34

● 8番、strokeを加える。
現在、外周に10ピクセルの余裕がありますので、その範囲でstrokeを加えることも可能です。
尚、vector-effect:non-scaling-stroke はIE11で機能しません。


var element8=SVG.get('rect_8')
element8.attr({fill:'#00F'})
.attr({'stroke':'#FFF','stroke-width':2,'vector-effect':'non-scaling-stroke'})//stroke

● HtmlへのviewBox属性の記入は、ほとんどがviewBoxを使用していますので、それを使用しました。
ちなみにSVG.jsの出力もviewBoxになっています。


viewBox="0 0 160 160"

すべて小文字でも問題なく認識実行するようです
viewbox="0 0 160 160"

サンプル9番の説明

サンプル9番は、下記URLの「SVG Logo」twitter.svg です。400x400前後の大きさで作られており、表示する大きさを指定して使用します。(viewPort(width heigh)指定無し)
グラフイック外側に余裕があるので装飾の追加など加工し易い。サンプルではsvg()で埋め込んで利用しています。
当然、imageで大きさを指定して、表示も可能です。


埋め込み使用SVGの頒布先、flaticon.com 使用LOGO Social Media Logos


● 埋め込みですから、改造など出来ます。
但し、pathが大きいため、strokeが見え難いので、vector-effect:non-scaling-stroke を設定しました。(IE11は機能しません)
ID名は自由に変更出来ます。SVG.get(ID名)で、SVG.jsのインスタンスに出来ますので、各要素にアクセス出来ます。
パスにpointerを設定してみました。

元のアイコンは、色などstyleで設定されていますので、style()で変更します。



表示の大きさを決定する

var tw_icon=SVG.get('Layer_1')
tw_icon.attr({width:80,height:80}).center(80,80)

--------------------------------------

pathインスタンス取得と色変更とpointer

var tw_icon_path=SVG.get('Layer_1_path')
tw_icon_path.style({fill:'#F00'})
.style({'cursor':'pointer'})//pointerOK

9番、サンプルJS


	//対象エレメントID
	var draw=SVG('geometry-5c').size(160,160)

	//TEXT
	var text=draw.text('KOKEKOKKOU pointer').font({leading:0.8})

	//http://www.flaticon.com/packs/social-media-logos-2
	var svg_group9=draw.group()
	svg_group9.svg('<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 410.155 410.155" style="enable-background:new 0 0 410.155 410.155;" xml:space="preserve"><path id="Layer_1_path" style="fill:#76A9EA;" d="M403.632,74.18c-9.113,4.041-18.573,7.229-28.28,9.537c10.696-10.164,18.738-22.877,23.275-37.067l0,0c1.295-4.051-3.105-7.554-6.763-5.385l0,0c-13.504,8.01-28.05,14.019-43.235,17.862c-0.881,0.223-1.79,0.336-2.702,0.336c-2.766,0-5.455-1.027-7.57-2.891c-16.156-14.239-36.935-22.081-58.508-22.081c-9.335,0-18.76,1.455-28.014,4.325c-28.672,8.893-50.795,32.544-57.736,61.724c-2.604,10.945-3.309,21.9-2.097,32.56c0.139,1.225-0.44,2.08-0.797,2.481c-0.627,0.703-1.516,1.106-2.439,1.106c-0.103,0-0.209-0.005-0.314-0.015c-62.762-5.831-119.358-36.068-159.363-85.14l0,0c-2.04-2.503-5.952-2.196-7.578,0.593l0,0C13.677,65.565,9.537,80.937,9.537,96.579c0,23.972,9.631,46.563,26.36,63.032c-7.035-1.668-13.844-4.295-20.169-7.808l0,0c-3.06-1.7-6.825,0.485-6.868,3.985l0,0c-0.438,35.612,20.412,67.3,51.646,81.569c-0.629,0.015-1.258,0.022-1.888,0.022c-4.951,0-9.964-0.478-14.898-1.421l0,0c-3.446-0.658-6.341,2.611-5.271,5.952l0,0c10.138,31.651,37.39,54.981,70.002,60.278c-27.066,18.169-58.585,27.753-91.39,27.753l-10.227-0.006c-3.151,0-5.816,2.054-6.619,5.106c-0.791,3.006,0.666,6.177,3.353,7.74c36.966,21.513,79.131,32.883,121.955,32.883c37.485,0,72.549-7.439,104.219-22.109c29.033-13.449,54.689-32.674,76.255-57.141c20.09-22.792,35.8-49.103,46.692-78.201c10.383-27.737,15.871-57.333,15.871-85.589v-1.346c-0.001-4.537,2.051-8.806,5.631-11.712c13.585-11.03,25.415-24.014,35.16-38.591l0,0C411.924,77.126,407.866,72.302,403.632,74.18L403.632,74.18z"/></svg>')
	var tw_icon=SVG.get('Layer_1')
	tw_icon.attr({width:80,height:80}).center(80,80)
	svg_group9.attr({'filter':'url(#dropShadow2)'})//陰影
	var tw_icon_path=SVG.get('Layer_1_path')
	tw_icon_path.style({fill:'#F00'})
	.style({'cursor':'pointer'})//pointerOK
	.attr({'stroke':'#FFF','stroke-width':2,'stroke-linejoin':'round','vector-effect':'non-scaling-stroke'})//stroke


 

サンプルJSの全表示

Chromeは文字化けしますのでエンコード(UTF-8)してご覧ください。

● サンプルJSの全表示1(解説ページ用) svg-sample16.js

 


 

dropshadowは当方自作の dropshadow-custom.js を使用します。
なおこのページはjQuery1.6.4のため dropshadow-custom-ie.js に成ります。

アニメーション書式などは下記の記事を参照ください参照ください。

【参照】当方の記事: SVG.js を使用してsvgコンテンツを作り表示します

【参照】当方の記事: SVG.js DropShadowの自作とBlur


問題があれば自己解決ください。以上です。

 


[ この記事のURL ]


タグ:javascript , SVG

 

ブログ記事一覧



[1]