mirror of
https://github.com/DavidHDev/vue-bits.git
synced 2026-04-21 17:44:39 -06:00
Resolve merge conflicts: sync OrbitImagesDemo.vue and registry JSON files with main
Co-authored-by: DavidHDev <48634587+DavidHDev@users.noreply.github.com>
This commit is contained in:
Generated
+1
-1
@@ -55,7 +55,7 @@
|
||||
"typescript": "~5.8.0",
|
||||
"vite": "^7.0.0",
|
||||
"vite-plugin-vue-devtools": "^7.7.7",
|
||||
"vue-tsc": "^2.2.10"
|
||||
"vue-tsc": "^2.2.12"
|
||||
}
|
||||
},
|
||||
"node_modules/@alvarosabu/utils": {
|
||||
|
||||
+1
-1
@@ -64,7 +64,7 @@
|
||||
"typescript": "~5.8.0",
|
||||
"vite": "^7.0.0",
|
||||
"vite-plugin-vue-devtools": "^7.7.7",
|
||||
"vue-tsc": "^2.2.10"
|
||||
"vue-tsc": "^2.2.12"
|
||||
},
|
||||
"lint-staged": {
|
||||
"src/**/*.{js,ts,jsx,tsx,vue}": [
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
{"name":"Counter","title":"Counter","description":"Flexible animated counter supporting increments + easing.","type":"registry:component","add":"when-added","files":[{"type":"registry:component","role":"file","content":"<template>\n <div class=\"relative inline-block\" :style=\"containerStyle\">\n <div class=\"flex overflow-hidden\" :style=\"counterStyles\">\n <div v-for=\"place in places\" :key=\"place\" class=\"relative w-[1ch] tabular-nums\" :style=\"digitStyles\">\n <Motion\n v-for=\"digit in 10\"\n :key=\"digit - 1\"\n tag=\"span\"\n class=\"absolute top-0 left-0 w-full h-full flex items-center justify-center\"\n :animate=\"{ y: getDigitPosition(place, digit - 1) }\"\n >\n {{ digit - 1 }}\n </Motion>\n </div>\n </div>\n <div class=\"pointer-events-none absolute inset-0\">\n <div class=\"absolute top-0 w-full\" :style=\"topGradientStyle ?? topGradientStyles\" />\n <div class=\"absolute bottom-0 w-full\" :style=\"bottomGradientStyle ?? bottomGradientStyles\" />\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue';\nimport { Motion } from 'motion-v';\nimport type { CSSProperties } from 'vue';\n\ninterface CounterProps {\n value: number;\n fontSize?: number;\n padding?: number;\n places?: number[];\n gap?: number;\n borderRadius?: number;\n horizontalPadding?: number;\n textColor?: string;\n fontWeight?: string | number;\n containerStyle?: CSSProperties;\n counterStyle?: CSSProperties;\n digitStyle?: CSSProperties;\n gradientHeight?: number;\n gradientFrom?: string;\n gradientTo?: string;\n topGradientStyle?: CSSProperties;\n bottomGradientStyle?: CSSProperties;\n}\n\nconst props = withDefaults(defineProps<CounterProps>(), {\n fontSize: 100,\n padding: 0,\n places: () => [100, 10, 1],\n gap: 8,\n borderRadius: 4,\n horizontalPadding: 8,\n textColor: 'white',\n fontWeight: 'bold',\n containerStyle: () => ({}),\n counterStyle: () => ({}),\n digitStyle: () => ({}),\n gradientHeight: 16,\n gradientFrom: 'black',\n gradientTo: 'transparent',\n topGradientStyle: undefined,\n bottomGradientStyle: undefined\n});\n\nconst digitHeight = computed(() => props.fontSize + props.padding);\n\nconst counterStyles = computed(() => ({\n fontSize: `${props.fontSize}px`,\n gap: `${props.gap}px`,\n borderRadius: `${props.borderRadius}px`,\n paddingLeft: `${props.horizontalPadding}px`,\n paddingRight: `${props.horizontalPadding}px`,\n color: props.textColor,\n fontWeight: props.fontWeight,\n ...props.counterStyle\n}));\n\nconst digitStyles = computed(() => ({\n height: `${digitHeight.value}px`,\n ...props.digitStyle\n}));\n\nconst topGradientStyles = computed(\n (): CSSProperties => ({\n height: `${props.gradientHeight}px`,\n background: `linear-gradient(to bottom, ${props.gradientFrom}, ${props.gradientTo})`\n })\n);\n\nconst bottomGradientStyles = computed(\n (): CSSProperties => ({\n height: `${props.gradientHeight}px`,\n background: `linear-gradient(to top, ${props.gradientFrom}, ${props.gradientTo})`\n })\n);\n\nconst springValues = ref<Record<number, number>>({});\n\nconst initializeSpringValues = () => {\n props.places.forEach(place => {\n springValues.value[place] = Math.floor(props.value / place);\n });\n};\n\ninitializeSpringValues();\n\nwatch(\n () => props.value,\n (newValue, oldValue) => {\n if (newValue === oldValue) return;\n\n props.places.forEach(place => {\n const newRoundedValue = Math.floor(newValue / place);\n const oldRoundedValue = springValues.value[place];\n\n if (newRoundedValue !== oldRoundedValue) {\n springValues.value[place] = newRoundedValue;\n }\n });\n },\n { immediate: true }\n);\n\nwatch(\n () => digitHeight.value,\n () => {\n positionCache.clear();\n }\n);\n\nconst positionCache = new Map<string, number>();\n\nconst getDigitPosition = (place: number, digit: number): number => {\n const springValue = springValues.value[place] || 0;\n const cacheKey = `${place}-${digit}-${springValue}`;\n\n if (positionCache.has(cacheKey)) {\n return positionCache.get(cacheKey)!;\n }\n\n const placeValue = springValue % 10;\n const offset = (10 + digit - placeValue) % 10;\n let position = offset * digitHeight.value;\n\n if (offset > 5) {\n position -= 10 * digitHeight.value;\n }\n\n if (positionCache.size > 200) {\n const firstKey = positionCache.keys().next().value;\n if (typeof firstKey === 'string') {\n positionCache.delete(firstKey);\n }\n }\n\n positionCache.set(cacheKey, position);\n return position;\n};\n</script>\n","path":"Counter/Counter.vue","_imports_":[],"registryDependencies":[],"dependencies":[],"devDependencies":[]}],"registryDependencies":[],"dependencies":[{"ecosystem":"js","name":"motion-v","version":"^1.10.2"}],"devDependencies":[],"categories":["Components"]}
|
||||
{"name":"Counter","title":"Counter","description":"Flexible animated counter supporting increments + easing.","type":"registry:component","add":"when-added","files":[{"type":"registry:component","role":"file","content":"<template>\n <div class=\"relative inline-block\" :style=\"containerStyle\">\n <div class=\"flex overflow-hidden\" :style=\"counterStyles\">\n <div v-for=\"place in places\" :key=\"place\" class=\"relative w-[1ch] tabular-nums\" :style=\"digitStyles\">\n <Motion\n v-for=\"digit in 10\"\n :key=\"digit - 1\"\n tag=\"span\"\n class=\"absolute top-0 left-0 w-full h-full flex items-center justify-center\"\n :animate=\"{ y: getDigitPosition(place, digit - 1) }\"\n >\n {{ digit - 1 }}\n </Motion>\n </div>\n </div>\n <div class=\"pointer-events-none absolute inset-0\">\n <div class=\"absolute top-0 w-full\" :style=\"topGradientStyle ?? topGradientStyles\" />\n <div class=\"absolute bottom-0 w-full\" :style=\"bottomGradientStyle ?? bottomGradientStyles\" />\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue';\nimport { Motion } from 'motion-v';\nimport type { CSSProperties } from 'vue';\n\ninterface CounterProps {\n value: number;\n fontSize?: number;\n padding?: number;\n places?: number[];\n gap?: number;\n borderRadius?: number;\n horizontalPadding?: number;\n textColor?: string;\n fontWeight?: string | number;\n containerStyle?: CSSProperties;\n counterStyle?: CSSProperties;\n digitStyle?: CSSProperties;\n gradientHeight?: number;\n gradientFrom?: string;\n gradientTo?: string;\n topGradientStyle?: CSSProperties;\n bottomGradientStyle?: CSSProperties;\n}\n\nconst props = withDefaults(defineProps<CounterProps>(), {\n fontSize: 100,\n padding: 0,\n places: () => [100, 10, 1],\n gap: 8,\n borderRadius: 4,\n horizontalPadding: 8,\n textColor: 'white',\n fontWeight: 'bold',\n containerStyle: () => ({}),\n counterStyle: () => ({}),\n digitStyle: () => ({}),\n gradientHeight: 16,\n gradientFrom: 'black',\n gradientTo: 'transparent',\n topGradientStyle: undefined,\n bottomGradientStyle: undefined\n});\n\nconst digitHeight = computed(() => props.fontSize + props.padding);\n\nconst counterStyles = computed(() => ({\n fontSize: `${props.fontSize}px`,\n gap: `${props.gap}px`,\n borderRadius: `${props.borderRadius}px`,\n paddingLeft: `${props.horizontalPadding}px`,\n paddingRight: `${props.horizontalPadding}px`,\n color: props.textColor,\n fontWeight: props.fontWeight,\n ...props.counterStyle\n}));\n\nconst digitStyles = computed(() => ({\n height: `${digitHeight.value}px`,\n ...props.digitStyle\n}));\n\nconst topGradientStyles = computed(\n (): CSSProperties => ({\n height: `${props.gradientHeight}px`,\n background: `linear-gradient(to bottom, ${props.gradientFrom}, ${props.gradientTo})`\n })\n);\n\nconst bottomGradientStyles = computed(\n (): CSSProperties => ({\n height: `${props.gradientHeight}px`,\n background: `linear-gradient(to top, ${props.gradientFrom}, ${props.gradientTo})`\n })\n);\n\nconst springValues = ref<Record<number, number>>({});\n\nconst initializeSpringValues = () => {\n props.places.forEach(place => {\n springValues.value[place] = Math.floor(props.value / place);\n });\n};\n\ninitializeSpringValues();\n\nwatch(\n () => props.value,\n (newValue, oldValue) => {\n if (newValue === oldValue) return;\n\n props.places.forEach(place => {\n const newRoundedValue = Math.floor(newValue / place);\n const oldRoundedValue = springValues.value[place];\n\n if (newRoundedValue !== oldRoundedValue) {\n springValues.value[place] = newRoundedValue;\n }\n });\n },\n { immediate: true }\n);\n\nwatch(\n () => digitHeight.value,\n () => {\n positionCache.clear();\n }\n);\n\nconst positionCache = new Map<string, number>();\n\nconst getDigitPosition = (place: number, digit: number): number => {\n const springValue = springValues.value[place] || 0;\n const cacheKey = `${place}-${digit}-${springValue}`;\n\n if (positionCache.has(cacheKey)) {\n return positionCache.get(cacheKey)!;\n }\n\n const placeValue = springValue % 10;\n const offset = (10 + digit - placeValue) % 10;\n let position = offset * digitHeight.value;\n\n if (offset > 5) {\n position -= 10 * digitHeight.value;\n }\n\n if (positionCache.size > 200) {\n const firstKey = positionCache.keys().next().value;\n if (typeof firstKey === 'string') {\n positionCache.delete(firstKey);\n }\n }\n\n positionCache.set(cacheKey, position);\n return position;\n};\n</script>\n","path":"Counter/Counter.vue","_imports_":[],"registryDependencies":[],"dependencies":[],"devDependencies":[]}],"registryDependencies":[],"dependencies":[{"ecosystem":"js","name":"motion-v","version":"^1.5.0"}],"devDependencies":[],"categories":["Components"]}
|
||||
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
{"name":"TiltedCard","title":"TiltedCard","description":"3D perspective tilt card reacting to pointer.","type":"registry:component","add":"when-added","files":[{"type":"registry:component","role":"file","content":"<template>\n <figure\n ref=\"cardRef\"\n class=\"relative w-full h-full [perspective:800px] flex flex-col items-center justify-center\"\n :style=\"{\n height: containerHeight,\n width: containerWidth\n }\"\n @mousemove=\"handleMouse\"\n @mouseenter=\"handleMouseEnter\"\n @mouseleave=\"handleMouseLeave\"\n >\n <div v-if=\"showMobileWarning\" class=\"absolute top-4 text-center text-sm block sm:hidden\">\n This effect is not optimized for mobile. Check on desktop.\n </div>\n\n <Motion\n tag=\"div\"\n class=\"relative [transform-style:preserve-3d]\"\n :style=\"{\n width: imageWidth,\n height: imageHeight\n }\"\n :animate=\"{\n rotateX: rotateXValue,\n rotateY: rotateYValue,\n scale: scaleValue\n }\"\n :transition=\"springTransition\"\n >\n <img\n :src=\"imageSrc\"\n :alt=\"altText\"\n class=\"absolute top-0 left-0 object-cover rounded-[15px] will-change-transform [transform:translateZ(0)]\"\n :style=\"{\n width: imageWidth,\n height: imageHeight\n }\"\n />\n\n <Motion\n v-if=\"displayOverlayContent && overlayContent\"\n tag=\"div\"\n class=\"absolute top-0 left-0 z-[2] will-change-transform [transform:translateZ(30px)]\"\n >\n <slot name=\"overlay\" />\n </Motion>\n </Motion>\n\n <Motion\n v-if=\"showTooltip && captionText\"\n tag=\"figcaption\"\n class=\"pointer-events-none absolute left-0 top-0 rounded-[4px] bg-white px-[10px] py-[4px] text-[10px] text-[#2d2d2d] opacity-0 z-[3] hidden sm:block\"\n :animate=\"{\n x: xValue,\n y: yValue,\n opacity: opacityValue,\n rotate: rotateFigcaptionValue\n }\"\n :transition=\"tooltipTransition\"\n >\n {{ captionText }}\n </Motion>\n </figure>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, useTemplateRef } from 'vue';\nimport { Motion } from 'motion-v';\n\ninterface TiltedCardProps {\n imageSrc: string;\n altText?: string;\n captionText?: string;\n containerHeight?: string;\n containerWidth?: string;\n imageHeight?: string;\n imageWidth?: string;\n scaleOnHover?: number;\n rotateAmplitude?: number;\n showMobileWarning?: boolean;\n showTooltip?: boolean;\n overlayContent?: boolean;\n displayOverlayContent?: boolean;\n}\n\nconst props = withDefaults(defineProps<TiltedCardProps>(), {\n altText: 'Tilted card image',\n captionText: '',\n containerHeight: '300px',\n containerWidth: '100%',\n imageHeight: '300px',\n imageWidth: '300px',\n scaleOnHover: 1.1,\n rotateAmplitude: 14,\n showMobileWarning: true,\n showTooltip: true,\n overlayContent: false,\n displayOverlayContent: false\n});\n\nconst cardRef = useTemplateRef<HTMLElement>('cardRef');\nconst xValue = ref(0);\nconst yValue = ref(0);\nconst rotateXValue = ref(0);\nconst rotateYValue = ref(0);\nconst scaleValue = ref(1);\nconst opacityValue = ref(0);\nconst rotateFigcaptionValue = ref(0);\nconst lastY = ref(0);\n\nconst springTransition = computed(() => ({\n type: 'spring' as const,\n damping: 30,\n stiffness: 100,\n mass: 2\n}));\n\nconst tooltipTransition = computed(() => ({\n type: 'spring' as const,\n damping: 30,\n stiffness: 350,\n mass: 1\n}));\n\nfunction handleMouse(e: MouseEvent) {\n if (!cardRef.value) return;\n\n const rect = cardRef.value.getBoundingClientRect();\n const offsetX = e.clientX - rect.left - rect.width / 2;\n const offsetY = e.clientY - rect.top - rect.height / 2;\n\n const rotationX = (offsetY / (rect.height / 2)) * -props.rotateAmplitude;\n const rotationY = (offsetX / (rect.width / 2)) * props.rotateAmplitude;\n\n rotateXValue.value = rotationX;\n rotateYValue.value = rotationY;\n\n xValue.value = e.clientX - rect.left;\n yValue.value = e.clientY - rect.top;\n\n const velocityY = offsetY - lastY.value;\n rotateFigcaptionValue.value = -velocityY * 0.6;\n lastY.value = offsetY;\n}\n\nfunction handleMouseEnter() {\n scaleValue.value = props.scaleOnHover;\n opacityValue.value = 1;\n}\n\nfunction handleMouseLeave() {\n opacityValue.value = 0;\n scaleValue.value = 1;\n rotateXValue.value = 0;\n rotateYValue.value = 0;\n rotateFigcaptionValue.value = 0;\n}\n</script>\n","path":"TiltedCard/TiltedCard.vue","_imports_":[],"registryDependencies":[],"dependencies":[],"devDependencies":[]}],"registryDependencies":[],"dependencies":[{"ecosystem":"js","name":"motion-v","version":"^1.10.2"}],"devDependencies":[],"categories":["Components"]}
|
||||
{"name":"TiltedCard","title":"TiltedCard","description":"3D perspective tilt card reacting to pointer.","type":"registry:component","add":"when-added","files":[{"type":"registry:component","role":"file","content":"<template>\n <figure\n ref=\"cardRef\"\n class=\"relative w-full h-full [perspective:800px] flex flex-col items-center justify-center\"\n :style=\"{\n height: containerHeight,\n width: containerWidth\n }\"\n @mousemove=\"handleMouse\"\n @mouseenter=\"handleMouseEnter\"\n @mouseleave=\"handleMouseLeave\"\n >\n <div v-if=\"showMobileWarning\" class=\"absolute top-4 text-center text-sm block sm:hidden\">\n This effect is not optimized for mobile. Check on desktop.\n </div>\n\n <Motion\n tag=\"div\"\n class=\"relative [transform-style:preserve-3d]\"\n :style=\"{\n width: imageWidth,\n height: imageHeight\n }\"\n :animate=\"{\n rotateX: rotateXValue,\n rotateY: rotateYValue,\n scale: scaleValue\n }\"\n :transition=\"springTransition\"\n >\n <img\n :src=\"imageSrc\"\n :alt=\"altText\"\n class=\"absolute top-0 left-0 object-cover rounded-[15px] will-change-transform [transform:translateZ(0)]\"\n :style=\"{\n width: imageWidth,\n height: imageHeight\n }\"\n />\n\n <Motion\n v-if=\"displayOverlayContent && overlayContent\"\n tag=\"div\"\n class=\"absolute top-0 left-0 z-[2] will-change-transform [transform:translateZ(30px)]\"\n >\n <slot name=\"overlay\" />\n </Motion>\n </Motion>\n\n <Motion\n v-if=\"showTooltip && captionText\"\n tag=\"figcaption\"\n class=\"pointer-events-none absolute left-0 top-0 rounded-[4px] bg-white px-[10px] py-[4px] text-[10px] text-[#2d2d2d] opacity-0 z-[3] hidden sm:block\"\n :animate=\"{\n x: xValue,\n y: yValue,\n opacity: opacityValue,\n rotate: rotateFigcaptionValue\n }\"\n :transition=\"tooltipTransition\"\n >\n {{ captionText }}\n </Motion>\n </figure>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, useTemplateRef } from 'vue';\nimport { Motion } from 'motion-v';\n\ninterface TiltedCardProps {\n imageSrc: string;\n altText?: string;\n captionText?: string;\n containerHeight?: string;\n containerWidth?: string;\n imageHeight?: string;\n imageWidth?: string;\n scaleOnHover?: number;\n rotateAmplitude?: number;\n showMobileWarning?: boolean;\n showTooltip?: boolean;\n overlayContent?: boolean;\n displayOverlayContent?: boolean;\n}\n\nconst props = withDefaults(defineProps<TiltedCardProps>(), {\n altText: 'Tilted card image',\n captionText: '',\n containerHeight: '300px',\n containerWidth: '100%',\n imageHeight: '300px',\n imageWidth: '300px',\n scaleOnHover: 1.1,\n rotateAmplitude: 14,\n showMobileWarning: true,\n showTooltip: true,\n overlayContent: false,\n displayOverlayContent: false\n});\n\nconst cardRef = useTemplateRef<HTMLElement>('cardRef');\nconst xValue = ref(0);\nconst yValue = ref(0);\nconst rotateXValue = ref(0);\nconst rotateYValue = ref(0);\nconst scaleValue = ref(1);\nconst opacityValue = ref(0);\nconst rotateFigcaptionValue = ref(0);\nconst lastY = ref(0);\n\nconst springTransition = computed(() => ({\n type: 'spring' as const,\n damping: 30,\n stiffness: 100,\n mass: 2\n}));\n\nconst tooltipTransition = computed(() => ({\n type: 'spring' as const,\n damping: 30,\n stiffness: 350,\n mass: 1\n}));\n\nfunction handleMouse(e: MouseEvent) {\n if (!cardRef.value) return;\n\n const rect = cardRef.value.getBoundingClientRect();\n const offsetX = e.clientX - rect.left - rect.width / 2;\n const offsetY = e.clientY - rect.top - rect.height / 2;\n\n const rotationX = (offsetY / (rect.height / 2)) * -props.rotateAmplitude;\n const rotationY = (offsetX / (rect.width / 2)) * props.rotateAmplitude;\n\n rotateXValue.value = rotationX;\n rotateYValue.value = rotationY;\n\n xValue.value = e.clientX - rect.left;\n yValue.value = e.clientY - rect.top;\n\n const velocityY = offsetY - lastY.value;\n rotateFigcaptionValue.value = -velocityY * 0.6;\n lastY.value = offsetY;\n}\n\nfunction handleMouseEnter() {\n scaleValue.value = props.scaleOnHover;\n opacityValue.value = 1;\n}\n\nfunction handleMouseLeave() {\n opacityValue.value = 0;\n scaleValue.value = 1;\n rotateXValue.value = 0;\n rotateYValue.value = 0;\n rotateFigcaptionValue.value = 0;\n}\n</script>\n","path":"TiltedCard/TiltedCard.vue","_imports_":[],"registryDependencies":[],"dependencies":[],"devDependencies":[]}],"registryDependencies":[],"dependencies":[{"ecosystem":"js","name":"motion-v","version":"^1.5.0"}],"devDependencies":[],"categories":["Components"]}
|
||||
File diff suppressed because one or more lines are too long
@@ -23,21 +23,71 @@
|
||||
</div>
|
||||
|
||||
<Customize>
|
||||
<PreviewSelect title="Shape" v-model="shape" :options="shapeOptions" />
|
||||
<PreviewSelect
|
||||
title="Shape"
|
||||
v-model="shape"
|
||||
:options="shapeOptions"
|
||||
/>
|
||||
|
||||
<PreviewSelect title="Direction" v-model="direction" :options="directionOptions" />
|
||||
<PreviewSelect
|
||||
title="Direction"
|
||||
v-model="direction"
|
||||
:options="directionOptions"
|
||||
/>
|
||||
|
||||
<PreviewSlider title="Radius X" v-model="radiusX" :min="50" :max="600" :step="10" value-unit="px" />
|
||||
<PreviewSlider
|
||||
title="Radius X"
|
||||
v-model="radiusX"
|
||||
:min="50"
|
||||
:max="600"
|
||||
:step="10"
|
||||
value-unit="px"
|
||||
/>
|
||||
|
||||
<PreviewSlider title="Radius Y" v-model="radiusY" :min="50" :max="600" :step="10" value-unit="px" />
|
||||
<PreviewSlider
|
||||
title="Radius Y"
|
||||
v-model="radiusY"
|
||||
:min="50"
|
||||
:max="600"
|
||||
:step="10"
|
||||
value-unit="px"
|
||||
/>
|
||||
|
||||
<PreviewSlider title="Radius" v-model="radius" :min="50" :max="600" :step="10" value-unit="px" />
|
||||
<PreviewSlider
|
||||
title="Radius"
|
||||
v-model="radius"
|
||||
:min="50"
|
||||
:max="600"
|
||||
:step="10"
|
||||
value-unit="px"
|
||||
/>
|
||||
|
||||
<PreviewSlider title="Rotation" v-model="rotation" :min="-180" :max="180" :step="1" value-unit="°" />
|
||||
<PreviewSlider
|
||||
title="Rotation"
|
||||
v-model="rotation"
|
||||
:min="-180"
|
||||
:max="180"
|
||||
:step="1"
|
||||
value-unit="°"
|
||||
/>
|
||||
|
||||
<PreviewSlider title="Duration" v-model="duration" :min="5" :max="120" :step="5" value-unit="s" />
|
||||
<PreviewSlider
|
||||
title="Duration"
|
||||
v-model="duration"
|
||||
:min="5"
|
||||
:max="120"
|
||||
:step="5"
|
||||
value-unit="s"
|
||||
/>
|
||||
|
||||
<PreviewSlider title="Item Size" v-model="itemSize" :min="20" :max="120" :step="4" value-unit="px" />
|
||||
<PreviewSlider
|
||||
title="Item Size"
|
||||
v-model="itemSize"
|
||||
:min="20"
|
||||
:max="120"
|
||||
:step="4"
|
||||
value-unit="px"
|
||||
/>
|
||||
|
||||
<PreviewSwitch title="Fill (Distribute Evenly)" v-model="fill" />
|
||||
|
||||
@@ -73,7 +123,8 @@ import PreviewSlider from '../../components/common/PreviewSlider.vue';
|
||||
import PreviewSwitch from '../../components/common/PreviewSwitch.vue';
|
||||
import PreviewSelect from '../../components/common/PreviewSelect.vue';
|
||||
import RefreshButton from '../../components/common/RefreshButton.vue';
|
||||
import OrbitImages, { type OrbitShape } from '../../content/Animations/OrbitImages/OrbitImages.vue';
|
||||
import OrbitImages from '../../content/Animations/OrbitImages/OrbitImages.vue';
|
||||
import type { OrbitShape } from '../../content/Animations/OrbitImages/OrbitImages.vue';
|
||||
import { orbitImages } from '@/constants/code/Animations/orbitImagesCode';
|
||||
import { useForceRerender } from '@/composables/useForceRerender';
|
||||
|
||||
@@ -119,79 +170,29 @@ const directionOptions = [
|
||||
|
||||
const propData = [
|
||||
{ name: 'images', type: 'string[]', default: '[]', description: 'Array of image URLs to orbit along the path.' },
|
||||
{
|
||||
name: 'altPrefix',
|
||||
type: 'string',
|
||||
default: '"Orbiting image"',
|
||||
description: 'Prefix for auto-generated alt attributes.'
|
||||
},
|
||||
{
|
||||
name: 'shape',
|
||||
type: 'OrbitShape',
|
||||
default: '"ellipse"',
|
||||
description: 'Preset shape: ellipse, circle, square, rectangle, triangle, star, heart, infinity, wave, or custom.'
|
||||
},
|
||||
{
|
||||
name: 'customPath',
|
||||
type: 'string',
|
||||
default: 'undefined',
|
||||
description: 'Custom SVG path string (used when shape="custom").'
|
||||
},
|
||||
{
|
||||
name: 'baseWidth',
|
||||
type: 'number',
|
||||
default: '1400',
|
||||
description: 'Base width for the design coordinate space used for responsive scaling.'
|
||||
},
|
||||
{ name: 'altPrefix', type: 'string', default: '"Orbiting image"', description: 'Prefix for auto-generated alt attributes.' },
|
||||
{ name: 'shape', type: 'OrbitShape', default: '"ellipse"', description: 'Preset shape: ellipse, circle, square, rectangle, triangle, star, heart, infinity, wave, or custom.' },
|
||||
{ name: 'customPath', type: 'string', default: 'undefined', description: 'Custom SVG path string (used when shape="custom").' },
|
||||
{ name: 'baseWidth', type: 'number', default: '1400', description: 'Base width for the design coordinate space used for responsive scaling.' },
|
||||
{ name: 'radiusX', type: 'number', default: '700', description: 'Horizontal radius for ellipse/rectangle shapes.' },
|
||||
{ name: 'radiusY', type: 'number', default: '170', description: 'Vertical radius for ellipse/rectangle shapes.' },
|
||||
{
|
||||
name: 'radius',
|
||||
type: 'number',
|
||||
default: '300',
|
||||
description: 'Radius for circle, square, triangle, star, heart shapes.'
|
||||
},
|
||||
{ name: 'radius', type: 'number', default: '300', description: 'Radius for circle, square, triangle, star, heart shapes.' },
|
||||
{ name: 'starPoints', type: 'number', default: '5', description: 'Number of points for star shape.' },
|
||||
{ name: 'starInnerRatio', type: 'number', default: '0.5', description: 'Inner radius ratio for star (0-1).' },
|
||||
{
|
||||
name: 'rotation',
|
||||
type: 'number',
|
||||
default: '-8',
|
||||
description: 'Rotation angle of the entire orbit path in degrees.'
|
||||
},
|
||||
{ name: 'rotation', type: 'number', default: '-8', description: 'Rotation angle of the entire orbit path in degrees.' },
|
||||
{ name: 'duration', type: 'number', default: '40', description: 'Duration of one complete orbit in seconds.' },
|
||||
{ name: 'itemSize', type: 'number', default: '64', description: 'Width/height of each orbiting item in pixels.' },
|
||||
{ name: 'direction', type: '"normal" | "reverse"', default: '"normal"', description: 'Animation direction.' },
|
||||
{
|
||||
name: 'fill',
|
||||
type: 'boolean',
|
||||
default: 'true',
|
||||
description: 'Whether to distribute items evenly around the orbit.'
|
||||
},
|
||||
{ name: 'fill', type: 'boolean', default: 'true', description: 'Whether to distribute items evenly around the orbit.' },
|
||||
{ name: 'width', type: 'number | "100%"', default: '100', description: 'Container width in pixels or "100%".' },
|
||||
{ name: 'height', type: 'number | "auto"', default: '100', description: 'Container height in pixels or "auto".' },
|
||||
{ name: 'className', type: 'string', default: '""', description: 'Additional CSS class for the container.' },
|
||||
{ name: 'showPath', type: 'boolean', default: 'false', description: 'Whether to show the orbit path for debugging.' },
|
||||
{
|
||||
name: 'pathColor',
|
||||
type: 'string',
|
||||
default: '"rgba(0,0,0,0.1)"',
|
||||
description: 'Stroke color when showPath is true.'
|
||||
},
|
||||
{ name: 'pathColor', type: 'string', default: '"rgba(0,0,0,0.1)"', description: 'Stroke color when showPath is true.' },
|
||||
{ name: 'pathWidth', type: 'number', default: '2', description: 'Stroke width when showPath is true.' },
|
||||
{
|
||||
name: 'easing',
|
||||
type: 'string',
|
||||
default: '"linear"',
|
||||
description: 'Animation easing: linear, easeIn, easeOut, easeInOut.'
|
||||
},
|
||||
{ name: 'easing', type: 'string', default: '"linear"', description: 'Animation easing: linear, easeIn, easeOut, easeInOut.' },
|
||||
{ name: 'paused', type: 'boolean', default: 'false', description: 'Whether the animation is paused.' },
|
||||
{
|
||||
name: 'responsive',
|
||||
type: 'boolean',
|
||||
default: 'false',
|
||||
description: 'Enable responsive scaling based on container width.'
|
||||
}
|
||||
{ name: 'responsive', type: 'boolean', default: 'false', description: 'Enable responsive scaling based on container width.' }
|
||||
];
|
||||
|
||||
watch([shape, direction], () => {
|
||||
|
||||
Reference in New Issue
Block a user