updated content

This commit is contained in:
Aminejvm 2021-03-31 20:00:12 +01:00
parent 1507320db3
commit bd17b1cb80
11 changed files with 136 additions and 68 deletions

View File

@ -19,6 +19,8 @@ export const Controller = ({
options,
onChange,
selectSuffix = "",
//NOTE(Amine): minWidth will remove junk when Select value change
selectMinWidth,
label,
min,
max,
@ -42,6 +44,7 @@ export const Controller = ({
value={value}
onChange={onChange}
placeholderSuffix={selectSuffix}
minWidth={selectMinWidth}
/>
<div style={{ width: "100%" }}>
<Slider
@ -203,7 +206,7 @@ export const AlignmentControl = ({
);
};
const STYLES_FEELING_LUCKY = (theme) => css`
const STYLES_SETTINGS_WRAPPER = (theme) => css`
box-sizing: border-box;
display: flex;
border-radius: 4px;
@ -236,11 +239,16 @@ const STYLES_FEELING_LUCKY = (theme) => css`
}
`;
const STYLES_FEELING_LUCKY = css`
width: 100%;
text-align: left;
`;
export const SettingsControl = ({ getRandomLayout, resetLayout }) => (
<div>
<P css={STYLES_LABEL}>Settings</P>
<div css={STYLES_FEELING_LUCKY}>
<button onClick={getRandomLayout}>
<div css={STYLES_SETTINGS_WRAPPER}>
<button css={STYLES_FEELING_LUCKY} onClick={getRandomLayout}>
<P
css={css`
font-size: 14px;
@ -251,7 +259,7 @@ export const SettingsControl = ({ getRandomLayout, resetLayout }) => (
</P>
</button>
<button className="reset_button" onClick={resetLayout}>
<SVG.RotateCcw />
<SVG.RotateCcw height={16} width={16} />
</button>
</div>
</div>

View File

@ -16,6 +16,9 @@ const CONTROLS_STYLES_WRAPPER = (theme) => css`
path {
stroke: ${theme.fontPreviewDarkMode ? theme.system.white : theme.system.black};
}
svg {
display: block;
}
`;
const CONTROLS_DARKMODE_WRAPPER = (theme) => css`
@ -34,9 +37,7 @@ const CONTROLS_DARKMODE_WRAPPER = (theme) => css`
button:focus {
outline: none;
}
svg {
display: block;
}
.lightmode_btn {
path {
stroke: ${theme.fontPreviewDarkMode ? theme.system.gray50 : theme.system.black};

View File

@ -9,15 +9,16 @@ export default function Select({
value,
placeholderSuffix = "",
inputStyle,
minWidth = "none",
...props
}) {
const label =
options.find((option) => option.value === value)?.name || `${value} ${placeholderSuffix}`;
options.find((option) => option.value === value)?.name || `${value}${placeholderSuffix}`;
return (
<div
css={css`
position: relative;
min-width: 69px;
min-width: ${minWidth};
`}
>
<div
@ -44,7 +45,7 @@ export default function Select({
>
{label}
</P>
<SVG.ChevronDown height="16px" display="block" />
<SVG.ChevronDown height="16px" width="16px" display="block" />
</div>
<select
css={css`

View File

@ -55,13 +55,25 @@ export const Controls = ({
label="Size"
{...defaultOptions.SIZE_OPTIONS}
options={[
{ value: 8, name: "8px" },
{ value: 12, name: "12px" },
{ value: 14, name: "14px" },
{ value: 20, name: "20px" },
{ value: 24, name: "24px" },
{ value: 32, name: "32px" },
{ value: 40, name: "40px" },
{ value: 64, name: "64px" },
{ value: 96, name: "96px" },
{ value: 120, name: "120px" },
{ value: 184, name: "184px" },
{ value: 280, name: "280px" },
{ value: 320, name: "320px" },
]}
value={settings.fontSize}
onChange={(e) => {
updateFontSize(e.target.value);
}}
selectMinWidth="67px"
disabled={view === "glyphs"}
/>
<Controller
@ -69,13 +81,16 @@ export const Controls = ({
selectSuffix="%"
{...defaultOptions.LINE_HEIGHT_OPTIONS}
options={[
{ value: 50, name: "50%" },
{ value: 100, name: "100%" },
{ value: 130, name: "130%" },
{ value: 150, name: "150%" },
{ value: 200, name: "200%" },
{ value: 300, name: "300%" },
{ value: 400, name: "400%" },
]}
value={settings.lineHeight}
onChange={(e) => updateLineHeight(e.target.value)}
selectMinWidth="63px"
disabled={view === "glyphs"}
/>
<Controller
@ -83,13 +98,14 @@ export const Controls = ({
selectSuffix="em"
{...defaultOptions.TRACKING_OPTIONS}
options={[
{ value: -1, name: "-1em" },
{ value: -0.1, name: "-0.1em" },
{ value: 0, name: "0em" },
{ value: 1, name: "1em" },
{ value: 2, name: "2em" },
{ value: 1.5, name: "1.5em" },
]}
value={settings.tracking}
onChange={(e) => updateTracking(e.target.value)}
selectMinWidth="82px"
disabled={view === "glyphs"}
/>
<Controller
@ -103,6 +119,7 @@ export const Controls = ({
]}
value={settings.column}
onChange={(e) => updateColumn(e.target.value)}
selectMinWidth="none"
disabled={view !== "paragraph"}
/>
</div>

View File

@ -21,7 +21,7 @@ const STYLES_GLYPHS_GRID = css`
overflow: hidden;
`;
export default function Glyphs() {
const content = `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!?()@$#%*[]{}\:;_""-`;
const content = `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890 ?!()[]{}&*^%$#@~`;
const glyphs = React.useMemo(() => new Array(6).fill(content).join("").split(""), []);
return (
<div css={STYLES_GLYPHS_WRAPPER}>

View File

@ -44,38 +44,41 @@ export default function Paragraph({
const handleFocus = () => setFocus(true);
const handleBlur = () => setFocus(false);
const mapAlignToFlex = { center: "center", top: "flex-start", bottom: "flex-end" };
const mapAlignToFlex = {
center: { marginTop: "auto", marginBottom: "auto" },
top: { marginBottom: "auto" },
bottom: { marginTop: "auto" },
};
return (
<div>
<div style={{ display: "flex", height: "100%", alignItems: mapAlignToFlex[valign] }}>
<div
contentEditable="true"
suppressContentEditableWarning={true}
style={{
fontSize: `${fontSize}px`,
lineHeight: `${lineHeight}%`,
letterSpacing: `${tracking}em`,
textAlign,
}}
css={[
STYLES_PARAGRAPH,
STYLES_TYPE_TO_EDIT(isFocused),
css`
width: 100%;
column-count: ${column};
column-gap: 24px;
`,
]}
onKeyDown={(e) => e.stopPropagation()}
onInput={(e) => {
onChange(e.currentTarget.innerText);
}}
onFocus={handleFocus}
onBlur={handleBlur}
>
<MemoizedChild shouldUpdateView={shouldUpdateView}>{content}</MemoizedChild>
</div>
<div style={{ display: "flex", height: "100%" }}>
<div
contentEditable="true"
suppressContentEditableWarning={true}
style={{
fontSize: `${fontSize}px`,
lineHeight: `${lineHeight}%`,
letterSpacing: `${tracking}em`,
textAlign,
...mapAlignToFlex[valign],
}}
css={[
STYLES_PARAGRAPH,
STYLES_TYPE_TO_EDIT(isFocused),
css`
width: 100%;
column-count: ${column};
column-gap: 24px;
`,
]}
onKeyDown={(e) => e.stopPropagation()}
onInput={(e) => {
onChange(e.currentTarget.innerText);
}}
onFocus={handleFocus}
onBlur={handleBlur}
>
<MemoizedChild shouldUpdateView={shouldUpdateView}>{content}</MemoizedChild>
</div>
</div>
);

View File

@ -41,10 +41,13 @@ export default function Sentence({
const handleFocus = () => setFocus(true);
const handleBlur = () => setFocus(false);
const mapAlignToFlex = { center: "center", top: "flex-start", bottom: "flex-end" };
const mapAlignToFlex = {
center: { marginTop: "auto", marginBottom: "auto" },
top: { marginBottom: "auto" },
bottom: { marginTop: "auto" },
};
return (
<div style={{ display: "flex", alignItems: mapAlignToFlex[valign], height: "100%" }}>
<div style={{ display: "flex", height: "100%" }}>
<div
contentEditable="true"
suppressContentEditableWarning={true}
@ -53,6 +56,7 @@ export default function Sentence({
lineHeight: `${lineHeight}%`,
letterSpacing: `${tracking}em`,
textAlign,
...mapAlignToFlex[valign],
}}
css={[STYLES_SENTENCE, STYLES_TYPE_TO_EDIT(isFocused)]}
onKeyDown={(e) => {

View File

@ -0,0 +1,25 @@
export const sentences = [
"Nothing is built on stone; all is built on sand, but we must build as if the sand were stone.",
"This web of time the strands of which approach one another, bifurcate, intersect or ignore each other through the centuries embraces every possibility. We do not exist in most of them. In some you exist and not I, while in others I do, and you do not.",
"What if everything is an illusion and nothing exists? In that case, I definitely overpaid for my carpet.",
"A good friend will always stab you in the front.",
"This mission is too important for me to allow you to jeopardize it.",
"Daisy, daisy.",
"Because nonbeing longs for being, on occasion it creates a stronger sense of being than being itself.",
"We are searching for some kind of harmony between two intangibles: a form which we have not yet designed and a context which we cannot properly describe.",
"In short, no pattern is an isolated entity. Each pattern can exist in the world only to the extent that is supported by other patterns: the larger patterns in which it is embedded, the patterns of the same size that surround it, and the smaller patterns which are embedded in it.",
"Dont worry about cool, make your own uncool.",
"The user illusion is theatre, the ultimate mirror. It is the audience (the user) that is intelligent and can be directed into a particular context. Giving the audience the appropriate cues is the essence of user-interface design.",
];
export const paragraphs = [
"Freedom isn't an illusion; it's perfectly real in the context of sequential consciousness. Within the context of simultaneous consciousness, freedom is not meaningful, but neither is coercion; it's simply a different context, no more or less valid than the other. It's like that famous optical illusion, the drawing of either an elegant young woman, face turned away from the viewer, or a wart-nosed crone, chin tucked down on her chest. There's no “correct” interpretation; both are equally valid. But you can't see both at the same time. \n \n Similarly, knowledge of the future was incompatible with free will. What made it possible for me to exercise freedom of choice also made it impossible for me to know the future. Conversely, now that I know the future, I would never act contrary to that future, including telling others what I know: those who know the future don't talk about it. Those who've read the Book of Ages never admit to it.",
`The idea that one person might understand everything that is understood may still seem fantastic, but it is distinctly less so than the idea that one person could memorise every known fact. For example, no one could possibly memorise all known observational data on even so narrow a subject as the motions of the planets, but many astrophysicists understand those motions to the full extent that they are understood. This is possible because understanding does not depend on knowing a lot of facts as such, but on having the right concepts, explanations and theories. One comparatively simple and comprehensible theory can cover an infinity of indigestible facts. Our best theory of planetary motions is Einsteins general theory of relativity, which, in the early twentieth century, superseded Newtons theories of gravity and motion. It correctly predicts, in principle, not only all planetary motions but also all other effects of gravity to the limits of accuracy of our best measurements. For a theory to predict something “in principle” means that as a matter of logic the predictions follow from the theory, even if in practice the amount of computation that would be needed to generate some of the predictions is too large to be technologically feasible, or even too large to be physically possible in the universe as we find it.\n \n Being able to predict things, or to describe them, however accurately, is not at all the same thing as understanding them. Predictions and descriptions in physics are often expressed as mathematical formulae. Suppose that I memorise the formula from which I could, if I had the time and inclination, calculate any planetary position that has been recorded in the astronomical archives. What exactly have I gained, compared with memorising those archives directly? The formula is easier to remember but then, looking a number up in the archives may be even easier than calculating it from the formula. The real advantage of the formula is that it can be used in an infinity of cases beyond the archived data, for instance to predict the results of future observations. It may also state the historical positions of the planets more accurately, because the archives contain observational errors. Yet, even though the formula summarises infinitely more facts than the archives do, it expresses no more understanding of the motions of the planets. Facts cannot be understood just by being summarised in a formula, any more than by being listed on paper or memorised in a brain. They can be understood only by being explained. Fortunately, our best theories contain deep explanations as well as accurate predictions. For example, the general theory of relativity explains gravity in terms of a new, four-dimensional geometry of curved space and time. It explains how, precisely and in complete generality, this geometry affects and is affected by matter. That explanation is the entire content of the theory. Predictions about planetary motions are merely some of the consequences that we can deduce from the explanation.\n \n Moreover, what makes the general theory of relativity so important is not that it can predict planetary motions a shade more accurately than Newtons theory can. It is that it reveals and explains previously unsuspected aspects of reality, such as the curvature of space and time. This is typical of scientific explanation. Scientific theories explain the objects and phenomena of our experience in terms of an underlying reality which we do not experience directly. But the ability of a theory to explain what we experience is not its most valuable attribute. Its most valuable attribute is that it explains the fabric of reality itself. As we shall see, one of the most valuable, significant and also useful attributes of human thought generally, is its ability to reveal and explain the fabric of reality.`,
`The fig tree is pollinated only by the insect Blastophaga grossorun. The larva of the insect lives in the ovary of the fig tree, and there it gets its food. The tree and the insect are thus heavily interdependent: the tree cannot reproduce wit bout the insect; the insect cannot eat wit bout the tree; together, they constitute not only a viable but a productive and thriving partnership. This cooperative "living together in intimate association, or even close union, of two dissimilar organisms" is called symbiosis.\n \n Man-computer symbiosis is a subclass of man-machine systems. There are many man-machine systems. At present, however, there are no man-computer symbioses. The purposes of this paper are to present the concept and, hopefully, to foster the development of man-computer symbiosis by analyzing some problems of interaction between men and computing machines, calling attention to applicable principles of man-machine engineering, and pointing out a few questions to which research answers are needed. The hope is that, in not too many years, human brains and computing machines will be coupled together very tightly, and that the resulting partnership will think as no human brain has ever thought and process data in a way not approached by the information-handling machines we know today.`,
`Watt's flyball governor is an early example of an automatic control system consisting of an error sensor connected by a negative feedback loop to a control device which drives the error to zero thus maintaining a desired operating point.\n\nThe drive shaft of Watt's speed sensor is geared to the steam engine's main drive shaft and rotates at a convenient speed in unison with it. As it rotates the two heavy balls are driven outwards by the centrifugal force. As the weights fly outwards, a sliding ring on the drive shaft is pulled downwards by the scissor mechanism supporting the weights. This displacement of the ring along the shaft represents the magnitude and direction of the speed error. A linkage mechanism provides the feedback loop which transfers this movement to the butterfly valve of the throttle control. The pivot in the linkage reverses the direction of the error signal thus providing the negative feedback.\n\nIf the engine speed is too high, the centrifugal force on the sensor's weights will cause the actuator rod to be raised, in turn causing the butterfy valve to move so as to restrict the flow of steam into the engine, hence reducing its speed.\n\nConversely, if the engine speed is too low, the centrifugal force will be lower and the weights will be closer to the drive shaft and the sliding ring will ride higher on the drive shaft. This will force the actuator rod downwards opening up the butterfly valve to admit more steam into the engine thus increasing its speed.\n\nThe desired speed of the engine is set by means of a screw thread on the actuator rod which adjusts the rod's length thus enabling the angle of the butterfly valve to be set to the corresponding operating point.`,
`Bottles are commonly used for liquid pharmaceuticals as well as formed tablets and capsules. Glass is most common for liquids because it is inert and has excellent barrier properties. Various types of plastic bottles are used both by drug producers as well as by pharmacists in a pharmacy.\n\nPrescription bottles have been around since the 19th century. Throughout the 19th and 20th centuries, prescription medication bottles were called medicinal bottles. There are many styles and shapes of prescription bottles. Bottles would often include cotton to cushion powdery, breakable pills. In modern times, pills are coated, and thus the inclusion of a cotton ball is no longer necessary. The U.S. National Institute of Health recommends consumers remove any cotton balls from opened pill bottles, as cotton balls may attract moisture into the bottle.\n\nPrescription bottles come in several different colors, the most common of which being orange or light brown due to its ability to prevent ultraviolet light from degrading the potentially photosensitive contents through photochemical reactions, while still letting enough visible light through for the contents to be easily visible. Other common colors include: Clear (for compounds that don't degrade in light), blue, dark brown, green, and various opaque hues.\n\nBottles are commonly used for liquid pharmaceuticals as well as formed tablets and capsules. Glass is most common for liquids because it is inert and has excellent barrier properties. Various types of plastic bottles are used both by drug producers as well as by pharmacists in a pharmacy.`,
];

View File

@ -6,8 +6,8 @@ export default function FontView({
settings,
view,
customView,
content: { sentence, paragraph, custom },
shouldUpdateView,
customViewContent,
updateCustomView,
}) {
const isCustomView = (value) => view === "custom" && customView === value;
@ -17,14 +17,10 @@ export default function FontView({
}
if (view === "paragraph" || isCustomView("paragraph")) {
const content =
view === "custom"
? customViewContent
: "The sun is gone but I have a light The day is done but I'm having fun I think I'm dumb or maybe I'm just happy I think I'm just happy I think I'm just happy I'm not like them but I can pretend The sun is gone but I have a light The day is done but I'm having fun I think I'm dumb or maybe I'm just happy I think I'm just happy I think I'm just happy I think I'm just happy My heart is broke but I have some glue Help me inhale and mend it with you We'll float around and hang out on clouds Then we'll come down and have a hangover We'll have a hangover We'll have a hangover We'll have a hangover Skin the sun, fall asleep The sun is gone but I have a light The day is done but I'm having fun I think I'm dumb or maybe I'm just happy I think I'm just happy I think I'm just happy I'm not like them but I can pretend The sun is gone but I have a light The day is done but I'm having fun I think I'm dumb or maybe I'm just happy I think I'm just happy I think I'm just happy I think I'm just happy My heart is broke but I have some glue Help me inhale and mend it with you We'll float around and hang out on clouds Then we'll come down and have a hangover We'll have a hangover We'll have a hangover We'll have a hangover Skin the sun, fall asleep The sun is gone but I have a light The day is done but I'm having fun I think I'm dumb or maybe I'm just happy I think I'm just happy I think I'm just happy I'm not like them but I can pretend The sun is gone but I have a light The day is done but I'm having fun I think I'm dumb or maybe I'm just happy I think I'm just happy I think I'm just happy I think I'm just happy My heart is broke but I have some glue Help me inhale and mend it with you We'll float around and hang out on clouds Then we'll come down and have a hangover We'll have a hangover We'll have a hangover We'll have a hangover Skin the sun, fall asleep";
return (
<Paragraph
shouldUpdateView={shouldUpdateView}
content={content}
content={view === "custom" ? custom : paragraph}
valign={settings.valign}
textAlign={settings.textAlign}
fontSize={settings.fontSize}
@ -36,14 +32,10 @@ export default function FontView({
);
}
const content =
view === "custom"
? customViewContent
: "The sun is gone but I have a light The day is done but I'm having fun I think I'm dumb or maybe I'm just happy I think I'm just happy I think I'm just happy I'm not like them but I can pretend The sun is gone but I have a light The day is done but I'm having fun I think I'm dumb or maybe I'm just happy";
return (
<Sentence
shouldUpdateView={shouldUpdateView}
content={content}
content={view === "custom" ? custom : sentence}
valign={settings.valign}
textAlign={settings.textAlign}
fontSize={settings.fontSize}

View File

@ -1,5 +1,6 @@
import * as React from "react";
import * as Events from "~/common/custom-events";
import * as Content from "./Views/content";
import { generateNumberByStep } from "~/common/utilities";
@ -35,6 +36,8 @@ const initialState = {
context: {
darkmode: true,
showSettings: true,
sentence: Content.sentences[0],
paragraph: Content.paragraphs[4],
customViewContent: "",
shouldUpdateView: false,
settings: {
@ -53,10 +56,10 @@ const initialState = {
const VIEW_OPTIONS = ["custom", "glyphs", "sentence", "paragraph"];
const VALIGN_OPTIONS = ["top", "center", "bottom"];
const ALIGN_OPTIONS = ["left", "center", "right"];
const SIZE_OPTIONS = { min: 12, max: 72, step: 2 };
const LINE_HEIGHT_OPTIONS = { min: 40, max: 400, step: 20 };
const TRACKING_OPTIONS = { min: -1, max: 1.5, step: 0.05 };
const COLUMN_OPTIONS = { min: 1, max: 6, step: 1 };
const SIZE_OPTIONS = { min: 8, max: 320, step: 1 };
const LINE_HEIGHT_OPTIONS = { min: 50, max: 300, step: 10 };
const TRACKING_OPTIONS = { min: -0.1, max: 0.2, step: 0.01 };
const COLUMN_OPTIONS = { min: 1, max: 4, step: 1 };
const reducer = (state, action) => {
const updateSettingsField = (field, newValue) => ({
@ -68,7 +71,15 @@ const reducer = (state, action) => {
});
switch (action.type) {
case "INITIATE_STATE": {
return action.value;
return {
...state,
...action.value,
context: {
...state.context,
...action.value.context,
settings: { ...state.context.settings, ...action.value.context.settings },
},
};
}
case "SET_DARK_MODE":
return { ...state, context: { ...state.context, darkmode: true } };
@ -119,13 +130,15 @@ const reducer = (state, action) => {
view: generatedView,
context: {
...state.context,
sentence: generateOption(Content.sentences),
paragraph: generateOption(Content.paragraphs),
settings: {
valign: generateOption(VALIGN_OPTIONS),
textAlign: generateOption(ALIGN_OPTIONS),
fontSize: generateNumberByStep(SIZE_OPTIONS),
column: generateNumberByStep(COLUMN_OPTIONS),
lineHeight: generateNumberByStep(LINE_HEIGHT_OPTIONS),
tracking: generateNumberByStep(TRACKING_OPTIONS).toPrecision(2),
fontSize: generateNumberByStep({ min: 16, max: 72, step: 1 }),
column: generateNumberByStep({ min: 1, max: 4, step: 1 }),
lineHeight: generateNumberByStep({ min: 100, max: 200, step: 10 }),
tracking: generateNumberByStep({ min: 0, max: 0.1, step: 0.01 }).toPrecision(1),
},
},
};

View File

@ -80,9 +80,13 @@ export default function FontFrame({ cid, url, ...props }) {
{isFontLoading && <FontLoader />}
<FontView
view={currentState.view}
content={{
paragraph: currentState.context.paragraph,
sentence: currentState.context.sentence,
custom: currentState.context.customViewContent,
}}
customView={currentState.customView}
shouldUpdateView={currentState.context.shouldUpdateView}
customViewContent={currentState.context.customViewContent}
settings={currentState.context.settings}
updateCustomView={updateCustomView}
/>