banner
AgedCoffee

AgedCoffee

テクニカルノート

FixedForwardRef#

import React, { forwardRef } from " react";
// ジェネリックコンポーネントで動作する型を宣言
type FixedForwardRef = <T, P= {}>(
  render: (props: P, ref: React.Ref<T>)=> React.ReactNode
=> (props: P & React.RefAttributes<T>)=> React.ReactNode;

// 古い forwardRef を新しいものにキャスト
export const fixedForwardRef = forwardRef as FixedForwardRef;

## グラデーションボーダーの tailwind 実装

```tsx
export const AnimatedGradientBorderTW: React.FC<{
  children: React.ReactNode
}> = ({ children }) => {
  const boxRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    const boxElement = boxRef.current

    if (!boxElement) {
      return
    }

    const updateAnimation = () => {
      const angle = (parseFloat(boxElement.style.getPropertyValue('--angle')) + 0.5) % 360
      boxElement.style.setProperty('--angle', `${angle}deg`)
      requestAnimationFrame(updateAnimation)
    }

    requestAnimationFrame(updateAnimation)
  }, [])

  return (
    <div
      ref={boxRef}
      style={
        {
          '--angle': '0deg',
          '--border-color': 'linear-gradient(var(--angle), #070707, #687aff)',
          '--bg-color': 'linear-gradient(#131219, #131219)',
        } as CSSProperties
      }
      className="flex h-[400px] w-[400px] items-center justify-center rounded-lg border-2 border-[#0000] p-3 [background:padding-box_var(--bg-color),border-box_var(--border-color)]"
    >
      {children}
    </div>
  )
}

iOS H5 history.back () で前のルートに戻る際のページ白画面問題#

history.scrollRestoration を変更

history.back で前のページに戻るとき、ブラウザはページのスクロール位置を記録しますが、iOS ではスクロール後に戻るとページのレンダリングに問題が発生し、白画面になります。scrollRestoration 属性を利用できます。デフォルトは auto で、スクロール位置を記録します(これは H5 で追加された属性なので、ブラウザがサポートしているかを判断する必要があります。私の実践ではほとんどのモバイル端末に対応できます)。

if ('scrollRestoration' in history) {
  history.scrollRestoration = 'manual' // manual に変更すると、スクロール位置は記録されません
}

Vite の ws 転送設定#

L3PbXs

スクリーンのズーム比が変わったときのページの処理方法#

  1. ホームページの最初のモジュールのすべての 100vh を動的に calc(100vh * 2)に変更する必要があります。
  2. 動画の幅は 100% に調整する必要があります(動画の動きがなくなります)。
  3. ログインモーダルの内部のロジックをズーム処理に調整します。
  • 問題のある動作モジュールは直接表示しないことにします。
  • さらに、URS モーダルの CSS を注入して、Win と Mac を区別できます。

antd-mobile CSS 変数の上書き#

:root:root {
  --adm-button-border-radius: 2px;
}

nginx の一般的なパスプロキシ設定#

location /docs/zh {
  proxy_pass https://your.domain.com/zh/;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";
}

nginx ネットワークセグメント禁止設定#

server {
  listen       80;
  server_name  domain1.com www.domain1.com;
  access_log   logs/domain1.access.log  main;
  root         html;

  deny 61.135.0.0/16;
}

nginx-openresty ログ位置の確認#

rahGOt

Canvas ツール関数#

// 画像のサイズを調整
function imageUrl2ExactCanvas(image: HTMLImageElement, imageSize: LimitImageSize) {
  const cvs = document.createElement('canvas')
  const ctx = cvs.getContext('2d')
  const width = imageSize[0]
  const height = imageSize[1]
  cvs.width = width
  cvs.height = height
  ctx!.drawImage(image, 0, 0, cvs.width, cvs.height)
  image2white(ctx!, width, height)
  return cvs
}

// 画像の透明部分を白に変換
function image2white(ctx: CanvasRenderingContext2D, width: number, height: number) {
  let imageData = ctx!.getImageData(0, 0, width, height)
  for (let i = 0; i < imageData.data.length; i += 4) {
    // そのピクセルが透明な場合、白に設定
    if (imageData.data[i + 3] === 0) {
      imageData.data[i] = 255
      imageData.data[i + 1] = 255
      imageData.data[i + 2] = 255
      imageData.data[i + 3] = 255
    }
  }
  ctx!.putImageData(imageData, 0, 0)
}

/**
 * @param image 画像
 * @param backType 戻り値のタイプ blob, file
 * @param quality 画像圧縮比 0-1, 数字が小さいほど画像圧縮が小さくなる
 * @returns
 */
function compressorImage(image: File, backType?: 'blob' | 'file', quality?: number) {
  return new Promise((resolve, reject) => {
    new Compressor(image, {
      quality: quality || 0.8,
      success(result) {
        let file = new File([result], image.name, { type: image.type })

        if (!backType || backType === 'blob') {
          resolve(result)
        } else if (backType === 'file') {
          resolve(file)
        } else {
          resolve(file)
        }
      },
      error(err) {
        reject(err)
      },
    })
  })
}

nginx の正規表現リバースプロキシ設定#

resolver 8.8.8.8;

location ~ /xx/([0-9a-z]+).html {
  proxy_pass http://your.domain/xx/$1/
}

FFmpeg スクリプト#

ffmpeg -i video.mp4 -i audio.mp4 -c:v copy -c:a aac -strict experimental output.mp4

webpack4 に強力なローカルキャッシュを追加#

const HardSourceWebpackPlugin = require('hard-source-webpack-plugin')

plugins: [
  new HardSourceWebpackPlugin({
    cacheDirectory: path.resolve(__dirname, '../cache'),
  }),
]

nextjs でプロジェクト外の .ts, .tsx ファイルのコンパイルをサポート#

const nextConfig = {
  webpack: (config, options) => {
    config.module.rules.forEach((rule) => {
      if (rule.test && rule.test.toString().includes('tsx|ts')) {
        rule.include = [...rule.include, path.resolve(__dirname, '../common-package/src')]
      }
      if (Array.isArray(rule.oneOf)) {
        rule.oneOf.forEach((rule_inner) => {
          if (rule_inner.test && rule_inner.test.toString().includes('tsx|ts')) {
            rule_inner.include = [
              ...rule_inner.include,
              path.resolve(__dirname, '../common-package/src'),
            ]
          }
        })
      }
    })
    return config
  },
}

H5 の使用テクニック#

// 1、カメラをキャッチ、user は前面カメラ、environment は背面カメラを示します
<input type="file" capture="user" accept="image/*" />

// 2、10 秒ごとにリフレッシュ
<meta http-equiv="refresh" content="10" />

// 3、input 入力ボックスのスペルチェックを有効にする
<input type="text" spellcheck="true" lang="en" />

// 4、ファイルをアップロードする際に許可されるファイル形式を指定
<input type="file" accept=".jpeg,.png" />

// 5、ブラウザの翻訳を防ぐ、ロゴやブランド名などのシーンに適用
<p translate="no">ブランド名</p>

// 6、複数のファイルを選択できるようにする
<input type="file" multiple />

// 7、video タグにサムネイルを追加
<video poster="picture.png"></video>

// 8、リソースファイルのダウンロードを宣言
<a href="image.png" download></a>

vite と whistle を組み合わせてローカル環境の server-hmr 設定を実行#

server: {
  hmr: {
    protocol: 'ws',
    host: 'localhost',
    },
  },
読み込み中...
ページは、創作者によって署名され、ブロックチェーンに安全に保存されています。