Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/430.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 带有动态子组件的自定义游标_Javascript_Reactjs_Code Splitting - Fatal编程技术网

Javascript 带有动态子组件的自定义游标

Javascript 带有动态子组件的自定义游标,javascript,reactjs,code-splitting,Javascript,Reactjs,Code Splitting,我有一个基于Codrops的自定义游标组件 我在每个页面上都能很好地工作,除了一个页面,它是一个基于当前状态动态显示/隐藏内容的公文包页面 如果更改状态(显示未初始加载的组件+隐藏初始组件或隐藏未初始加载的组件+显示初始加载的内容),自定义光标将不再对类名作出反应 我根据组件的当前状态显示/隐藏内容 我试图重新“初始化”光标,但这会导致自定义光标的大小/位置出现问题 我知道Cursor.js不知道在状态更改后什么时候“查找”新类,但我不知道如何让它“监视”更改,而且由于重新初始化游标不起作用,我

我有一个基于Codrops的自定义游标组件

我在每个页面上都能很好地工作,除了一个页面,它是一个基于当前状态动态显示/隐藏内容的公文包页面

如果更改状态(显示未初始加载的组件+隐藏初始组件或隐藏未初始加载的组件+显示初始加载的内容),自定义光标将不再对类名作出反应

我根据组件的当前状态显示/隐藏内容

我试图重新“初始化”光标,但这会导致自定义光标的大小/位置出现问题

我知道Cursor.js不知道在状态更改后什么时候“查找”新类,但我不知道如何让它“监视”更改,而且由于重新初始化游标不起作用,我不确定应该尝试什么。我是否应该尝试使用eventListener强制光标再次查看类

理想情况下,自定义游标将与动态和非动态元素交互,但我怀疑这是否可行

如有任何建议,将不胜感激。或者,如果有人有一个在这个场景中工作的React自定义游标的示例,我很乐意查看它

Portfolio.js

render() {
return (
  <div>
    <div className="cursor">
      <div className="circle-cursor circle-cursor--inner"></div>
    </div>
    <canvas
      className="circle-cursor circle-cursor--outer"
      resize="true"
    ></canvas>
    //CURSOR
    <CustomCursor />
    //SHOW ALL PROJECTS ON STATE CHANGE
    { this.state.showAllItems ? 
    <div className={styles.grid}>
      {list.map(item => (
        <div key={item.index} className={styles.grid__item}>
          <a href="#/a" key={item.index} value={item.index} onClick={e => this.onClick(e, item)} >
            <div key={item.index}  className={styles.glitch + " portfolioLinkHover " + styles.glitchStyle1}>
              <div className={styles.glitch__img + " img"} style={{background: 'url('+ item.imgSrc + ') no-repeat 50% 0'}}></div>
              <div className={styles.glitch__img + " img"} style={{background: 'url('+ item.imgSrc + ') no-repeat 50% 0'}}></div>
            </div>
          </a>
          <h2>{item.itemTitle} <span>{item.itemSubtitle}</span></h2>
            </a>
          </p>
        </div>
      ))}
    </div>
    : null }
    //SHOW PROJECT ON STATE CHANGE
    { this.state.currentProject ? 
      <div className={styles.projectContainer + " portfolioLinkHover"}>
        <Project />
      </div>  : null }
  </div>
);
}
render(){
返回(
//光标
//显示状态更改时的所有项目
{this.state.showAllItems?
{list.map(项=>(
{item.itemTitle}{item.itemSubtitle}

))} :null} //在状态更改时显示项目 {this.state.currentProject? :null} ); }
Cursor.js

import React, {Component} from 'react';
import Util from "./utils/util";
import './styles/cursor.scss';
import TweenMax from 'gsap';

class CustomCursor extends Component{
  constructor(props) {
    super(props);
    this.state = { isOn: this.props.isOn };
  }

  componentDidMount(){
    if(this.state.isOn == "true"){
      this.initHovers();
    }
    else{
      this.initCursor();
      this.initCanvas();
      this.initHovers();
    }
  }

  initCursor() {
    this.clientX = -100;
    this.clientY = -100;
    this.innerCursor = document.querySelector(".circle-cursor--inner");
    this.outerCursor = document.querySelector(".custom-cursor--outer");
    this.outerCursorSpeed = 1;
    this.lastX = 0;
    this.lastY = 0;
    this.isStuck = false;
    this.showCursor = false;
    const { paper } = window;

    const unveilCursor = e => {
      this.group.position = new paper.Point(e.clientX, e.clientY);
      setTimeout(() => {
        this.outerCursorSpeed = 0.2;
      }, 100);
      this.showCursor = true;
    };
    document.addEventListener("mousemove", unveilCursor);

    document.addEventListener("mousemove", e => {
      this.clientX = e.clientX;
      this.clientY = e.clientY;
    });

    const render = () => {
      TweenMax.set(this.innerCursor, {
        x: this.clientX,
        y: this.clientY
      });
      if (this.showCursor) {
        document.removeEventListener("mousemove", unveilCursor);
      }
      requestAnimationFrame(render);
    };
    requestAnimationFrame(render);
  }

  initCanvas() {
    const { paper, SimplexNoise } = window;
    const canvas = document.querySelector(".circle-cursor--outer");
    const shapeBounds = {
      width: 75,
      height: 75
    };
    paper.setup(canvas);

    const strokeColor = "rgba(255, 0, 0, 0.5)";
    const strokeWidth = 1;
    const segments = 8;
    const radius = 25;
    const noiseScale = 150; // speed
    const noiseRange = 4; // range of distortion
    let isNoisy = false;

    const polygon = new paper.Path.RegularPolygon(
      new paper.Point(0, 0),
      segments,
      radius
    );
    polygon.strokeColor = strokeColor;
    polygon.strokeWidth = strokeWidth;
    polygon.smooth();

    this.group = new paper.Group([polygon]);
    this.group.applyMatrix = false;

    const noiseObjects = polygon.segments.map(() => new SimplexNoise());
    let bigCoordinates = [];

    paper.view.onFrame = event => {
      if (!this.isStuck) {
        // move circle around normally
        this.lastX = Util.lerp(this.lastX, this.clientX, this.outerCursorSpeed);
        this.lastY = Util.lerp(this.lastY, this.clientY, this.outerCursorSpeed);
        this.group.position = new paper.Point(this.lastX, this.lastY);
      } else if (this.isStuck) {
        // fixed position on a nav item
        this.lastX = Util.lerp(this.lastX, this.stuckX, this.outerCursorSpeed);
        this.lastY = Util.lerp(this.lastY, this.stuckY, this.outerCursorSpeed);
        this.group.position = new paper.Point(this.lastX, this.lastY);
      }

      if (this.isStuck && polygon.bounds.width < shapeBounds.width) {
        // scale up the shape
        polygon.scale(1.08);
      } else if (!this.isStuck && polygon.bounds.width > 30) {
        // remove noise
        if (isNoisy) {
          polygon.segments.forEach((segment, i) => {
            segment.point.set(bigCoordinates[i][0], bigCoordinates[i][1]);
          });
          isNoisy = false;
          bigCoordinates = [];
        }

        // scale down the shape
        const scaleDown = 0.92;
        polygon.scale(scaleDown);
      }

      // while stuck and when big, do perlin noise
      if (this.isStuck && polygon.bounds.width >= shapeBounds.width) {
        isNoisy = true;

        // first get coordinates of large circle
        if (bigCoordinates.length === 0) {
          polygon.segments.forEach((segment, i) => {
            bigCoordinates[i] = [segment.point.x, segment.point.y];
          });
        }

        // calculate noise value for each point at that frame
        polygon.segments.forEach((segment, i) => {
          const noiseX = noiseObjects[i].noise2D(event.count / noiseScale, 0);
          const noiseY = noiseObjects[i].noise2D(event.count / noiseScale, 1);

          const distortionX = Util.map(noiseX, -1, 1, -noiseRange, noiseRange);
          const distortionY = Util.map(noiseY, -1, 1, -noiseRange, noiseRange);

          const newX = bigCoordinates[i][0] + distortionX;
          const newY = bigCoordinates[i][1] + distortionY;

          segment.point.set(newX, newY);
        });
      }

      // hover state for main nav items
      if (this.fillOuterCursor && polygon.fillColor !== strokeColor) {
        polygon.fillColor = strokeColor;
        polygon.strokeColor = "transparent";
      } else if (!this.fillOuterCursor && polygon.fillColor !== "transparent") {
        polygon.strokeColor = "rgba(255, 0, 0, 0.5)";
        polygon.fillColor = "transparent";
      }

      // hover state for portfolio nav items
      if (this.isOnPortfolioItem) {
        polygon.fillColor = strokeColor;
        polygon.strokeColor = "rgba(255, 226, 0, 0.5)";
        // scale up the shape
        polygon.bounds.width = 45;
        polygon.bounds.height = 45;
      } else if (!this.fillOuterCursor) {
        polygon.strokeColor = "rgba(255, 0, 0, 0.5)";
        polygon.fillColor = "transparent";
      }
      polygon.smooth();
    };
  }

  initHovers() {
    const handleMouseEnter = e => {
      const navItem = e.currentTarget;
      const navItemBox = navItem.getBoundingClientRect();
      this.stuckX = Math.round(navItemBox.left + navItemBox.width / 2);
      this.stuckY = Math.round(navItemBox.top + navItemBox.height / 2);
      this.isStuck = true;
    };

    const handleMouseLeave = () => {
      this.isStuck = false;
    };

    const linkItems = document.querySelectorAll(".browser-window__link");
    linkItems.forEach(item => {
      item.addEventListener("mouseenter", handleMouseEnter);
      item.addEventListener("mouseleave", handleMouseLeave);
    });

    const mainNavItemMouseEnter = () => {
      this.outerCursorSpeed = 0.8;
      this.fillOuterCursor = true;
    };
    const mainNavItemMouseLeave = () => {
      this.outerCursorSpeed = 0.2;
      this.fillOuterCursor = false;
    };
    const portfolioItems = document.querySelectorAll(".portfolioLinkHover");
    portfolioItems.forEach(item => {
      item.addEventListener("mouseenter", handleLinkEnter);
      item.addEventListener("mouseleave", handleLinkLeave);
    });
  }
  render() {
    return (
      <div></div>
    );
  }
}

export default CustomCursor;
import React,{Component}来自'React';
从“/utils/Util”导入Util;
导入“./styles/cursor.scss”;
从“gsap”进口TweenMax;
类CustomCursor扩展组件{
建造师(道具){
超级(道具);
this.state={isOn:this.props.isOn};
}
componentDidMount(){
如果(this.state.isOn==“true”){
this.inithover();
}
否则{
this.initCursor();
this.initCanvas();
this.inithover();
}
}
initCursor(){
this.clientX=-100;
this.clientY=-100;
this.innerCursor=document.querySelector(“.circle cursor--inner”);
this.outerCursor=document.querySelector(“.custom cursor--outer”);
此.outerCursorSpeed=1;
这个.lastX=0;
此.lastY=0;
this.isStuck=false;
this.showCursor=false;
const{paper}=窗口;
常数=e=>{
this.group.position=新纸张点(e.clientX,e.clientY);
设置超时(()=>{
该速度为0.2;
}, 100);
this.showCursor=true;
};
文件。添加的文件列表器(“鼠标移动”,光标);
document.addEventListener(“mousemove”,e=>{
this.clientX=e.clientX;
this.clientY=e.clientY;
});
常量渲染=()=>{
TweenMax.set(此.innerCursor{
x:这个,clientX,
y:这个,克利提
});
if(this.showCursor){
document.removeEventListener(“mousemove”,鼠标指针);
}
请求动画帧(渲染);
};
请求动画帧(渲染);
}
initCanvas(){
const{paper,SimplexNoise}=窗口;
const canvas=document.querySelector(“.circle cursor--outer”);
常量形状块={
宽度:75,
身高:75
};
纸。设置(画布);
const strokeColor=“rgba(255,0,0,0.5)”;
常数冲程宽度=1;
常数段=8;
常数半径=25;
const noiseScale=150;//速度
const noiseRange=4;//失真范围
让isnoise=false;
常量多边形=新的paper.Path.RegularPolygon(
新纸点(0,0),
部分,
半径
);
polygon.strokeColor=strokeColor;
polygon.strokeWidth=strokeWidth;
多边形平滑();
this.group=new paper.group([polygon]);
this.group.applyMatrix=false;
const noiseObjects=polygon.segments.map(()=>new SimplexNoise());
设bigCoordinates=[];
paper.view.onFrame=事件=>{
如果(!this.isStuck){
//正常地转一圈
this.lastX=Util.lerp(this.lastX、this.clientX、this.outerCursorSpeed);
this.lastY=Util.lerp(this.lastY,this.clientY,this.outerCursorSpeed);
this.group.position=新纸张.Point(this.lastX,this.lastY);
}else if(this.isStuck){
//导航设备上的固定位置
this.lastX=Util.lerp(this.lastX,this.stuckX,this.outerCursorSpeed);
this.lastY=Util.lerp(this.lastY,this.stuckY,this.outercurspeed);
this.group.position=新纸张.Point(this.lastX,this.lastY);
}
if(this.isStuck&&polygon.bounds.width30),则为else{
//消除噪音
如果(有噪音){
多边形.segments.forEach((段,i)=>{
segment.point.set(bigCoordinates[i][0],bigCoordinates[i][1]);
});
isnoised=假;
大坐标=[];
}
//缩小形状
常数scaleDown=0.92;
多边形。缩放(缩放向下);
}
//卡住时和较大时,是否有柏林噪音
if(this.isStuck&&polygon.bounds.width>=shapeBounds.width){
isnoise=true;
//首先得到大圆的坐标
if(bigCoordinates.length==0){
多边形.segments.forEach((段,i)=>{
BigCoordinations[i]=[段.点.x,段.点.y];
});
}
//计算该帧上每个点的噪波值
多边形.segments.forEach((段,i)=>{
const noiseX=noiseObjects[i].noise2D(event.count/noiseScale,0);
const noiseY=noiseObjects[i].noise2D(event.count/noiseS