Skip to content

Commit

Permalink
Updates
Browse files Browse the repository at this point in the history
  • Loading branch information
QuazChick committed Oct 8, 2022
1 parent 098737b commit 6179c88
Show file tree
Hide file tree
Showing 15 changed files with 220 additions and 166 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
.DS_Store
node_modules
.cache
dist
dist
4 changes: 2 additions & 2 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2022 QuazChick
Copyright (c) 2022 Uspel

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand All @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SOFTWARE.
197 changes: 128 additions & 69 deletions README.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion example/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Playground</title>
<title>Framage Playground</title>
</head>

<body>
Expand Down
25 changes: 8 additions & 17 deletions example/index.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,25 @@
import "react-app-polyfill/ie11";
import React, { useState } from "react";
import React from "react";
import { createRoot } from "react-dom/client";
import Framage, { FramageElement } from ".././";
import Framage from ".././";
import "./styles.scss";

const App = () => {
const framage = React.useRef<FramageElement>(null);
const [clicked, setClicked] = React.useState<boolean | undefined>();
const [frame, setFrame] = useState(0);
return (
<main>
<div>
<Framage
ref={framage}
src="https://react-texture-atlas.quazchick.com/demo.png"
src="https://github.com/Uspel/react-framage/blob/main/images/demo.png"
alt=""
view={{ width: 15, height: 15 }}
animation={{
frames: clicked
? [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
initial: clicked === undefined ? 9 : undefined,
frames: {
amount: 10,
pattern: f => [...f, ...[...f].reverse()]
},
step: 15,
fps: 1,
mode: "keep-on-last",
mode: "loop",
orientation: "horizontal",
onStart(e) {
console.log(`onStart:\n frame ${e.frame}\n steps ${e.steps}`);
Expand All @@ -36,15 +32,10 @@ const App = () => {
},
onChange(e) {
console.log(`onChange:\n frame ${e.frame}\n steps ${e.steps}`);
e.frame === 1 && setFrame(e.frame);
}
}}
/>
</div>

<button onClick={() => setClicked(c => (!c ? true : false))}>
Click {frame}
</button>
</main>
);
};
Expand Down
8 changes: 0 additions & 8 deletions example/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,4 @@ main {
display: block;
border: 3px solid #bbb;
padding: 0;
button {
display: block;
width: 100%;
height: 30px;
border-radius: 0;
border: 3px solid #ccc;
background-color: #fff;
}
}
Binary file added images/demo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 7 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
{
"version": "1.0.0",
"name": "react-framage",
"description": "Display specific portions of an image, and animate between sprites.",
"description": "Display specific portions of an image, and animate between frames.",
"keywords": [
"animation",
"atlas",
"image",
"react",
"react-component",
"reactjs",
"spritesheet",
"texture"
"spritesheet"
],
"author": "QuazChick",
"author": "Uspel",
"license": "MIT",
"main": "dist/index.js",
"homepage": "https://react-texture-atlas.quazchick.com",
"repository": "https://github.com/QuazChick/react-texture-atlas",
"repository": "https://github.com/Uspel/react-framage",
"typings": "dist/index.d.ts",
"files": [
"dist"
Expand Down Expand Up @@ -48,14 +45,14 @@
"singleQuote": false,
"trailingComma": "none"
},
"module": "dist/react-texture-atlas.esm.js",
"module": "dist/react-framage.esm.js",
"size-limit": [
{
"path": "dist/react-texture-atlas.cjs.production.min.js",
"path": "dist/react-framage.cjs.production.min.js",
"limit": "10 KB"
},
{
"path": "dist/react-texture-atlas.esm.js",
"path": "dist/react-framage.esm.js",
"limit": "10 KB"
}
],
Expand Down
19 changes: 14 additions & 5 deletions src/components/framage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,21 @@ export const Framage = forwardRef(function Framage(
const [frame, isDestroyed] = useFramage(animation, wrapper.current);

const origins = {
x: view.originX ?? 0,
y: view.originY ?? 0
x: view.left ?? 0,
y: view.top ?? 0
};
const steps =
const frames = Array.from(
{ length: animation && animation.frames.amount },
(_, i) => i
);
const pattern =
animation &&
(animation.frames instanceof Array ? animation.frames[frame] : frame);
(animation.frames.pattern
? typeof animation.frames.pattern === "function"
? animation.frames.pattern(frames)
: animation.frames.pattern
: frames);
const steps = pattern[frame];

function getPosition(orientation: "vertical" | "horizontal") {
const axis = orientation === "vertical" ? "y" : "x";
Expand Down Expand Up @@ -112,7 +121,7 @@ react-framage img {
return !isDestroyed ? (
<react-framage
ref={wrapper}
frame={frame}
frame={!frame ? undefined : frame}
steps={steps}
style={{ img, ...style }}
>
Expand Down
7 changes: 7 additions & 0 deletions src/elements/framage.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
/// <reference path="../types.ts"/>

/**
`<react-framage>` element created by `<Framage>` component.
@version 1.0.0
@see https://npmjs.com/package/react-framage#framageelement
*/
export class FramageElement extends HTMLElement {
readonly frame: number;
readonly steps: number;
Expand Down
37 changes: 20 additions & 17 deletions src/hooks/framage.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/// <reference path="../types.ts"/>
import { useEffect, useRef, useState } from "react";
/** Hook used by `<Framage />`.
/** A custom hook used by `<Framage>`.
Returns an array containing the current frame index and a boolean representing whether or not the animation is destroyed.
@param animation Animation settings, the same options as the `<Framage />` prop.
@param animation Animation settings, the same options as the `<Framage>` prop.
@param element `HTMLElement` to trigger events on. Prop event handlers do not require this.
@version 1.0.0
@see https://npmjs.com/package/react-framage#useframage
Expand All @@ -12,16 +12,26 @@ export function useFramage(
animation: FramageAnimation,
element?: HTMLElement
): [number, boolean] {
const [frame, setFrame] = useState((animation && animation.initial) ?? 0);
const [frame, setFrame] = useState(
(animation && animation.frames.initial) ?? 0
);
const [isDestroyed, setIsDestroyed] = useState(false);
const interval = useRef<NodeJS.Timer | undefined>();

// Final frame index
const finalFrame =
const frames = Array.from(
{ length: animation && animation.frames.amount },
(_, i) => i
);
const pattern =
animation &&
(animation.frames instanceof Array
? animation.frames.length
: animation.frames) - 1;
(animation.frames.pattern
? typeof animation.frames.pattern === "function"
? animation.frames.pattern(frames)
: animation.frames.pattern
: frames);

// Final frame index
const finalFrame = pattern.length - 1;

function triggerEvent(
type: "start" | "end" | "destroy" | "change",
Expand All @@ -30,11 +40,7 @@ export function useFramage(
// Event running
const e = new Event("framageanimation" + type) as FramageEvent;
// Amount of steps taken after frame change
const nextSteps =
animation &&
(animation.frames instanceof Array
? animation.frames[nextFrame]
: nextFrame);
const nextSteps = pattern[nextFrame];
e.frame = nextFrame;
e.steps = nextSteps;
element?.dispatchEvent(e);
Expand All @@ -51,9 +57,6 @@ export function useFramage(
: animation.mode === "keep-on-last" && frame === finalFrame
? finalFrame
: frame + 1);
console.log(
"Final: " + finalFrame + "\nNext: " + nextFrame + "\nCurrent: " + frame
);
if (animation && animation.fps !== 0) {
// ---------------
// Destruction
Expand Down Expand Up @@ -124,7 +127,7 @@ export function useFramage(
}
}, [animation]);
function setDefaults() {
setFrame((animation && animation.initial) ?? 0);
setFrame((animation && animation.frames.initial) ?? 0);
}
useEffect(() => {
if (animation) {
Expand Down
40 changes: 22 additions & 18 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,24 @@ declare global {
interface FramageProps extends React.ImgHTMLAttributes<HTMLImageElement> {
/**
Portion of the source image visible.
@param width Pixel width of the UV.
@param height Pixel height of the UV.
@param originX Initial X position of the UV (from the left).
@param originY Initial Y position of the UV (from the top).
@param width Pixel width.
@param height Pixel height.
@param left Initial X position of the view portion (from the left).
@param top Initial Y position of the view prtion (from the top).
*/
view: {
width: number;
height: number;
/** @default 0 */
originX?: number;
left?: number;
/** @default 0 */
originY?: number;
top?: number;
};
style?: React.CSSProperties & {
img?: React.CSSProperties;
};
/**
Settings for the atlas' animation - set to `false` for no animation.
Settings for the component's animation - set to `false` for no animation.
@default false (no animation)
*/
animation?: FramageAnimation;
Expand All @@ -33,37 +33,41 @@ declare global {
steps: number;
};
type FramageEventHandler = (e: FramageEvent) => void;
type FramageFramePattern = number[] | ((frames: number[]) => number[]);
type FramageAnimation =
| false
| ({
/**
Number of frames for the animation or array of frames as a pattern.
A value of the number `3` would have the same result as an array of `[0,1,2]`.
Animation's frame configuration.
*/
frames: number | number[];
/** Initial frame index. */
initial?: number;
/** Number of pixels the UV moves across the source image. */
frames: {
/** Number of frames in total on source. */
amount: number;
/** Order to display frames in. */
pattern?: FramageFramePattern;
/** Frame to start on first mount. */
initial?: number;
};
/** Number of pixels until next frame (usually view width). */
step: number;
/**
How the animation behaves.
How the animation cycles.
`"loop"` - repeats frames infinitely.
`"loop"` - repeats animation infinitely.
`"keep-on-last"` - once the last frame is reached, it will stay on that frame.
`"destroy-after-last"` - removes element when animation is complete.
@default "loop"
*/
mode?: "loop" | "keep-on-last" | "destroy-after-last";
/** X/Y direction the UV moves in for each frame. */
/** Direction the view portion moves in for each frame. */
orientation?: "horizontal" | "vertical";
/** Function to run on first frame. */
onStart?: FramageEventHandler;
/** Function to run on last frame. */
onEnd?: FramageEventHandler;
/** Function to run when atlas is destroyed by the `"destroy-after-last"` mode. */
/** Function to run when animation is destroyed by the `"destroy-after-last"` mode. */
onDestroy?: FramageEventHandler;
/**
Function to run every frame change.
Expand Down
24 changes: 8 additions & 16 deletions test/blah.test.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,12 @@
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import TextureAtlas from '../src';
/// <reference path="../src/types.ts"/>
import * as React from "react";
import * as ReactDOM from "react-dom";
import Framage from "../";

describe('it', () => {
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(
<TextureAtlas
src=""
width={10}
height={10}
uv={{ width: 1, height: 1 }}
base={{ width: 1, height: 1 }}
/>,
div
);
describe("it", () => {
it("renders without crashing", () => {
const div = document.createElement("div");
ReactDOM.render(<Framage src="" view={{ width: 1, height: 1 }} />, div);
ReactDOM.unmountComponentAtNode(div);
});
});

0 comments on commit 6179c88

Please sign in to comment.