npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@edv4h/usketch-plugin-shape-card

v1.3.1

Published

トランプ・UNO・メディアカード等を表現できる **card-type 拡張ポイント**を持つカードシェイプ・プラグイン。 カードは表/裏を持ち、**ダブルクリックで裏返し(flip)**でき、**配置時アニメーション**と **デッキ(山札)機構**を備える。

Readme

@edv4h/usketch-plugin-shape-card

トランプ・UNO・メディアカード等を表現できる card-type 拡張ポイントを持つカードシェイプ・プラグイン。 カードは表/裏を持ち、**ダブルクリックで裏返し(flip)**でき、配置時アニメーションデッキ(山札)機構を備える。

使い方

このプラグインはコア機構のみを提供し、card-type は既定では空です。 トランプ等は同梱の**サンプル(EXAMPLE_CARD_TYPES)**で、明示的に渡したときだけ有効になります。 (card-type が1つも無いと描画ツールは表示されません。)

import { createCardPlugin, EXAMPLE_CARD_TYPES } from "@edv4h/usketch-plugin-shape-card";

createApp({
  plugins: [
    // サンプル(media / playing-card / uno / custom)を使う:
    createCardPlugin({ cardTypes: EXAMPLE_CARD_TYPES }),
    // 自前の card-type だけにするなら:
    // createCardPlugin({ cardTypes: [myCardType] }),
    // 空でも生成可能(描画ツールは出ない):
    // createCardPlugin(),
  ],
});

ツール(card-type が1つ以上ある場合のみ表示):

  • card-draw(ショートカット k)— カードを描画。ドラッグでサイズ(アスペクト比固定)、クリックで既定サイズ。
  • card-deck-draw — 山札を配置。

インタラクション:

  • カードをダブルクリックで裏返し(0.4s の 3D フリップ)。
  • 山札をダブルクリックで1枚ドロー(最前面に配置)。
  • 山札を選択して Shift+S でシャッフル。
  • カード/山札はアスペクト比を保ったままのみリサイズ可能。

card-type の追加

CardTypeDefinition を満たすオブジェクトを createCardPlugin に渡す:

import { createCardPlugin, type CardTypeDefinition } from "@edv4h/usketch-plugin-shape-card";

interface TarotFields { name: string; }

const tarotCardType: CardTypeDefinition<TarotFields> = {
  id: "tarot",
  label: "タロット",
  icon: () => <svg width="16" height="16" viewBox="0 0 16 16">{/* ... */}</svg>,
  defaultSize: { width: 120, height: 210 },
  aspectRatio: 120 / 210,
  createDefaultFields: () => ({ name: "The Fool" }),
  renderFront: (f) => <div>{f.name}</div>,
  renderBack: () => <div>★</div>,
  placementAnimation: { preset: "deal" },
  buildDeck: () => [/* 78枚 */],
};

createCardPlugin({ cardTypes: [tarotCardType] });

サンプル card-type: media / playing-card / uno / customEXAMPLE_CARD_TYPES)。既定では未登録なので、使うときに明示的に渡す。

テクスチャ + テキスト配置(custom card-type / CardFace

コードを書かずに、表/裏それぞれの**テクスチャ(背景画像・色・グラデーション)**と、 テキストの配置を細かく指定できます。サンプルの custom card-type が meta.fields{ front: CardFace; back: CardFace } を持ち、データ差し替えだけで見た目を完全制御できます。

import type { CardFace } from "@edv4h/usketch-plugin-shape-card";

const front: CardFace = {
  texture: { image: "https://.../bg.png", fit: "cover" }, // cover|contain|fill|tile / color も可
  texts: [
    {
      text: "見出し",
      x: 0.5, y: 0.2,          // 既定は割合(ratio, 0..1)。unit:"px" で px 指定も可
      align: "center", vAlign: "middle", // アンカー(x,y が指す基準点)
      rotation: -6,            // 回転(度)
      fontSize: 24, fontWeight: 700, color: "#fff",
      letterSpacing: 2, lineHeight: 1.4, maxWidth: 200, // maxWidth で折り返し
    },
  ],
};
  • 位置は unit: "ratio"(既定・リサイズ追従)か "px"
  • align / vAlign で x,y がテキストのどこを指すか(左上・中央・右下など)を決定。
  • renderFace(face) をエクスポートしているので、独自 card-type の renderFront/renderBack でも再利用できます。

カード / デッキの生成(ファクトリ)

生成は「データ作り」なので、store.addShape に渡せる shape データを返す純ファクトリを提供します (ツールも内部でこれを使っています)。Undo したい場合は createAddShapeCommand に渡します。

import { createCardShape, createDeckShape } from "@edv4h/usketch-plugin-shape-card";

// 1枚配置
store.addShape(createCardShape(myCardType, { x, y }));

// 既定デッキ(card-type の buildDeck() を使用)
store.addShape(createDeckShape(myCardType, { x, y }));

// 可変デッキ(TCG の構築済みデッキなど): cards を明示的に渡す
store.addShape(
  createDeckShape(myTcgType, { x, y, cards: playerDeckList /* 先頭が山の一番上 */ }),
);

cards は任意の配列なので、固定構成だけでなく**プレイヤーが組んだ山(TCG)**も表現できます。 ドロー(ダブルクリック)/シャッフル(Shift+S)はこの配列に対して動きます。

オプション

createCardPlugin({
  cardTypes,                         // 追加 card-type
  placementAnimation: { preset: "drop" }, // 既定の配置アニメ(card-type 個別指定が優先)
  enableDeck: true,                  // デッキ機構の ON/OFF(既定 true)
});

配置アニメは次のいずれか:

  • プリセット { preset: "deal" | "drop" | "bounce" | "none" }
  • Slam(ドン!) { preset: "slam-light" | "slam-medium" | "slam-heavy" } — 重みのある着地。 **一瞬持ち上がってから加速して着地(ズドン)**し、衝撃リング + 全周への放射状飛沫がカードの外側に弾ける。 重いほど大きく・ゆっくり(light < medium < heavy)。 組込例では playing-card = slam-medium、uno = slam-heavy
  • 独自 { keyframes: string; durationMs: number; easing?: string }

Slam の見た目・重み3段階は Claude Design の「Card Animations」ショーケース(Slam Place)を移植したもの。 ドロップ/移動(shapes:move-end)/ドロー時に、配置点を中心とした一発の衝撃エフェクトとして再生される。

アーキテクチャ

  • データモデルは ShapeData<CardMeta> / ShapeData<DeckMeta>generic(meta) 方式。
  • 単一 card shape type + meta.cardType ディスクリミネータ + 内部 card-type レジストリ。
  • 配置アニメは ctx.transient(ripple と同じ transient レイヤー)で実装。
  • 山札は card データ配列を保持するデータパイル方式(枚数分の shape を作らない)。