1
0
Fork 0

New image loader

This commit is contained in:
Pabloader 2024-07-06 20:06:11 +00:00
parent d1ab00c558
commit 877742cafb
16 changed files with 84 additions and 84 deletions

View File

@ -1,20 +0,0 @@
import { plugin, type BunPlugin } from "bun";
const dataUrlPlugin: BunPlugin = {
name: "Data-url loader",
async setup(build) {
build.onLoad({ filter: /\.(png)$/ }, async (args) => {
const arrayBuffer = await Bun.file(args.path).arrayBuffer();
const buffer = Buffer.from(arrayBuffer);
return {
contents: `data:;base64,${buffer.toString('base64')}`,
loader: 'text',
};
});
}
};
plugin(dataUrlPlugin);
export default dataUrlPlugin;

View File

@ -1,7 +1,7 @@
import path from 'path';
import { minify } from 'html-minifier';
import dataUrlPlugin from './dataUrlPlugin';
import imagePlugin from './imagePlugin';
import fontPlugin from './fontPlugin';
import lightningcss from 'bun-lightningcss';
@ -22,7 +22,7 @@ export async function buildHTML(game: string, production = false) {
GAMES: JSON.stringify(await getGames()),
},
plugins: [
dataUrlPlugin,
imagePlugin,
fontPlugin,
lightningcss(),
]

24
src/build/imagePlugin.ts Normal file
View File

@ -0,0 +1,24 @@
import { plugin, type BunPlugin } from "bun";
const imagePlugin: BunPlugin = {
name: "Image loader",
async setup(build) {
build.onLoad({ filter: /\.(png|jpe?g)$/ }, async (args) => {
const arrayBuffer = await Bun.file(args.path).arrayBuffer();
const buffer = Buffer.from(arrayBuffer);
const src = `data:;base64,${buffer.toString('base64')}`;
return {
contents: `
const img = new Image();
img.src = (${JSON.stringify(src)});
export default img;
`,
loader: 'js',
};
});
}
};
plugin(imagePlugin);
export default imagePlugin;

12
src/common/types.d.ts vendored Normal file
View File

@ -0,0 +1,12 @@
declare module "*.png" {
const image: HTMLImageElement;
export default image;
}
declare module "*.jpg" {
const image: HTMLImageElement;
export default image;
}
declare module "*.jpeg" {
const image: HTMLImageElement;
export default image;
}

View File

@ -1,3 +1,22 @@
export const delay = async (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
export const nextFrame = async (): Promise<number> => new Promise((resolve) => requestAnimationFrame(resolve));
export const randInt = (min: number, max: number) => Math.round(min + (max - min - 1) * Math.random());
export const choice = (array: any[]) => array[randInt(0, array.length)];
export const range = (size: number | string) => Object.keys((new Array(+size)).fill(0)).map(k => +k);
export const prevent = (e: Event) => (e.preventDefault(), false);
export const intHash = (seed: number, ...parts: number[]) => {
let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed;
for (let i = 0; i < parts.length; i++) {
const ch = parts[i];
h1 = Math.imul(h1 ^ ch, 2654435761);
h2 = Math.imul(h2 ^ ch, 1597334677);
}
h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507);
h1 ^= Math.imul(h2 ^ (h2 >>> 13), 3266489909);
return h1;
};
export const sinHash = (...data: number[]) => data.reduce((hash, n) => Math.sin((hash * 123.12 + n) * 756.12), 0) / 2 + 0.5;

View File

