diff --git a/build/configure/src/web.rs b/build/configure/src/web.rs index 2312eb541..52e096177 100644 --- a/build/configure/src/web.rs +++ b/build/configure/src/web.rs @@ -394,7 +394,7 @@ fn build_and_check_editor(build: &mut Build) -> Result<()> { } fn build_and_check_reviewer(build: &mut Build) -> Result<()> { - let reviewer_deps = inputs![":ts:lib", glob!("ts/reviewer/**")]; + let reviewer_deps = inputs![":ts:lib", glob!("ts/reviewer/**"),]; build.add( "ts:reviewer:reviewer.js", EsbuildScript { @@ -410,7 +410,7 @@ fn build_and_check_reviewer(build: &mut Build) -> Result<()> { CompileSass { input: inputs!["ts/reviewer/reviewer.scss"], output: "ts/reviewer/reviewer.css", - deps: ":sass".into(), + deps: inputs![":sass", "ts/image-occlusion/review.scss"], load_paths: vec!["."], }, )?; diff --git a/rslib/src/image_occlusion/image_occlusion_styling.css b/rslib/src/image_occlusion/image_occlusion_styling.css deleted file mode 100644 index ac8a7e25b..000000000 --- a/rslib/src/image_occlusion/image_occlusion_styling.css +++ /dev/null @@ -1,41 +0,0 @@ -.image-occlusion-canvas { - --inactive-shape-color: #ffeba2; - --active-shape-color: #ff8e8e; - --inactive-shape-border: 1px #212121; - --active-shape-border: 1px #212121; -} - -.card { - font-family: arial; - font-size: 20px; - text-align: center; - color: black; - background-color: white; -} - -.cloze { - font-weight: bold; - color: blue; -} - -.nightMode .cloze { - color: lightblue; -} - -#container { - position: relative; -} - -img { - position: absolute; - top: 0; - left: 50%; - transform: translate(-50%, 0); -} - -#canvas { - position: absolute; - top: 0; - left: 50%; - transform: translate(-50%, 0); -} diff --git a/rslib/src/image_occlusion/imagedata.rs b/rslib/src/image_occlusion/imagedata.rs index 9e103f27b..bf85448c6 100644 --- a/rslib/src/image_occlusion/imagedata.rs +++ b/rslib/src/image_occlusion/imagedata.rs @@ -47,10 +47,7 @@ impl Collection { let mgr = MediaManager::new(&self.media_folder, &self.media_db)?; let actual_image_name_after_adding = mgr.add_file(&image_filename, &image_bytes)?; - let image_tag = format!( - r#""#, - &actual_image_name_after_adding - ); + let image_tag = format!(r#""#, &actual_image_name_after_adding); let current_deck = self.get_current_deck()?; self.transact(Op::ImageOcclusion, |col| { diff --git a/rslib/src/image_occlusion/notetype.css b/rslib/src/image_occlusion/notetype.css new file mode 100644 index 000000000..359781dbb --- /dev/null +++ b/rslib/src/image_occlusion/notetype.css @@ -0,0 +1,14 @@ +#image-occlusion-canvas { + --inactive-shape-color: #ffeba2; + --active-shape-color: #ff8e8e; + --inactive-shape-border: 1px #212121; + --active-shape-border: 1px #212121; +} + +.card { + font-family: arial; + font-size: 20px; + text-align: center; + color: black; + background-color: white; +} diff --git a/rslib/src/image_occlusion/notetype.rs b/rslib/src/image_occlusion/notetype.rs index e0e2febb7..a192e0083 100644 --- a/rslib/src/image_occlusion/notetype.rs +++ b/rslib/src/image_occlusion/notetype.rs @@ -51,7 +51,7 @@ impl Collection { } pub(crate) fn image_occlusion_notetype(tr: &I18n) -> Notetype { - const IMAGE_CLOZE_CSS: &str = include_str!("image_occlusion_styling.css"); + const IMAGE_CLOZE_CSS: &str = include_str!("notetype.css"); let mut nt = empty_stock( NotetypeKind::Cloze, OriginalStockKind::ImageOcclusion, @@ -71,31 +71,29 @@ pub(crate) fn image_occlusion_notetype(tr: &I18n) -> Notetype { let err_loading = tr.notetypes_error_loading_image_occlusion(); let qfmt = format!( - "\ -{{{{#{header}}}}}
{{{{{header}}}}}
{{{{/{header}}}}} -
{{{{cloze:{occlusion}}}}}
-
-
+ r#"{{{{#{header}}}}}
{{{{{header}}}}}
{{{{/{header}}}}} +
{{{{cloze:{occlusion}}}}}
+
+
{{{{{image}}}}} - +
-" +"# ); let toggle_masks = tr.notetypes_toggle_masks(); let afmt = format!( - "\ -{qfmt} -
+ r#"{qfmt} +
{{{{#{back_extra}}}}}
{{{{{back_extra}}}}}
{{{{/{back_extra}}}}} -", +"#, ); nt.add_template(nt.name.clone(), qfmt, afmt); nt diff --git a/ts/image-occlusion/review.scss b/ts/image-occlusion/review.scss new file mode 100644 index 000000000..d640b4986 --- /dev/null +++ b/ts/image-occlusion/review.scss @@ -0,0 +1,28 @@ +#image-occlusion-container { + position: relative; + // if height-constrained, ensure container is centered + left: 50%; + transform: translate(-50%, 0); + // allow for 20px margin on html element, or short windows can truncate + // image + max-height: calc(95vh - 40px); +} + +#image-occlusion-container img { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + // remove the default image limits, as we rely on container + max-width: unset; + max-height: unset; +} + +#image-occlusion-canvas { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} \ No newline at end of file diff --git a/ts/reviewer/image_occlusion.ts b/ts/reviewer/image_occlusion.ts index 319e27221..454f371a4 100644 --- a/ts/reviewer/image_occlusion.ts +++ b/ts/reviewer/image_occlusion.ts @@ -12,17 +12,14 @@ export function setupImageCloze(): void { } function setupImageClozeInner(): void { - const canvas = document.querySelector("canvas") as HTMLCanvasElement | null; + const canvas = document.querySelector("#image-occlusion-canvas") as HTMLCanvasElement | null; if (canvas == null) { return; } - canvas.style.maxWidth = "100%"; - canvas.style.maxHeight = "95vh"; - const ctx: CanvasRenderingContext2D = canvas.getContext("2d")!; - const container = document.getElementById("container") as HTMLDivElement; - const image = document.getElementById("img") as HTMLImageElement; + const container = document.getElementById("image-occlusion-container") as HTMLDivElement; + const image = document.querySelector("#image-occlusion-container img") as HTMLImageElement; if (image == null) { container.innerText = tr.notetypeErrorNoImageToShow(); return; @@ -32,8 +29,8 @@ function setupImageClozeInner(): void { canvas.width = size.width; canvas.height = size.height; - // set height for div container (used 'relative' in css) - container.style.height = `${image.height}px`; + // Enforce aspect ratio of image + container.style.aspectRatio = `${size.width / size.height}`; // setup button for toggle image occlusion const button = document.getElementById("toggle"); @@ -151,7 +148,7 @@ function getShapeProperty(): { activeBorder: { width: number; color: string }; inActiveBorder: { width: number; color: string }; } { - const canvas = document.getElementById("canvas"); + const canvas = document.getElementById("image-occlusion-canvas"); const computedStyle = window.getComputedStyle(canvas!); // it may throw error if the css variable is not defined try { @@ -199,7 +196,7 @@ function getShapeProperty(): { } const toggleMasks = (): void => { - const canvas = document.getElementById("canvas") as HTMLCanvasElement; + const canvas = document.getElementById("image-occlusion-canvas") as HTMLCanvasElement; const display = canvas.style.display; if (display === "none") { canvas.style.display = "unset"; diff --git a/ts/reviewer/reviewer.scss b/ts/reviewer/reviewer.scss index 5f1e9d97f..dde99dee3 100644 --- a/ts/reviewer/reviewer.scss +++ b/ts/reviewer/reviewer.scss @@ -2,6 +2,7 @@ * License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html */ @use "sass/vars"; +@use "ts/image-occlusion/review"; hr { background-color: vars.palette(darkgray, 0);