Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

除夜の鐘を打てるように #167

Merged
merged 8 commits into from
Dec 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"react-dom": "^16.11.0",
"react-h5-audio-player": "^3.4.1",
"react-helmet": "^5.2.1",
"react-rnd": "^10.2.4",
"react-transition-group": "^4.4.1",
"remark-html": "^13.0.1",
"remark-parse": "^9.0.0",
Expand Down
215 changes: 215 additions & 0 deletions src/components/bigBell.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
import React, { useRef, useState } from 'react';
import { useStaticQuery, graphql } from 'gatsby';
import Img from 'gatsby-image';
import styled from 'styled-components';
import { Rnd } from 'react-rnd';
import UseWindowDimensions from './useWindowDimensions';
import Omikuji from './omikuji';

const BigBellContainer = styled.div`
position: absolute;
pointer-events: none;
display: ${(props) => (props.display ? 'flex' : 'none')};
justify-content: center;
width: 100%;
align-items: flex-end;
height: 100%;
z-index: 2;
> div {
text-align: center;
width: 50%;
display: flex;
}
`;
const BigBellImg = styled((props) => <Img {...props} />)`
flex: 1 1 auto;
align-items: flex-end;
`;

const StickImg = styled((props) => <Img {...props} />)`
pointer-events: none;
display: ${(props) => (props.display ? 'flex' : 'none')};
`;

const StickContainer = styled.div`
position: relative;
height: 50%;
`;

const Counter = styled.p`
margin-bottom: ${(props) => props.margin}px;
font-size: ${(props) => props.fontSize}px;
`;

const NumberText = styled.span`
color: #ebff00;
background-color: #000000;
padding: 2px 3px 2px 5px;
margin: 0 2px;
box-sizing: border-box;
`;

const style = {
'pointer-events': 'auto',
alignItems: 'center',
justifyContent: 'center',
border: 'solid 0px',
background: 'transparent',
cursor: 'ew-resize',
};

const BigBell = () => {
const data = useStaticQuery(
graphql`
query {
bigBell: file(
relativePath: { eq: "big_bell.png" }
) {
childImageSharp {
fluid {
...GatsbyImageSharpFluid
}
}
}
stick1: file(
relativePath: { eq: "kanetukibou_1.png" }
) {
childImageSharp {
fluid {
...GatsbyImageSharpFluid
}
}
}
stick2: file(
relativePath: { eq: "kanetukibou_2.png" }
) {
childImageSharp {
fluid {
...GatsbyImageSharpFluid
}
}
}
}
`,
);
const el = useRef(null);
const special = useRef(null);
const stick1Img = useRef(null);
const stick2Img = useRef(null);
const windowWidth =
UseWindowDimensions().width > 1080
? 1080
: UseWindowDimensions().width;
const BONNOU_COUNT = 108;
const [count, setCount] = useState(BONNOU_COUNT);
const [isSeparated, separate] = useState(true);
const [isWoundUp, windUp] = useState(false);
const [
isSpecialContentOpened,
openSpecialContent,
] = useState(false);

return (
<>
<BigBellContainer display="true">
<StickContainer>
<Rnd
style={style}
size={{
width: windowWidth / 12,
height: windowWidth / 12,
}}
position={{
x: windowWidth / 4 + windowWidth / 10,
y: ((windowWidth / 2) * (180 / 328)) / 2,
}}
dragAxis="x"
enableResizing={false}
onDrag={(_e, d) => {
if (d.x <= windowWidth / 3.5) {
if (isSeparated) {
try {
if (!el.current.paused) {
el.current.pause();
el.current.currentTime = 0;
}
el.current.play();
windUp(false);
} catch (e) {}
setCount(count - 1);
if (count <= 1) {
openSpecialContent(true);
setCount(BONNOU_COUNT);
special.current.play();
}
console.log('PLAY');
separate(false);
}
} else {
separate(true);
openSpecialContent(false);
if (d.deltaX < -2) {
windUp(true);
} else if (d.deltaX > 0) {
windUp(false);
}
}
}}
>
<StickImg
ref={stick1Img}
display={!isWoundUp}
fluid={data.stick1.childImageSharp.fluid}
alt="鐘付き棒"
/>
<StickImg
ref={stick2Img}
display={isWoundUp}
fluid={data.stick2.childImageSharp.fluid}
alt="振りかぶった鐘付き棒"
/>
</Rnd>
<audio ref={el}>
<source
src="/mp3/bell03.mp3"
type="audio/mp3"
/>
</audio>
<audio ref={special}>
<source
src="/mp3/bonnou_taisan.mp3"
type="audio/mp3"
/>
</audio>
</StickContainer>
</BigBellContainer>
<BigBellContainer display="true">
<div>
<BigBellImg
fluid={data.bigBell.childImageSharp.fluid}
alt="除夜の鐘"
/>
</div>
</BigBellContainer>
<BigBellContainer display="true">
<Counter
margin={windowWidth / 5}
fontSize={windowWidth / 50}
>
{[...count.toString()].map((str, index) => {
return (
<NumberText key={str + String(index)}>
{str}
</NumberText>
);
})}
</Counter>
</BigBellContainer>
<BigBellContainer display={isSpecialContentOpened}>
<Omikuji />
</BigBellContainer>
</>
);
};

export default BigBell;
40 changes: 26 additions & 14 deletions src/components/hero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import styled from 'styled-components';
import moment from 'moment';
import SunCalc from 'suncalc';
import Mochimaki from './mochimaki';
import BigBell from './bigBell';

const HeroContainer = styled.div`
position: relative;
Expand Down Expand Up @@ -59,7 +60,7 @@ const TempleContainer = styled.div`
align-items: flex-end;
height: 100%;
z-index: 2;
div {
> div {
text-align: center;
width: 50%;
display: flex;
Expand Down Expand Up @@ -141,6 +142,10 @@ const Hero = () => {
times.sunriseEnd,
times.night,
);
const isLastDay = currentTime.isSame(
moment().endOf('year'),
'day',
);

return (
<HeroContainer>
Expand All @@ -161,19 +166,26 @@ const Hero = () => {
/>
</div>
</LogoContainer>
<Mochimaki />
<TempleContainer>
<div>
<TempleImg
fluid={
isDayTime
? data.templedDay.childImageSharp.fluid
: data.templedNight.childImageSharp.fluid
}
alt="本堂"
/>
</div>
</TempleContainer>
{isLastDay ? (
<BigBell />
) : (
<>
<Mochimaki />
<TempleContainer>
<div>
<TempleImg
fluid={
isDayTime
? data.templedDay.childImageSharp.fluid
: data.templedNight.childImageSharp
.fluid
}
alt="本堂"
/>
</div>
</TempleContainer>
</>
)}
<ScaffoldContainer>
<div>
{isUnderConstruction && (
Expand Down
70 changes: 70 additions & 0 deletions src/components/omikuji.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import React from 'react';
import { useStaticQuery, graphql } from 'gatsby';
import Img from 'gatsby-image';
import styled from 'styled-components';

const OmikujiStyle = styled.div`
display: inline-block !important;
margin: auto;
`;

const Omikuji = () => {
const data = useStaticQuery(
graphql`
query {
nenga1: file(relativePath: { eq: "nenga1.png" }) {
childImageSharp {
fluid {
...GatsbyImageSharpFluid
}
}
}
nenga2: file(relativePath: { eq: "nenga2.png" }) {
childImageSharp {
fluid {
...GatsbyImageSharpFluid
}
}
}
nenga3: file(relativePath: { eq: "nenga3.png" }) {
childImageSharp {
fluid {
...GatsbyImageSharpFluid
}
}
}
nenga4: file(relativePath: { eq: "nenga4.png" }) {
childImageSharp {
fluid {
...GatsbyImageSharpFluid
}
}
}
nenga5: file(relativePath: { eq: "nenga5.png" }) {
childImageSharp {
fluid {
...GatsbyImageSharpFluid
}
}
}
}
`,
);
const omikujiList = [
data.nenga1.childImageSharp.fluid,
data.nenga2.childImageSharp.fluid,
data.nenga3.childImageSharp.fluid,
data.nenga4.childImageSharp.fluid,
data.nenga5.childImageSharp.fluid,
];
const selectList = () => {
return Math.floor(Math.random() * omikujiList.length);
};
return (
<OmikujiStyle>
<Img fluid={omikujiList[selectList()]} />
</OmikujiStyle>
);
};

export default Omikuji;
28 changes: 28 additions & 0 deletions src/components/useWindowDimensions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { useState, useEffect } from 'react';

const UseWindowDimensions = () => {
const getWindowDimensions = () => {
const {
innerWidth: width,
innerHeight: height,
} = window;
return {
width,
height,
};
};
const [windowDimensions, setWindowDimensions] = useState(
getWindowDimensions(),
);
useEffect(() => {
const onResize = () => {
setWindowDimensions(getWindowDimensions());
};
window.addEventListener('resize', onResize);
return () =>
window.removeEventListener('resize', onResize);
}, []);
return windowDimensions;
};

export default UseWindowDimensions;
Binary file added src/contents/images/big_bell.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 src/contents/images/kanetukibou_1.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 src/contents/images/kanetukibou_2.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 static/mp3/bell03.mp3
Binary file not shown.
Binary file added static/mp3/bonnou_taisan.mp3
Binary file not shown.
Loading