p5 js in react : Expected an assignment or function call and instead saw an expression no-unused-expressions - reactjs

When running this script on p5 js's sandbox it's working really fine
When trying to use it inside react i get : Expected an assignment or function call and instead saw an expression no-unused-expressions
I checked previous questions and found out that most of the problems are syntax ones due to not using brackets or semicolons . I did all the good syntax practices but didn't get to make it function
Here is my sketch code on react :
export default function sketch(p){
var t;
var canvas ;
var w = window.innerWidth;
var h = window.innerHeight;
var x , y , d , T;
p.setup=()=>{
// put setup code here
t=0;
}
p.draw = () => {
canvas =p.createCanvas(w-50, h-50);
canvas.style('display','block');
var x_center = (p.windowWidth - w) / 2;
var y_center = (p.windowHeight - h) / 2;
canvas.position(x_center, y_center);
t += .01;
for (var j = 2; x = y = j--;){
for (var i = w; d = p.noise(t - i / 99) * 3, i--; x += Math.cos(d) * 6, y += Math.sin(d) * 6){
j ? i - w / 2 || ( T = p.translate)(-x, -y) : p.push() + T(x + w / 2, y + w / 2) + p.rotate(d + Math.PI / 4) + p.line(-600, 100, 600, 100) + p.pop(i % 100 || p.scale(80));
}
}
}
window.onresize = function() {
// assigns new values for width and height variables
w = window.innerWidth;
h = window.innerHeight;
canvas.size(w,h);
}
}

Write out p.translate(x, y) every time rather than using T = p.translate and then T(x, y), e.g.,
export default function sketch(p){
let t;
let canvas ;
let w = window.innerWidth;
let h = window.innerHeight;
let x ; let y ; let d ;
p.setup=()=>{
canvas =p.createCanvas(w-50, h-50);
canvas.style('display','block');
// put setup code here
t=0;
const x_center = (p.windowWidth - w) / 2;
const y_center = (p.windowHeight - h) / 2;
canvas.position(x_center, y_center);
}
p.draw = () => {
p.background(255);
t += .0008;
for (let j = 2; x = y = j--;){ // j >0
for (let i = w-200; d = p.noise(t - i / 99) * 3, i--; x += Math.cos(d) * 6, y += Math.sin(d) * 6, i>0){ // i >0
j ? i - w / 2 || p.translate(-x, -y) : p.push() + p.translate(x + w / 2, y + w / 2) + p.rotate(d + Math.PI / 4) + p.line(-600, 100, 600, 100) + p.pop(i % 100 || p.scale(80));
}
}
}
}
Your initial version does not work because in instance mode translate() is a method belonging to p, and thus wants to access other methods or fields of p. The function T that you defined along the way, however, does not belong to p and thus does not have access to any this.foos.

Related

Three JS MeshSurfaceSampler not sampling translated points

