mirror of
https://github.com/ankitects/anki.git
synced 2025-11-06 12:47:11 -05:00
This PR adds the "hide all but one" occlusion mode. An example use case is a note containing a collection of pairs of selection, where each selection is the prompt for the other in its pair. For example, given a table like | small | big | |-------+-----| | a | A | | b | B | | c | C | in each card, five letters are occluded, and one is shown. The user is prompted to state the occluded symbol that is adjacent to the shown symbol.
95 lines
2.6 KiB
TypeScript
95 lines
2.6 KiB
TypeScript
// Copyright: Ankitects Pty Ltd and contributors
|
|
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|
|
|
import { fabric } from "fabric";
|
|
|
|
import { SHAPE_MASK_COLOR } from "../tools/lib";
|
|
import type { ConstructorParams, Size } from "../types";
|
|
import { angleToStored, floatToDisplay } from "./lib";
|
|
import { xFromNormalized, xToNormalized, yFromNormalized, yToNormalized } from "./position";
|
|
|
|
export type ShapeOrShapes = Shape | Shape[];
|
|
|
|
/** Defines a basic shape that can have its coordinates stored in either
|
|
absolute pixels (relative to a containing canvas), or in normalized 0-1
|
|
form. Can be converted to a fabric object, or to a format suitable for
|
|
storage in a cloze note.
|
|
*/
|
|
export class Shape {
|
|
left: number;
|
|
top: number;
|
|
angle?: number; // polygons don't use it
|
|
fill: string;
|
|
/** Occlusion mode: 0=HideOne, 1=HideAll, 2=HideAllButOne.
|
|
* Used only in reviewer code.
|
|
*/
|
|
occlusionMode?: number;
|
|
/* Cloze ordinal */
|
|
ordinal: number | undefined;
|
|
id: string | undefined;
|
|
|
|
constructor(
|
|
{ left = 0, top = 0, angle = 0, fill = SHAPE_MASK_COLOR, occlusionMode, ordinal = undefined }:
|
|
ConstructorParams<Shape> = {},
|
|
) {
|
|
this.left = left;
|
|
this.top = top;
|
|
this.angle = angle;
|
|
this.fill = fill;
|
|
this.occlusionMode = occlusionMode;
|
|
this.ordinal = ordinal;
|
|
}
|
|
|
|
/** Format numbers and remove default values, for easier serialization to
|
|
* text.
|
|
*/
|
|
toDataForCloze(): ShapeDataForCloze {
|
|
const angle = angleToStored(this.angle);
|
|
return {
|
|
left: floatToDisplay(this.left),
|
|
top: floatToDisplay(this.top),
|
|
...(!angle ? {} : { angle: angle.toString() }),
|
|
};
|
|
}
|
|
|
|
toFabric(size: Size): fabric.Object {
|
|
const absolute = this.toAbsolute(size);
|
|
return new fabric.Object(absolute);
|
|
}
|
|
|
|
normalPosition(size: Size) {
|
|
return {
|
|
left: xToNormalized(size, this.left),
|
|
top: yToNormalized(size, this.top),
|
|
};
|
|
}
|
|
|
|
toNormal(size: Size): Shape {
|
|
return new Shape({
|
|
...this,
|
|
...this.normalPosition(size),
|
|
});
|
|
}
|
|
|
|
absolutePosition(size: Size) {
|
|
return {
|
|
left: xFromNormalized(size, this.left),
|
|
top: yFromNormalized(size, this.top),
|
|
};
|
|
}
|
|
|
|
toAbsolute(size: Size): Shape {
|
|
return new Shape({
|
|
...this,
|
|
...this.absolutePosition(size),
|
|
});
|
|
}
|
|
}
|
|
|
|
export interface ShapeDataForCloze {
|
|
left: string;
|
|
top: string;
|
|
angle?: string;
|
|
fill?: string;
|
|
oi?: string;
|
|
}
|