
Research
Security News
Lazarus Strikes npm Again with New Wave of Malicious Packages
The Socket Research Team has discovered six new malicious npm packages linked to North Korea’s Lazarus Group, designed to steal credentials and deploy backdoors.
animation-timeline-js
Advanced tools
Animation timeline is a TypeScript, no-dependency, canvas component designed to visualize and manipulate animation keyframes.
Features:
npm i animation-timeline-js
<div id="timeline"></div>
<script type="text/javascript">
let rows = [
{
keyframes: [
{
val: 40,
},
{
val: 3000
}
]
}];
let timeline = new timelineModule.Timeline({id:'timeline'})
timeline.setModel({ rows: rows });
</script>
import {
Timeline,
TimelineRow,
TimelineModel,
TimelineOptions,
} from "animation-timeline-js";
const model = { rows: [] as Array<TimelineRow> } as TimelineModel;
const options = {
id: "timeline",
rowsStyle: {
height: 35,
} as TimelineRowStyle,
} as TimelineOptions;
const timeline = new Timeline(options, model);
import React, { useEffect, useRef, useState } from "react";
import { Timeline, TimelineModel } from "animation-timeline-js";
type Props = {
time?: number;
model: TimelineModel;
};
function TimelineComponent(props: Props) {
const { model, time } = props;
const timelineElRef = useRef<HTMLDivElement>(null);
const [timeline, setTimeline] = useState<Timeline>();
useEffect(() => {
let newTimeline: Timeline | null = null;
// On component init
if (timelineElRef.current) {
newTimeline = new Timeline({ id: timelineElRef.current });
// Here you can subscribe on timeline component events
setTimeline(newTimeline);
}
// cleanup on component unmounted.
return () => newTimeline?.dispose();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [timelineElRef.current]);
// Example to subscribe and pass model or time update:
useEffect(() => {
timeline?.setModel(model);
}, [model, timeline]);
// Example to subscribe and pass model or time update:
useEffect(() => {
if (time || time === 0) {
timeline?.setTime(time);
}
}, [time, timeline]);
return <div style={{ width: "100%", minHeight: 300 }} ref={timelineElRef} />;
}
export default TimelineComponent;
// Usage:
<TimelineComponent
time={0}
model={{
rows: [
{
keyframes: [
{
val: 40,
},
{
val: 3000,
},
],
},
],
}}
></TimelineComponent>
<script lang="ts">
import { Timeline } from "animation-timeline-js";
import type { TimelineModel } from "animation-timeline-js";
import { onMount } from "svelte";
export let time: number = 0;
export let model: TimelineModel;
let timelineEl!: HTMLDivElement;
let timeline: Timeline | null = null;
// Equivalent to componentDidMount and componentWillUnmount
onMount(() => {
let newTimeline: Timeline | null = null;
if (timelineEl) {
newTimeline = new Timeline({ id: timelineEl });
}
timeline = newTimeline;
// Cleanup
return () => {
if (newTimeline) {
newTimeline.dispose();
}
};
});
$: if (model) {
// Reactive statements for model and time
timeline?.setModel(model);
}
$: if (time || time === 0) {
timeline?.setTime(time);
}
</script>
<div bind:this={timelineEl} class="editor"></div>
<style>
.editor {
width: 100%;
min-height: 300px;
}
</style>
// Usage:
<TimelineComponent
time={0}
model={{
rows: [
{
keyframes: [
{
val: 40,
},
{
val: 3000,
},
],
},
],
}}
></TimelineComponent>
Outline list\tree can implemented as a separate HTML component and scrolling needs to be synchronized with the timeline. See the live demo
Next steps has to be followed to synchronize custom tree view html with the timeline component:
Keyframes model is used to pass keyframes and rows to be visualized. Component is using passed model for the visualization purpose and has no method to manage tracks or keyframes. It also means that any attached metadata can be passed and it will be preserved (Use case: you can attach additional data for each keyframe).
Read only and defined by the interfaces:
Example on how to add a keyframe to existing model:
const existingModel = timeline.getModel();
existingModel.rows[0].keyframes.append({ val: 20 });
timeline.setModel(existingModel);
Event name | description |
---|---|
timeChanged | time changed. source can be used to check event sender. args type: TimelineTimeChangedEvent |
selected | keyframe is selected. args type: TimelineSelectedEvent |
scroll | On scroll. args type: TimelineScrollEvent |
scrollFinished | On scroll finished. args type: TimelineScrollEvent |
dragStarted | emitted on drag started. args type: TimelineDragEvent |
drag | emitted when dragging. args type: TimelineDragEvent |
dragFinished | emitted when drag finished. args type: TimelineDragEvent |
keyframeChanged | emitted when drag finished. args type: TimelineKeyframeChangedEvent |
onContextMenu | emitted on context menu displayed. args type: TimelineKeyframeChangedEvent |
Events can be prevented by calling args.preventDefault()
Events subscription is performed in the JavaScript (not a DOM events):
this.timeline.onDragStarted((args: TimelineDragEvent) => {
if (args) {
}
});
Method name | description |
---|---|
setTime | set current active time. Returns bool to indicate whether time was set. Ex: cannot be changed when dragged. Also timeline interactions can be disabled. |
getTime | get current position of the timeline. |
dispose | Call to unsubscribe from all the events. Important when UI component is unmounted or page is closed. |
setOptions | Set timeline properties |
getOptions | Get current options of the timeline. |
getAllKeyframes | Get array of all keyframes from the current active model. |
Options can be passed when timeline is created or by calling setOptions method. See all options in the TimelineOptions interface.
Main options:
Property | description |
---|---|
groupsDraggable | keyframes group is draggable. Default: true |
keyframesDraggable | keyframes group is draggable. Default: true |
timelineDraggable | Timeline can be dragged or position can be changed by user interaction. Default True |
Keyframes can be marked as selectable = false to prevent interaction.
Selection - allow to select one or group of the keyframes.
Example:
timeline.setInteractionMode('none');
For the TypeScript TimelineInteractionMode enum is used.
Expected that you have a component or engine that can execute playing a timeline. Ex: SVG has events to run the animations and report current time position. This component is meant only to visualize the position.
Time indicator position can be changed by a method call:
timeline.setTime(1000);
Current time can be fetched by a method call or by an event:
let value = timeline.getTime();
timeline.onTimeChanged((event: TimelineTimeChangedEvent) => {
if(event.source !== TimelineEventSource.User) {
value = event.val;
}
});
Displayed units text can be changed by overriding a method:
timeline._formatUnitsText = (val)=> { return val + ' ms'; };
The timeline component is rendered as a canvas and has no HTML elements for CSS styling. Styles are applied as a part of the keyframes model and can be applied in a cascade order from bottom to the top:
Separate global styles for the timeline indicator are used:
See Changelog here
run once to install development references:
npm install
Run next command to pack JavaScript as a bundle:
npm run build
VSCode is used as IDE and configuration is included to the project sources.
To debug project you should run command once files are changed:
npm run build
Then navigate to the VsCode debug window and click 'Launch Debug File'. Put breakpoint in any typescript file and trigger function from the browser.
Recommended extensions:
Component has no production dependencies when built. TypeScript Babel + Webpack is used to pack and transpile the library. Mocha and chai are used as test & assertion library.
npm run test
MIT
[2.3.5] - 21.07.2024
FAQs
animation timeline control based on the canvas.
We found that animation-timeline-js demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
The Socket Research Team has discovered six new malicious npm packages linked to North Korea’s Lazarus Group, designed to steal credentials and deploy backdoors.
Security News
Socket CEO Feross Aboukhadijeh discusses the open web, open source security, and how Socket tackles software supply chain attacks on The Pair Program podcast.
Security News
Opengrep continues building momentum with the alpha release of its Playground tool, demonstrating the project's rapid evolution just two months after its initial launch.