@ -1,9 +1,10 @@
import Graphics from "./graphics";
import UI from "./ui";
import World from "./world";
import { pointsEquals, prevent } from "./utils";
import { pointsEquals } from "./utils";
import { prevent } from "@common/utils";
export default class Binario implements IGame {
export default class Binario {
private running = false;
private mouseDown: false | number = false;
private graphics;

View File

@ -11,7 +11,6 @@ export default class Graphics {
private offset: Point = [0, 0];
private highlighted: Point = [0, 0];
private tooltip: [Point, string] | null = null;
private firstStyleReset = false;
constructor(private canvas: HTMLCanvasElement) {
this.context = this.canvas.getContext('2d')!;

View File

@ -1,12 +1,12 @@
import { type Tile, TileType, getPortDirections, PortDirection, LIMITS, type Resource, getTileOutput, ResourceType } from "./world";
import { type Tile, TileType, getPortDirections, PortDirection, type Resource, getTileOutput, ResourceType } from "./world";
import { ALL_DIRECTIONS, Direction, makeImage, movePoint } from "./utils";
import { ALL_DIRECTIONS, Direction, movePoint } from "./utils";
import emptySrc from './assets/img/empty.png';
import extractorSrc from './assets/img/extractor.png';
import notSrc from './assets/img/not.png';
import andSrc from './assets/img/and.png';
import orSrc from './assets/img/or.png';
import emptyImage from './assets/img/empty.png';
import extractorImage from './assets/img/extractor.png';
import notImage from './assets/img/not.png';
import andImage from './assets/img/and.png';
import orImage from './assets/img/or.png';
export interface ViewConfig {
tileSize: number;
@ -19,12 +19,6 @@ type Renderers = {
[K in Tile['type']]?: Renderer<Extract<Tile, { type: K }>>
}
const emptyImage = makeImage(emptySrc);
const extractorImage = makeImage(extractorSrc);
const notImage = makeImage(notSrc);
const andImage = makeImage(andSrc);
const orImage = makeImage(orSrc);
export const renderResource = (ctx: CanvasRenderingContext2D, view: ViewConfig, tile: Tile) => {
let resources: [Direction, Resource | undefined][] | undefined;
if (tile.type === TileType.SOURCE) {

View File

@ -1,14 +1,14 @@
import React, { render } from 'preact';
import cn from 'classnames';
import { range } from './utils';
import { TileType } from './world';
import styles from './assets/ui.module.css';
import conveyorSrc from './assets/img/conveyor.png';
import extractorSrc from './assets/img/extractor.png';
import notSrc from './assets/img/not.png';
import andSrc from './assets/img/and.png';
import orSrc from './assets/img/or.png';
import conveyorImage from './assets/img/conveyor.png';
import extractorImage from './assets/img/extractor.png';
import notImage from './assets/img/not.png';
import andImage from './assets/img/and.png';
import orImage from './assets/img/or.png';
import { range } from '@common/utils';
export enum ToolType {
SELECT,
@ -30,31 +30,31 @@ const TOOLS: (Tool | null)[] = [
{
type: ToolType.EXTRACTOR,
title: 'Extractor',
icon: extractorSrc,
icon: extractorImage.src,
tileType: TileType.EXTRACTOR,
},
{
type: ToolType.CONVEYOR,
title: 'Conveyor',
icon: conveyorSrc,
icon: conveyorImage.src,
tileType: TileType.CONVEYOR,
},
{
type: ToolType.NOT,
title: 'Logical NOT',
icon: notSrc,
icon: notImage.src,
tileType: TileType.NOT,
},
{
type: ToolType.AND,
title: 'Logical AND',
icon: andSrc,
icon: andImage.src,
tileType: TileType.AND,
},
{
type: ToolType.OR,
title: 'Logical OR',
icon: orSrc,
icon: orImage.src,
tileType: TileType.OR,
},
null, // 6

View File

@ -105,22 +105,6 @@ export function trunc(input: Point): Point {
const EPS = 0.001;
export const pointsEquals = (a: Point, b: Point) => Math.abs(a[0] - b[0]) < EPS && Math.abs(a[1] - b[1]) < EPS;
export const prevent = (e: Event) => (e.preventDefault(), false);
export const cyrb32 = (seed: number, ...parts: number[]) => {
let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed;
for (let i = 0; i < parts.length; i++) {
const ch = parts[i];
h1 = Math.imul(h1 ^ ch, 2654435761);
h2 = Math.imul(h2 ^ ch, 1597334677);
}
h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507);
h1 ^= Math.imul(h2 ^ (h2 >>> 13), 3266489909);
return h1;
};
export const sinHash = (...data: number[]) => data.reduce((hash, n) => Math.sin((hash * 123.12 + n) * 756.12), 0) / 2 + 0.5;
export const range = (size: number | string) => Object.keys((new Array(+size)).fill(0)).map(k => +k);
export const getDirection = (point: Point): Direction => {
const [x, y] = point;
const absX = Math.abs(x);
@ -158,9 +142,3 @@ export const movePoint = (point: Point, direction: Direction, scale: number = 1)
point[0] + DIRECTION_VECTORS[direction][0] * scale,
point[1] + DIRECTION_VECTORS[direction][1] * scale,
];
export const makeImage = (src: string): HTMLImageElement => {
const image = new Image();
image.src = src;
return image;
}

View File

@ -1,4 +1,5 @@
import { ALL_DIRECTIONS, Direction, NEXT_DIRECTION, cyrb32, exp, getDirection, getOppositeDirection, isDirection, movePoint, pointsEquals, trunc } from "./utils";
import { intHash } from "@common/utils";
import { ALL_DIRECTIONS, Direction, NEXT_DIRECTION, exp, getDirection, getOppositeDirection, isDirection, movePoint, pointsEquals, trunc } from "./utils";
export enum TileType {
DESTINATION,
@ -343,7 +344,7 @@ export default class World {
}
private genTile(position: Point): Tile | null {
const hash = cyrb32(this.seed, ...position);
const hash = intHash(this.seed, ...position);
if ([42, 69, 0x42, 0x69].includes(hash & 0xFF)) {
let mask = 1;

View File

@ -1,7 +1,5 @@
import '@common/assets/vga.font.css';
import './assets/style.css';
import './assets/vga.font.css';
export default async function run(canvas: HTMLCanvasElement) {
canvas.remove();

View File

@ -6,8 +6,6 @@ export const randChar = (min = ' ', max = '~') =>
max.charCodeAt(0) + 1,
));
export const choice = (array: any[]) => array[randInt(0, array.length)];
export const generateColors = () => {
const colors: string[] = [];
for (let i = 0; i < 16; i++) {

4
src/types.d.ts vendored
View File

@ -3,10 +3,6 @@ type Rect = [number, number, number, number];
type RunGame = (canvas: HTMLCanvasElement) => Promise<void>;
declare module "*.png" {
const content: string;
export default content;
}
declare module '*.module.css' {
const classes: { [key: string]: string };
export default classes;