I am trying to create a random terrain in THREE JS using the plane geometry and randomizing the pos array using this method:
let side = 200;
const geometry = new PlaneGeometry(80, 20, side, 100);
// const material = new MeshStandardMaterial({ color: '#271033'});
let material = new THREE.MeshStandardMaterial({
roughness: 1,
color: new THREE.Color('#271033'),
flatShading: true,
});
const plane = new Mesh(geometry, material);
plane.rotation.x = - Math.PI / 2 - Math.PI / 20;
plane.position.y = - 4;
plane.position.z = - 5;
plane.castShadow = true;
plane.receiveShadow = true;
let pos = geometry.getAttribute("position");
let pa = pos.array as any;
const hVerts = geometry.parameters.heightSegments + 1;
const wVerts = geometry.parameters.widthSegments + 1;
let noise2D = createNoise2D();
for (let j = 0; j < hVerts; j++) {
for (let i = 0; i < wVerts; i++) {
const ex = 1.1;
pa[3 * (j * wVerts + i) + 2] =
( noise2D(i / 100, j / 100) + noise2D((i + 100) / 50, j / 50) * Math.pow(ex, 0) );
}
}
When I try to sample points on the mesh(so that I can place tree's or whatever at said point) the points don't seem to be valid points on the Mesh. I believe it may be return points from a plane that didn't receive the rotation/position transform, but I'm not sure.
Here is the code for the sampling:
const plane = createPlane();
plane1Sampler = new MeshSurfaceSampler(plane).build();
// add plane to scene etc...
for ( let i = 0; i < 10; i ++ ) {
const tree = await loadTree();
const _position = new THREE.Vector3();
const _normal = new THREE.Vector3();
plane1Sampler.sample( _position, _normal );
tree.scale.set(0.1, 0.1, 0.1);
tree.position.set(_position.x, _position.y, _position.z);
this.scene.add( tree );
}
Finally, here's a picture of the result, the tree's should be positioned on the first lighter purple plane. I'm not really sure what the issue here is so any help is very much appreciated! Also, the project is in React and TS.
For whatever reason the sampler was indeed not sampling from a plane with the translations applied. By applying the same translation to the points I was able to get valid points.
// translation applied to the plane, which for some reason the sampler doesn't take into account
_position.applyAxisAngle(new Vector3(1, 0, 0), - Math.PI / 2 - Math.PI / 20);
_position.y -= 6.1;
_position.z -= 5;

React hooks - Update State in function

hi i have an issue with set state , i write the function that i get Position x,y and size of width , height(That is the name of the state that holds them POx1, POY1, widthSize, heightSize) and depend on user choise, i change the state's that user get to me and Use them. but after the first setSate for all these State i can't update and or change them . these are my code's:
function DrawPicture() { // this function call after click
setCountClick(CountClick + 1);
var Se_image = new Image();
Se_image.src = ImgSRC;// (ImgSRC) is the State i define it before
Se_image.onload = function () {
ctxRef.current.globalCompositeOperation = "source-over";
if (CountClick === 2) {// For some reason, I want this condition to be executed after calling the above function twice
var img = Se_image
PictureCategory(img) // This function is shown below
var canvas = canvasRef.current
var ctx = canvas.getContext('2d');
var imageData = ctx.getImageData(POx1, POY1, widthSize, heightSize);
var data = imageData.data;
console.log(lineColor);
const r = parseInt(lineColor.substr(1, 2), 16)
const g = parseInt(lineColor.substr(3, 2), 16)
const b = parseInt(lineColor.substr(5, 2), 16)
var changeColor = function () {
for (var i = 0; i < data.length; i += 4) {
data[i] = r
data[i + 1] = g
data[i + 2] = b
}
ctx.putImageData(imageData, POx1, POY1);
};
changeColor();
setCountClick(1);
setPointer(false);
}
}
}
and this is my PictureCategory() function:
For convenience, I only took one of the modes
function PictureCategory(image) {
switch (PictureTopic) {
case "Girl":
const XG = POx1 - (0.5 * widthSize) < 0 ? 0 : POx1 - (0.5 * widthSize);
const newWidth= 2.4*widthSize;
const newheight= 2.5*widthSize;
setPOx1(XG)
setwidthSize(newWidth)
setheightSize(newheight)
ctxRef.current.clearRect(XG, POY1, newWidth, newheight);
ctxRef.current.drawImage(image, XG, POY1, 2.4 * widthSize, 2.5 * heightSize);
break;
default:
ctxRef.current.drawImage(image, POx1, POY1, widthSize, heightSize);
break;
}
}
i want to change state's with above function please help me !!!
Not sure if it'll fix your issue, but the following has to be done in any case.
It should be
setCountClick(countClick=> countClick + 1);
When state is updated using its previous value, the callback argument of the state setter should be used.
See https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous
i know it's not your answer for this question. but you can use this codes for have new value .
I stored the new values in an object and returned them:
function DrawPicture() {
setCountClick(CountClick + 1);
var Se_image = new Image();
Se_image.src = ImgSRC;
Se_image.onload = function () {
ctxRef.current.globalCompositeOperation = "source-over";
if (CountClick === 2) {
var img = Se_image
const Sizes =PictureCategory(img) // you can store new value in valible
var canvas = canvasRef.current
var ctx = canvas.getContext('2d');
var imageData = ctx.getImageData(Sizes[0].x, Sizes[0].y, Sizes[0].width, Sizes[0].height);
var data = imageData.data;
console.log(lineColor);
const r = parseInt(lineColor.substr(1, 2), 16)
const g = parseInt(lineColor.substr(3, 2), 16)
const b = parseInt(lineColor.substr(5, 2), 16)
var changeColor = function () {
for (var i = 0; i < data.length; i += 4) {
data[i] = r
data[i + 1] = g
data[i + 2] = b
}
ctx.putImageData(imageData,Sizes[0].x, Sizes[0].y);
};
changeColor();
setCountClick(1);
setPointer(false);
}
}
}
function PictureCategory(image) {
switch (PictureTopic) {
case "Girl":
const XG = POx1 - (0.5 * widthSize) < 0 ? 0 : POx1 - (0.5 * widthSize);
const newWidth= 2.4*widthSize;
const newheight= 2.5*widthSize;
ctxRef.current.clearRect(XG, POY1, newWidth, newheight);
ctxRef.current.drawImage(image, XG, POY1, 2.4 * widthSize, 2.5 * heightSize);
return[{x: XG,y:POY1,width:newWidth,height:newheight}]
default:
ctxRef.current.drawImage(image, POx1, POY1, widthSize, heightSize);
break;
}
}

Add text of UILabel from database by loop - Swift 3

I'm creating UILabel by for loop and I wanna adding text in the UILabel from database, the text in database a String but I'm converting String to Array Characters, for example I've 4 labels and 4 characters (A, B, C, D), I want to add each characters in one label how can I do that ??
I wanna create like this :
And this my code :
func createTarget(id: Int) {
listdata = dbHelpr.getDatabase(rowId: id)
var targetHeigt = CGFloat()
let viewWidth = self.view.frame.size.width
if viewWidth == 320 {
targetHeigt = 2.5
} else {
targetHeigt = 5
}
for data in listdata { // listdata is (Database) has a variable (ans)
let yAxis : CGFloat = (self.view.frame.height) * 60%
let i = data.ans.length
// char count
let width: Int = Int(view.frame.size.width) - 40
// frame width
var targetWidth: Int = (width - (i - 1) * 5) / i
if targetWidth > 50 {
targetWidth = 50
}
let totalWidth: Int = (targetWidth * i) + ((i - 1) * 5)
for x in 0..<i {
let currentWidth: Int = (width / 2) - (totalWidth / 2) + (x * targetWidth) + (x * 5) + 20
let targetLabel = UILabel(frame: CGRect(x: CGFloat(currentWidth), y: yAxis, width: CGFloat(targetWidth), height: 50))
targetLabel.backgroundColor = .white
targetLabel.layer.masksToBounds = true
targetLabel.layer.cornerRadius = 5
targetLabel.textAlignment = .center
targetLabel.textColor = .black
for tar in data.ans.characters {
targetLabel.text = String(tar)
}
self.view.addSubview(targetLabel)
}
}
}
When I run my code above show me this :
My output :
D
D
D
D
And when I edited and added my code to :
for data in listdata { // listdata is (Database) has a variable (ans)
let tar = data.ans.characters.map{String($0)}
lblLabel.text = tar.joined(separator: " ")
}
This a result of my code above :
My output :
D C B A
D C B A
D C B A
D C B A
What's the best solve to create label whit characters exactly like 1st picture ??
You're already creating one label for each character, so there is no need to loop over them again.
Try this:
for (x, tar) in data.ans.characters.reversed().enumerated() {
let currentWidth: Int = (width / 2) - (totalWidth / 2) + (x * targetWidth) + (x * 5) + 20
let targetLabel = UILabel(frame: CGRect(x: CGFloat(currentWidth), y: yAxis, width: CGFloat(targetWidth), height: 50))
targetLabel.backgroundColor = .white
targetLabel.layer.masksToBounds = true
targetLabel.layer.cornerRadius = 5
targetLabel.textAlignment = .center
targetLabel.textColor = .black
targetLabel.text = String(tar)
self.view.addSubview(targetLabel)
}

Use Raphael in Angular-Meteor project

I have a working raphael.js fiddle : http://jsfiddle.net/El4a/sbxjfafx/10/
Now, I need the created svg inside my angular-meteor project. I need it on several places so it has to be abstract. So first question already: should I use a factory or a directive for this?
I've been trying to make it a factory for now, but to be honest, I have no idea what I'm doing. I don't have any errors, but the image doesn't show up.
This is the raphael code inside a factory :
'use strict';
angular.module('timeAppApp').factory('svgFactory', function($rootScope){
Raphael.fn.pieChart = function (cx, cy, r, values) {
var paper = this,
rad = Math.PI / 180,
chart = this.set();
function sector(cx, cy, r, startAngle, endAngle, params) {
var x1 = cx + r * Math.cos(-startAngle * rad),
x2 = cx + r * Math.cos(-endAngle * rad),
y1 = cy + r * Math.sin(-startAngle * rad),
y2 = cy + r * Math.sin(-endAngle * rad);
return paper.path(["M", cx, cy, "L", x1, y1, "A", r, r, 0, +(endAngle - startAngle > 180), 0, x2, y2, "z"]).attr(params);
}
var bcolors = ['#d667cd','#3D8C1E','#00b9ff'];
var colors = ['FF5DF4','#69F233', '#0080B0'];
var angle = 0,
total = 0,
start = 0,
process = function (j) {
var value = values[j],
angleplus = 360 * value / total,
popangle = angle + (angleplus / 2),
// color = "hsb(" + start + ", 1, .5)",
color = colors[j%colors.length],
ms = 500,
delta = 30,
//bcolor = "hsb(" + start + ", 1, 1)",
bcolor = bcolors[j%bcolors.length],
p = sector(cx, cy, r, angle, angle + angleplus, {gradient: "100-" + bcolor + "-" + color}),
txt = paper.text(cx + (r + delta + 55) * Math.cos(-popangle * rad), cy + (r + delta + 25) * Math.sin(-popangle * rad));
angle += angleplus;
chart.push(p);
chart.push(txt);
start += .1;
};
for (var i = 0, ii = values.length; i < ii; i++) {
total += values[i];
}
for (var i = 0; i < ii; i++) {
process(i);
}
return chart;
};
Raphael.fn.circle = function(cx, cy, r){
var paper = this,
rad = Math.PI / 180,
chart = this.set();
var circle = paper.circle(280, 180, 175);
circle.attr("fill", "white");
circle.attr("stroke", "#fff");
return chart;
};
var r;
var svg = function (raphael) {
$(function () {
var values = [20, 60, 20];
r = raphael("svg", 700, 700);
r.pieChart(350, 350, 100, values, "#fff");
r.circle(350, 350, 85).attr({ fill: 'white' });
})
};
svg(raphael);
return{r : r};
When I debug in the browser, it shows that all the raphael functions get skipped. I havent a clue as to why.
The console says : "ReferenceError: raphael is not defined",
but when I watch Raphael I get a running version :
"Raphael: Your browser supports SVG. You are running Raphaƫl 2.1.2"
So I'm trying to get the div with id "svg", and draw the image inside that. This does not happen and the div remains empty.
I have injected the new factory
angular.module('timeAppApp')
.controller('ProjectDetailController', function($scope, $meteor, $state, $stateParams, svgFactory)
and try to draw the image in the matching view. <div id="svg"></div>
I know I'm probably doing 127things wrong and raphael/angular enthousiast are crying blood, but I really don't know what :(
As an added plus, I also kinda need to be able to pass 3 values to the factory, instead of having them hardcoded.
Thanks in advance for drudging through this mess!
I'm not sure how, but it all worked out. I ditched the factory idea, and used a directive. This worked without any issues.

set array to hold images verses text, flash actionscript

the following flash actionscript below stores letters and numbers into an array and displays them randomly in a flash movie as "falling text" down the screen. I'd like to modify this script so I can have the array store multiple images verses letters and numbers.
source:
http://www.flashcomponents.net/tutorials/letter_and_number_rain_flash_tutorial/page_1.html
--- layer script
var letter_array = new Array("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","1","2","3","4","5","6","7","8","9","0");
var i = 0;
setInterval(nLetter, 70);
function nLetter()
{
duplicateMovieClip(letterMC, "letter" + i, 10 + i);
i++
}
-------- symbol script
onClipEvent(load)
{
var index = Math.round(Math.random() * _root.letter_array.length - 1)
this.letter.text = _root.letter_array[index];
_x = Math.round(Math.random() * 540) + 5
_y = Math.round(Math.random() * -20) - 10;
var gravity = 0.2;
var ran = Math.round(Math.random() * 50) + 50;
_alpha = ran + 10;
_xscale = _yscale = ran;
speed = Math.round(Math.random() * 5) + 10;
rotSpeed = Math.round(Math.random() * 6) - 3;
//this.letter.textColor = Math.random() * 0xFFFFFF
}
onClipEvent(enterFrame)
{
_y += speed;
_rotation += rotSpeed
speed += gravity;
if(_y > 410)
{
this.removeMovieClip();
}
}
You need to add this at the top of your code:
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.events.*;
In the layer script you need to have an array of images, so the first thing would be to load all your images and store them in an array when the loading is complete.
in the following code , replace i "inferior to" totalNumImages with
i < totalNumImages , I can't use the "<" character in the code.
//your images location
var url1:String = "images/image1.jpg";
var url2:String = "images/image2.jpg";
var urls:Array = [ url1 , url2 ];
var images:Array = [];
//the total number of images
var totalNumImages:int = 2;
for(var i:int ;i "inferior to" totalNumImages ; ++i )
{
loadImage(images[i] );
}
function loadImage(url:String):void
{
var loader:Loader = new Loader();
var info:LoaderInfo = loader.contentLoaderInfo;
info.addEventListener(Event.COMPLETE , loadComplete );
info.addEventListener(IOErrorEvent.IO_ERROR , errorHandler );
loader.load ( new URLRequest(url ));
}
function errorHandler(event:IOErrorEvent):void
{
trace( event );
}
function loadComplete(event:Event):void
{
//assuming the order doesn't matter
images.push(event.currentTarget.loader.content );
//all images are loaded, let's start...
if(images.length == totalNumImages )
nLetter();
}
After all your images have loaded you can start the nLetter() function. Each time a MovieClip is added to the stage, it will load its image from the array of images that you've created.
change this:
this.letter.text = _root.letter_array[index];
to this:
//assumes that you have an array of DisplayObject
addChild( _root.images[index]);

Resources