每條游來游去的小魚,都是正在瀏覽這一頁的訪客,有一條是你自己 ( ´ ▽ ` )ノ 覺得干擾閱讀的話,可以把小魚關掉。
當機卡片
card致敬 Windows XP 卡住時,視窗移動疊影 BUG
| 名稱 | 描述 |
|---|---|
| Pointer 事件 | 偵測滑鼠或觸控點移動、點擊、懸停等等事件,取得座標、目標等等資訊 |
| Canvas 2D API | 基礎的 2D 繪圖 API,可以高效繪製比 DOM 更複雜的圖形 |
| CSS 動畫 | 基於 CSS transition 和 animation 實現 |
| DOM to Image | 將 DOM 元素轉換為圖片的技術,基於 SVG foreignObject 實現 |
拉拉看視窗吧 ( ´ ▽ ` )ノ
Hello, Windows XP!
嘗試拖動這個視窗
<template> <div class="w-full flex flex-col gap-4 py-4"> <div class="flex items-center justify-center py-[8vh]"> <card-render-glitch v-slot="{ bindHandle }" :draggable class="window z-50 overflow-hidden border rounded-xl shadow-xl" > <div :ref="bindHandle" class="handle w-full flex items-center px-4" :class="draggable ? 'cursor-move' : 'cursor-no-drop'" > <div class="flex-1 select-none text-center text-sm font-medium"> Hello, Windows XP! </div>
<button class="mb-1 text-2xl"> × </button> </div>
<div class="flex flex-col gap-2 p-8 px-12"> <base-checkbox v-model="draggable" :label="t('enableDrag')" />
<p class="leading-relaxed"> {{ t('tryDrag') }} </p> </div> </card-render-glitch> </div> </div></template>
<script setup lang="ts">import { ref } from 'vue'import { useI18n } from 'vue-i18n'import BaseCheckbox from '../../base-checkbox.vue'import CardRenderGlitch from '../card-render-glitch.vue'
const draggable = ref(true)
const { t } = useI18n()</script>
<style lang="sass" scoped>:deep(.window) background: light-dark(#FFF, #1e1e1e) border-color: light-dark(#d0d0d0, #888) color: light-dark(#374151, #d1d5db) .handle background: light-dark(#f3f4f6, #111827) color: light-dark(#1f2937, #d1d5db)</style>將 DOM 轉換成圖片,然後不斷繪製圖片至 canvas。
如何將 DOM 變成 Image?
Section titled “如何將 DOM 變成 Image?”原本實作方式想說同 btn-ninja 一樣,使用 v-for 產生多個 default slot 內容,但是性能實在過於慘烈,所以改用 canvas 實現。
想是這麼想,這裡會遇到難題,要怎麼將 DOM 畫到 canvas 上?ლ(╹ε╹ლ)」
html2canvas 與 dom-to-image 都不太理想,後來發現 vfx.js 這個套件內有完整實作。
於是我就直接複製過來,並稍微修改成符合我需求的版本惹。◝( •ω• )◟
interface Props { draggable?: boolean; throttle?: number;}Methods
Section titled “Methods”interface Expose { clearArtifacts: () => void;}interface SlotScope { isDragging: boolean; /** * 用於綁定拖動把手 * @param el - 要綁定的元素 */ bindHandle: (el: any) => void;}
interface Slots { default?: (params: SlotScope) => unknown;}