<div class="other-28__layout">
<div class="other-28 js-other-28">
<div class="other-28__container"><svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path d="M384,46.469c-70.688,0-128,57.313-128,128.016c0-70.703-57.313-128.016-128-128.016S0,103.781,0,174.484 c0,66.484,31.313,193.391,218.563,276.234c11.844,5.25,35.703,14.469,35.703,14.469c0.547,0.219,1.141,0.344,1.734,0.344 s1.188-0.125,1.734-0.344c0,0,23.859-9.219,35.703-14.469C480.688,367.875,512,240.969,512,174.484 C512,103.781,454.688,46.469,384,46.469z"></path>
</svg></div>
<div class="other-28__particles">
<div class="other-28__particle"></div>
<div class="other-28__particle"></div>
<div class="other-28__particle"></div>
<div class="other-28__particle"></div>
<div class="other-28__particle"></div>
<div class="other-28__particle"></div>
</div>
</div>
<div class="other-28 js-other-28" style="--size: 32px; --color-active: #ffd000; --color-hover: #fdefaf; --color-decoration: #ffe880;">
<div class="other-28__container"><svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path d="M215.906,35.272C223.438,20.006,238.984,10.35,256,10.35s32.563,9.656,40.094,24.922l44.484,90.141 c6.516,13.188,19.094,22.344,33.656,24.453l99.484,14.453c16.844,2.453,30.828,14.25,36.094,30.438 c5.266,16.172,0.875,33.953-11.313,45.828l-71.984,70.156c-10.531,10.281-15.344,25.078-12.859,39.578l17,99.062 c2.875,16.781-4.031,33.734-17.797,43.734s-32.016,11.313-47.078,3.406l-88.984-46.781c-13.016-6.844-28.578-6.844-41.609,0 l-88.969,46.781c-15.063,7.906-33.313,6.594-47.078-3.406c-13.781-10-20.672-26.953-17.797-43.734l17-99.062 c2.484-14.5-2.328-29.297-12.859-39.578L13.5,240.584C1.313,228.709-3.078,210.928,2.188,194.756 c5.266-16.188,19.25-27.984,36.094-30.438l99.484-14.453c14.547-2.109,27.141-11.266,33.656-24.453L215.906,35.272z"></path>
</svg></div>
<div class="other-28__particles">
<div class="other-28__particle"></div>
<div class="other-28__particle"></div>
<div class="other-28__particle"></div>
<div class="other-28__particle"></div>
<div class="other-28__particle"></div>
<div class="other-28__particle"></div>
</div>
</div>
<div class="other-28 js-other-28" style="--size: 20px; --color-active: #00e9c6; --color-hover: #a2fff1; --color-decoration: #71ffea;">
<div class="other-28__container"><svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path d="M37.246,0v479.924c0,11.47,6.122,22.064,16.052,27.786c9.945,5.732,22.173,5.717,32.103-0.029l138.445-80.198 c19.889-11.514,44.42-11.514,64.309,0l138.453,80.198c9.922,5.746,22.158,5.761,32.088,0.029 c9.938-5.723,16.059-16.316,16.059-27.786V0H37.246z M359.816,208.419l-50.144,41.274c-1.922,1.583-2.762,4.147-2.129,6.564 l16.303,62.858c0.662,2.556-0.303,5.252-2.439,6.8c-2.129,1.554-4.994,1.635-7.219,0.221l-54.733-34.94 c-2.107-1.34-4.803-1.34-6.91,0l-54.74,34.94c-2.218,1.414-5.09,1.333-7.226-0.221c-2.129-1.547-3.094-4.243-2.431-6.8 l16.309-62.858c0.634-2.416-0.206-4.98-2.128-6.564l-50.144-41.274c-2.033-1.68-2.843-4.427-2.025-6.932 c0.818-2.512,3.086-4.265,5.709-4.427l64.824-3.904c2.49-0.155,4.671-1.738,5.584-4.058l23.749-60.442 c0.972-2.453,3.337-4.067,5.974-4.067c2.637,0,5.002,1.62,5.974,4.067l23.742,60.442c0.906,2.32,3.086,3.904,5.583,4.058 l64.824,3.904c2.638,0.162,4.9,1.915,5.717,4.427C362.659,203.992,361.856,206.739,359.816,208.419z"></path>
</svg></div>
<div class="other-28__particles">
<div class="other-28__particle"></div>
<div class="other-28__particle"></div>
<div class="other-28__particle"></div>
<div class="other-28__particle"></div>
<div class="other-28__particle"></div>
<div class="other-28__particle"></div>
</div>
</div>
</div>
.other-28__layout
//- ハート
.other-28.js-other-28
.other-28__container
svg(
version='1.1',
xmlns='http://www.w3.org/2000/svg',
viewBox='0 0 512 512',
)
path(d=path.heart)
.other-28__particles
- for (var i = 0; i < 6; i++)
.other-28__particle
//- 星
.other-28.js-other-28(
style='--size: 32px; --color-active: #ffd000; --color-hover: #fdefaf; --color-decoration: #ffe880;'
)
.other-28__container
svg(
version='1.1',
xmlns='http://www.w3.org/2000/svg',
viewBox='0 0 512 512',
)
path(d=path.star)
.other-28__particles
- for (var i = 0; i < 6; i++)
.other-28__particle
//- ブックマーク
.other-28.js-other-28(
style='--size: 20px; --color-active: #00e9c6; --color-hover: #a2fff1; --color-decoration: #71ffea;'
)
.other-28__container
svg(
version='1.1',
xmlns='http://www.w3.org/2000/svg',
viewBox='0 0 512 512',
)
path(d=path.bookmark)
.other-28__particles
- for (var i = 0; i < 6; i++)
.other-28__particle
{
"path": {
"heart": "M384,46.469c-70.688,0-128,57.313-128,128.016c0-70.703-57.313-128.016-128-128.016S0,103.781,0,174.484 c0,66.484,31.313,193.391,218.563,276.234c11.844,5.25,35.703,14.469,35.703,14.469c0.547,0.219,1.141,0.344,1.734,0.344 s1.188-0.125,1.734-0.344c0,0,23.859-9.219,35.703-14.469C480.688,367.875,512,240.969,512,174.484 C512,103.781,454.688,46.469,384,46.469z",
"star": "M215.906,35.272C223.438,20.006,238.984,10.35,256,10.35s32.563,9.656,40.094,24.922l44.484,90.141 c6.516,13.188,19.094,22.344,33.656,24.453l99.484,14.453c16.844,2.453,30.828,14.25,36.094,30.438 c5.266,16.172,0.875,33.953-11.313,45.828l-71.984,70.156c-10.531,10.281-15.344,25.078-12.859,39.578l17,99.062 c2.875,16.781-4.031,33.734-17.797,43.734s-32.016,11.313-47.078,3.406l-88.984-46.781c-13.016-6.844-28.578-6.844-41.609,0 l-88.969,46.781c-15.063,7.906-33.313,6.594-47.078-3.406c-13.781-10-20.672-26.953-17.797-43.734l17-99.062 c2.484-14.5-2.328-29.297-12.859-39.578L13.5,240.584C1.313,228.709-3.078,210.928,2.188,194.756 c5.266-16.188,19.25-27.984,36.094-30.438l99.484-14.453c14.547-2.109,27.141-11.266,33.656-24.453L215.906,35.272z",
"bookmark": "M37.246,0v479.924c0,11.47,6.122,22.064,16.052,27.786c9.945,5.732,22.173,5.717,32.103-0.029l138.445-80.198 c19.889-11.514,44.42-11.514,64.309,0l138.453,80.198c9.922,5.746,22.158,5.761,32.088,0.029 c9.938-5.723,16.059-16.316,16.059-27.786V0H37.246z M359.816,208.419l-50.144,41.274c-1.922,1.583-2.762,4.147-2.129,6.564 l16.303,62.858c0.662,2.556-0.303,5.252-2.439,6.8c-2.129,1.554-4.994,1.635-7.219,0.221l-54.733-34.94 c-2.107-1.34-4.803-1.34-6.91,0l-54.74,34.94c-2.218,1.414-5.09,1.333-7.226-0.221c-2.129-1.547-3.094-4.243-2.431-6.8 l16.309-62.858c0.634-2.416-0.206-4.98-2.128-6.564l-50.144-41.274c-2.033-1.68-2.843-4.427-2.025-6.932 c0.818-2.512,3.086-4.265,5.709-4.427l64.824-3.904c2.49-0.155,4.671-1.738,5.584-4.058l23.749-60.442 c0.972-2.453,3.337-4.067,5.974-4.067c2.637,0,5.002,1.62,5.974,4.067l23.742,60.442c0.906,2.32,3.086,3.904,5.583,4.058 l64.824,3.904c2.638,0.162,4.9,1.915,5.717,4.427C362.659,203.992,361.856,206.739,359.816,208.419z"
}
}
$BLOCK_NAME: '.other-28';
// 変数
// min関数のエラー回避:https://note.com/takamoso/n/n82cdb89f024f
$offset_decoration: unquote('min(-35%, -8px)');
$transition: 0.5s;
#{$BLOCK_NAME} {
// コンポーネント集のレイアウト用のクラス(実際のプロジェクトで利用するときは不要)
&__layout {
display: flex;
gap: 24px;
}
--size: 24px;
--color-base: #ddd;
--color-active: #f00;
--color-hover: #ff9cf0;
--color-decoration: #ff9cf0;
cursor: pointer;
position: relative;
width: var(--size);
height: var(--size);
&__container {
position: relative;
width: 100%;
height: 100%;
z-index: 2;
> svg {
fill: var(--color-base);
transition: fill 0.3s;
@at-root #{$BLOCK_NAME}:hover & {
fill: var(--color-hover);
}
@at-root #{$BLOCK_NAME}.--checked & {
fill: var(--color-active);
// transition: fill 0.3s;
// transition: fill $transition;
}
@at-root #{$BLOCK_NAME}.--checked.--anim & {
animation: other28Icon $transition forwards;
}
}
}
&__particles {
position: absolute;
top: $offset_decoration;
bottom: $offset_decoration;
left: $offset_decoration;
right: $offset_decoration;
z-index: 1;
pointer-events: none;
}
&__particle {
position: absolute;
top: 0;
// bottom: 50%;
bottom: 75%;
left: 0;
right: 0;
width: 4px;
margin: auto;
overflow: hidden;
border-radius: 9999px;
// transform-origin: bottom;
transform-origin: center 200%;
&:nth-child(1) {
transform: rotate(0);
}
&:nth-child(2) {
transform: rotate(60deg);
}
&:nth-child(3) {
transform: rotate(120deg);
}
&:nth-child(4) {
transform: rotate(180deg);
}
&:nth-child(5) {
transform: rotate(240deg);
}
&:nth-child(6) {
transform: rotate(300deg);
}
&::before {
content: '';
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: var(--color-decoration);
border-radius: 9999px;
transform: translateY(105%);
// opacity: 0;
transition: all 0s;
@at-root #{$BLOCK_NAME}.--checked.--anim & {
opacity: 1;
transform: translateY(-105%);
transition: all $transition;
}
}
}
}
@keyframes other28Icon {
0% {
transform: scale(1);
}
10% {
transform: scale(0.8);
}
50% {
transform: scale(1.2);
}
70% {
transform: scale(1);
}
100% {
transform: scale(1);
// fill: $c_active;
}
}
'use strict';
// import { gsap } from 'gsap';
export const other28 = () => {
const other = new Other28('.js-other-28');
other.init();
};
class Other28 {
els: NodeListOf<HTMLElement>;
constructor(selector: string) {
this.els = document.querySelectorAll(selector);
if (!this.els.length) return;
}
/**
* 初期化
*/
init(): void {
if (!this.els.length) return;
this.clickHandler();
}
/**
* クリックイベント設定
*/
clickHandler(): void {
[...this.els].forEach((el) => {
el.addEventListener('click', (e) => {
e.preventDefault();
const isChecked = el.classList.contains('--checked');
if (isChecked) {
el.classList.remove('--checked', '--anim');
} else {
el.classList.add('--checked', '--anim');
}
});
});
}
}