WIP
This commit is contained in:
11
package-lock.json
generated
11
package-lock.json
generated
@@ -17,6 +17,7 @@
|
|||||||
"h264-mp4-encoder": "^1.0.12",
|
"h264-mp4-encoder": "^1.0.12",
|
||||||
"hammerjs": "^2.0.8",
|
"hammerjs": "^2.0.8",
|
||||||
"i": "^0.3.7",
|
"i": "^0.3.7",
|
||||||
|
"is-mobile": "^3.0.0",
|
||||||
"npm": "^8.4.0",
|
"npm": "^8.4.0",
|
||||||
"webfontloader": "^1.6.28",
|
"webfontloader": "^1.6.28",
|
||||||
"webm-writer": "^1.0.0"
|
"webm-writer": "^1.0.0"
|
||||||
@@ -1078,6 +1079,11 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-mobile": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-mobile/-/is-mobile-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-UruBjgykgDJ5zRpJ8Zgh9ZUe4jQaHD8klX9FlkOt0oPyu3FpwJpxHvKg4+lhJOWGxSrMKsRuPFk60xeltvyliQ=="
|
||||||
|
},
|
||||||
"node_modules/is-what": {
|
"node_modules/is-what": {
|
||||||
"version": "4.1.7",
|
"version": "4.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.7.tgz",
|
||||||
@@ -4471,6 +4477,11 @@
|
|||||||
"has": "^1.0.3"
|
"has": "^1.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"is-mobile": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-mobile/-/is-mobile-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-UruBjgykgDJ5zRpJ8Zgh9ZUe4jQaHD8klX9FlkOt0oPyu3FpwJpxHvKg4+lhJOWGxSrMKsRuPFk60xeltvyliQ=="
|
||||||
|
},
|
||||||
"is-what": {
|
"is-what": {
|
||||||
"version": "4.1.7",
|
"version": "4.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.7.tgz",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"h264-mp4-encoder": "^1.0.12",
|
"h264-mp4-encoder": "^1.0.12",
|
||||||
"hammerjs": "^2.0.8",
|
"hammerjs": "^2.0.8",
|
||||||
"i": "^0.3.7",
|
"i": "^0.3.7",
|
||||||
|
"is-mobile": "^3.0.0",
|
||||||
"npm": "^8.4.0",
|
"npm": "^8.4.0",
|
||||||
"webfontloader": "^1.6.28",
|
"webfontloader": "^1.6.28",
|
||||||
"webm-writer": "^1.0.0"
|
"webm-writer": "^1.0.0"
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ class Board {
|
|||||||
|
|
||||||
private style: Style = boards.standard;
|
private style: Style = boards.standard;
|
||||||
private header: { [key: string]: string | undefined } = {};
|
private header: { [key: string]: string | undefined } = {};
|
||||||
private borderVisible: boolean = true;
|
|
||||||
private lastPosition: Position | null = null;
|
private lastPosition: Position | null = null;
|
||||||
private background: HTMLCanvasElement | null = null;
|
private background: HTMLCanvasElement | null = null;
|
||||||
private currentScreen: "title" | "move" = "move";
|
private currentScreen: "title" | "move" = "move";
|
||||||
@@ -100,7 +99,7 @@ class Board {
|
|||||||
this.tempCanvas.height = height;
|
this.tempCanvas.height = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tempBorderWidth = this.borderVisible ? this.size / 32 : 0;
|
const tempBorderWidth = this.cfg.showBorder ? this.size / 32 : 0;
|
||||||
const tempInnerSize = this.size - tempBorderWidth * 2;
|
const tempInnerSize = this.size - tempBorderWidth * 2;
|
||||||
this.squareSize = Math.floor(tempInnerSize / this.cfg.tiles);
|
this.squareSize = Math.floor(tempInnerSize / this.cfg.tiles);
|
||||||
this.innerSize = this.squareSize * this.cfg.tiles;
|
this.innerSize = this.squareSize * this.cfg.tiles;
|
||||||
@@ -132,21 +131,21 @@ class Board {
|
|||||||
}
|
}
|
||||||
|
|
||||||
hideBorder() {
|
hideBorder() {
|
||||||
this.borderVisible = false;
|
this.cfg.showBorder = false;
|
||||||
this.setSize(this.size);
|
this.setSize(this.size);
|
||||||
this.refresh();
|
this.refresh();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
showBorder() {
|
showBorder() {
|
||||||
this.borderVisible = true;
|
this.cfg.showBorder = true;
|
||||||
this.setSize(this.size);
|
this.setSize(this.size);
|
||||||
this.refresh();
|
this.refresh();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleBorder() {
|
toggleBorder() {
|
||||||
this.borderVisible = !this.borderVisible;
|
this.cfg.showBorder = !this.cfg.showBorder;
|
||||||
this.setSize(this.size);
|
this.setSize(this.size);
|
||||||
this.refresh();
|
this.refresh();
|
||||||
return this;
|
return this;
|
||||||
@@ -188,8 +187,8 @@ class Board {
|
|||||||
ctx,
|
ctx,
|
||||||
this.innerSize,
|
this.innerSize,
|
||||||
this.innerSize,
|
this.innerSize,
|
||||||
this.borderVisible ? this.borderWidth : 0,
|
this.cfg.showBorder ? this.borderWidth : 0,
|
||||||
(this.borderVisible ? this.borderWidth : 0) + this.margin,
|
(this.cfg.showBorder ? this.borderWidth : 0) + this.margin,
|
||||||
background
|
background
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -208,7 +207,7 @@ class Board {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.borderVisible && this.cfg.showCoords) {
|
if (this.cfg.showBorder && this.cfg.showCoords) {
|
||||||
drawCoords(
|
drawCoords(
|
||||||
ctx,
|
ctx,
|
||||||
coords,
|
coords,
|
||||||
@@ -217,7 +216,7 @@ class Board {
|
|||||||
this.cfg.flipped,
|
this.cfg.flipped,
|
||||||
this.borderWidth,
|
this.borderWidth,
|
||||||
this.size,
|
this.size,
|
||||||
this.borderVisible,
|
this.cfg.showBorder,
|
||||||
this.margin
|
this.margin
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -254,7 +253,7 @@ class Board {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.borderVisible && this.cfg.showCoords) {
|
if (!this.cfg.showBorder && this.cfg.showCoords) {
|
||||||
drawCoords(
|
drawCoords(
|
||||||
this.tempCtx,
|
this.tempCtx,
|
||||||
this.style.coords,
|
this.style.coords,
|
||||||
@@ -263,7 +262,7 @@ class Board {
|
|||||||
this.cfg.flipped,
|
this.cfg.flipped,
|
||||||
this.borderWidth,
|
this.borderWidth,
|
||||||
this.size,
|
this.size,
|
||||||
this.borderVisible,
|
this.cfg.showBorder,
|
||||||
this.margin
|
this.margin
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,10 +29,10 @@ const drawExtraInfo = async (
|
|||||||
|
|
||||||
ctx.fillStyle = style.coords.onBorder;
|
ctx.fillStyle = style.coords.onBorder;
|
||||||
|
|
||||||
if (data.White) {
|
{
|
||||||
const w = drawText(
|
const w = drawText(
|
||||||
ctx,
|
ctx,
|
||||||
data.White,
|
data.White ?? "White",
|
||||||
"Ubuntu",
|
"Ubuntu",
|
||||||
fontSize,
|
fontSize,
|
||||||
700,
|
700,
|
||||||
@@ -56,13 +56,10 @@ const drawExtraInfo = async (
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.Black) {
|
{
|
||||||
const elo =
|
|
||||||
data.BlackElo && data.BlackElo !== "?" ? ` ${data.BlackElo}` : "";
|
|
||||||
|
|
||||||
const w = drawText(
|
const w = drawText(
|
||||||
ctx,
|
ctx,
|
||||||
data.Black,
|
data.Black ?? "Black",
|
||||||
"Ubuntu",
|
"Ubuntu",
|
||||||
fontSize,
|
fontSize,
|
||||||
700,
|
700,
|
||||||
@@ -71,6 +68,9 @@ const drawExtraInfo = async (
|
|||||||
"left"
|
"left"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const elo =
|
||||||
|
data.BlackElo && data.BlackElo !== "?" ? ` ${data.BlackElo}` : "";
|
||||||
|
|
||||||
drawText(
|
drawText(
|
||||||
ctx,
|
ctx,
|
||||||
elo,
|
elo,
|
||||||
|
|||||||
@@ -1,17 +1,28 @@
|
|||||||
import { BoardConfig } from "../types";
|
import { BoardConfig, Size } from "../types";
|
||||||
import Board from "../board/Board";
|
import Board from "../board/Board";
|
||||||
import Game from "../game/Game";
|
import Game from "../game/Game";
|
||||||
|
import sizeToPX from "./sizeToPX";
|
||||||
|
|
||||||
const createImage = async (
|
const createImage = async (
|
||||||
fen: string,
|
fen: string,
|
||||||
|
pgn: string | null,
|
||||||
|
ply: number = 0,
|
||||||
boardConfig: BoardConfig,
|
boardConfig: BoardConfig,
|
||||||
size: number
|
size: Size
|
||||||
) => {
|
) => {
|
||||||
const game = new Game().loadFEN(fen);
|
console.log({ fen, pgn, ply, size });
|
||||||
const board = new Board({ ...boardConfig, size });
|
const game = new Game();
|
||||||
|
|
||||||
const position = game.getPosition(0);
|
if (pgn) {
|
||||||
await board.frame(position, {});
|
game.loadPGN(pgn);
|
||||||
|
} else {
|
||||||
|
game.loadFEN(fen);
|
||||||
|
}
|
||||||
|
|
||||||
|
const board = new Board({ ...boardConfig, size: sizeToPX[size] });
|
||||||
|
|
||||||
|
const position = game.getPosition(ply);
|
||||||
|
await board.frame(position, game.header);
|
||||||
board.render();
|
board.render();
|
||||||
|
|
||||||
return board.toImgUrl();
|
return board.toImgUrl();
|
||||||
|
|||||||
9
src/encoders/sizeToPX.ts
Normal file
9
src/encoders/sizeToPX.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
const sizeToPX = {
|
||||||
|
XS: 256,
|
||||||
|
S: 512,
|
||||||
|
M: 720,
|
||||||
|
L: 1024,
|
||||||
|
XL: 1440,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default sizeToPX;
|
||||||
@@ -76,8 +76,8 @@ class Game {
|
|||||||
move: null,
|
move: null,
|
||||||
end: 0,
|
end: 0,
|
||||||
fen,
|
fen,
|
||||||
check: false,
|
check: this.game.in_check(),
|
||||||
mate: false,
|
mate: this.game.in_checkmate(),
|
||||||
turn: this.game.turn(),
|
turn: this.game.turn(),
|
||||||
material: this.materialInfo(this.game.board()),
|
material: this.materialInfo(this.game.board()),
|
||||||
placement: this.getPlacement(this.game.fen()),
|
placement: this.getPlacement(this.game.fen()),
|
||||||
|
|||||||
24
src/main.tsx
24
src/main.tsx
@@ -67,7 +67,12 @@ const main = async () => {
|
|||||||
const player = new Player(board, gameConfig);
|
const player = new Player(board, gameConfig);
|
||||||
const game = new Game().loadPGN(pgn);
|
const game = new Game().loadPGN(pgn);
|
||||||
|
|
||||||
setState({ moves: game.getMoves() });
|
setState({
|
||||||
|
moves: game.getMoves(),
|
||||||
|
pgn,
|
||||||
|
ply: 0,
|
||||||
|
fen: game.getPosition(0).fen,
|
||||||
|
});
|
||||||
|
|
||||||
const handlers = {
|
const handlers = {
|
||||||
prev() {
|
prev() {
|
||||||
@@ -88,19 +93,24 @@ const main = async () => {
|
|||||||
},
|
},
|
||||||
toggleBorder() {
|
toggleBorder() {
|
||||||
board.toggleBorder();
|
board.toggleBorder();
|
||||||
|
setState("board", "showBorder", !state.board.showBorder);
|
||||||
},
|
},
|
||||||
|
|
||||||
showBorder() {
|
showBorder() {
|
||||||
board.showBorder();
|
board.showBorder();
|
||||||
|
setState("board", "showBorder", true);
|
||||||
},
|
},
|
||||||
hideBorder() {
|
hideBorder() {
|
||||||
board.hideBorder();
|
board.hideBorder();
|
||||||
|
setState("board", "showBorder", false);
|
||||||
},
|
},
|
||||||
toggleExtraInfo() {
|
toggleExtraInfo() {
|
||||||
board.toggleExtraInfo();
|
board.toggleExtraInfo();
|
||||||
|
setState("board", "showExtraInfo", !state.board.showExtraInfo);
|
||||||
},
|
},
|
||||||
flip() {
|
flip() {
|
||||||
board.flip();
|
board.flip();
|
||||||
|
setState("board", "flipped", !state.board.flipped);
|
||||||
},
|
},
|
||||||
togglePlay() {
|
togglePlay() {
|
||||||
player.playing ? player.pause() : player.play();
|
player.playing ? player.pause() : player.play();
|
||||||
@@ -111,9 +121,11 @@ const main = async () => {
|
|||||||
},
|
},
|
||||||
changeBoardStyle(style: BoardStyle) {
|
changeBoardStyle(style: BoardStyle) {
|
||||||
board.setStyle(style);
|
board.setStyle(style);
|
||||||
|
setState("board", "boardStyle", style);
|
||||||
},
|
},
|
||||||
changePiecesStyle(style: PiecesStyle) {
|
changePiecesStyle(style: PiecesStyle) {
|
||||||
board.setPiecesStyle(style);
|
board.setPiecesStyle(style);
|
||||||
|
setState("board", "piecesStyle", style);
|
||||||
},
|
},
|
||||||
async loadPGN(pgn: string) {
|
async loadPGN(pgn: string) {
|
||||||
const game = new Game().loadPGN(pgn);
|
const game = new Game().loadPGN(pgn);
|
||||||
@@ -126,13 +138,21 @@ const main = async () => {
|
|||||||
await player.load(game);
|
await player.load(game);
|
||||||
},
|
},
|
||||||
async downloadImage() {
|
async downloadImage() {
|
||||||
const data = await createImage(state.fen, state.board, 1024);
|
const data = await createImage(
|
||||||
|
state.fen,
|
||||||
|
state.pgn,
|
||||||
|
state.ply,
|
||||||
|
state.board,
|
||||||
|
state.game.picSize
|
||||||
|
);
|
||||||
download(data, "fen", "png");
|
download(data, "fen", "png");
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
window.handlers = handlers;
|
window.handlers = handlers;
|
||||||
|
// @ts-ignore
|
||||||
|
window.state = state;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RENDER
|
* RENDER
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import isMobile from "is-mobile";
|
||||||
import { createStore } from "solid-js/store";
|
import { createStore } from "solid-js/store";
|
||||||
import { BoardConfig, GameConfig } from "./types";
|
import { BoardConfig, GameConfig } from "./types";
|
||||||
|
|
||||||
@@ -32,6 +33,7 @@ export type State = {
|
|||||||
fen: string;
|
fen: string;
|
||||||
moves: string[];
|
moves: string[];
|
||||||
ply: number;
|
ply: number;
|
||||||
|
mobile: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const initialState: State = {
|
const initialState: State = {
|
||||||
@@ -41,6 +43,7 @@ const initialState: State = {
|
|||||||
fen: "",
|
fen: "",
|
||||||
moves: [],
|
moves: [],
|
||||||
ply: 0,
|
ply: 0,
|
||||||
|
mobile: isMobile(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const [state, setState] = createStore(initialState);
|
const [state, setState] = createStore(initialState);
|
||||||
|
|||||||
@@ -131,14 +131,16 @@ export type BoardConfig = {
|
|||||||
flipped: boolean;
|
flipped: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type Size = "XS" | "S" | "M" | "L" | "XL";
|
||||||
|
|
||||||
export type GameConfig = {
|
export type GameConfig = {
|
||||||
titleScreen: boolean;
|
titleScreen: boolean;
|
||||||
fromPly: number | null;
|
fromPly: number | null;
|
||||||
toPly: number | null;
|
toPly: number | null;
|
||||||
loop: boolean;
|
loop: boolean;
|
||||||
format: "GIF" | "MP4" | "WebM";
|
format: "GIF" | "MP4" | "WebM";
|
||||||
picSize: "XS" | "S" | "M" | "L" | "XL";
|
picSize: Size;
|
||||||
animationSize: "XS" | "S" | "M" | "L" | "XL";
|
animationSize: Size;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type MaterialCount = {
|
export type MaterialCount = {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Component, createSignal } from "solid-js";
|
import { Component, createSignal, Show } from "solid-js";
|
||||||
import { Handlers } from "../../types";
|
import { Handlers } from "../../types";
|
||||||
import Scrollable from "./reusable/Scrollable";
|
import Scrollable from "./reusable/Scrollable";
|
||||||
import { state, setState } from "../../state";
|
import { state, setState } from "../../state";
|
||||||
@@ -83,60 +83,62 @@ const Share: Component<{ handlers: Handlers }> = (props) => {
|
|||||||
{copyId() === "fen-link" ? "Copied!" : "Copy link"}
|
{copyId() === "fen-link" ? "Copied!" : "Copy link"}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<h3>Image</h3>
|
<Show when={!state.mobile}>
|
||||||
<button
|
<h3>Image</h3>
|
||||||
classList={{
|
<button
|
||||||
share__size: true,
|
classList={{
|
||||||
"share__size--first": true,
|
share__size: true,
|
||||||
"share__size--active": state.game.animationSize === "XS",
|
"share__size--first": true,
|
||||||
}}
|
"share__size--active": state.game.picSize === "XS",
|
||||||
onClick={() => setState("game", "animationSize", "XS")}
|
}}
|
||||||
>
|
onClick={() => setState("game", "picSize", "XS")}
|
||||||
XS
|
>
|
||||||
</button>
|
XS
|
||||||
<button
|
</button>
|
||||||
classList={{
|
<button
|
||||||
share__size: true,
|
classList={{
|
||||||
"share__size--active": state.game.animationSize === "S",
|
share__size: true,
|
||||||
}}
|
"share__size--active": state.game.picSize === "S",
|
||||||
onClick={() => setState("game", "animationSize", "S")}
|
}}
|
||||||
>
|
onClick={() => setState("game", "picSize", "S")}
|
||||||
S
|
>
|
||||||
</button>
|
S
|
||||||
<button
|
</button>
|
||||||
classList={{
|
<button
|
||||||
share__size: true,
|
classList={{
|
||||||
"share__size--active": state.game.animationSize === "M",
|
share__size: true,
|
||||||
}}
|
"share__size--active": state.game.picSize === "M",
|
||||||
onClick={() => setState("game", "animationSize", "M")}
|
}}
|
||||||
>
|
onClick={() => setState("game", "picSize", "M")}
|
||||||
M
|
>
|
||||||
</button>
|
M
|
||||||
<button
|
</button>
|
||||||
classList={{
|
<button
|
||||||
share__size: true,
|
classList={{
|
||||||
"share__size--active": state.game.animationSize === "L",
|
share__size: true,
|
||||||
}}
|
"share__size--active": state.game.picSize === "L",
|
||||||
onClick={() => setState("game", "animationSize", "L")}
|
}}
|
||||||
>
|
onClick={() => setState("game", "picSize", "L")}
|
||||||
L
|
>
|
||||||
</button>
|
L
|
||||||
<button
|
</button>
|
||||||
classList={{
|
<button
|
||||||
share__size: true,
|
classList={{
|
||||||
"share__size--last": true,
|
share__size: true,
|
||||||
"share__size--active": state.game.animationSize === "XL",
|
"share__size--last": true,
|
||||||
}}
|
"share__size--active": state.game.picSize === "XL",
|
||||||
onClick={() => setState("game", "animationSize", "XL")}
|
}}
|
||||||
>
|
onClick={() => setState("game", "picSize", "XL")}
|
||||||
XL
|
>
|
||||||
</button>
|
XL
|
||||||
<button
|
</button>
|
||||||
class="share__btn"
|
<button
|
||||||
onClick={() => props.handlers.downloadImage()}
|
class="share__btn"
|
||||||
>
|
onClick={() => props.handlers.downloadImage()}
|
||||||
Save as image
|
>
|
||||||
</button>
|
Save as image
|
||||||
|
</button>
|
||||||
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
<div class="share__pgn">
|
<div class="share__pgn">
|
||||||
<h2>Game</h2>
|
<h2>Game</h2>
|
||||||
@@ -149,88 +151,88 @@ const Share: Component<{ handlers: Handlers }> = (props) => {
|
|||||||
<button class="share__btn">Copy markdown</button>
|
<button class="share__btn">Copy markdown</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="share__animation">
|
<Show when={!state.mobile}>
|
||||||
<h3>Animation</h3>
|
<div class="share__animation">
|
||||||
<button
|
<h3>Animation</h3>
|
||||||
classList={{
|
<button
|
||||||
share__size: true,
|
classList={{
|
||||||
"share__size--first": true,
|
share__size: true,
|
||||||
"share__size--active": state.game.picSize === "XS",
|
"share__size--first": true,
|
||||||
}}
|
"share__size--active": state.game.animationSize === "XS",
|
||||||
onClick={() => setState("game", "picSize", "XS")}
|
}}
|
||||||
>
|
onClick={() => setState("game", "animationSize", "XS")}
|
||||||
XS
|
>
|
||||||
</button>
|
XS
|
||||||
<button
|
</button>
|
||||||
classList={{
|
<button
|
||||||
share__size: true,
|
classList={{
|
||||||
"share__size--active": state.game.picSize === "S",
|
share__size: true,
|
||||||
}}
|
"share__size--active": state.game.animationSize === "S",
|
||||||
onClick={() => setState("game", "picSize", "S")}
|
}}
|
||||||
>
|
onClick={() => setState("game", "animationSize", "S")}
|
||||||
S
|
>
|
||||||
</button>
|
S
|
||||||
<button
|
</button>
|
||||||
classList={{
|
<button
|
||||||
share__size: true,
|
classList={{
|
||||||
"share__size--active": state.game.picSize === "M",
|
share__size: true,
|
||||||
}}
|
"share__size--active": state.game.animationSize === "M",
|
||||||
onClick={() => setState("game", "picSize", "M")}
|
}}
|
||||||
>
|
onClick={() => setState("game", "animationSize", "M")}
|
||||||
M
|
>
|
||||||
</button>
|
M
|
||||||
<button
|
</button>
|
||||||
classList={{
|
<button
|
||||||
share__size: true,
|
classList={{
|
||||||
"share__size--active": state.game.picSize === "L",
|
share__size: true,
|
||||||
}}
|
"share__size--active": state.game.animationSize === "L",
|
||||||
onClick={() => setState("game", "picSize", "L")}
|
}}
|
||||||
>
|
onClick={() => setState("game", "animationSize", "L")}
|
||||||
L
|
>
|
||||||
</button>
|
L
|
||||||
<button
|
</button>
|
||||||
classList={{
|
<button
|
||||||
share__size: true,
|
classList={{
|
||||||
"share__size--last": true,
|
share__size: true,
|
||||||
"share__size--active": state.game.picSize === "XL",
|
"share__size--last": true,
|
||||||
}}
|
"share__size--active": state.game.animationSize === "XL",
|
||||||
onClick={() => setState("game", "picSize", "XL")}
|
}}
|
||||||
>
|
onClick={() => setState("game", "animationSize", "XL")}
|
||||||
XL
|
>
|
||||||
</button>
|
XL
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
classList={{
|
classList={{
|
||||||
share__format: true,
|
share__format: true,
|
||||||
"share__format--first": true,
|
"share__format--first": true,
|
||||||
"share__format--active": state.game.format === "GIF",
|
"share__format--active": state.game.format === "GIF",
|
||||||
}}
|
}}
|
||||||
onClick={() => setState("game", "format", "GIF")}
|
onClick={() => setState("game", "format", "GIF")}
|
||||||
>
|
>
|
||||||
GIF
|
GIF
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
classList={{
|
classList={{
|
||||||
share__format: true,
|
share__format: true,
|
||||||
"share__format--active": state.game.format === "MP4",
|
"share__format--active": state.game.format === "MP4",
|
||||||
}}
|
}}
|
||||||
onClick={() => setState("game", "format", "MP4")}
|
onClick={() => setState("game", "format", "MP4")}
|
||||||
>
|
>
|
||||||
MP4
|
MP4
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
classList={{
|
classList={{
|
||||||
share__format: true,
|
share__format: true,
|
||||||
"share__format--last": true,
|
"share__format--last": true,
|
||||||
"share__format--active": state.game.format === "WebM",
|
"share__format--active": state.game.format === "WebM",
|
||||||
}}
|
}}
|
||||||
onClick={() => setState("game", "format", "WebM")}
|
onClick={() => setState("game", "format", "WebM")}
|
||||||
>
|
>
|
||||||
WebM
|
WebM
|
||||||
</button>
|
</button>
|
||||||
|
<button class="share__create-animation">Save animation</button>
|
||||||
<button class="share__create-animation">Save animation</button>
|
</div>
|
||||||
</div>
|
</Show>
|
||||||
</Scrollable>
|
</Scrollable>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
const sizeToPX = {
|
|
||||||
XS: "256",
|
|
||||||
S: "512",
|
|
||||||
M: "720",
|
|
||||||
L: "1024",
|
|
||||||
XL: "1440",
|
|
||||||
};
|
|
||||||
|
|
||||||
export default sizeToPX;
|
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
const download = (data: string | Blob, name: string, ext: string) => {
|
const download = (data: string, name: string, ext: string) => {
|
||||||
const url = typeof data === "string" ? data : URL.createObjectURL(data);
|
const url = typeof data === "string" ? data : URL.createObjectURL(data);
|
||||||
|
|
||||||
const link = document.createElement("a");
|
const link = document.createElement("a");
|
||||||
link.href = url;
|
link.href = url;
|
||||||
link.download = `${name}_${Date.now()}.${ext}`;
|
link.download = `${name}_${Date.now()}.${ext}`;
|
||||||
|
link.target = "_blank";
|
||||||
link.click();
|
link.click();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user