Don't use canvas I guess

This commit is contained in:
Lani Aung
2021-10-11 21:08:17 -06:00
parent 590c84b81f
commit d1d891881f
11 changed files with 84 additions and 111 deletions
+5 -7
View File
@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using fxl.codes.kisekae.Services; using fxl.codes.kisekae.Services;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@@ -58,13 +59,10 @@ namespace fxl.codes.kisekae.Models
public bool[] Sets { get; } = new bool[10]; public bool[] Sets { get; } = new bool[10];
public string Comment { get; init; } public string Comment { get; init; }
public Coordinate[] InitialPositions { get; } = new Coordinate[10]; public Coordinate[] InitialPositions { get; } = new Coordinate[10];
public string DefaultImage => ImageByPalette.ContainsKey(PaletteId) ? ImageByPalette[PaletteId] : null; [JsonIgnore] public string DefaultImage => ImageByPalette.ContainsKey(PaletteId) ? ImageByPalette[PaletteId] : null;
public Coordinate Offset { get; set; } public Coordinate Offset { get; set; }
[JsonIgnore] public int Height { get; internal set; }
public Coordinate PositionForSet(int set) [JsonIgnore] public int Width { get; internal set; }
{ [JsonIgnore] public int ZIndex { get; internal set; }
var current = InitialPositions[set];
return current == null ? new Coordinate(0, 0) : new Coordinate(current.X + Offset.X, current.Y + Offset.Y);
}
} }
} }
+6 -8
View File
@@ -1,17 +1,17 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Serialization;
using SixLabors.ImageSharp; using SixLabors.ImageSharp;
namespace fxl.codes.kisekae.Models namespace fxl.codes.kisekae.Models
{ {
public class PlaysetModel public class PlaysetModel
{ {
public int[] CurrentPalettes = new int[10];
public string Name { get; set; } public string Name { get; set; }
public int Height { get; set; } public int Height { get; set; }
public int Width { get; set; } public int Width { get; set; }
public Color BorderColor { get; set; } = Color.Black; [JsonIgnore] public Color BorderColor { get; set; } = Color.Black;
[JsonIgnore] public List<PaletteModel> Palettes { get; } = new();
public List<PaletteModel> Palettes { get; } = new();
public List<CelModel> Cels { get; } = new(); public List<CelModel> Cels { get; } = new();
public bool[] EnabledSets public bool[] EnabledSets
@@ -19,10 +19,8 @@ namespace fxl.codes.kisekae.Models
get get
{ {
var enabled = new bool[10]; var enabled = new bool[10];
foreach (var cel in Cels)
for (var index = 0; index < cel.Sets.Length; index++) for (var index = 0; index < enabled.Length; index++) enabled[index] = Cels.Any(x => x.Sets[index]);
if (cel.Sets[index])
enabled[index] = true;
return enabled; return enabled;
} }
+14 -33
View File
@@ -1,43 +1,24 @@
import {ICel, IPlayset} from "./pto" import {Playset} from "./pto"
import Builder from "./utility";
export function draw(playset: IPlayset, canvas: HTMLCanvasElement, set: number): void { const cssClass = "active-set"
let context = canvas.getContext("2d")
context.clearRect(0, 0, canvas.width, canvas.height)
playset.cels.forEach(cel => { export function setPlayArea(header: HTMLElement, container: HTMLElement, playset: Playset, set: number): void {
drawToCanvas2dContext(cel, context, set)
})
}
export function drawToCanvas2dContext(cel: ICel, context: CanvasRenderingContext2D, set: number): void {
if (!cel.sets[set]) return
let image = new Image()
image.onload = () => {
context.drawImage(image, cel.initialPositions[set].x + cel.offset.x, cel.initialPositions[set].y + cel.offset.y)
}
image.src = `data:image/gif;base64,${cel.defaultImage}`
}
export function setPlayArea(header: HTMLElement, container: HTMLElement, playset: IPlayset, set: number): void {
const cssClass = "active-set"
header.querySelectorAll("button").forEach(button => { header.querySelectorAll("button").forEach(button => {
button.classList.remove(cssClass) button.classList.remove(cssClass)
}) })
header.querySelector(`button[data-set="${set}"]`).classList.add(cssClass) header.querySelector(`button[data-set="${set}"]`).classList.add(cssClass)
let elements = container.querySelectorAll(".cel-image")
let canvases = container.getElementsByTagName("canvas") playset.cels.forEach((cel, index) => {
if (canvases.length) { let element = elements[index] as HTMLDivElement
draw(playset, canvases[0], set) element.style.visibility = "hidden"
return
}
let canvas = new Builder("canvas") if (cel.sets[set]) {
.addAttributes({"height": playset.height, "width": playset.width}) let position = cel.currentPositions[set]
.build() element.style.visibility = "visible"
container.appendChild(canvas) element.style.left = `${position.x}px`
draw(playset, canvases[0], set) element.style.top = `${position.y}px`
}
})
} }
+7 -3
View File
@@ -2,7 +2,7 @@ import {MDCLinearProgress} from "@material/linear-progress"
import {MDCRipple} from "@material/ripple" import {MDCRipple} from "@material/ripple"
import {MDCTopAppBar} from "@material/top-app-bar" import {MDCTopAppBar} from "@material/top-app-bar"
import {setPlayArea} from "./function" import {setPlayArea} from "./function"
import {IPlayset} from "./pto" import {Playset} from "./pto"
import Builder from "./utility" import Builder from "./utility"
declare global { declare global {
@@ -28,7 +28,7 @@ export default class Main {
this.init() this.init()
} }
public load(containerId: string, headerId: string, playset: IPlayset, set: number = 0): void { public load(containerId: string, headerId: string, playset: Playset, set: number = 0): void {
let container = document.getElementById(containerId) let container = document.getElementById(containerId)
let header = document.getElementById(headerId) let header = document.getElementById(headerId)
let menu = header.querySelector("ul") let menu = header.querySelector("ul")
@@ -36,7 +36,7 @@ export default class Main {
let reset = header.querySelector(`button[data-rel="reset"]`) let reset = header.querySelector(`button[data-rel="reset"]`)
reset.addEventListener("click", () => { reset.addEventListener("click", () => {
// TODO reset positions // TODO reset positions
setPlayArea(header, container, playset, 0) setPlayArea(header, container, playset, set)
}) })
playset.enabledSets.forEach((enabled, index) => { playset.enabledSets.forEach((enabled, index) => {
@@ -58,6 +58,10 @@ export default class Main {
} }
}) })
playset.cels.forEach(cel => {
cel.currentPositions = [...cel.initialPositions]
})
setPlayArea(header, container, playset, set) setPlayArea(header, container, playset, set)
} }
+10 -3
View File
@@ -1,20 +1,27 @@
export interface IPlayset { export class Playset {
name: string name: string
height: number height: number
width: number width: number
cels: ICel[] cels: Cel[]
enabledSets: boolean[] enabledSets: boolean[]
} }
export interface ICel { export class Cel {
defaultImage: string defaultImage: string
initialPositions: Coordinate[] initialPositions: Coordinate[]
offset: Coordinate offset: Coordinate
sets: boolean[] sets: boolean[]
currentPositions: Coordinate[]
} }
export class Coordinate { export class Coordinate {
x: number x: number
y: number y: number
constructor(x: number = 0, y: number = 0) {
this.x = x
this.y = y
}
} }
+5 -19
View File
@@ -4,15 +4,14 @@ using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using fxl.codes.kisekae.Models; using fxl.codes.kisekae.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace fxl.codes.kisekae.Services namespace fxl.codes.kisekae.Services
{ {
public class ConfigurationReaderService public class ConfigurationReaderService
{ {
private readonly ILogger<ConfigurationReaderService> _logger;
private readonly FileParserService _fileParser; private readonly FileParserService _fileParser;
private readonly ILogger<ConfigurationReaderService> _logger;
public ConfigurationReaderService(ILogger<ConfigurationReaderService> logger, FileParserService fileParser) public ConfigurationReaderService(ILogger<ConfigurationReaderService> logger, FileParserService fileParser)
{ {
@@ -20,14 +19,6 @@ namespace fxl.codes.kisekae.Services
_fileParser = fileParser; _fileParser = fileParser;
} }
public PlaysetModel ReadCnf(IFormFile file)
{
_logger.LogTrace($"Reading filename {file.FileName}");
var set = ParseStream(file.OpenReadStream());
set.Name = file.FileName;
return set;
}
public PlaysetModel ParseStream(Stream fileStream, string directory = null) public PlaysetModel ParseStream(Stream fileStream, string directory = null)
{ {
var model = new PlaysetModel(); var model = new PlaysetModel();
@@ -69,18 +60,17 @@ namespace fxl.codes.kisekae.Services
SetInitialPositions(model, initialPositions.ToString()); SetInitialPositions(model, initialPositions.ToString());
if (string.IsNullOrEmpty(directory)) return model; if (string.IsNullOrEmpty(directory)) return model;
foreach (var palette in model.Palettes) foreach (var palette in model.Palettes) _fileParser.ParsePalette(directory, palette);
{
_fileParser.ParsePalette(directory, palette);
}
var celIndex = 0;
foreach (var cel in model.Cels.Where(x => !string.IsNullOrEmpty(x.FileName))) foreach (var cel in model.Cels.Where(x => !string.IsNullOrEmpty(x.FileName)))
{ {
_fileParser.ParseCel(directory, cel, model.Palettes); _fileParser.ParseCel(directory, cel, model.Palettes);
cel.ZIndex = (model.Cels.Count - celIndex) * 10;
celIndex++;
} }
if (model.Palettes.Any() && model.Palettes[0].Colors.Any()) model.BorderColor = model.Palettes[0].Colors[borderColorIndex]; if (model.Palettes.Any() && model.Palettes[0].Colors.Any()) model.BorderColor = model.Palettes[0].Colors[borderColorIndex];
model.Cels.Reverse();
return model; return model;
} }
@@ -91,17 +81,13 @@ namespace fxl.codes.kisekae.Services
for (var index = 0; index < sets.Length; index++) for (var index = 0; index < sets.Length; index++)
{ {
var value = sets[index].Split(' ', StringSplitOptions.RemoveEmptyEntries); var value = sets[index].Split(' ', StringSplitOptions.RemoveEmptyEntries);
model.CurrentPalettes[index] = int.Parse(value[0]);
for (var innerIndex = 1; innerIndex < value.Length; innerIndex++) for (var innerIndex = 1; innerIndex < value.Length; innerIndex++)
{ {
if (value[innerIndex] == "*") continue; if (value[innerIndex] == "*") continue;
var point = value[innerIndex].Split(',', StringSplitOptions.RemoveEmptyEntries); var point = value[innerIndex].Split(',', StringSplitOptions.RemoveEmptyEntries);
foreach (var cel in model.Cels.Where(x => x.Id == innerIndex - 1)) foreach (var cel in model.Cels.Where(x => x.Id == innerIndex - 1))
{
cel.InitialPositions[index] = new Coordinate(int.Parse(point[0]), int.Parse(point[1])); cel.InitialPositions[index] = new Coordinate(int.Parse(point[0]), int.Parse(point[1]));
}
} }
} }
} }
+4
View File
@@ -108,6 +108,8 @@ namespace fxl.codes.kisekae.Services
cel.ImageByPalette = GetCelImages(buffer[32..], palettes.ToArray(), width, height, pixelBits); cel.ImageByPalette = GetCelImages(buffer[32..], palettes.ToArray(), width, height, pixelBits);
cel.Offset = new Coordinate(xOffset, yOffset); cel.Offset = new Coordinate(xOffset, yOffset);
cel.Height = height;
cel.Width = width;
} }
else else
{ {
@@ -115,6 +117,8 @@ namespace fxl.codes.kisekae.Services
var height = BitConverter.ToInt16(buffer, 2); var height = BitConverter.ToInt16(buffer, 2);
cel.ImageByPalette = GetCelImages(buffer[4..], palettes.ToArray(), width, height); cel.ImageByPalette = GetCelImages(buffer[4..], palettes.ToArray(), width, height);
cel.Height = height;
cel.Width = width;
} }
} }
-20
View File
@@ -1,20 +0,0 @@
/* Error: Can't find stylesheet to import.
* ,
* 4 | / @use "~@material/theme" with (
* 5 | | $primary: $fxl-orange,
* 6 | | $on-primary: $fxl-gray
* 7 | | );
* | '-^
* '
* main.scss 4:1 root stylesheet */
body::before {
font-family: "Source Code Pro", "SF Mono", Monaco, Inconsolata, "Fira Mono",
"Droid Sans Mono", monospace, monospace;
white-space: pre;
display: block;
padding: 1em;
margin-bottom: 1em;
border-bottom: 2px solid black;
content: "Error: Can't find stylesheet to import.\a \2577 \a 4 \2502 \250c @use \"~@material/theme\" with (\a 5 \2502 \2502 $primary: $fxl-orange,\a 6 \2502 \2502 $on-primary: $fxl-gray\a 7 \2502 \2502 );\a \2502 \2514 \2500 ^\a \2575 \a main.scss 4:1 root stylesheet";
}
+7 -1
View File
@@ -53,8 +53,14 @@ body {
flex: 1; flex: 1;
text-align: center; text-align: center;
canvas { #play_space {
margin: 2em auto; margin: 2em auto;
position: relative;
.cel-image {
visibility: hidden;
position: absolute;
}
} }
} }
} }
+13 -4
View File
@@ -1,8 +1,7 @@
@model PlaysetModel @model PlaysetModel
@{ @{
ViewBag.Title = $"Play with {Model.Name}"; ViewData["Title"] = $"Play with {Model.Name}";
Layout = "_Layout";
} }
<header id="play_menu"> <header id="play_menu">
@@ -17,10 +16,20 @@
<li class="mdc-typography--button">Sets</li> <li class="mdc-typography--button">Sets</li>
</ul> </ul>
</header> </header>
<article id="play_area" style="background-color: #@Model.BorderColor"></article> <article id="play_area" style="background-color: #@Model.BorderColor">
<div id="play_space" style="height: @(Model.Height)px; width: @(Model.Width)px">
@foreach (var cel in Model.Cels)
{
<div class="cel-image"
style="background-image: url('data:image/gif;base64,@cel.DefaultImage'); height: @(cel.Height)px; width: @(cel.Width)px; z-index: @cel.ZIndex;"
data-id="@cel.Id"
data-fix="@cel.Fix"></div>
}
</div>
</article>
@section Scripts @section Scripts
{ {
<script> <script>
document.kisekae.load("play_area", "play_menu", @Json.Serialize(Model)) document.kisekae.load("play_space", "play_menu", @Json.Serialize(Model))
</script> </script>
} }
+6 -6
View File
@@ -2046,9 +2046,9 @@
"dev": true "dev": true
}, },
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.3.864", "version": "1.3.866",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.864.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.866.tgz",
"integrity": "sha512-v4rbad8GO6/yVI92WOeU9Wgxc4NA0n4f6P1FvZTY+jyY7JHEhw3bduYu60v3Q1h81Cg6eo4ApZrFPuycwd5hGw==", "integrity": "sha512-iYze6TpDXWxk+sfcpUUdTs6Pv/3kG45Pnjer2DxEeFw0N08bZeNLuz97s2lMgy8yObon48o0WHY2Bkg3xuAPOA==",
"dev": true "dev": true
}, },
"node_modules/emojis-list": { "node_modules/emojis-list": {
@@ -6018,9 +6018,9 @@
"dev": true "dev": true
}, },
"electron-to-chromium": { "electron-to-chromium": {
"version": "1.3.864", "version": "1.3.866",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.864.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.866.tgz",
"integrity": "sha512-v4rbad8GO6/yVI92WOeU9Wgxc4NA0n4f6P1FvZTY+jyY7JHEhw3bduYu60v3Q1h81Cg6eo4ApZrFPuycwd5hGw==", "integrity": "sha512-iYze6TpDXWxk+sfcpUUdTs6Pv/3kG45Pnjer2DxEeFw0N08bZeNLuz97s2lMgy8yObon48o0WHY2Bkg3xuAPOA==",
"dev": true "dev": true
}, },
"emojis-list": { "emojis-list": {