Border
This commit is contained in:
parent
9c0f10b977
commit
5218669744
@ -73,6 +73,7 @@
|
|||||||
const isModalOpen = computed(() => store.isModalOpen.value);
|
const isModalOpen = computed(() => store.isModalOpen.value);
|
||||||
const sprites = computed(() => store.sprites.value);
|
const sprites = computed(() => store.sprites.value);
|
||||||
const animation = computed(() => store.animation);
|
const animation = computed(() => store.animation);
|
||||||
|
const previewBorder = computed(() => store.previewBorder);
|
||||||
|
|
||||||
const currentFrame = ref(0);
|
const currentFrame = ref(0);
|
||||||
const position = ref({ x: 0, y: 0 });
|
const position = ref({ x: 0, y: 0 });
|
||||||
@ -268,6 +269,17 @@
|
|||||||
{ deep: true }
|
{ deep: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Watch for changes in border settings to update the preview
|
||||||
|
watch(
|
||||||
|
() => previewBorder.value,
|
||||||
|
() => {
|
||||||
|
if (isModalOpen.value && sprites.value.length > 0) {
|
||||||
|
store.renderAnimationFrame(currentFrame.value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
);
|
||||||
|
|
||||||
// Expose openModal for external use
|
// Expose openModal for external use
|
||||||
defineExpose({ openModal });
|
defineExpose({ openModal });
|
||||||
</script>
|
</script>
|
||||||
|
@ -59,6 +59,36 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Preview Border Settings Section -->
|
||||||
|
<div class="mb-8">
|
||||||
|
<h3 class="text-lg font-medium text-gray-200 mb-4 flex items-center gap-2"><i class="fas fa-border-style text-blue-500"></i> Preview border</h3>
|
||||||
|
<div class="mb-4">
|
||||||
|
<div class="flex items-center justify-between mb-2">
|
||||||
|
<label class="text-sm text-gray-400">Enable border (preview only)</label>
|
||||||
|
<div class="relative inline-block w-10 align-middle select-none">
|
||||||
|
<input type="checkbox" v-model="previewBorder.enabled" id="toggle-border" class="sr-only" />
|
||||||
|
<label for="toggle-border" class="block h-6 rounded-full bg-gray-600 cursor-pointer"></label>
|
||||||
|
<div :class="{ 'translate-x-4': previewBorder.enabled, 'translate-x-0': !previewBorder.enabled }" class="absolute left-0 top-0 w-6 h-6 rounded-full bg-white border border-gray-300 transform transition-transform duration-200 ease-in-out"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-2 gap-4 mt-4" v-if="previewBorder.enabled">
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm text-gray-400 mb-2">Border color</label>
|
||||||
|
<input type="color" v-model="previewBorder.color" class="w-full h-8 bg-gray-700 rounded cursor-pointer" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm text-gray-400 mb-2">Border width: {{ previewBorder.width }}px</label>
|
||||||
|
<input type="range" v-model.number="previewBorder.width" min="1" max="10" class="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-xs text-gray-400 mt-2">
|
||||||
|
<i class="fas fa-info-circle mr-1"></i> Border will only be visible in the preview and won't be included in the downloaded spritesheet.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Keyboard Shortcuts Section -->
|
<!-- Keyboard Shortcuts Section -->
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-lg font-medium text-gray-200 mb-4 flex items-center gap-2"><i class="fas fa-keyboard text-blue-500"></i> Keyboard shortcuts</h3>
|
<h3 class="text-lg font-medium text-gray-200 mb-4 flex items-center gap-2"><i class="fas fa-keyboard text-blue-500"></i> Keyboard shortcuts</h3>
|
||||||
@ -93,6 +123,7 @@
|
|||||||
const store = useSpritesheetStore();
|
const store = useSpritesheetStore();
|
||||||
const sprites = computed(() => store.sprites.value);
|
const sprites = computed(() => store.sprites.value);
|
||||||
const isModalOpen = computed(() => store.isSettingsModalOpen.value);
|
const isModalOpen = computed(() => store.isSettingsModalOpen.value);
|
||||||
|
const previewBorder = computed(() => store.previewBorder);
|
||||||
|
|
||||||
// Column count control
|
// Column count control
|
||||||
const columnCount = ref(store.columns.value);
|
const columnCount = ref(store.columns.value);
|
||||||
@ -130,3 +161,47 @@
|
|||||||
store.showNotification(`Column count updated to ${columnCount.value}`);
|
store.showNotification(`Column count updated to ${columnCount.value}`);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* Toggle switch styles */
|
||||||
|
input[type='checkbox'] + label {
|
||||||
|
width: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type='checkbox']:checked + label {
|
||||||
|
background-color: #0096ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Range input styles */
|
||||||
|
input[type='range']::-webkit-slider-thumb {
|
||||||
|
appearance: none;
|
||||||
|
width: 15px;
|
||||||
|
height: 15px;
|
||||||
|
background: #0096ff;
|
||||||
|
border-radius: 50%;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type='range']::-moz-range-thumb {
|
||||||
|
width: 15px;
|
||||||
|
height: 15px;
|
||||||
|
background: #0096ff;
|
||||||
|
border-radius: 50%;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Color input styles */
|
||||||
|
input[type='color'] {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type='color']::-webkit-color-swatch-wrapper {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type='color']::-webkit-color-swatch {
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -41,6 +41,13 @@ const isSettingsModalOpen = ref(false);
|
|||||||
const isSpritesModalOpen = ref(false);
|
const isSpritesModalOpen = ref(false);
|
||||||
const zoomLevel = ref(1); // Default zoom level (1 = 100%)
|
const zoomLevel = ref(1); // Default zoom level (1 = 100%)
|
||||||
|
|
||||||
|
// Preview border settings
|
||||||
|
const previewBorder = reactive({
|
||||||
|
enabled: false,
|
||||||
|
color: '#ff0000', // Default red color
|
||||||
|
width: 2 // Default width in pixels
|
||||||
|
});
|
||||||
|
|
||||||
export function useSpritesheetStore() {
|
export function useSpritesheetStore() {
|
||||||
const animation = reactive<AnimationState>({
|
const animation = reactive<AnimationState>({
|
||||||
canvas: null,
|
canvas: null,
|
||||||
@ -399,6 +406,10 @@ export function useSpritesheetStore() {
|
|||||||
|
|
||||||
animation.ctx.clearRect(0, 0, animation.canvas.width, animation.canvas.height);
|
animation.ctx.clearRect(0, 0, animation.canvas.width, animation.canvas.height);
|
||||||
|
|
||||||
|
// Draw background (transparent by default)
|
||||||
|
animation.ctx.fillStyle = 'transparent';
|
||||||
|
animation.ctx.fillRect(0, 0, animation.canvas.width, animation.canvas.height);
|
||||||
|
|
||||||
const currentSprite = sprites.value[frameIndex % sprites.value.length];
|
const currentSprite = sprites.value[frameIndex % sprites.value.length];
|
||||||
|
|
||||||
const cellX = Math.floor(currentSprite.x / cellSize.width);
|
const cellX = Math.floor(currentSprite.x / cellSize.width);
|
||||||
@ -408,6 +419,13 @@ export function useSpritesheetStore() {
|
|||||||
const offsetY = currentSprite.y - cellY * cellSize.height;
|
const offsetY = currentSprite.y - cellY * cellSize.height;
|
||||||
|
|
||||||
animation.ctx.drawImage(currentSprite.img, offsetX, offsetY);
|
animation.ctx.drawImage(currentSprite.img, offsetX, offsetY);
|
||||||
|
|
||||||
|
// Draw border if enabled (only for preview, not included in download)
|
||||||
|
if (previewBorder.enabled) {
|
||||||
|
animation.ctx.strokeStyle = previewBorder.color;
|
||||||
|
animation.ctx.lineWidth = previewBorder.width;
|
||||||
|
animation.ctx.strokeRect(0, 0, animation.canvas.width, animation.canvas.height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function animationLoop(timestamp?: number) {
|
function animationLoop(timestamp?: number) {
|
||||||
@ -480,6 +498,7 @@ export function useSpritesheetStore() {
|
|||||||
animation,
|
animation,
|
||||||
notification,
|
notification,
|
||||||
zoomLevel,
|
zoomLevel,
|
||||||
|
previewBorder,
|
||||||
addSprites,
|
addSprites,
|
||||||
updateCellSize,
|
updateCellSize,
|
||||||
updateCanvasSize,
|
updateCanvasSize,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user