图像滑块反应模因生成器

如何解决图像滑块反应模因生成器

我有一个关于 React 中的 ImageSlider 的问题,从 Imgflip API 获取图片以用于 Meme 生成器。 附上你找到的app.js。 ImageSlider 应该发生在“Meme Editor”部分(从第 175 行开始),它在我也附上的 index.js 中编码。 我尝试在 App.js 和 index.js 中实现按钮并通过数组状态工作,但图片没有相应改变。

我知道制作一个Imageslider应该很容易,但是由于我们远程处理代码并且结构在某个时候变得非常不清楚,我有点迷茫。 非常感谢您的帮助。

import React,{ useState,useEffect } from "react";

import { Meme } from "./components/Meme";
import Topbar from "./components/Topbar";
import TemplatePicker from "./components/TemplatePicker";
import Editor from "./components/Editor";

//MaterialUI
import Grid from "@material-ui/core/Grid";
import Paper from "@material-ui/core/Paper";
import { makeStyles } from "@material-ui/core/styles";
import Typography from "@material-ui/core/Typography";
import { TextField } from "@material-ui/core";
import Box from "@material-ui/core/Box";
import MemeHistory from "./components/MemeHistory";
import TemplateOverview from "./components/TemplateOverview";

const useStyles = makeStyles((theme) => ({
  grid: {
    width: "100%",height: "100%",margin: "0px",},root: {
    flexGrow: 1,paper: {
    padding: theme.spacing(2),textAlign: "center",color: theme.palette.text.secondary,scroll: {
    overflow: "scroll",height: "700px",scroll2: {
    overflow: "scroll",height: "500px",search: {
    overflow: "scroll",height: "430px",margin: {
    margin: theme.spacing(1),}));



function App() {
  const [templates,setTemplates] = useState([]);
  const [template,setTemplate] = useState(null);
  const [newMemeCreated,setNewMemeCreated] = useState(false);
  const [newTemplateCreated,setNewTemplateCreated] = useState(false);
  const [index,setIndex] = useState(0); // create state to keep track of images index,set the default index to 0


  const slideRight = () => {
    setIndex((index + 1) % templates.length); // increases index by 1
    console.log(index);
    console.log(templates.length);
    setTemplate(index)
  };
  

  // let [editedMemeUrl,setEditedMemeUrl] = useState("");

  const classes = useStyles(); // const classes is created,which refers to useStyles

  // here,we get the images from the Imgflip API through a backend request,it can be found in the routes folder
  useEffect(() => {
    fetch("http://localhost:3001/memes")
      .then((x) => x.json())
      .then((response) => setTemplates(response.data.memes));
  },[]);

  // Text update function => !!! Redundant,put can potentially be re-used for image sharing functionalities
  // const updateText = async (e) => {
  //   if (!template.isUserUploaded) {
  //     // if template is not user uploaded,then use the updateText function. This needs to be changed into an editor that can both handle text inputs for Imgflip API templates and customones.
  //     console.log("button update text");
  //     e.preventDefault(); // This makes sure that the Form is not refreshed every time it is submitted
  //     // add the logic to create meme from the imgflip api
  //     const params = {
  //       //these are the properties of caption_image of the imgflip api
  //       template_id: template.id,//       text0: topText,//       text1: bottomText,//       username: "isakl",//       password: "omm2020",//     };
  //     const response = await fetch(
  //       `https://api.imgflip.com/caption_image${objectToQueryParam(params)}`
  //     );
  //     const imgFlipResponse = await response.json();
  //     editedMemeUrl = imgFlipResponse.data.url;
  //     setEditedMemeUrl(imgFlipResponse.data.url);
  //     console.log(editedMemeUrl);

  //     function pictureChange() {
  //       document.getElementById("memeStateDiv").innerHTML =
  //         "<img id='memeState' src='' alt='memeState' width='250'>";
  //       document.getElementById("memeState").src = editedMemeUrl;
  //     }
  //     pictureChange();

  //     //setMeme(editedMemeUrl); // After editing the Meme,the Imgflip API creates a new URL with the edited Meme which is even accessible over the Imgflip site.
  //   }
  // };

  // we are displaying a list of memes until a meme is selected
  return (
    <div style={{ textAlign: "center" }}>
      <div className={classes.root}>
        <Grid container spacing={2} direction="row" alignItems="stretch">
          <Grid item xs={12}>
            <Paper className={classes.paper} elevation={3}>
              <Topbar></Topbar>
            </Paper>
          </Grid>
        </Grid>

{/* Search function */}
        <Grid item xs={3}>
          <TextField
            className={classes.margin}
            id="input-with-icon-textfield"
            label="Search for Meme"
          ></TextField>
        </Grid>

        <Grid container spacing={2} direction="row">
          <Grid item xs={3}>
            <Paper className={classes.paper} elevation={3} position="fixed">
              <div elevation={3} className={classes.scroll}>
                {/* {" "} */}
{/* Get MEMES for the sidebar */}
                <Grid container spacing={3}>
                  <Grid item sm={3} elevation={3}>
                    <Box>
                      {templates.map((template) => {
                        return (
                          <Meme // the image logic is extracted into the Meme.js component so it does not have to be rewritten
                            template={template}
                            onClick={() => {
                              // The image that is clicked on,will be selected as the template and the useState is being updated
                              setTemplate(template);
                            }}
                          />
                        );
                      })}
                    </Box>
                  </Grid>
                </Grid>
              </div>
            </Paper>
          </Grid>
          <Grid item xs={6} className={classes.grid}>
            <Grid container spacing={1} direction="row">
              <Grid item xs={12}>
                <Paper
                  className={classes.paper}
                  elevation={3}
                  position="center"
                >
{/* Meme Editor */}
                  <Typography variant="h5" color="primary">
                    EDITOR
                  </Typography>
                  <Box>
                  <button onClick={slideRight}>{">"}</button>
    
                  <Editor
                    memeToEdit={template}
                    handleReloadMemes={(bool) => setNewMemeCreated(bool)}
                  >

                  </Editor>
                  </Box>
                </Paper>
              </Grid>
            </Grid>
          </Grid>
          <Grid item xs={3}>
            <Paper className={classes.paper} elevation={3}>
{/* Settings */}
              <Typography variant="h5" color="primary">
                SETTINGS
              </Typography>
              <TemplatePicker
                setShouldReloadSavedTemplates={(bool) =>
                  setNewTemplateCreated(bool)
                }
                // passing our uploaded image up to the App.js,to pass it down to the Meme component
                setTemplateInEditor={(img) => setTemplate(img)}
              ></TemplatePicker>
            </Paper>
          </Grid>
        </Grid>
        <Grid container spacing={2} direction="row" alignItems="stretch">
          <Grid item xs={12}>
            <Paper className={classes.paper} elevation={3} position="fixed">
{/* Your Memes */}
              <Typography variant="h5" color="primary">
                YOUR MEMES
              </Typography>
              <div elevation={3} className={classes.scroll2}>
                <MemeHistory
                  setShouldReloadSavedMemes={(bool) => setNewMemeCreated(bool)}
                  shouldReloadSavedMemes={newMemeCreated}
                />
              </div>
            </Paper>
          </Grid>
        </Grid>
        <Grid container spacing={2} direction="row" alignItems="stretch">
          <Grid item xs={12}>
            <Paper className={classes.paper} elevation={3}>
{/* Your Templates */}
              <Typography variant="h5" color="primary">
                YOUR CUSTOM TEMPLATES
              </Typography>
              <div elevation={3} className={classes.scroll2}>
                <TemplateOverview
                  setShouldReloadSavedTemplates={(bool) =>
                    setNewTemplateCreated(bool)
                  }
                  shouldReloadSavedTemplates={newTemplateCreated}
                  setTemplateInEditor={(img) => {
                    setTemplate(img);
                  }}
                />
              </div>
            </Paper>
          </Grid>
        </Grid>
      </div>
    </div>
  );
}

export default App;

// This is the Component for the Editor Box in the Middle of the webapp in which Meme Templates are selected into in order to be edited.
import React,useEffect,useRef } from "react";
import { Button } from "@material-ui/core";
import { TextField } from "@material-ui/core";
import IconButton from "@material-ui/core/IconButton";
import ArrowBackIcon from "@material-ui/icons/ArrowBack";
import ArrowForwardIcon from "@material-ui/icons/ArrowForward";
import ArrowDownwardIcon from "@material-ui/icons/ArrowDownward";
import ArrowUpwardIcon from "@material-ui/icons/ArrowUpward";
//Share Buttons
import {
  EmailShareButton,FacebookShareButton,TwitterShareButton,EmailIcon,FacebookIcon,TwitterIcon,} from "react-share";

// we pre-define the canvas width and height
const CANVAS_WIDTH = 300; // Wie können wir die variabel machen => Abängig von der Größe des Originalbildes??
const CANVAS_HEIGHT = 300;

const Editor = (props) => {
  const { memeToEdit,handleReloadMemes } = props;
  console.log("memeToEdit",memeToEdit);

  const [image,setImage] = useState(null);
  const [imageWidth,setImageWidth] = useState(0);
  const [imageHeight,setImageHeight] = useState(0);
  const [templates,setTemplate] = useState(null);
  const [index,set the default index to 0

  const canvas = useRef(null);
  const [fontColor,setFontColor] = useState("white");
  const [fontStyle,setFontStyle] = useState("30px Impact");
  const [topText,setTopText] = useState("");
  const [topTextPosX,setTopTextPosX] = useState(CANVAS_WIDTH / 2);
  const [topTextPosY,setTopTextPosY] = useState(CANVAS_HEIGHT * 0.1);
  const [bottomTextPosX,setBottomTextPosX] = useState(CANVAS_WIDTH / 2);
  const [bottomTextPosY,setBottomTextPosY] = useState(CANVAS_HEIGHT * 0.9);
  const [bottomText,setBottomText] = useState("");
  const [additionalTextA,setAdditionalTextA] = useState("");
  const [additionalTextAPosX,setAdditionalTextAPosX] = useState(
    CANVAS_WIDTH / 2
  );
  const [additionalTextAPosY,setAdditionalTextAPosY] = useState(
    CANVAS_HEIGHT * 0.5
  );

  useEffect(() => {
    fetch("http://localhost:3001/memes")
      .then((x) => x.json())
      .then((response) => setTemplates(response.data.memes));
  },[]);

  // Define functions with which the font colors and styles are changed OnClick => See Buttons at the bottom
  const changeFontColorBlack = () => {
    setFontColor("black");
  };
  const changeFontColorWhite = () => {
    setFontColor("white");
  };
  const changeFontBold = () => {
    setFontStyle("30px Impact");
  };
  const changeFontItalic = () => {
    setFontStyle("Italic 30px Impact");
  };
  const changeFontStyle = () => {
    setFontStyle("50px Impact");
  };

  //ImageSlider
  const slideRight = () => {
    setIndex((index + 1) % templates.length); // increases index by 1
    console.log(index);
    console.log(image);
    console.log(templates.length);
  };

  const slideLeft = () => {
    const nextIndex = index - 1;
    if (nextIndex < 0) {
      setIndex(templates.length - 1); // returns last index of images array if index is less than 0
    } else {
      setIndex(nextIndex);
    }
    console.log(index);
  };

  // Function to save Meme to DB (takes the exported Canvas)
  const saveMemeFromEditorToDB = () => {
    const bodyToSend = JSON.stringify({
      url: memeToEdit.url,exportedImage: exportCanvasAsImage(),});

    // the upcoming fetch function sends the generated Meme (accessible throught the new URL above) to the Express Backend Server. In the Express App,there is a route "saveMeme" in the Meme.js file that sends the URL with the generated Meme to the Server.
    fetch("http://localhost:3001/memes/saveMeme",{
      method: "POST",headers: {
        "Content-Type": "application/json",body: bodyToSend,})
      .then((x) => x.json())
      .then((response) => handleReloadMemes(true));
  };

  // Here,we export the current state of the canvas to an image,so it can be dowloaded at a later stage.
  const exportCanvasAsImage = () => {
    const ctx = document.getElementById("meme-canvas");
    return ctx.toDataURL("image/png");
  };

  // Download Meme
  const downloadMeme = () => {
    var link = document.createElement("a");
    link.download = "meme.png";
    link.href = exportCanvasAsImage();
    link.click();
  };

  // Here,we set the "Image" which is the template to be edited for our Meme
  useEffect(() => {
    try {
      if (!memeToEdit) return; // if there is no Template to edit,do nothing

      const { url } = memeToEdit;

      console.log("url",url);
      const meme = new Image();
      meme.src = url;

      console.log("meme",meme);
      meme.onload = () => {
        setImage(meme);
        const { height,width } = meme;
        setImageHeight(height);
        setImageWidth(width);
      };

      meme.setAttribute("crossorigin","anonymous"); // Added this,so the url of the meme can be worked with.
    } catch (error) {
      console.log("error",error);
    }
  },[memeToEdit]);

  useEffect(
    () => {
      if (image && canvas) {
        const ctx = canvas.current.getContext("2d");

        ctx.fillStyle = "black"; // the canvas is filled with black background color
        ctx.fillRect(0,CANVAS_WIDTH,CANVAS_HEIGHT); // the canvas rectangle is filled according to the set width and height (which is fixed at the moment)

        console.log("imageHeight,imageWidth",imageHeight,imageWidth);

        const contentOffset = 10;
        const factorWidth = CANVAS_WIDTH / imageWidth;
        const factorHeight = CANVAS_HEIGHT / imageHeight;

        // drawImage is responsible for taking the image that you selected and putting it on the Canvas (ctx). Source: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage
        ctx.drawImage(
          image,contentOffset,imageWidth * factorWidth - contentOffset * 2,imageHeight * factorHeight - contentOffset * 2
        );

        // set the font with which the text is entered
        ctx.font = fontStyle;
        ctx.fillStyle = fontColor;
        ctx.textAlign = "center";
        // text edit options
        ctx.fillText(topText,topTextPosX,topTextPosY);
        ctx.fillText(bottomText,bottomTextPosX,bottomTextPosY);
        ctx.fillText(additionalTextA,additionalTextAPosX,additionalTextAPosY);
      }
    },//Remember to add each const here at the end if you define it
    [
      image,canvas,topText,bottomText,additionalTextA,topTextPosY,bottomTextPosY,additionalTextAPosY,imageWidth,fontColor,fontStyle,]
  );

  return (
    <div>
      <div>
        <h2>Meme Title : XY </h2>
      </div>
      <div>
        <button onClick={slideLeft}>{"<"}</button>
        {image ? (
          <canvas
            id={"meme-canvas"}
            ref={canvas}
            width={CANVAS_WIDTH}
            height={CANVAS_HEIGHT}
          />
        ) : (
          // if no image is selected,show the following message
          <p>Select a meme,please</p>
        )}
        <button onClick={slideRight}>{">"}</button>
      </div>
      <br></br>
      <div>
        <TextField
          style={{ width: 200 }}
          size="small"
          type="text"
          label="Upper text"
          variant="outlined"
          value={topText}
          onChange={(e) => setTopText(e.target.value)}
        />
        <IconButton
          size="large"
          variant="contained"
          onClick={(e) => setTopTextPosX(topTextPosX - 10)}
        >
          <ArrowBackIcon />
        </IconButton>
        <TextField
          style={{ width: 80 }}
          size="small"
          type="text"
          variant="outlined"
          label="Position X"
          value={topTextPosX}
          onChange={(e) => setTopTextPosX(e.target.value)}
        />
        <IconButton
          size="large"
          variant="contained"
          onClick={(e) => setTopTextPosX(topTextPosX + 10)}
        >
          <ArrowForwardIcon />
        </IconButton>
        <IconButton
          size="large"
          variant="contained"
          onClick={(e) => setTopTextPosY(topTextPosY - 10)}
        >
          <ArrowUpwardIcon />
        </IconButton>
        <TextField
          style={{ width: 80 }}
          size="small"
          type="text"
          variant="outlined"
          label="Position Y"
          value={topTextPosY}
          onChange={(e) => setTopTextPosY(e.target.value)}
        />
        <IconButton
          size="large"
          variant="contained"
          onClick={(e) => setTopTextPosY(topTextPosY + 10)}
        >
          <ArrowDownwardIcon />
        </IconButton>
        <br />
        <br></br>
        <TextField
          style={{ width: 200 }}
          size="small"
          type="text"
          label="Bottom text"
          variant="outlined"
          value={bottomText}
          onChange={(e) => setBottomText(e.target.value)}
        />
        <IconButton
          size="large"
          variant="contained"
          onClick={(e) => setBottomTextPosX(bottomTextPosX - 10)}
        >
          <ArrowBackIcon />
        </IconButton>
        <TextField
          style={{ width: 80 }}
          size="small"
          type="text"
          variant="outlined"
          label="Position X"
          value={bottomTextPosX}
          onChange={(e) => setBottomTextPosX(e.target.value)}
        />
        <IconButton
          size="large"
          variant="contained"
          onClick={(e) => setBottomTextPosX(bottomTextPosX + 10)}
        >
          <ArrowForwardIcon />
        </IconButton>
        <IconButton
          size="large"
          variant="contained"
          onClick={(e) => setBottomTextPosY(bottomTextPosY - 10)}
        >
          <ArrowUpwardIcon />
        </IconButton>
        <TextField
          style={{ width: 80 }}
          size="small"
          type="text"
          variant="outlined"
          label="Position Y"
          value={bottomTextPosY}
          onChange={(e) => setBottomTextPosY(e.target.value)}
        />
        <IconButton
          size="large"
          variant="contained"
          onClick={(e) => setBottomTextPosY(bottomTextPosY + 10)}
        >
          <ArrowDownwardIcon />
        </IconButton>
        <br />
        <br></br>
        <TextField
          style={{ width: 200 }}
          size="small"
          type="text"
          label="Additional Text A"
          variant="outlined"
          value={additionalTextA}
          onChange={(e) => setAdditionalTextA(e.target.value)}
        />
        <IconButton
          size="large"
          variant="contained"
          onClick={(e) => setAdditionalTextAPosX(additionalTextAPosX - 10)}
        >
          <ArrowBackIcon />
        </IconButton>
        <TextField
          style={{ width: 80 }}
          size="small"
          type="text"
          variant="outlined"
          label="Position X"
          value={additionalTextAPosX}
          onChange={(e) => setAdditionalTextAPosX(e.target.value)}
        />
        <IconButton
          size="large"
          variant="contained"
          onClick={(e) => setAdditionalTextAPosX(additionalTextAPosX + 10)}
        >
          <ArrowForwardIcon />
        </IconButton>
        <IconButton
          size="large"
          variant="contained"
          onClick={(e) => setAdditionalTextAPosY(additionalTextAPosY - 10)}
        >
          <ArrowUpwardIcon />
        </IconButton>
        <TextField
          style={{ width: 80 }}
          size="small"
          type="text"
          variant="outlined"
          label="Position Y"
          value={additionalTextAPosY}
          onChange={(e) => setAdditionalTextAPosY(e.target.value)}
        />
        <IconButton
          size="large"
          variant="contained"
          onClick={(e) => setAdditionalTextAPosY(additionalTextAPosY + 10)}
        >
          <ArrowDownwardIcon />
        </IconButton>
      </div>
      <br></br>
      <div>
        <Button
          size="small"
          variant="outlined"
          color="black"
          onClick={changeFontColorBlack}
        >
          Font: Black
        </Button>
        <Button size="small" variant="outlined" onClick={changeFontColorWhite}>
          Font: White
        </Button>
        <Button size="small" variant="outlined" onClick={changeFontItalic}>
          Font: Italic
        </Button>
        <Button size="small" variant="outlined" onClick={changeFontBold}>
          Font: Bold
        </Button>
        <Button size="small" variant="outlined" onClick={changeFontStyle}>
          Bigger Font
        </Button>
      </div>
      <br></br>
      <div>
        <Button
          variant="contained"
          color="primary"
          onClick={saveMemeFromEditorToDB}
          disabled={!image && true}
        >
          SAVE MEME
        </Button>

        <Button
          variant="contained"
          color="primary"
          onClick={downloadMeme}
          disabled={!image && true}
        >
          DOWNLOAD
        </Button>
      </div>
      <div>
        <FacebookShareButton url={memeToEdit}>
          <FacebookIcon size={32} round />
        </FacebookShareButton>
        <TwitterShareButton url={memeToEdit}>
          <TwitterIcon size={32} round />
        </TwitterShareButton>
        <EmailShareButton url={memeToEdit}>
          <EmailIcon size={32} round />
        </EmailShareButton>
      </div>
    </div>
  );
};

export default Editor;

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res