Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add scan effect using <canvas> #151

Merged
merged 32 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
1300772
add canvas scan function
rwv Nov 13, 2023
6af1580
add canvas scan
rwv Nov 13, 2023
bbf812f
canvas scan settings
rwv Nov 13, 2023
4ddde05
add PDF upload
rwv Nov 13, 2023
323a14c
add pdf preview canvas
rwv Nov 13, 2023
8cf4c00
add side-by-side preview
rwv Nov 13, 2023
c77d972
ImagePreview
rwv Nov 13, 2023
1b54afe
add preview compare
rwv Nov 13, 2023
7ca5d27
add canvas scanner
rwv Nov 13, 2023
f7ec99d
deep watch scanRenderer
rwv Nov 13, 2023
6690458
add abort signal to scanner
rwv Nov 13, 2023
cbd3e63
add pagination
rwv Nov 13, 2023
32777be
add noise i18n
rwv Nov 14, 2023
e77ad80
add scan actions card
rwv Nov 14, 2023
4f28b23
add download Save
rwv Nov 14, 2023
a7aa967
add progress
rwv Nov 14, 2023
5860cf5
add progress to save button card
rwv Nov 14, 2023
bb4ad22
generate noise svg on the fly
rwv Nov 14, 2023
e21499a
rename to scan-canvas
rwv Nov 14, 2023
9be9f22
use offscreen canvas
rwv Nov 14, 2023
3068a8a
make ts happy
rwv Nov 14, 2023
4e59c43
make ts happy
rwv Nov 14, 2023
ea838f3
canvas.convertToBlob use output format
rwv Nov 14, 2023
faa0efb
update output filename
rwv Nov 14, 2023
6312dc3
rename example pdf file
rwv Nov 14, 2023
766a375
fix image preview aspect-ratio
rwv Nov 14, 2023
2098e96
update defaultConfig
rwv Nov 14, 2023
ed0c2eb
update pdf-upload
rwv Nov 14, 2023
988fe4c
add brightness and contrast
rwv Nov 14, 2023
80e63a7
add display: block to image preview n-image
rwv Nov 14, 2023
baca631
add pdf info card
rwv Nov 14, 2023
839cd4f
use canvas scan as default
rwv Nov 14, 2023
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
14 changes: 14 additions & 0 deletions package-lock.json

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

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
},
"dependencies": {
"browser-fs-access": "^0.29.5",
"filesize": "^10.1.0",
"jspdf": "^2.5.1",
"magica": "^0.2.17",
"magica-re-export": "^1.0.9",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<template>
<n-card
:segmented="{
content: true,
footer: 'soft',
}"
>
<n-collapse :default-expanded-names="['Settings']">
<template #header-extra>
<n-icon><ChevronDown12Regular /></n-icon>
</template>
<template #arrow>
<n-icon style="margin-right: 2px">
<AreaCustom />
</n-icon>
</template>
<n-collapse-item :title="t('settings.settings')" name="Settings">
<!-- Scan Settings -->
<n-space :size="40" style="margin-bottom: 10px">
<ColorspaceSetting v-model:colorspace="config.colorspace" />
<BorderSetting v-model:border="config.border" />
</n-space>

<RotateSetting v-model:rotate="config.rotate" />
<RotateVarianceSetting v-model:rotate_var="config.rotate_var" />
<BrightnessSetting v-model:brightness="config.brightness" />
<ContrastSetting v-model:contrast="config.contrast" />
<BlurSetting v-model:blur="config.blur" />
<NoiseSetting v-model:noise="config.noise" />
<ScaleSetting v-model:scale="config.scale" />
</n-collapse-item>
</n-collapse>
</n-card>
</template>

<script lang="ts" setup>
import { NCard, NSpace, NCollapse, NCollapseItem, NIcon } from "naive-ui";
import { AreaCustom } from "@vicons/carbon";
import { ChevronDown12Regular } from "@vicons/fluent";

import BorderSetting from "./settings/BorderSetting.vue";
import RotateSetting from "./settings/RotateSetting.vue";
import RotateVarianceSetting from "./settings/RotateVarianceSetting.vue";
import ColorspaceSetting from "./settings/ColorspaceSetting.vue";
import BlurSetting from "./settings/BlurSetting.vue";
import NoiseSetting from "./settings/NoiseSetting.vue";
import ScaleSetting from "./settings/ScaleSetting.vue";
import BrightnessSetting from "./settings/BrightnessSetting.vue";
import ContrastSetting from "./settings/ContrastSetting.vue";

import type { ScanConfig } from "@/utils/canvas-scan";
import { useI18n } from "vue-i18n";
import { useVModel } from "@vueuse/core";

const { t } = useI18n();

const props = defineProps<{
config: ScanConfig;
}>();

const emit = defineEmits<{
(e: "update:config", config: ScanConfig): void;
}>();

const config = useVModel(props, "config", emit);
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<template>
<n-form-item :label="t('settings.blur')" :show-feedback="false">
<template #label>
<span :style="style">
{{ t("settings.blur") }}
</span>
</template>
<n-slider v-model:value="blur_computed" :max="1" :min="0" :step="0.01" />
</n-form-item>
</template>

<script lang="ts" setup>
import { computed } from "vue";
import { NFormItem, NSlider } from "naive-ui";
import { useI18n } from "vue-i18n";
const { t } = useI18n();

type blurType = number;

const props = defineProps<{
blur: blurType;
}>();

const emit = defineEmits<{
(e: "update:blur", value: blurType): void;
}>();

const blur_computed = computed({
get: () => props.blur,
set: (value) => emit("update:blur", value),
});

const style = computed(() => {
return {
filter: `blur(${blur_computed.value}px)`,
};
});
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<template>
<n-form-item :show-feedback="false">
<template #label>
<span :style="style">{{ t("settings.border.label") }}</span>
</template>
<NSwitch v-model:value="borderSwitch"></NSwitch>
</n-form-item>
</template>

<script lang="ts" setup>
import { computed } from "vue";
import { NFormItem, NSwitch } from "naive-ui";
import { useI18n } from "vue-i18n";
const { t } = useI18n();

type borderType = boolean;

const props = defineProps<{
border: borderType;
}>();

const emit = defineEmits<{
(e: "update:border", value: borderType): void;
}>();

const borderSwitch = computed({
get: () => props.border == true,
set: (border) => emit("update:border", border ? true : false),
});

const style = computed(() => {
if (borderSwitch.value) {
return {
outline: "1px solid var(--n-label-text-color)",
};
} else {
return {};
}
});
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<template>
<n-form-item :label="t('settings.brightness')" :show-feedback="false">
<template #label>
<span :style="style">
{{ t("settings.brightness") }}
</span>
</template>
<n-slider
v-model:value="brightness_computed"
:max="2"
:min="0"
:step="0.01"
/>
</n-form-item>
</template>

<script lang="ts" setup>
import { computed } from "vue";
import { NFormItem, NSlider } from "naive-ui";
import { useI18n } from "vue-i18n";
const { t } = useI18n();

type brightnessType = number;

const props = defineProps<{
brightness: brightnessType;
}>();

const emit = defineEmits<{
(e: "update:brightness", value: brightnessType): void;
}>();

const brightness_computed = computed({
get: () => props.brightness,
set: (value) => emit("update:brightness", value),
});

const style = computed(() => {
return {
filter: `brightness(${brightness_computed.value})`,
};
});
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<template>
<n-form-item :label="t('settings.colorspace.label')" :show-feedback="false">
<template #label>
<n-gradient-text :gradient="linearGradient" v-show="colorspaceSwitch">
{{ t("settings.colorspace.label") }}
</n-gradient-text>
<n-text v-show="!colorspaceSwitch">{{
t("settings.colorspace.label")
}}</n-text>
</template>
<NSwitch v-model:value="colorspaceSwitch" :rail-style="railStyle">
<template #checked>{{ t("settings.colorspace.colorful") }}</template>
<template #unchecked>{{ t("settings.colorspace.grayscale") }}</template>
</NSwitch>
</n-form-item>
</template>

<script lang="ts" setup>
import { type CSSProperties, computed } from "vue";
import { NFormItem, NSwitch, NGradientText, NText } from "naive-ui";
import { useI18n } from "vue-i18n";
const { t } = useI18n();

type colorspaceType = "sRGB" | "gray";

const props = defineProps<{
colorspace: colorspaceType;
}>();

const emit = defineEmits<{
(e: "update:colorspace", value: colorspaceType): void;
}>();

const colorspaceSwitch = computed({
get: () => props.colorspace !== "gray",
set: (colorspace) => emit("update:colorspace", colorspace ? "sRGB" : "gray"),
});

const linearGradient =
"linear-gradient(to right top, #845ec2, #a55dbd, #c15db5, #d95fab, #ec64a0, #f76e91, #fd7b84, #ff8a7a, #ffa26e, #ffbd66, #ffda65, #f9f871)";

const railStyle = ({
focused,
checked,
}: {
focused: boolean;
checked: boolean;
}) => {
const style: CSSProperties = {};
if (checked) {
// If colorspace is colorful, the rail is colored.
// get random color from array
style.background = linearGradient;
if (focused) {
style.boxShadow = "0 0 0 2px #FF6F9140";
}
} else {
style.background = "#000000";
if (focused) {
style.boxShadow = "0 0 0 2px #00000040";
}
}
return style;
};
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<template>
<n-form-item :label="t('settings.contrast')" :show-feedback="false">
<template #label>
<span :style="style">
{{ t("settings.contrast") }}
</span>
</template>
<n-slider
v-model:value="contrast_computed"
:max="2"
:min="0"
:step="0.01"
/>
</n-form-item>
</template>

<script lang="ts" setup>
import { computed } from "vue";
import { NFormItem, NSlider } from "naive-ui";
import { useI18n } from "vue-i18n";
const { t } = useI18n();

type contrastType = number;

const props = defineProps<{
contrast: contrastType;
}>();

const emit = defineEmits<{
(e: "update:contrast", value: contrastType): void;
}>();

const contrast_computed = computed({
get: () => props.contrast,
set: (value) => emit("update:contrast", value),
});

const style = computed(() => {
return {
filter: `contrast(${contrast_computed.value})`,
};
});
</script>
Loading