mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2024-12-11 16:21:04 -05:00
Merge pull request #8950 from MiroslavDionisiev/UEPR-88
feat: [UEPR-88] added modal for written guides
This commit is contained in:
commit
2230378351
17 changed files with 449 additions and 34 deletions
143
src/components/cards-modal/cards-modal.jsx
Normal file
143
src/components/cards-modal/cards-modal.jsx
Normal file
|
@ -0,0 +1,143 @@
|
|||
import React, {useCallback, useState} from 'react';
|
||||
import ReactModal from 'react-modal';
|
||||
import PropTypes from 'prop-types';
|
||||
import Button from '../forms/button.jsx';
|
||||
import {FormattedMessage, useIntl} from 'react-intl';
|
||||
import ModalNavigation from '../modal-navigation/modal-navigation.jsx';
|
||||
|
||||
import './cards-modal.scss';
|
||||
|
||||
const GUIDES_SECTIONS = [
|
||||
{
|
||||
titleId: 'ideas.modalSectionTitleSpritesAndSounds',
|
||||
imgSrc: '/images/ideas/sprites-sounds.svg',
|
||||
cards: [
|
||||
{
|
||||
cardId: 'ideas.modalCardNameCreateSprite',
|
||||
hrefId: 'guides.ScratchLearningResource_CreateOriginalSpriteLink'
|
||||
},
|
||||
{
|
||||
cardId: 'ideas.modalCardNameRemix',
|
||||
hrefId: 'guides.ScratchLearningResource_RemixRe-imagineSpritesLink'
|
||||
},
|
||||
{
|
||||
cardId: 'ideas.modalCardNameBringDrawingsIntoScratch',
|
||||
hrefId: 'guides.ScratchLearningResource_BringYourDrawingsIntoScratchLink'
|
||||
},
|
||||
{
|
||||
cardId: 'ideas.modalCardNameSound',
|
||||
hrefId: 'guides.ScratchLearningResource_SoundsAddRecordText-to-SpeechLink'
|
||||
},
|
||||
{
|
||||
cardId: 'ideas.modalCardNameCreateAsset',
|
||||
hrefId: 'guides.ScratchLearningResource_CreateanAssetPackLink'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
titleId: 'ideas.modalSectionTitleAdvancedTopics',
|
||||
imgSrc: '/images/ideas/advanced-topics.svg',
|
||||
cards: [
|
||||
{
|
||||
cardId: 'ideas.modalCardNameConditionalStatements',
|
||||
hrefId: 'guides.ScratchLearningResource_ConditionalStatementsLink'
|
||||
},
|
||||
{
|
||||
cardId: 'ideas.modalCardNameVariablesLists',
|
||||
hrefId: 'guides.ScratchLearningResource_VariablesandListsLink'
|
||||
},
|
||||
{
|
||||
cardId: 'ideas.modalCardNameCustomBlocks',
|
||||
hrefId: 'guides.ScratchLearningResource_MyBlocksLink'
|
||||
},
|
||||
{
|
||||
cardId: 'ideas.modalCardNameFaceSensing',
|
||||
hrefId: 'cards.paperplanes-turtlegraphics-cardsLink'
|
||||
},
|
||||
{
|
||||
cardId: 'ideas.modalCardNameComputationalConcepts',
|
||||
hrefId: 'cards.facesensing-cardsLink'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
export const CardsModal = ({isOpen, onClose = () => {}}) => {
|
||||
const [currentPage, setCurrentPage] = useState(0);
|
||||
const intl = useIntl();
|
||||
const onNextPage = useCallback(() => {
|
||||
if (currentPage < GUIDES_SECTIONS.length - 1) {
|
||||
setCurrentPage(currentPage + 1);
|
||||
}
|
||||
}, [currentPage]);
|
||||
const onBackPage = useCallback(() => {
|
||||
if (currentPage > 0) {
|
||||
setCurrentPage(currentPage - 1);
|
||||
}
|
||||
}, [currentPage]);
|
||||
|
||||
if (!isOpen) return null;
|
||||
return (
|
||||
<ReactModal
|
||||
isOpen={isOpen}
|
||||
onRequestClose={onClose}
|
||||
className="cards-modal-container"
|
||||
overlayClassName="cards-modal-overlay"
|
||||
>
|
||||
<div className="cards-modal-header">
|
||||
<div className="cards-title">
|
||||
<FormattedMessage id={'ideas.modalTitle'} />
|
||||
</div>
|
||||
<Button
|
||||
className="close-button"
|
||||
isCloseType
|
||||
onClick={onClose}
|
||||
/>
|
||||
</div>
|
||||
<div className="cards-modal-section-title">
|
||||
<FormattedMessage id={GUIDES_SECTIONS[currentPage].titleId} />
|
||||
</div>
|
||||
<div className="cards-modal-section-content">
|
||||
<img
|
||||
className="section-img"
|
||||
src={GUIDES_SECTIONS[currentPage].imgSrc}
|
||||
/>
|
||||
<div className="cards-modal-cards-list">
|
||||
{GUIDES_SECTIONS[currentPage].cards.map(card => (
|
||||
<div
|
||||
key={card.cardId}
|
||||
className="card"
|
||||
>
|
||||
<FormattedMessage id={card.cardId} />
|
||||
<a
|
||||
href={intl.formatMessage({
|
||||
id: card.hrefId
|
||||
})}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Button>
|
||||
<img src="/images/ideas/download-icon.svg" />
|
||||
</Button>
|
||||
</a>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<ModalNavigation
|
||||
currentPage={currentPage}
|
||||
totalDots={GUIDES_SECTIONS.length}
|
||||
nextButtonImageSrc="/images/ideas/right-arrow.svg"
|
||||
prevButtonImageSrc="/images/ideas/left-arrow.svg"
|
||||
onNextPage={onNextPage}
|
||||
onBackPage={onBackPage}
|
||||
className="cards-modal-navigation"
|
||||
/>
|
||||
</ReactModal>
|
||||
);
|
||||
};
|
||||
|
||||
CardsModal.propTypes = {
|
||||
isOpen: PropTypes.bool,
|
||||
onClose: PropTypes.func
|
||||
};
|
150
src/components/cards-modal/cards-modal.scss
Normal file
150
src/components/cards-modal/cards-modal.scss
Normal file
|
@ -0,0 +1,150 @@
|
|||
@import "../../colors";
|
||||
@import "../../frameless";
|
||||
|
||||
.cards-modal-overlay {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 510;
|
||||
|
||||
background-color: $box-shadow-light-gray;
|
||||
border-color: unset;
|
||||
}
|
||||
|
||||
.cards-modal-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
width: 640px;
|
||||
|
||||
box-shadow: 0 0 0 4px $ui-blue-25percent;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.cards-modal-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
padding: 10px;
|
||||
background-color: $ui-blue;
|
||||
border-radius: 8px 8px 0 0;
|
||||
|
||||
.cards-title {
|
||||
font-size: 1rem;
|
||||
font-weight: 700;
|
||||
line-height: 1.25rem;
|
||||
color: $ui-white;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.close-button {
|
||||
position: unset;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.cards-modal-section-title {
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
|
||||
color: $header-gray;
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
line-height: 2rem;
|
||||
|
||||
padding: 0.5rem 0;
|
||||
margin: 0.75rem 0
|
||||
}
|
||||
|
||||
.cards-modal-section-content {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin: 0 1.25rem;
|
||||
gap: 1.25rem;
|
||||
|
||||
.section-img {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.cards-modal-cards-list {
|
||||
flex: 1;
|
||||
|
||||
.card {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
|
||||
|
||||
.button {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.card + .card {
|
||||
border-top: 1px solid $box-shadow-light-gray;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cards-modal-navigation {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin: 1.75rem 0;
|
||||
|
||||
.navigation-button {
|
||||
padding: 0;
|
||||
margin: 0 1rem;
|
||||
}
|
||||
|
||||
.dotRow{
|
||||
width: 32px;
|
||||
height: 16px;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.dot{
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background-color: transparent;
|
||||
border: 2px solid $ui-blue;
|
||||
}
|
||||
|
||||
.active{
|
||||
background-color: $ui-blue;
|
||||
box-shadow: 0 0 0 4px $ui-blue-25percent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cards-modal-container:focus {
|
||||
outline: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $mobileIntermediate) {
|
||||
.cards-modal-container {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
|
@ -36,13 +36,25 @@ export const CommunityGuidelinesModal = props => {
|
|||
<CommunityGuidelines
|
||||
userId={props.userId}
|
||||
currentPage={currentPage}
|
||||
onNextPage={currentPage < communityGuidelines.length - 1 ? onNextPage : onComplete}
|
||||
nextButtonText={currentPage === communityGuidelines.length - 1 ?
|
||||
<FormattedMessage id={'communityGuidelines.buttons.finish'} /> :
|
||||
null}
|
||||
onNextPage={
|
||||
currentPage < communityGuidelines.length - 1 ?
|
||||
onNextPage :
|
||||
onComplete
|
||||
}
|
||||
nextButtonText={
|
||||
currentPage === communityGuidelines.length - 1 ? (
|
||||
<FormattedMessage id={'communityGuidelines.buttons.finish'} />
|
||||
) : (
|
||||
<FormattedMessage id={'communityGuidelines.buttons.next'} />
|
||||
)
|
||||
}
|
||||
prevButtonText={
|
||||
<FormattedMessage id={'communityGuidelines.buttons.back'} />
|
||||
}
|
||||
onBackPage={currentPage > 0 ? onBackPage : null}
|
||||
/>
|
||||
</ReactModal>);
|
||||
</ReactModal>
|
||||
);
|
||||
};
|
||||
|
||||
CommunityGuidelinesModal.propTypes = {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, {useEffect} from 'react';
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
import thumbnailUrl from '../../lib/user-thumbnail.js';
|
||||
import OnboardingNavigation from '../onboarding-navigation/onboarding-navigation.jsx';
|
||||
import ModalNavigation from '../modal-navigation/modal-navigation.jsx';
|
||||
|
||||
import './community-guidelines.scss';
|
||||
import PropTypes from 'prop-types';
|
||||
|
@ -65,6 +65,7 @@ export const CommunityGuidelines = ({
|
|||
userId,
|
||||
currentPage,
|
||||
nextButtonText,
|
||||
prevButtonText,
|
||||
onNextPage,
|
||||
onBackPage
|
||||
}) => {
|
||||
|
@ -108,10 +109,11 @@ export const CommunityGuidelines = ({
|
|||
</div>
|
||||
)}
|
||||
</div>
|
||||
<OnboardingNavigation
|
||||
<ModalNavigation
|
||||
currentPage={currentPage}
|
||||
totalDots={communityGuidelines.length}
|
||||
nextButtonText={nextButtonText}
|
||||
prevButtonText={prevButtonText}
|
||||
onNextPage={onNextPage}
|
||||
onBackPage={onBackPage}
|
||||
/>
|
||||
|
@ -123,7 +125,8 @@ CommunityGuidelines.propTypes = {
|
|||
currentPage: PropTypes.number,
|
||||
userId: PropTypes.string,
|
||||
constructHeader: PropTypes.func,
|
||||
nextButtonText: PropTypes.string,
|
||||
nextButtonText: PropTypes.node,
|
||||
prevButtonText: PropTypes.node,
|
||||
onNextPage: PropTypes.func,
|
||||
onBackPage: PropTypes.func
|
||||
};
|
||||
|
|
|
@ -39,6 +39,10 @@ $pass-bg: $ui-aqua;
|
|||
box-shadow: none;
|
||||
}
|
||||
|
||||
&.transparent {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
&.large {
|
||||
border-radius: .25rem;
|
||||
font-size: 1rem;
|
||||
|
|
|
@ -1,21 +1,24 @@
|
|||
import React, {useEffect, useMemo} from 'react';
|
||||
import Button from '../forms/button.jsx';
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import './onboarding-navigation.scss';
|
||||
import './modal-navigation.scss';
|
||||
import classNames from 'classnames';
|
||||
|
||||
const OnboardingNavigation = ({
|
||||
const ModalNavigation = ({
|
||||
currentPage,
|
||||
totalDots,
|
||||
onNextPage,
|
||||
onBackPage,
|
||||
nextButtonText
|
||||
nextButtonText,
|
||||
prevButtonText,
|
||||
nextButtonImageSrc,
|
||||
prevButtonImageSrc,
|
||||
className
|
||||
}) => {
|
||||
useEffect(() => {
|
||||
new Image().src = '/images/onboarding/right-arrow.svg';
|
||||
new Image().src = '/images/onboarding/left-arrow.svg';
|
||||
new Image().src = nextButtonImageSrc;
|
||||
new Image().src = prevButtonImageSrc;
|
||||
}, []);
|
||||
|
||||
const dots = useMemo(() => {
|
||||
|
@ -32,49 +35,62 @@ const OnboardingNavigation = ({
|
|||
}, [currentPage, totalDots]);
|
||||
|
||||
return (
|
||||
<div className="navigation">
|
||||
<div className={classNames('navigation', className)}>
|
||||
{
|
||||
<Button
|
||||
onClick={onBackPage}
|
||||
className={classNames({
|
||||
hidden: !onBackPage
|
||||
className={classNames('navigation-button', {
|
||||
hidden: !onBackPage,
|
||||
transparent: !prevButtonText
|
||||
})}
|
||||
>
|
||||
<img
|
||||
className="left-arrow"
|
||||
alt=""
|
||||
src="/images/onboarding/left-arrow.svg"
|
||||
src={prevButtonImageSrc}
|
||||
/>
|
||||
<span className="navText">
|
||||
{<FormattedMessage
|
||||
id={'communityGuidelines.buttons.back'}
|
||||
/>}
|
||||
{prevButtonText}
|
||||
</span>
|
||||
</Button> }
|
||||
{(currentPage >= 0 && totalDots) &&
|
||||
<div className="dotRow">
|
||||
{dots}
|
||||
</div>}
|
||||
<Button onClick={onNextPage}>
|
||||
<Button
|
||||
onClick={onNextPage}
|
||||
className={classNames('navigation-button', {
|
||||
transparent: !nextButtonText
|
||||
})}
|
||||
>
|
||||
<span className="navText">
|
||||
{nextButtonText || <FormattedMessage id={'communityGuidelines.buttons.next'} />}
|
||||
{nextButtonText}
|
||||
</span>
|
||||
<img
|
||||
className="right-arrow"
|
||||
alt=""
|
||||
src="/images/onboarding/right-arrow.svg"
|
||||
src={nextButtonImageSrc}
|
||||
/>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
);
|
||||
};
|
||||
OnboardingNavigation.propTypes = {
|
||||
ModalNavigation.propTypes = {
|
||||
currentPage: PropTypes.number,
|
||||
totalDots: PropTypes.number,
|
||||
onNextPage: PropTypes.func,
|
||||
onBackPage: PropTypes.func,
|
||||
nextButtonText: PropTypes.node
|
||||
nextButtonText: PropTypes.node,
|
||||
prevButtonText: PropTypes.node,
|
||||
nextButtonImageSrc: PropTypes.string,
|
||||
prevButtonImageSrc: PropTypes.string,
|
||||
className: PropTypes.string
|
||||
};
|
||||
|
||||
export default OnboardingNavigation;
|
||||
ModalNavigation.defaultProps = {
|
||||
nextButtonImageSrc: '/images/onboarding/right-arrow.svg',
|
||||
prevButtonImageSrc: '/images/onboarding/left-arrow.svg'
|
||||
};
|
||||
|
||||
export default ModalNavigation;
|
|
@ -1,7 +1,7 @@
|
|||
@import "../../colors";
|
||||
@import "../../frameless";
|
||||
|
||||
.button{
|
||||
.navigation-button{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
@ -35,6 +35,7 @@
|
|||
.dotRow{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 244px;
|
||||
min-width: 0px;
|
||||
padding: 0px 5px;
|
|
@ -5,10 +5,10 @@
|
|||
|
||||
.playlist-title {
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
font-size: 2rem;
|
||||
font-weight: 700;
|
||||
line-height: 2.5rem;
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
|
|
|
@ -14,7 +14,7 @@ import Button from '../../components/forms/button.jsx';
|
|||
import Modal from '../../components/modal/base/modal.jsx';
|
||||
import NotAvailable from '../../components/not-available/not-available.jsx';
|
||||
import WarningBanner from '../../components/title-banner/warning-banner.jsx';
|
||||
import OnboardingNavigation from '../../components/onboarding-navigation/onboarding-navigation.jsx';
|
||||
import ModalNavigation from '../../components/modal-navigation/modal-navigation.jsx';
|
||||
import {
|
||||
CommunityGuidelines,
|
||||
communityGuidelines
|
||||
|
@ -285,10 +285,11 @@ const BecomeAScratcher = ({user, invitedScratcher, scratcher, sessionStatus}) =>
|
|||
<FormattedMessage id={'becomeAScratcher.toBeAScratcher.communityGuidelines'} />
|
||||
</div>
|
||||
</div>
|
||||
<OnboardingNavigation
|
||||
<ModalNavigation
|
||||
onNextPage={nextPage}
|
||||
onBackPage={backPage}
|
||||
nextButtonText={<FormattedMessage id={'becomeAScratcher.buttons.communityGuidelines'} />}
|
||||
prevButtonText={<FormattedMessage id={'communityGuidelines.buttons.back'} />}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -13,6 +13,7 @@ const {
|
|||
YoutubeVideoModal
|
||||
} = require('../../components/youtube-video-modal/youtube-video-modal.jsx');
|
||||
const {YoutubePlaylistItem} = require('../../components/youtube-playlist-item/youtube-playlist-item.jsx');
|
||||
const {CardsModal} = require('../../components/cards-modal/cards-modal.jsx');
|
||||
|
||||
require('./ideas.scss');
|
||||
|
||||
|
@ -98,6 +99,7 @@ const playlists = {
|
|||
const Ideas = () => {
|
||||
const intl = useIntl();
|
||||
const [youtubeVideoId, setYoutubeVideoId] = useState('');
|
||||
const [isCardsModalOpen, setCardsModalOpen] = useState(false);
|
||||
|
||||
const onCloseVideoModal = useCallback(() => setYoutubeVideoId(''), [setYoutubeVideoId]);
|
||||
const onSelectedVideo = useCallback(
|
||||
|
@ -105,6 +107,9 @@ const Ideas = () => {
|
|||
[setYoutubeVideoId]
|
||||
);
|
||||
|
||||
const onCardsModalOpen = useCallback(() => setCardsModalOpen(true), [isCardsModalOpen]);
|
||||
const onCardsModalClose = useCallback(() => setCardsModalOpen(false), [isCardsModalOpen]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="banner-wrapper">
|
||||
|
@ -202,6 +207,27 @@ const Ideas = () => {
|
|||
onClose={onCloseVideoModal}
|
||||
/>
|
||||
</section>
|
||||
<div
|
||||
className="download-cards"
|
||||
>
|
||||
<Button
|
||||
className="pass"
|
||||
onClick={onCardsModalOpen}
|
||||
>
|
||||
<img src="/images/ideas/download-icon.svg" />
|
||||
</Button>
|
||||
<FormattedMessage
|
||||
id="ideas.downloadGuides"
|
||||
values={{
|
||||
strong: chunks => <strong>{chunks}</strong>,
|
||||
a: chunks => <a onClick={onCardsModalOpen}>{chunks}</a>
|
||||
}}
|
||||
/>
|
||||
<CardsModal
|
||||
isOpen={isCardsModalOpen}
|
||||
onClose={onCardsModalClose}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="physical-ideas">
|
||||
|
|
|
@ -117,6 +117,33 @@ $base-bg: $ui-white;
|
|||
gap: 3rem;
|
||||
margin-bottom: 3rem;
|
||||
}
|
||||
|
||||
.download-cards {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
|
||||
margin-bottom: 3.5rem;
|
||||
|
||||
.button {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 1rem;
|
||||
line-height: 1.5rem;
|
||||
text-align: start;
|
||||
|
||||
a {
|
||||
font-weight: 400;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -207,10 +234,10 @@ $base-bg: $ui-white;
|
|||
.tips, .physical-ideas {
|
||||
.section-header {
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
font-size: 2rem;
|
||||
font-weight: 700;
|
||||
line-height: 2.5rem;
|
||||
text-align: start;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
"cards.pong-cardsLink": "https://resources.scratch.mit.edu/www/cards/en/pong-cards.pdf",
|
||||
"cards.fly-cardsLink": "https://resources.scratch.mit.edu/www/cards/en/fly-cards.pdf",
|
||||
"cards.imagine-cardsLink": "https://resources.scratch.mit.edu/www/cards/en/imagine-cards.pdf",
|
||||
"cards.paperplanes-turtlegraphics-cardsLink": "https://resources.scratch.mit.edu/www/cards/en/paperplanes-turtlegraphics-cards.pdf",
|
||||
"cards.facesensing-cardsLink": "https://resources.scratch.mit.edu/www/cards/en/facesensing-cards.pdf",
|
||||
"guides.NameGuideLink": "https://resources.scratch.mit.edu/www/guides/en/NameGuide.pdf",
|
||||
"guides.AnimateGuideLink": "https://resources.scratch.mit.edu/www/guides/en/AnimateGuide.pdf",
|
||||
"guides.MusicGuideLink": "https://resources.scratch.mit.edu/www/guides/en/MusicGuide.pdf",
|
||||
|
@ -19,5 +21,13 @@
|
|||
"guides.VideoGuideLink": "https://resources.scratch.mit.edu/www/guides/en/VideoGuide.pdf",
|
||||
"guides.PongGuideLink": "https://resources.scratch.mit.edu/www/guides/en/PongGuide.pdf",
|
||||
"guides.FlyGuideLink": "https://resources.scratch.mit.edu/www/guides/en/FlyGuide.pdf",
|
||||
"guides.ImagineGuideLink": "https://resources.scratch.mit.edu/www/guides/en/ImagineGuide.pdf"
|
||||
"guides.ImagineGuideLink": "https://resources.scratch.mit.edu/www/guides/en/ImagineGuide.pdf",
|
||||
"guides.ScratchLearningResource_CreateOriginalSpriteLink": "https://resources.scratch.mit.edu/www/guides/en/ScratchLearningResource_CreateOriginalSprite.pdf",
|
||||
"guides.ScratchLearningResource_RemixRe-imagineSpritesLink": "https://resources.scratch.mit.edu/www/guides/en/ScratchLearningResource_RemixRe-imagineSprites.pdf",
|
||||
"guides.ScratchLearningResource_BringYourDrawingsIntoScratchLink": "https://resources.scratch.mit.edu/www/guides/en/ScratchLearningResource_BringYourDrawingsIntoScratch.pdf",
|
||||
"guides.ScratchLearningResource_SoundsAddRecordText-to-SpeechLink": "https://resources.scratch.mit.edu/www/guides/en/ScratchLearningResource_SoundsAddRecordText-to-Speech.pdf",
|
||||
"guides.ScratchLearningResource_CreateanAssetPackLink": "https://resources.scratch.mit.edu/www/guides/en/ScratchLearningResource_CreateanAssetPack.pdf",
|
||||
"guides.ScratchLearningResource_ConditionalStatementsLink": "https://resources.scratch.mit.edu/www/guides/en/ScratchLearningResource_ConditionalStatements.pdf",
|
||||
"guides.ScratchLearningResource_VariablesandListsLink": "https://resources.scratch.mit.edu/www/guides/en/ScratchLearningResource_VariablesandLists.pdf",
|
||||
"guides.ScratchLearningResource_MyBlocksLink": "https://resources.scratch.mit.edu/www/guides/en/ScratchLearningResource_MyBlocks.pdf"
|
||||
}
|
||||
|
|
|
@ -54,5 +54,19 @@
|
|||
"ideas.PongImageDescription": "A ball bounces off a digital paddle.",
|
||||
"ideas.ImagineTitle": "Imagine a World",
|
||||
"ideas.ImagineDescription": "Imagine a world where anything is possible.",
|
||||
"ideas.ImagineImageDescription": "A girl stands proudly in front of a thought bubble as big as the Earth and as intricate as butterfly wings."
|
||||
"ideas.ImagineImageDescription": "A girl stands proudly in front of a thought bubble as big as the Earth and as intricate as butterfly wings.",
|
||||
"ideas.modalTitle": "Written Guides",
|
||||
"ideas.modalSectionTitleSpritesAndSounds": "Sprites and Sounds",
|
||||
"ideas.modalSectionTitleAdvancedTopics": "Advanced Topics",
|
||||
"ideas.modalCardNameCreateSprite": "Create a Sprite with the Paint Editor",
|
||||
"ideas.modalCardNameRemix": "Remix and Re-Imagine Sprites",
|
||||
"ideas.modalCardNameBringDrawingsIntoScratch": "Bring Your Drawings Into Scratch",
|
||||
"ideas.modalCardNameSound": "Sound: Add, Record, and Use Text to Speech Blocks",
|
||||
"ideas.modalCardNameCreateAsset": "Create Your Own Asset Pack",
|
||||
"ideas.modalCardNameConditionalStatements": "Conditional Statements",
|
||||
"ideas.modalCardNameVariablesLists": "Variables and Lists",
|
||||
"ideas.modalCardNameCustomBlocks": "Make Your Custom My Blocks",
|
||||
"ideas.modalCardNameFaceSensing": "Scratch Lab Face Sensing Coding Cards",
|
||||
"ideas.modalCardNameComputationalConcepts": "Turtle Graphics Coding Cards",
|
||||
"ideas.downloadGuides": "<strong>Computer doesn’t allow Youtube?</strong> Download <a>written guides</a> for these topics."
|
||||
}
|
||||
|
|
1
static/images/ideas/advanced-topics.svg
Normal file
1
static/images/ideas/advanced-topics.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 14 KiB |
3
static/images/ideas/left-arrow.svg
Normal file
3
static/images/ideas/left-arrow.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg width="24" height="19" viewBox="0 0 24 19" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.558139 10.7977L7.83016 18.2108C8.42768 18.7845 9.26604 18.9379 9.9863 18.6192C10.7066 18.3028 11.1512 17.604 11.1512 16.7943L11.1512 13.9825L21.2718 12.5494C22.8212 12.344 24 10.97 24 9.35284C24 9.21355 23.9907 9.0719 23.9745 8.93261C23.7499 7.4736 22.6336 6.34747 21.2603 6.17041L11.1512 4.6996L11.1512 2.01058C11.1512 1.19137 10.6788 0.461858 9.94924 0.152587C9.21509 -0.156686 8.4022 0.0109341 7.83016 0.594066L0.558139 8.00716C0.199169 8.37545 -8.6648e-07 8.87123 -8.20042e-07 9.40242C-7.73604e-07 9.93361 0.199169 10.4294 0.558139 10.7977Z" fill="#4C97FF"/>
|
||||
</svg>
|
After Width: | Height: | Size: 718 B |
3
static/images/ideas/right-arrow.svg
Normal file
3
static/images/ideas/right-arrow.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg width="24" height="19" viewBox="0 0 24 19" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M23.4419 10.7977L16.1698 18.2108C15.5723 18.7845 14.734 18.9379 14.0137 18.6192C13.2934 18.3028 12.8488 17.604 12.8488 16.7943L12.8488 13.9825L2.72817 12.5494C1.17881 12.344 6.82997e-07 10.97 8.24376e-07 9.35284C8.36553e-07 9.21355 0.00926484 9.0719 0.0254754 8.93261C0.250121 7.4736 1.3664 6.34747 2.73975 6.17041L12.8488 4.6996L12.8488 2.01058C12.8488 1.19137 13.3212 0.461858 14.0508 0.152587C14.7849 -0.156686 15.5978 0.0109341 16.1698 0.594066L23.4419 8.00716C23.8008 8.37545 24 8.87123 24 9.40242C24 9.93361 23.8008 10.4294 23.4419 10.7977Z" fill="#4C97FF"/>
|
||||
</svg>
|
After Width: | Height: | Size: 717 B |
1
static/images/ideas/sprites-sounds.svg
Normal file
1
static/images/ideas/sprites-sounds.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 9.6 KiB |
Loading…
Reference in a new issue