自分の新しいロゴを作ってみた。
このロゴはアニメーションを想定して作っている。
SVGの中身はこんなふうになっている。
<?xml version="1.0" encoding="UTF-8"?>
<svg id="layer1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 583 583">
<defs>
<style>
#layer1{
--logo-color:#333;
/* linear */
--ease-linear:cubic-bezier(0.0, 0.0, 1.0, 1.0);
/* Sine(最も弱い) */
--ease-in-sine:cubic-bezier(0.47, 0, 0.745, 0.715);
--ease-out-sine:cubic-bezier(0.39, 0.575, 0.565, 1);
--ease-in-out-sine:cubic-bezier(0.445, 0.05, 0.55, 0.95);
/* Quad(弱め。Sineより強く、Cubicより弱い) */
--ease-in-quad:cubic-bezier(0.55, 0.085, 0.68, 0.53);
--ease-out-quad:cubic-bezier(0.25, 0.46, 0.45, 0.94);
--ease-in-out-quad:cubic-bezier(0.455, 0.03, 0.515, 0.955);
/* Cubic(Quadより強く、Quartより弱い) */
--ease-in-cubic:cubic-bezier(0.55, 0.055, 0.675, 0.19);
--ease-out-cubic:cubic-bezier(0.215, 0.61, 0.355, 1);
--ease-in-out-cubic:cubic-bezier(0.645, 0.045, 0.355, 1);
/* Quart(Cubicより強く、Quintより弱い) */
--ease-in-quart:cubic-bezier(0.895, 0.03, 0.685, 0.22);
--ease-out-quart:cubic-bezier(0.165, 0.84, 0.44, 1);
--ease-in-out-quart:cubic-bezier(0.77, 0, 0.175, 1);
/* Quint(Quartより強く、Expoより弱い) */
--ease-in-quint:cubic-bezier(0.755, 0.05, 0.855, 0.06);
--ease-out-quint:cubic-bezier(0.23, 1, 0.32, 1);
--ease-in-out-quint:cubic-bezier(0.86, 0, 0.07, 1);
/* Expo(最も強い) */
--ease-in-expo:cubic-bezier(0.95, 0.05, 0.795, 0.035);
--ease-out-expo:cubic-bezier(0.19, 1, 0.22, 1);
--ease-in-out-expo:cubic-bezier(1, 0, 0, 1);
/* Circ(Expoのような強さを持つが、加速や減速の時間がよりゆるやか。) */
--ease-in-circ:cubic-bezier(0.6, 0.04, 0.98, 0.335);
--ease-out-circ:cubic-bezier(0.075, 0.82, 0.165, 1);
--ease-in-out-circ:cubic-bezier(0.785, 0.135, 0.15, 0.86);
/* Back(少し行き過ぎてから戻ってくるような動き) */
--ease-in-back:cubic-bezier(0.6, -0.28, 0.735, 0.045);
--ease-out-back:cubic-bezier(0.175, 0.885, 0.32, 1.275);
--ease-in-out-back:cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
.cls-1{fill:none;}
.cls-2{clip-path:url(#clippath);}
.cls-3{clip-path:url(#clippath-1);}
.cls-4{clip-path:url(#clippath-3);}
.cls-5{clip-path:url(#clippath-2);}
.cls-6{stroke-linecap:square;}
.cls-6,.cls-7{
fill:transparent;
stroke:var(--logo-color);
stroke-miterlimit:10;
stroke-width:30px;
}
#huyu-dot1,#huyu-dot2{
fill:var(--logo-color);
}
@media (prefers-reduced-motion: no-preference) {
.cls-6,.cls-7{
stroke-dasharray: 583;
stroke-dashoffset: 583;
animation: line 1.5s var(--ease-out-expo) forwards;
}
#huyu-line1,#huyu-line2{
animation-delay: 0.2s;
}
#huyu-line3{
animation-delay: 0.4s;
}
#huyu-dot1,#huyu-dot2{
transform: scale(0);
animation: dot 0.8s var(--ease-out-back) forwards;
}
#huyu-dot1{
animation-delay: 0.4s;
transform-origin: 74.96% 65.69%; /* (座標/viewBoxサイズ*100)% */
}
#huyu-dot2{
animation-delay: 0.6s;
transform-origin: 74.96% 87.99%; /* (座標/viewBoxサイズ*100)% */
}
}
@keyframes line {
to {
stroke-dashoffset: 0;
}
}
@keyframes dot {
to {
transform: scale(1);
}
}
</style>
<clipPath id="clippath"><rect id="huyu-clippath" class="cls-1" x="291" width="292" height="583"/></clipPath>
<clipPath id="clippath-1"><polygon id="huyu-line3-clippath" class="cls-1" points="583 0 291 291.5 291 583 583 583 583 0"/></clipPath>
<clipPath id="clippath-2"><rect id="ki-bottom-clippath" class="cls-1" y="270" width="230" height="313"/></clipPath>
<clipPath id="clippath-3"><rect id="ki-top-clippath" class="cls-1" width="230" height="167"/></clipPath>
</defs>
<g id="huyu">
<g class="cls-2">
<circle id="huyu-dot2" cx="437" cy="513" r="30"/>
<circle id="huyu-dot1" cx="437" cy="383" r="30"/>
<g id="huyu-line3-mask">
<g class="cls-3">
<line id="huyu-line3" class="cls-6" x1="291.25" x2="582.38" y2="291.12"/>
</g>
</g>
<line id="huyu-line2" class="cls-6" x1="582.75" y1="-.25" x2="291" y2="291.5"/>
<line id="huyu-line1" class="cls-6" x1="436.75" y1="-.25" x2="145" y2="291.5"/>
</g>
</g>
<g id="ki">
<g id="ki-bottom">
<g class="cls-5">
<line id="ki-line3-bottom" class="cls-7" x1="215" y1="583" x2="215" y2="0"/>
<line id="ki-line2-bottom" class="cls-7" x1="15" y1="583" x2="15" y2="0"/>
</g>
</g>
<g id="ki-top">
<g class="cls-4">
<line id="ki-line3-top" class="cls-7" x1="215" y1="583" x2="215" y2="0"/>
<line id="ki-line2-top" class="cls-7" x1="15" y1="583" x2="15" y2="0"/>
</g>
</g>
<line id="ki-line1" class="cls-7" x1="115" x2="115" y2="583"/>
</g>
</svg>
解説
ストロークのアニメーション
.cls-6,.cls-7{
stroke-dasharray: 583;
stroke-dashoffset: 583;
animation: line 1.5s var(--ease-out-expo) forwards;
}
@keyframes line {
to {
stroke-dashoffset: 0;
}
}
stroke-dasharray
でストロークの長さと同じ長さの破線を作り、stroke-dashoffset
で破線の基準位置をずらしてあげる。
とりあえずstroke-dasharray: 1000;
とか適当な数字で紹介している記事もあるが、アニメーションのイージングや細かいタイミングの調整が難しくなるので、ここはちゃんと調整するべき。
その場で拡大するアニメーション
#huyu-dot1,#huyu-dot2{
transform: scale(0);
animation: dot 0.8s var(--ease-out-back) forwards;
}
#huyu-dot1{
animation-delay: 0.4s;
transform-origin: 74.96% 65.69%; /* (座標/viewBoxサイズ*100)% */
}
#huyu-dot2{
animation-delay: 0.6s;
transform-origin: 74.96% 87.99%; /* (座標/viewBoxサイズ*100)% */
}
transform: scale();
で拡大する場合、viewBox
の中心を基準に拡大してしまう。rotate
の場合は中心座標を指定できるがscale
だとできないので、transform-origin
を使っている。
「視差効果を減らす」への対応
prefers-reduced-motionメディアクエリの中にアニメーション関連の指示をまとめておくと、「視差効果を減らす」などOSのアクセシビリティ機能に対応できる。
reduce
が「視差効果を減らす」が有効な状態。no-preference
が「視差効果を減らす」の設定が行われていない状態。
img
か、svg
か、object
か、インラインか
実際にサイトに読み込むときにいつもimg
タグを使っていたのだが、img
の場合svg
ファイルが読み込まれた最初の1回目のみアニメーションが動き、その後の読み込みではキャッシュクリアしない限りアニメーションは動作しなかった。
インラインにしても良かったのだけど結構コードが長くなるし、svg
のuse
タグとかもsymbol
タグとか準備が面倒だったので、今回はobject
で行くことにした。
<a href="<?php echo home_url(); ?>">
<object type="image/svg+xml" data="<?php echo get_template_directory_uri(); ?>/images/logo_animation.svg" width="60" height="60" aria-label="<?php bloginfo('name'); ?>"></object>
</a>
この場合object
にマウスカーソルが吸われてa
要素がクリックできない。object
要素にpointer-events: none;
をかけて対処した。
コメント