Skip to content

Commit

Permalink
Merge pull request #188 from mitsuyoshi-yamazaki/add-combination-sandbox
Browse files Browse the repository at this point in the history
ふたつのルールの結合
  • Loading branch information
mitsuyoshi-yamazaki authored Jan 2, 2025
2 parents 7ee6381 + 88bcbb6 commit c7e3f09
Show file tree
Hide file tree
Showing 11 changed files with 177 additions and 0 deletions.
28 changes: 28 additions & 0 deletions pages/drawer_combination.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<html>
<head prefix="og: http://ogp.me/ns#">
<title></title>
<meta property="og:title" content="" />
<meta property="og:description" content="" />
<meta property="og:type" content="article" />
<meta property="og:image" content="" />
<meta property="og:url" content="https://mitsuyoshi-yamazaki.github.io/ALifeLab/pages/drawer_combination.html" />

<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-154586552-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() { dataLayer.push(arguments); }
gtag('js', new Date());

gtag('config', 'UA-154586552-1');
</script>

<meta http-equiv="content-type" charset="utf-8">
</head>

<body>
<div id="root"></div>

<script src="../dist/drawer_combination.js"></script>
</body>
</html>
1 change: 1 addition & 0 deletions src/simulations/drawer/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export const constants = {
lineLifeSpan: parameters.int("simulation.line_life_span", 10, "s.ls"),
lineLengthType: parameters.int("simulation.line_line_length_type", 0, "s.ll"),
symmetric: parameters.boolean("simulation.force_simmetric", false, "s.sy"),
lineWeight: parameters.float("simulation.line_weight", -1, "s.w"),

// drawer_change_parameter.html でのみ有効
changeParameter: {
Expand Down
3 changes: 3 additions & 0 deletions src/simulations/drawer/source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,9 @@ const generateNextRule = (rule: VanillaLSystemRule): VanillaLSystemRule => {
function createModel(rules: VanillaLSystemRule[]): Model {
const modelOf = (colorTheme: ColorTheme): Model => {
const lineWeight = (() => {
if (constants.simulation.lineWeight !== -1) {
return constants.simulation.lineWeight
}
if (constants.system.fieldSize >= 1000) {
return 1
}
Expand Down
6 changes: 6 additions & 0 deletions src/simulations/drawer_combination/html_arguments.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"page_title": "",
"og_description": "",
"og_image": "",
"script_path": "../dist/drawer_combination.js"
}
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/simulations/drawer_combination/images/002.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/simulations/drawer_combination/images/003.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/simulations/drawer_combination/images/004.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
138 changes: 138 additions & 0 deletions src/simulations/drawer_combination/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import p5 from "p5"
import React, { useState } from "react"
import ReactDOM from "react-dom"
import { DetailPage, ScreenshotButtonCustom } from "../../react-components/lab/detail_page"
import { changeRule, main, saveCurrentState } from "../drawer_sandbox/source"
import { Button } from "@material-ui/core"

type LocalPattern = {
readonly imagePath: string
angle: number
readonly ruleConstructor: (angleInput: number) => string
}

const AngleInput = (props: { angle: number, didChangeAngle: (angle: number) => void }) => {
const didChangeAngle = (event: React.ChangeEvent<HTMLInputElement>): void => {
const newAngle = parseInt(event.target.value, 10)
if (isNaN(newAngle)) {
console.log(`Program error: angle is NaN (${event.target.value})`)
return
}
props.didChangeAngle(newAngle)
}

return (<input
type="range"
min="-180"
max="180"
value={props.angle}
onChange={event => didChangeAngle(event)}
/>)
}

const PatternGallery = (props: {patterns: LocalPattern[], selectingPatternIndex: number, didSelectRule: (index: number) => void}) => {
return (
<div style={{ overflowX: "scroll", whiteSpace: "nowrap", padding: "10px" }}>
{props.patterns.map((pattern, index) => (
<div
key={index}
onClick={() => props.didSelectRule(index)}
style={{
display: "inline-block",
marginRight: "10px",
outline: index === props.selectingPatternIndex ? "3px solid blue" : "none",
cursor: "pointer",
}}
>
<img
src={pattern.imagePath}
style={{
width: "100px",
height: "100px",
objectFit: "cover",
borderRadius: "8px",
}}
/>
</div>
))}
</div>
)
}

const stringRepresentation = (rule: string): string => {
return rule.replace(/,/g, "").replace(/;/g, ", ").replace(/:/g, "→")
}

const stemPatterns: LocalPattern[] = [
{ imagePath: "", angle: 0, ruleConstructor: () => "A:0,Z" },
{ imagePath: "../src/simulations/drawer_combination/images/001.png", angle: 0, ruleConstructor: angle => `A:0,B;B:${angle},C;C:0,A,0,Z` },
{ imagePath: "../src/simulations/drawer_combination/images/003.png", angle: 0, ruleConstructor: angle => `A:0,B;B:${angle},C,${-2 * angle},C;C:0,A,0,Z` },
{ imagePath: "../src/simulations/drawer_combination/images/003.png", angle: 2, ruleConstructor: angle => `A:0,B;B:0,C;C:${angle},A,${-2 * angle},A,0,Z` },
{ imagePath: "../src/simulations/drawer_combination/images/003.png", angle: 2, ruleConstructor: angle => `A:0,B;B:${angle},C,${-2 * angle},C;C:0,D;D:0,E;E:A,0,Z` },
]

const leafPatterns: LocalPattern[] = [
{ imagePath: "", angle: 0, ruleConstructor: () => "Z:." },
{ imagePath: "", angle: -6, ruleConstructor: angle => `Z:0,Y;Y:-101,X;X:0,X,${angle},X` },
]


const App = () => {
const screenshotButton: ScreenshotButtonCustom = {
kind: "custom",
button: (
<div>
<Button variant="contained" color="primary" onClick={() => saveCurrentState()}>Save Screenshot & Parameters</Button>
<a id="link" />
</div>
)
}

const [selectedStemIndex, setSelectedStemIndex] = useState<number>(0)
const [selectedLeafIndex, setSelectedLeafIndex] = useState<number>(0)

const stemPattern = stemPatterns[selectedStemIndex]
const leafPattern = leafPatterns[selectedLeafIndex]

const [stemAngle, setStemAngle] = useState<number>(stemPattern.angle)
const [leafAngle, setLeafAngle] = useState<number>(leafPattern.angle)

const stemRule = stemPattern.ruleConstructor(stemAngle)
const leafRule = leafPattern.ruleConstructor(leafAngle)
const constructedRule = stemRule + ";" + leafRule

console.log(`Rule changed to: ${stringRepresentation(constructedRule)}`)
changeRule(constructedRule)

const changeStem = (index: number): void => {
stemPattern.angle = stemAngle
setSelectedStemIndex(index)
setStemAngle(stemPatterns[index].angle)

console.log(`[S] current: ${stemAngle} => index: ${index}, ${stemPatterns[index].angle}; ${stemPattern === stemPatterns[selectedStemIndex]}, ${stemPatterns[selectedStemIndex].angle}`)
}
const changeLeaf = (index: number): void => {
leafPattern.angle = stemAngle
setSelectedLeafIndex(index)
setLeafAngle(leafPatterns[index].angle)

console.log(`[L] current: ${leafAngle} => index: ${index}, ${leafPatterns[index].angle}`)
}

return (
<DetailPage screenshotButtonType={screenshotButton}>
<h2>パターンを選択する</h2>
<h3>{`幹:${stringRepresentation(stemRule)}`}</h3>
<PatternGallery patterns={stemPatterns} selectingPatternIndex={selectedStemIndex} didSelectRule={index => changeStem(index)} />
<AngleInput angle={stemAngle} didChangeAngle={setStemAngle} />
<hr />
<h3>{`葉:${stringRepresentation(leafRule)}`}</h3>
<PatternGallery patterns={leafPatterns} selectingPatternIndex={selectedLeafIndex} didSelectRule={index => changeLeaf(index)} />
<AngleInput angle={leafAngle} didChangeAngle={setLeafAngle} />
</DetailPage>
)
}

ReactDOM.render(<App />, document.getElementById("root"))
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const sketch = new p5(main)
1 change: 1 addition & 0 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ module.exports = {
drawer_symmetry: "./src/simulations/drawer_symmetry/layout.tsx",
drawer_fullscreen: "./src/simulations/drawer_fullscreen/layout.tsx",
drawer_sandbox: "./src/simulations/drawer_sandbox/layout.tsx",
drawer_combination: "./src/simulations/drawer_combination/layout.tsx",
lines_and_angles: "./src/simulations/lines_and_angles/layout.tsx",
la_fullscreen: "./src/simulations/la_fullscreen/layout.tsx",
la_interactive_fullscreen: "./src/simulations/la_interactive_fullscreen/layout.tsx",
Expand Down

0 comments on commit c7e3f09

Please sign in to comment.