HomeiOS Developmentjavascript - React Native View Top and Top of a div inside...

javascript – React Native View Top and Top of a div inside an internet view


I do know the title isnt clear however what im basically attempting to do is do my very own rendering for an EPUB and im at present taking a naive method in direction of paginating the chapter content material and attempting to render it in a WebView after splitting the content material based mostly on the tags.

My challenge begins from the purpose the place i can’t appear to precisely cut up the content material to suit into the web page, and it overflows within the rendered net view.

I’ve a separate net view which renders off display screen and calculates the scrollHeight of the div the place the content material is being injected in.

The web page is mainly constructed block by block (tag by tag) till the div begins to overflow and the peak of the div is bigger than the View that its rendered to.

The pagination operate yields the content material collected simply earlier than the peak is exceeded.

The issue is that it by no means suits to display screen and there may be all the time a little bit of vertical overflow left.

My goal is to finally generate a listing of animated WebViews the consumer can scroll via horizontally like an precise web page flip of a ebook.

I might actually recognize some assist in figuring out the logic or calculation flaw right here within the structure top comparisons. Let me know if ive missed one thing.

Under is the react native part which does the pagination and rendering

import { EPUBChapter, epubHtmlTemplate, ParsedEPUB } from "@/lib/EpubParser";
import { useEffect, useRef, useState } from "react";
import { parseDocument, DomUtils } from "htmlparser2";
import render from "dom-serializer";
import { WebView } from "react-native-webview";
import { Textual content } from "./ui/textual content";
import { useHtmlHeightMeasurer } from "@/hooks/useHtmlHeightMeasurer";
import { View, PixelRatio, FlatList } from "react-native";

export operate WebViewCarousel({
  parsedEpub,
  currentChapterIndex = 0,
}: {
  parsedEpub: ParsedEPUB;
  currentChapterIndex: quantity;
}) {
  const chapters = parsedEpub.chapters;
  const [currentChapter, setCurrentChapter] = useState(
    undefined
  );
  const view = useRef(null);
  // const { html } = useHtmlHeightMeasurer(viewDimensions.width, viewDimensions.top);
  const { measureHtmlHeight, MeasuringWebView, resizeWebView } =
    useHtmlHeightMeasurer(355, 355);
  const [pages, setPages] = useState([]);

  async operate* pageGenerator(
    chapterHtml: string,
    dimensions: { width: quantity; top: quantity }
  ) {
    resizeWebView({ top: dimensions.width, width: dimensions.top });
    const parsedChapterHtml = parseDocument(chapterHtml);
    const htmlNodes = parsedChapterHtml.youngsters;
    let pageNodes: typeof parsedChapterHtml.youngsters = [];
    const chapterContent = DomUtils.findOne(
      (elem) => elem.title === "part",
      htmlNodes
    );
    // const pixelHeight = PixelRatio.getPixelSizeForLayoutSize(dimensions.top);
    const pixelHeight = dimensions.top;


    if (chapterContent) {
      for (const [index, node] of chapterContent.youngsters.entries()) {
        const testPage = render([...pageNodes, node]);
        // console.log('Node: ' + render(node));
        if (testPage.trim()) {
          const webViewHeight = await measureHtmlHeight(
            epubHtmlTemplate(testPage)
          );
          console.log("View top: " + pixelHeight);
          console.log("Measured Top: " + webViewHeight);
          if (webViewHeight >= pixelHeight) {
            console.log("Yielding Web page");
            
            yield pageNodes;
            pageNodes = [];
          }

          pageNodes.push(node);
        }
      }
    }

    console.log("Remaining web page");
    return pageNodes;
  }

  // const generatePage = pageGenerator(chapters[currentChapterIndex].content material);

  async operate generatePages({
    width,
    top,
  }: {
    width: quantity;
    top: quantity;
  }) {
    const pagesToAdd = [];

    for await (const web page of pageGenerator(
      chapters[currentChapterIndex].content material,
      { width, top }
    )) {
      console.log(render(web page));
      pagesToAdd.push(render(web page));
    }

    setPages([...pages, ...pagesToAdd]);
  }

  return (
     {
        generatePages({
          top: e.nativeEvent.structure.top,
          width: e.nativeEvent.structure.width,
        });
      }}
    >
      
      {pages.size > 0 && (
        
      )}
    
  );
}

The offscreen part used to measure the content material till it overflows

import { epubHtmlTemplate } from "@/lib/EpubParser";
import React, { useRef, useState } from "react";
import { View } from "react-native";
import { WebView } from "react-native-webview";

const measureJs = `
  (() => {
    const observer = new MutationObserver(measure)
    let debounce;
    
    operate measure() {
      clearTimeout(debounce);
      debounce = setTimeout(() => {
        attempt {
          const container = doc.getElementById('epub-content');
          if(container) {
            const top = container.scrollHeight;
            window.ReactNativeWebView.postMessage(JSON.stringify({
              sort: 'measurement',
              worth: top
            }));
          } else {
            window.ReactNativeWebView.postMessage(JSON.stringify({
              sort: 'error',
              worth: 'Lacking container with id epub-content'
            }));
          }
        } catch (error) {
          window.ReactNativeWebView.postMessage(JSON.stringify({
            sort: 'error',
            worth: error.message
          }));
        }
      }, 150);
    }

    observer.observe(doc.physique, { 
      childList: true, 
      subtree: true,
      attributes: true
    });

    measure();
  })()
`;

export operate useHtmlHeightMeasurer(width: quantity, top: quantity) {
  const [html, setHtml] = useState("");
  const resolver = useRef void>();
  const webViewRef = useRef(null);
  const [webViewDimensions, setWebViewDimensions] = useState({
    top: 0,
    width: 0
  });

  const measureHtmlHeight = (htmlString: string) =>
    new Promise((resolve) => {
      resolver.present = resolve;
      setHtml(htmlString);
    });
  
  const resizeWebView = ({ width, top }: { width: quantity, top: quantity }) => {
    setWebViewDimensions({ width, top })
  }

  const MeasuringWebView = () => (
    
       {
          const knowledge = JSON.parse(occasion.nativeEvent.knowledge);
          if(knowledge.sort === 'error') {
            console.error(knowledge.worth)
          }
          if (knowledge.sort === "measurement") {
            const h = Quantity(knowledge.worth);
            if (resolver.present) {
              resolver.present(h);
              resolver.present = undefined;
            }
          }
        }}
        model={{ width: webViewDimensions.width, top: webViewDimensions.top, backgroundColor: "clear" }}
      />
    
  );

  return { measureHtmlHeight, MeasuringWebView, resizeWebView };
}

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments