Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
xtal
Jan 9, 2011

by Fluffdaddy

Newf posted:

Where can I read about js variable declarations that look like this:

JavaScript code:
const [a, b] = someObject;
const {something: c, d} = someOtherObject;
I know that the first line takes the properties a and b from someObject and assigns them to a and b, but I'm honestly not sure about the second line. If I knew the names of these styles of simultaneous declarations that would be a great start.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

Adbot
ADBOT LOVES YOU

teen phone cutie
Jun 18, 2012

last year i rewrote something awful from scratch because i hate myself

Newf posted:

Where can I read about js variable declarations that look like this:

JavaScript code:
const [a, b] = someObject;
const {something: c, d} = someOtherObject;
I know that the first line takes the properties a and b from someObject and assigns them to a and b, but I'm honestly not sure about the second line. If I knew the names of these styles of simultaneous declarations that would be a great start.

the first line is an array, not an object. a and b are the first 2 values in the array.

the second line is destructuring an object that looks like

code:
{
  something: 'hi',
  d: 'hello'
}
and renaming something to c

Newf
Feb 14, 2006
I appreciate hacky sack on a much deeper level than you.

Grump posted:

the first line is an array, not an object. a and b are the first 2 values in the array.

Whoops, I knew that!

But thanks, both, for the reference and explanation.

LifeLynx
Feb 27, 2001

Dang so this is like looking over his shoulder in real-time
Grimey Drawer
Dumb React question time:

I have this code:

code:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import {useState, useEffect} from 'react';
import axios from 'axios';


function GetData() {

  const [theWeather, SetTheWeather] = useState([]);

  const fetchData = async () => {
    const weather = await axios.get('http://api.openweathermap.org/data/2.5/weather?q=Richmond&appid=APIKEY');
    SetTheWeather(weather.data);
  }

  return (
    <section>
      <p>{theWeather.name}</p>
      <button className="fetch-button" onClick={fetchData}>Fetch!</button>
    </section>
  )
}

ReactDOM.render(
  <GetData />,
  document.querySelector('#root')
);
The JSON response is this:

code:
{"coord":{"lon":-77.4603,"lat":37.5538},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04n"}],"base":"stations","main":{"temp":290.94,"feels_like":290.34,"temp_min":289.82,"temp_max":293.15,"pressure":1013,"humidity":60},"visibility":10000,"wind":{"speed":4.63,"deg":50},"clouds":{"all":90},"dt":1618444560,"sys":{"type":1,"id":5662,"country":"US","sunrise":1618396546,"sunset":1618443832},"timezone":-14400,"id":4781708,"name":"Richmond","cod":200}
In JS/React, why is "theWeather.name" perfectly valid, but I get an "Objects are not valid as a React child" if I try "theWeather.weather" (which makes sense) and if I try "theWeather.weather.main" I get an "TypeError: Cannot read property 'main' of undefined" error? I guess my question is, why can't I cascade down like that, and what's the right way to do it if I wanted to grab that main or description or icon field and display it in whatever HTML tag?

xtal
Jan 9, 2011

by Fluffdaddy
It's an array of objects, I think you want theWeather.weather[0].main

Empress Brosephine
Mar 31, 2012

by Jeffrey of YOSPOS
Yeah weather is an array within an array so that should work. Tbh I would just map over it because that means at some point you're going to run into multiple weather's, so something like'



JavaScript code:

<Ul>
theWeather.weather.map(conditions => { <li><p>{conditions.main}</p></li>};)
</Ul>

Should get you what you want I believe

Osmosisch
Sep 9, 2007

I shall make everyone look like me! Then when they trick each other, they will say "oh that Coyote, he is the smartest one, he can even trick the great Coyote."



Grimey Drawer

Empress Brosephine posted:

Yeah weather is an array within an array so that should work. Tbh I would just map over it because that means at some point you're going to run into multiple weather's, so something like'



JavaScript code:

<Ul>
theWeather.weather.map(conditions => { <li><p>{conditions.main}</p></li>};)
</Ul>

Should get you what you want I believe

Yeah, just remember to set a key on each li.

In general, you can't just plonk any old object into a react jsx with curlies, it needs to be a primitive or an element itself.

teen phone cutie
Jun 18, 2012

last year i rewrote something awful from scratch because i hate myself

xtal posted:

It's an array of objects, I think you want theWeather.weather[0].main

this but you've also got a few other problems here.

You're initializing theWeather as an array, and setting it with axios' data property, which is an object, so you keep the primitives the same across the board.

Also when you're rendering your html, you're trying to access a property that only exists after the network request finishes, so you need to add some check to first see if the data actually exists first.

Skyarb
Sep 20, 2018

MMMPH MMMPPHH MPPPH GLUCK GLUCK OH SORRY I DIDNT SEE YOU THERE I WAS JUST CHOKING DOWN THIS BATTLEFIELD COCK DID YOU KNOW BATTLEFIELD IS THE BEST VIDEO GAME EVER NOW IF YOULL EXCUSE ME ILL GO BACK TO THIS BATTLECOCK
I'm making a very simple app, its a SPA and I am hoping to have it all delivered in basically one big bundle. What is the best hosting package to use for this? I'm used express in the past but that feels like extreme overkill. I just want, if people hit my url, to be given this big ol' bundle. All the routing is local so there is really only one serverside end point. I am planning on hosting this on a cheap digital ocean droplet at some point.

gbut
Mar 28, 2008

😤I put the UN🇺🇳 in 🎊FUN🎉


Netlify, if it doesn't require backend. Free tier allows hosting React apps created with CRA with ease. Integrates with github. Offers more advanced stuff if you need it.

Skyarb
Sep 20, 2018

MMMPH MMMPPHH MPPPH GLUCK GLUCK OH SORRY I DIDNT SEE YOU THERE I WAS JUST CHOKING DOWN THIS BATTLEFIELD COCK DID YOU KNOW BATTLEFIELD IS THE BEST VIDEO GAME EVER NOW IF YOULL EXCUSE ME ILL GO BACK TO THIS BATTLECOCK

gbut posted:

Netlify, if it doesn't require backend. Free tier allows hosting React apps created with CRA with ease. Integrates with github. Offers more advanced stuff if you need it.

I appreciate this post, but I was control over my server solution. So I am going with a digital ocean droplet, I am just not sure what framework to use to act as a server, probably leaning towards nginx but not sure.

Impotence
Nov 8, 2010
Lipstick Apathy
anything works. nginx, apache 2.4+ is decent (don't go below 2.4), you're effectively serving static files

Ape Fist
Feb 23, 2007

Nowadays, you can do anything that you want; anal, oral, fisting, but you need to be wearing gloves, condoms, protection.
Anyone used NX? I actually love it. It takes a bit to configure it how you like it but I'm using it with NestJS/Angular & SSR and its a really loving solid full stack mono-repo solution. It feels like it was basically made to marry NestJS & Angular together (in fairness the whole thing is a heavily modified Angular webpack config) though it can be used with React/Vue/Express, etc.

Empress Brosephine
Mar 31, 2012

by Jeffrey of YOSPOS
Any of you have experience with apollo and wpgraphql? Or I guess NextJs in general. I have a odd question that no one's answered on stack overflow yet and goons usually know their stuff. Thanks


https://stackoverflow.com/questions/67291378/nextjs-apollo-wpgraphql-combining-or-retrieving-more-than-100-records

Chas McGill
Oct 29, 2010

loves Fat Philippe

Ape Fist posted:

Anyone used NX? I actually love it. It takes a bit to configure it how you like it but I'm using it with NestJS/Angular & SSR and its a really loving solid full stack mono-repo solution. It feels like it was basically made to marry NestJS & Angular together (in fairness the whole thing is a heavily modified Angular webpack config) though it can be used with React/Vue/Express, etc.

Using it with React and Koa and I like it. The library organisation and commands are solid.

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.

Empress Brosephine posted:

Any of you have experience with apollo and wpgraphql? Or I guess NextJs in general. I have a odd question that no one's answered on stack overflow yet and goons usually know their stuff. Thanks


https://stackoverflow.com/questions/67291378/nextjs-apollo-wpgraphql-combining-or-retrieving-more-than-100-records

dataset2 is undefined because dataset2 isn't a property you get back from calling client.query().

I think you meant to rename the data property instead?

JavaScript code:
const { data: dataset2 } = await client.query({
  // ...
});
Also, I would recommend defining your queries in a separate file, or at least at module scope level, instead of defining them inside of getStaticProps, for better readability and to avoid re-compiling the strings into queries on every call.

Ima Computer fucked around with this message at 04:28 on Apr 28, 2021

Empress Brosephine
Mar 31, 2012

by Jeffrey of YOSPOS
You are a genius thank you so much.

Empress Brosephine
Mar 31, 2012

by Jeffrey of YOSPOS
Quick second question because I apparently can't figure it out...how do I join the two pieces of data? I tried:

code:
  const allCampgrounds = {
    ...data,
    ...dataset2,
  };
but that just returns dataset2's data and not data's, so its merging I guess :( . For reference, here's the objects:

code:
dataset1:  
Object { features: {…}, regions: {…}, ownerships: {…}, campgrounds: {…} }
&#8203;
campgrounds: Object { __typename: "RootQueryToCampgroundConnection", pageInfo: {…}, edges: (100) […] }
&#8203;
features: Object { __typename: "RootQueryToFeatureConnection", nodes: (38) […] }
&#8203;
ownerships: Object { __typename: "RootQueryToOwnershipConnection", nodes: (3) […] }
&#8203;
regions: Object { __typename: "RootQueryToRegionConnection", nodes: (7) […] }
&#8203;
<prototype>: Object { … }
camps.js:21:10
dataset2:  
Object { features: {…}, regions: {…}, ownerships: {…}, campgrounds: {…} }
&#8203;
campgrounds: Object { __typename: "RootQueryToCampgroundConnection", pageInfo: {…}, edges: (36) […] }
&#8203;
features: Object { __typename: "RootQueryToFeatureConnection", nodes: (38) […] }
&#8203;
ownerships: Object { __typename: "RootQueryToOwnershipConnection", nodes: (3) […] }
&#8203;
regions: Object { __typename: "RootQueryToRegionConnection", nodes: (7) […] }
Or is a map function the best way to do it?

xtal
Jan 9, 2011

by Fluffdaddy
What are you hoping for the results to be? The spread operator should work for joining objects, but it's going to overwrite keys if there are duplicates. Do you want to merge the values inside the keys like a deep merge?

Empress Brosephine
Mar 31, 2012

by Jeffrey of YOSPOS
Yeah, essentially just concat dataset2.campgrounds.edges onto data so I end up with

code:
dataset3:
Object { features: {…}, regions: {…}, ownerships: {…}, campgrounds: {…} }
&#8203;
campgrounds: Object { __typename: "RootQueryToCampgroundConnection", pageInfo: {…}, edges: (136) […] }
&#8203;
features: Object { __typename: "RootQueryToFeatureConnection", nodes: (38) […] }
&#8203;
ownerships: Object { __typename: "RootQueryToOwnershipConnection", nodes: (3) […] }
&#8203;
regions: Object { __typename: "RootQueryToRegionConnection", nodes: (7) […] }
Object
I asked on StackOverflow who suggested the concat and spread operator, but the spread operator just returns the 36 listings from dataset2 and disregards data's uh data. If I try .concat I get:

code:
TypeError: data.concat is not a function
Then they closed my thread lol.

Thank you all for the help!

edit:

I've gotten a little closer. Using

code:
const dataset3 = [{...data.campgrounds.edges, ...dataset2}] 

I've gotten:

code:
0: Object { __typename: "RootQueryToCampgroundConnectionEdge", cursor: "YXJyYXljb25uZWN0aW9uOjcyNA==", node: {…} }
&#8203;&#8203;
...
&#8203;&#8203;
99: Object { __typename: "RootQueryToCampgroundConnectionEdge", cursor: "YXJyYXljb25uZWN0aW9uOjQ5NQ==", node: {…} }
&#8203;&#8203;
campgrounds: Object { __typename: "RootQueryToCampgroundConnection", pageInfo: {…}, edges: (36) […] }

Empress Brosephine fucked around with this message at 15:21 on Apr 28, 2021

Empress Brosephine
Mar 31, 2012

by Jeffrey of YOSPOS
I figured it out :D

code:
  const dataset3 = data.campgrounds.edges.concat(dataset2);
Arrays and Objects can be confusing...

Skyarb
Sep 20, 2018

MMMPH MMMPPHH MPPPH GLUCK GLUCK OH SORRY I DIDNT SEE YOU THERE I WAS JUST CHOKING DOWN THIS BATTLEFIELD COCK DID YOU KNOW BATTLEFIELD IS THE BEST VIDEO GAME EVER NOW IF YOULL EXCUSE ME ILL GO BACK TO THIS BATTLECOCK
I have a dev dependency that requires java to run (its used to generate code). However on my pipeline servers java isn't installed. Instead of changing how those pipeline machines are configured, would installing java as a dev dependency actually work?

Roadie
Jun 30, 2013

Skyarb posted:

I have a dev dependency that requires java to run (its used to generate code). However on my pipeline servers java isn't installed. Instead of changing how those pipeline machines are configured, would installing java as a dev dependency actually work?

What do you even mean by "installing java as a dev dependency", specifically?

Skyarb
Sep 20, 2018

MMMPH MMMPPHH MPPPH GLUCK GLUCK OH SORRY I DIDNT SEE YOU THERE I WAS JUST CHOKING DOWN THIS BATTLEFIELD COCK DID YOU KNOW BATTLEFIELD IS THE BEST VIDEO GAME EVER NOW IF YOULL EXCUSE ME ILL GO BACK TO THIS BATTLECOCK

Roadie posted:

What do you even mean by "installing java as a dev dependency", specifically?

npm install --save-dev java

Roadie
Jun 30, 2013

Skyarb posted:

npm install --save-dev java

That's not a Java installation, it's a library to invoke a JDK installation from JS.

Skyarb
Sep 20, 2018

MMMPH MMMPPHH MPPPH GLUCK GLUCK OH SORRY I DIDNT SEE YOU THERE I WAS JUST CHOKING DOWN THIS BATTLEFIELD COCK DID YOU KNOW BATTLEFIELD IS THE BEST VIDEO GAME EVER NOW IF YOULL EXCUSE ME ILL GO BACK TO THIS BATTLECOCK

Yeah that was my assumption as well. Its annoying to setup an environment with npm (whcih really isn't its purpose so I get it). Guess I gotta gently caress with doicker.

Skyarb
Sep 20, 2018

MMMPH MMMPPHH MPPPH GLUCK GLUCK OH SORRY I DIDNT SEE YOU THERE I WAS JUST CHOKING DOWN THIS BATTLEFIELD COCK DID YOU KNOW BATTLEFIELD IS THE BEST VIDEO GAME EVER NOW IF YOULL EXCUSE ME ILL GO BACK TO THIS BATTLECOCK
Anyone know of any good extensions or anything to make typescript errors in vscode any more legible. If I have a type conflict trying to parse those errors can be incredibly difficult.

Empress Brosephine
Mar 31, 2012

by Jeffrey of YOSPOS
Any of you handy with jQuery and might know the answer to this question?

https://stackoverflow.com/questions/67541201/jquery-wordpress-redirect-to-a-page-and-attach-html-data-to-div-on-new-page

I'd post it here but the forums don't like jQuery being posted

Khorne
May 1, 2002

Empress Brosephine posted:

Any of you handy with jQuery and might know the answer to this question?

https://stackoverflow.com/questions/67541201/jquery-wordpress-redirect-to-a-page-and-attach-html-data-to-div-on-new-page

I'd post it here but the forums don't like jQuery being posted
(1) Can you not edit the page that is being redirected to for some reason?

Assuming you can edit it:

(2) Querying the data on the page you want to display it on is the idiomatic approach
(3) You could probably set url parameters, a cookie, or a local data store with the inputs and then perform the query on the second page by reading the inputs from where you stored them.

Maybe there's some other approach I am overlooking because I am a caveman who always uses #2, #3, or some solution involving the backend.

Khorne fucked around with this message at 02:10 on May 15, 2021

Empress Brosephine
Mar 31, 2012

by Jeffrey of YOSPOS
Nah those both sound like better approaches. I'll do that, thank you very much.

Data Graham
Dec 28, 2009

📈📊🍪😋



Hey, two questions I guess:

1) Is there by any chance a dedicated Three.JS/WebGL thread I'm not seeing, or is this as good a place as any?

2) Are there any Three.js gurus in the house?

I'm trying to create what I think should be an extremely simple and computationally inexpensive scene (a six-sided box made of planes, each ultimately with a different image mapped onto the surface, with an OrbitControls so I can spin it around and loooook at it), and it makes my fans spin up to MAX POWER and never spin down and I can't even type smoothly in my IDE anymore. I've simplified it as much as possible and used all the tricks I think are applicable from https://discoverthreejs.com/tips-and-tricks/, and this loving thing runs as cool as a cucumber compared to my stupid green cube.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Data Graham posted:

I'm trying to create what I think should be an extremely simple and computationally inexpensive scene (a six-sided box made of planes, each ultimately with a different image mapped onto the surface, with an OrbitControls so I can spin it around and loooook at it)
Seems weird to link to other things but not to your own thing so we could tell you what's wrong. But it *sounds like* you're queuing a rerender at the end of the render, rather than at the end of a frame, so you're rendering at maximum possible fps instead of 30 or 60fps. Or, if it's a slow ramp-up to problematic, you might be doing requestAnimationFrame every frame *and* somewhere else, which causes gradually increasing double/triple/etc. renders per frame.

gbut
Mar 28, 2008

😤I put the UN🇺🇳 in 🎊FUN🎉


That's the first place I'd look too. You're doing something computationally intensive somewhere by accident, as once you have the mesh and materials set up, it should be able to run a huge number of triangles (compared to a simple cube).

Data Graham
Dec 28, 2009

📈📊🍪😋



Thanks, yeah, I didn't want to code-dump as step one before I knew this was the right place to post. Here's what I'm doing (this is Vue):

code:
  mounted: function() {
    const container = this.$refs.container;

    // SET AND ADD CAMERA
    this.camera = new THREE.PerspectiveCamera(
      75,
      300 / 300,
      0.1,
      1000
    );
    this.camera.position.set(0, 2, 4);

    // ADD SCENE
    this.scene = new THREE.Scene();

    // ADD LIGHT TO SCENE
    this.ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
    this.directionalLight = new THREE.DirectionalLight(0xffffff, 1);
    this.directionalLight.position.set(5, 10, 5);
    this.directionalLight.target.position.set(5, 0, 0);
    this.scene.add(this.ambientLight);
    this.scene.add(this.directionalLight);

    // RENDER IN PAGE
    this.renderer = new THREE.WebGLRenderer({ antialias: true });
    this.renderer.setClearColor('#dbdbdb');
    this.renderer.setSize(window.innerWidth, window.innerHeight);
    this.renderer.gammaFactor = 2.2;
    this.renderer.outputEncoding = THREE.sRGBEncoding;
    container.appendChild(this.renderer.domElement);

    // SET GRID HELPER
    const size = 10;
    const divisions = 25;
    this.gridHelper = new THREE.GridHelper(size, divisions);
    this.scene.add(this.gridHelper);

    // SET ORBIT CONTROLS
    this.orbitControls = new OrbitControls(
      this.camera,
      this.renderer.domElement
    );
    this.orbitControls.addEventListener('change', () =>
      this.renderer.render(this.scene, this.camera)
    );

    this.animate();
  },

    setupBox () {
      // Initial setup of the box geometry; this only gets called once
      this.box = {};
      Array.from(this.boxFaces).forEach((face) => {
        console.log(face);
        const geometry = new THREE.PlaneGeometry(face.planeGeometry.width, face.planeGeometry.height);
        const material = new THREE.MeshBasicMaterial({ color: 'green' });
        material.color.convertSRGBToLinear();
        const facePlane = new THREE.Mesh(geometry, material);
        facePlane.rotation.x = face.planeGeometry.rotation.x;
        facePlane.rotation.y = face.planeGeometry.rotation.y;
        facePlane.rotation.z = face.planeGeometry.rotation.z;
        facePlane.position.x = face.planeGeometry.position.x;
        facePlane.position.y = face.planeGeometry.position.y;
        facePlane.position.z = face.planeGeometry.position.z;
        console.log(facePlane);
        this.box[face.id] = facePlane;
        this.scene.add(facePlane);
      });
    },

    refreshFaces () {
      // Refresh the box faces by dumping the canvas to an image; triggered only when the canvas has changed
      console.log('Refreshing faces');
      const backgroundImage = this.canvas.backgroundImage;
      this.canvas.setBackgroundImage(null);
      const dataURL = this.canvas.toDataURL();
      this.canvas.setBackgroundImage(backgroundImage);

      Object.keys(this.box).forEach((key) => {
        const facePlane = this.box[key];
        const texture = new THREE.TextureLoader().load(dataURL);
        facePlane.material = new THREE.MeshPhongMaterial({ map: texture });
      });
      console.log(this.box);
    },

    animate: function() {
      requestAnimationFrame(this.animate);
      // this.box is null initially
      // this.boxFaces is a data blob being passed in to this component via a prop
      if (this.box === null && this.boxFaces) {
        console.log('Setting up box');
        this.setupBox();
      }
      // this.canvas generates a uuid.v4 by which I trigger a refresh of the box faces by dumping the canvas to an image
      // This way I don't run this code during every loop, only when the canvas has changed
      // Note that the fans spin up even if I comment this stuff out and use a flat BasicMaterial
      if (this.box != null && this.canvas && this.canvas.stateHash !== this.canvasStateHash) {
        console.log('Canvas has changed');
        this.canvasStateHash = this.canvas.stateHash;
        this.refreshFaces();
      }
      this.renderer.render(this.scene, this.camera);
    }
Apologies for any terrible style, I have eslint watching my back but I'm more of a backend guy during the day.

I can't really see where I might be calling anything recursively or anything like that, but I could well be going about this the entirely wrong way. I haven't done 3D stuff since POVRAY on a 386 in high school

Data Graham fucked around with this message at 22:32 on May 30, 2021

gbut
Mar 28, 2008

😤I put the UN🇺🇳 in 🎊FUN🎉


I might be wrong here, but aren't you introducing another recursive requestAnimationFrame on each mount?

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

gbut posted:

I might be wrong here, but aren't you introducing another recursive requestAnimationFrame on each mount?
I'm not familiar with vue, but I would test for anything like this by incrementing a global counter in the animate function, and having a once-per-second timer that console.logs then clears the counter - if that number *doesn't* go higher than 60 then you can assume the problem is somewhere else.

I'd also be concerned that refreshFaces might be getting called more than you expect, but I would think you'd have seen that already if that was the issue since you have a console.log for it. (Making a canvas into a dataUrl every frame does seem like the sort of thing that would be a heavy load though.)

roomforthetuna fucked around with this message at 23:37 on May 30, 2021

Data Graham
Dec 28, 2009

📈📊🍪😋



Interesting idea, thanks ... I just tried that and it mostly pegs at 60, and I can get it to drop down to like 43 by grabbing and spinning the box a lot, but it never goes above 60 (well I saw 62 once).

Maybe it's okay, I'm not sure. This is on a 2014 MBP that otherwise gets like 20 FPS on that "Littlest Tokyo" thing, whereas I also have a 2019 MBP that gets 30 FPS on the same scene, but I haven't tried it on my box scene. Maybe this is more just a "modern hardware won't ever notice an issue" thing? After more experimentation it seems the fans do spin down eventually if I leave the scene untouched, but the CPU stays hot and scrolling the forums in another window is choppy. This doesn't feel like something I ought to be yeeting into production without understanding it better in any case.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!
Another possibility is this.canvas being something surprising (it seems to be defined outside of what we can see). I don't know if it's still typically problematic to have textures that aren't squares with sides that are a power of two long, or maybe that canvas is just huge.

(The code there seems weird too, clearing the background image before calling toDataUrl then setting it to something afterwards? But I don't even know what that canvas object is; HTMLCanvasElement has toDataUrl but doesn't have setBackgroundImage, so I guess it's some kind of wrapper, maybe Fabric?)

Data Graham
Dec 28, 2009

📈📊🍪😋



Yeah, it's Fabric. What I'm trying to do there is composite some images together to use as the mapping texture, because apparently I can't layer multiple textures together in Three itself?

It's an editable canvas where you can place images and text elements on a guide which then get mapped onto the box in the inner Three component. So I'm taking the canvas (which is in the outer component, as you deduced), which has a backgroundImage set already as a guide for the box faces, and then to make the mapping I'm experimenting with various approaches where currently I'm trying to swap in another backgroundImage which is an underlying texture tile pattern, and then dump the canvas to a data URL so I can map it in Three. And then reset the canvas back to the original backgroundImage before the UI notices ... I guess.

Still doing a bunch of floundering and tinkering there. It seems to involve stuff like using setBackgroundImage() which takes a callback function which executes when the image is loaded, and then doing the dataURL/mapping stuff in that callback; but right now I'm still wrestling with making the canvas aware that the backgroundImage has been updated in the callback function (it still seems to dump out with the original backgroundImage at that point).

I've been trying to experiment with stuff like maintaining a separate shadow canvas with the other (texture) backgroundImage already set, but that creates further issues and dumping that out is even wronger, because the canvas in question has to be displayed and at full-size in order to work, and maintaining state on that shadow canvas seems like a lot of background processing anyway, so that's probably a dead end.

Not sure if I'm explaining it clearly here, but I'll probably figure it out eventually. Unless of course someone knows an obvious path forward that I have yet to discover :buddy:


e: hell yeah I got it, turns out I didn't understand how .bind works on callback functions, so I needed to do that and then manually renderAll() the canvas within the callback :thurman:

Data Graham fucked around with this message at 03:57 on May 31, 2021

Adbot
ADBOT LOVES YOU

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Data Graham posted:

It's an editable canvas where you can place images and text elements on a guide which then get mapped onto the box in the inner Three component. So I'm taking the canvas (which is in the outer component, as you deduced), which has a backgroundImage set already as a guide for the box faces, and then to make the mapping I'm experimenting with various approaches where currently I'm trying to swap in another backgroundImage which is an underlying texture tile pattern, and then dump the canvas to a data URL so I can map it in Three. And then reset the canvas back to the original backgroundImage before the UI notices ... I guess.
Using toDataUrl for this seems like a smell. If Fabric wasn't involved I'd have a better idea what's going on, but the general way to do that sort of thing is to create an HTMLCanvasElement, paint everything you need onto it, then texture = THREE.CanvasTexture(canvasElement) - no need to go through a loader or turn it into a URL.
code:
var canvasElement = document.createElement("CANVAS");
canvasElement.width = 512;
canvasElement.height = 512;
var canvasContext = canvasElement.getContext("2d");
canvasContext.drawImage(backgroundImage, 0, 0, 512, 512);
// Draw other layers.
var texture = THREE.CanvasTexture(canvasElement);
If you're going to update the layers I'd recommend keeping an off-screen canvas for each surface rather than creating a new one each time, that way you can just redraw the canvas and do texture.needsUpdate = true rather than creating a new canvas and texture every update, and you'll avoid being dependent on garbage collection and possible races with three's decisions as to when to do the work.

(For your user-drawn on-screen canvas you'd want to put the background image below the canvas the user actually draws on, then on the off-screen canvas draw your other background and drawImage(onScreenCanvas, ...) onto it.)

roomforthetuna fucked around with this message at 12:26 on May 31, 2021

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply