@abcnews/scrollyteller 中文文档教程
Scrollyteller
React
Usage
的 scrollyteller 组件 scrollyteller 获取一系列 panels 内容节点,并将它们转换为一系列元素,这些元素在
组件的子组件上滚动。
panels
属性的格式为:
[
{
data: {
info: 'Some kind of config that is given when this marker is active'
},
nodes: [<DOM elements for this panel>]
},
{
data: {
thing: 'This will be given when the second marker is hit'
},
nodes: [<DOM elements for this panel>]
}
]
当一个新框进入视图时,将使用传入面板的 data
调用 onMarker
。
import * as React from 'react';
import Scrollyteller from '@abcnews/scrollyteller';
// Some kind of dockable visualisation that goes with the scrolling text
import GraphicOfSomeKind from './GraphicOfSomeKind';
export default () => {
const [something, setSomething] = React.useState('');
const [progressPct, setProgresPct] = React.useState('');
// Content is loaded somehow into an array of { data: {...}, nodes: [...DOMNodes] }
const panels = ...?
return (
<Scrollyteller
panels={panels}
onMarker={({thing}) => setSomething(data.thing)}
onProgress={({pctAboveFold}) => setProgress(pctAboveFold)}>
<GraphicOfSomeKind property={something} />
</Scrollyteller>
);
}
有关使用 Typescript 的更完整示例,请参阅 vanilla 示例应用程序。
Customising
Scrollyteller
可以获取一个 panelClassName
属性,它将传递给每个面板组件以自定义外观。 它还可以采用 firstPanelClassName
和 lastPanelClassName
道具,它将传递给相应的面板组件,以自定义它们的特定外观。
要完全自定义面板的呈现方式,您可以传入 panelComponent
。 这个组件的主要要求是它调用 props.reference
并引用其最外层包装器。
import * as React from 'react';
interface Props {
nodes: HTMLElement[];
reference: (el: HTMLElement) => void;
}
export default (({nodes, reference}): Props) => {
const base = React.useRef(null);
const innerBase = React.useRef(null);
React.useEffect(() => {
reference(base.current);
nodes.forEach((node: HTMLElement) => {
innerBase.current.appendChild(node);
});
}, [reference]);
return (
<div ref={base} style={{ zIndex: 1, height: '80vh', fontSize: '40px' }}>
<strong>THIS IS A PANEL:</strong>
<div ref={innerBase} />
</div>
);
};
然后指定
。
Usage with Odyssey
使用 OdysseyABC News 故事时> 您可以使用 loadScrollyteller
函数在 CoreMedia 文章中收集 panels
。
在示例项目中查看更完整的Odyssey 用法示例。
CoreMedia 文本:
#scrollytellerVARIABLEvalue
This is the opening paragraph panel
#markVARIABLEvalue
This is a second panel
#markVARval
This is another paragraph
#endscrollyteller
JS 代码:
import Scrollyteller, { loadScrollyteller } from '@abcnews/scrollyteller';
const scrollyData = loadScrollyteller(
"", // If set to eg. "one" use #scrollytellerNAMEone in CoreMedia
"u-full", // Class to apply to mount point u-full makes it full width in Odyssey
"mark" // Name of marker in CoreMedia eg. for "point" use #point default: #mark
);
// Then pass them to the Scrollyteller component
ReactDOM.render(
<Scrollyteller panels={scrollyData.panels} {...scrollyData.config} />,
scrollyData.mountNode
);
// You could also use React Portals to mount on the mount node
ReactDOM.createPortal(
<Scrollyteller ... />,
scrollyData.mountNode
);
Development
该项目使用 tsdx 构建/开发工具和 np 用于发布管理。
推荐的工作流程是在一个终端中运行 TSDX:
npm start
这构建到 /dist
并以监视模式运行项目,因此您在 src
中保存的任何编辑都会导致重建到 /分布。
然后在另一个中运行示例:
cd example
npm i
aunty serve
该示例导入并实时重新加载 /dist
中的任何内容,因此如果您看到过时的组件,确保 TSDX 按照上面的建议在监视模式下运行。
要进行一次性构建,请使用 npm run build
。
要运行测试,请使用 npm test
或 yarn test
。
Example
主要是为了帮助开发和演示用法,/example
中有一个示例项目。 它使用 aunty 作为构建工具来匹配通常的 ABC 新闻交互式开发工作流程。
Jest
Jest 测试设置为使用 npm test
或 yarn test
运行。
Bundle analysis
使用 size-limit 和 npm run size
计算你的库的实际成本,并用<代码>npm 运行分析。
Releasing
要将新版本发布到 NPM,请运行 npm run release
并按照提示操作。
Jest
Jest 测试设置为使用 npm test
或 yarn test
运行。
Bundle analysis
使用 size-limit 和 npm run size
计算你的库的实际成本,并用<代码>npm 运行分析。
Optimizations
请参阅主要的 tsdx
优化文档。 尤其要知道您可以利用仅限开发的优化:
// ./types/index.d.ts
declare var __DEV__: boolean;
// inside your code...
if (__DEV__) {
console.log('foo');
}
Authors
- Nathan Hoad (nathan@nathanhoad.net)
- Simon Elvery (elvery.simon@abc.net.au)
- Joshua Byrd (byrd.joshua@abc.net.au)
- Colin Gourlay (gourlay.colin@abc.net.au)
请参阅贡献者的完整列表。
Scrollyteller
A scrollyteller component for React
Usage
The scrollyteller takes a series of panels of content nodes and turns them into a series of elements which scroll over the <Scrollyteller>
component's children.
The panels
prop is in the format of:
[
{
data: {
info: 'Some kind of config that is given when this marker is active'
},
nodes: [<DOM elements for this panel>]
},
{
data: {
thing: 'This will be given when the second marker is hit'
},
nodes: [<DOM elements for this panel>]
}
]
When a new box comes into view onMarker
will be called with the data
of the incoming panel.
import * as React from 'react';
import Scrollyteller from '@abcnews/scrollyteller';
// Some kind of dockable visualisation that goes with the scrolling text
import GraphicOfSomeKind from './GraphicOfSomeKind';
export default () => {
const [something, setSomething] = React.useState('');
const [progressPct, setProgresPct] = React.useState('');
// Content is loaded somehow into an array of { data: {...}, nodes: [...DOMNodes] }
const panels = ...?
return (
<Scrollyteller
panels={panels}
onMarker={({thing}) => setSomething(data.thing)}
onProgress={({pctAboveFold}) => setProgress(pctAboveFold)}>
<GraphicOfSomeKind property={something} />
</Scrollyteller>
);
}
For a more complete example using Typescript see the vanilla example app.
Customising
The Scrollyteller
can take a panelClassName
prop which it will pass to each panel component for customising the look. It can also take firstPanelClassName
and lastPanelClassName
props which it will pass to the respective panel components, for customising their specific looks.
To completely customise how panels are rendered you can pass in panelComponent
. The main requirement for this component is that it calls props.reference
with a ref to its outermost wrapper.
import * as React from 'react';
interface Props {
nodes: HTMLElement[];
reference: (el: HTMLElement) => void;
}
export default (({nodes, reference}): Props) => {
const base = React.useRef(null);
const innerBase = React.useRef(null);
React.useEffect(() => {
reference(base.current);
nodes.forEach((node: HTMLElement) => {
innerBase.current.appendChild(node);
});
}, [reference]);
return (
<div ref={base} style={{ zIndex: 1, height: '80vh', fontSize: '40px' }}>
<strong>THIS IS A PANEL:</strong>
<div ref={innerBase} />
</div>
);
};
And then specify <Scrollyteller panelComponent={CustomPanel}>
.
Usage with Odyssey
When developing ABC News stories with Odyssey you can use the loadScrollyteller
function to gather panels
within a CoreMedia article.
See a more complete usage example with Odyssey in the example project.
CoreMedia text:
#scrollytellerVARIABLEvalue
This is the opening paragraph panel
#markVARIABLEvalue
This is a second panel
#markVARval
This is another paragraph
#endscrollyteller
JS Code:
import Scrollyteller, { loadScrollyteller } from '@abcnews/scrollyteller';
const scrollyData = loadScrollyteller(
"", // If set to eg. "one" use #scrollytellerNAMEone in CoreMedia
"u-full", // Class to apply to mount point u-full makes it full width in Odyssey
"mark" // Name of marker in CoreMedia eg. for "point" use #point default: #mark
);
// Then pass them to the Scrollyteller component
ReactDOM.render(
<Scrollyteller panels={scrollyData.panels} {...scrollyData.config} />,
scrollyData.mountNode
);
// You could also use React Portals to mount on the mount node
ReactDOM.createPortal(
<Scrollyteller ... />,
scrollyData.mountNode
);
Development
This project uses tsdx for build/dev tooling and np for release management.
The recommended workflow is to run TSDX in one terminal:
npm start
This builds to /dist
and runs the project in watch mode so any edits you save inside src
causes a rebuild to /dist
.
Then run the example inside another:
cd example
npm i
aunty serve
The example imports and live reloads whatever is in /dist
, so if you are seeing an out of date component, make sure TSDX is running in watch mode as recommended above.
To do a one-off build, use npm run build
.
To run tests, use npm test
or yarn test
.
Example
Mostly to aid development and demonstrate usage, there is an example project in /example
. It uses aunty as the build tool to match the usual ABC News interactive development work flow.
Jest
Jest tests are set up to run with npm test
or yarn test
.
Bundle analysis
Calculates the real cost of your library using size-limit with npm run size
and visulize it with npm run analyse
.
Releasing
To release a new version to NPM run npm run release
and follow the prompts.
Jest
Jest tests are set up to run with npm test
or yarn test
.
Bundle analysis
Calculates the real cost of your library using size-limit with npm run size
and visulize it with npm run analyze
.
Optimizations
Please see the main tsdx
optimizations docs. In particular, know that you can take advantage of development-only optimizations:
// ./types/index.d.ts
declare var __DEV__: boolean;
// inside your code...
if (__DEV__) {
console.log('foo');
}
Authors
- Nathan Hoad (nathan@nathanhoad.net)
- Simon Elvery (elvery.simon@abc.net.au)
- Joshua Byrd (byrd.joshua@abc.net.au)
- Colin Gourlay (gourlay.colin@abc.net.au)
See the full list of contributors.