Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
"@vitest/coverage-v8": "catalog:",
"@vitest/ui": "catalog:",
"@vue/test-utils": "catalog:",
"@webgpu/types": "catalog:",
"cross-env": "catalog:",
"eslint": "catalog:",
"eslint-config-prettier": "catalog:",
Expand Down Expand Up @@ -112,6 +113,7 @@
"typescript": "catalog:",
"typescript-eslint": "catalog:",
"unplugin-icons": "catalog:",
"unplugin-typegpu": "catalog:",
"unplugin-vue-components": "catalog:",
"uuid": "^11.1.0",
"vite": "catalog:",
Expand Down Expand Up @@ -175,6 +177,7 @@
"semver": "^7.7.2",
"three": "^0.170.0",
"tiptap-markdown": "^0.8.10",
"typegpu": "catalog:",
"vue": "catalog:",
"vue-i18n": "catalog:",
"vue-router": "catalog:",
Expand Down
86 changes: 82 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions pnpm-workspace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ catalog:
'@vue/test-utils': ^2.4.6
'@vueuse/core': ^11.0.0
'@vueuse/integrations': ^13.9.0
'@webgpu/types': ^0.1.66
algoliasearch: ^5.21.0
axios: ^1.8.2
cross-env: ^10.1.0
Expand Down Expand Up @@ -82,9 +83,11 @@ catalog:
tailwindcss-primeui: ^0.6.1
tsx: ^4.15.6
tw-animate-css: ^1.3.8
typegpu: ^0.8.2
typescript: ^5.9.2
typescript-eslint: ^8.44.0
unplugin-icons: ^0.22.0
unplugin-typegpu: 0.8.0
unplugin-vue-components: ^0.28.0
vite: ^5.4.19
vite-plugin-dts: ^4.5.4
Expand Down
24 changes: 19 additions & 5 deletions src/components/maskeditor/BrushCursor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
<script setup lang="ts">
import { computed } from 'vue'

import {
getEffectiveBrushSize,
getEffectiveHardness
} from '@/composables/maskeditor/brushUtils'
import { BrushShape } from '@/extensions/core/maskeditor/types'
import { useMaskEditorStore } from '@/stores/maskEditorStore'

Expand All @@ -36,11 +40,14 @@ const { containerRef } = defineProps<{
const store = useMaskEditorStore()

const brushOpacity = computed(() => {
return store.brushVisible ? '1' : '0'
return store.brushVisible ? 1 : 0
})
Comment on lines 42 to 44
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Aligns cursor preview with effective brush size/hardness; consider relaxing float equality

Using getEffectiveBrushSize/getEffectiveHardness for both the cursor radius and gradient makes the preview much closer to the actual brush behavior and the new soft‑edge model, and switching brushOpacity to numeric values is also cleaner for CSS.

One minor robustness point: if (effectiveHardness === 1) relies on an exact floating‑point comparison. If effectiveHardness is computed (rather than directly set to 1), you could occasionally get 0.999... and skip the solid‑brush shortcut unintentionally. Consider either:

  • Checking the original store.brushSettings.hardness === 1, or
  • Using a tolerance (e.g., if (effectiveHardness >= 0.999)).

This would make the “fully hard” visual consistent even in the face of small floating‑point rounding differences.

Also applies to: 46-51, 87-109

🤖 Prompt for AI Agents
In src/components/maskeditor/BrushCursor.vue around lines 42-44 (and also
affecting lines 46-51 and 87-109), the cursor preview should use
getEffectiveBrushSize and getEffectiveHardness for both the radius and gradient,
and brushOpacity should be numeric (1 or 0) for cleaner CSS; replace usages that
compute cursor geometry from raw settings with the effective helpers and set
brushOpacity to numeric values. Also replace the exact floating-point check if
(effectiveHardness === 1) with a robust test such as checking the original
store.brushSettings.hardness === 1 or using a tolerance (e.g., effectiveHardness
>= 0.999) so fully-hard brushes still use the solid shortcut despite tiny
rounding errors.


const brushRadius = computed(() => {
return store.brushSettings.size * store.zoomRatio
const size = store.brushSettings.size
const hardness = store.brushSettings.hardness
const effectiveSize = getEffectiveBrushSize(size, hardness)
return effectiveSize * store.zoomRatio
})

const brushSize = computed(() => {
Expand Down Expand Up @@ -78,19 +85,26 @@ const gradientVisible = computed(() => {
})

const gradientBackground = computed(() => {
const size = store.brushSettings.size
const hardness = store.brushSettings.hardness
const effectiveSize = getEffectiveBrushSize(size, hardness)
const effectiveHardness = getEffectiveHardness(size, hardness, effectiveSize)

if (hardness === 1) {
if (effectiveHardness === 1) {
return 'rgba(255, 0, 0, 0.5)'
}

const midStop = hardness * 100
const midStop = effectiveHardness * 100
const outerStop = 100
// Add an intermediate stop to approximate the squared falloff
// At 50% of the fade region, squared falloff is 0.25 (relative to max)
const fadeMidStop = midStop + (outerStop - midStop) * 0.5

return `radial-gradient(
circle,
rgba(255, 0, 0, 0.5) 0%,
rgba(255, 0, 0, 0.25) ${midStop}%,
rgba(255, 0, 0, 0.5) ${midStop}%,
rgba(255, 0, 0, 0.125) ${fadeMidStop}%,
rgba(255, 0, 0, 0) ${outerStop}%
)`
})
Expand Down
12 changes: 6 additions & 6 deletions src/components/maskeditor/BrushSettingsPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
<SliderControl
:label="t('maskEditor.thickness')"
:min="1"
:max="100"
:max="500"
:step="1"
:model-value="store.brushSettings.size"
@update:model-value="onThicknessChange"
Expand All @@ -80,12 +80,12 @@
/>

<SliderControl
:label="t('maskEditor.smoothingPrecision')"
label="Stepsize"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add it into en/main.json for i18n?

:min="1"
:max="100"
:step="1"
:model-value="store.brushSettings.smoothingPrecision"
@update:model-value="onSmoothingPrecisionChange"
:model-value="store.brushSettings.stepSize"
@update:model-value="onStepSizeChange"
/>
</div>
</template>
Expand Down Expand Up @@ -119,8 +119,8 @@ const onHardnessChange = (value: number) => {
store.setBrushHardness(value)
}

const onSmoothingPrecisionChange = (value: number) => {
store.setBrushSmoothingPrecision(value)
const onStepSizeChange = (value: number) => {
store.setBrushStepSize(value)
}

const resetToDefault = () => {
Expand Down
Loading