How to resize a window/app to appear on a second monitor using Phoenix macOS window and app manager? - javascript

I have this code installed and it's working. If I'm on my second monitor and run the commands it resizes and positions the window to the main screen.
How do I set it so that if the window/app is open on the second monitor then running the key command resizes/positions the window to that second monitor and not to the main monitor? So I want to resize the window to whatever the current screen that the window is on.
I'm not a programmer at all...barely able to read the basics of the code below so I'd need very specific help here...like where to add what code/what code to replace with what...
I read the Phoenix documentation but don't understand it.
https://kasper.github.io/phoenix/api/screen
Here is the js code:
function resizeToFraction(
xNumerator,
xDenominator,
widthNumerator,
widthDenominator,
yNumerator,
yDenominator,
heightNumerator,
heightDenominator,
) {
return () => {
const window = Window.focused();
if (window) {
const screen = window.screen().flippedVisibleFrame();
const x = (screen.width / xDenominator) * xNumerator;
const y = (screen.height / yDenominator) * yNumerator;
const width = (screen.width / widthDenominator) * widthNumerator;
const height = (screen.height / heightDenominator) * heightNumerator;
window.setFrame({ x, y, width, height });
}
};
}
function resizeVerticallyInPlace(
yNumerator,
yDenominator,
heightNumerator,
heightDenominator,
) {
return () => {
const window = Window.focused();
if (window) {
const screen = window.screen().flippedVisibleFrame();
const currentFrame = window.frame();
const x = currentFrame.x;
const y = (screen.height / yDenominator) * yNumerator;
const width = currentFrame.width;
const height = (screen.height / heightDenominator) * heightNumerator;
window.setFrame({ x, y, width, height });
}
};
}
function focusClosestNeighbor(direction) {
return () => {
const window = Window.focused();
const currentApp = window.app();
const appWindows = currentApp.windows();
const neighbors = window.neighbors(direction);
const thisAppNeighbor = neighbors.find((n) => appWindows.includes(n));
if (thisAppNeighbor) {
thisAppNeighbor.focus();
} else if (neighbors.length > 0) {
const visibleNeighbor = neighbors.find((n) => n.isVisible() && n.isNormal());
if (visibleNeighbor) {
visibleNeighbor.focus();
}
}
};
}
// fourths
["o", "p", "[", "]"].forEach((key, index) => {
Key.on(key, ["ctrl", "shift", "cmd"], resizeToFraction(index, 4, 1, 4, 0, 1, 1, 1));
});
// thirds
["j", "k", "l"].forEach((key, index) =>
Key.on(key, ["ctrl", "cmd"], resizeToFraction(index, 3, 1, 3, 0, 1, 1, 1)),
);
// halves
[";", "'"].forEach((key, index) =>
Key.on(key, ["ctrl", "cmd"], resizeToFraction(index, 2, 1, 2, 0, 1, 1, 1)),
);
// two-thirds
Key.on("j", ["ctrl", "cmd", "shift"], resizeToFraction(0, 3, 2, 3, 0, 1, 1, 1));
Key.on("l", ["ctrl", "cmd", "shift"], resizeToFraction(1, 3, 2, 3, 0, 1, 1, 1));
// divide into half up/down
Key.on("k", ["ctrl", "shift", "cmd", "alt"], resizeVerticallyInPlace(0, 2, 1, 2));
Key.on("j", ["ctrl", "shift", "cmd", "alt"], resizeVerticallyInPlace(1, 2, 1, 2));
// fill
Key.on("m", ["ctrl", "cmd"], resizeToFraction(0, 1, 1, 1, 0, 1, 1, 1));
// focus
// Key.on("left", ["ctrl", "shift", "cmd"], focusClosestNeighbor("west"));
// Key.on("right", ["ctrl", "shift", "cmd"], focusClosestNeighbor("east"));
// Key.on("up", ["ctrl", "shift", "cmd"], focusClosestNeighbor("north"));
// Key.on("down", ["ctrl", "shift", "cmd"], focusClosestNeighbor("south"));

Related

Time Converter: split content time with ads time

I'm sorry I have a trying to find & fix a math problem
Let's say I have 2 List or array
Content Array
0-50 = C1
50-100 = C2
AD Array
10-20 = A1
30-60 = A2
80-140 = A3
OutPut Should be Like this
0-10 = C1
10-20 = A1
20-30 = C1
30-60 = A2
60-80 = C2
80-100 = A3
Here ads are replacing actual content and splitting the content into a new array of items.
const content = [
{start: 0, end: 50, id: 'C1'},
{start: 50, end: 100, id: 'C2'},
]
const ad = [
{start:10, end: 20, id: 'A1' },
{start:30, end: 60, id: 'A2' },
{start:80, end: 140, id: 'A3' },
]
const newList = []
content.forEach(content => {
ad.forEach((ad, index) => {
//0 > 0 && 20 < 50
if(content.start < ad.start && content.end > ad.end){
newList.push({start: content.start, end: ad.start, id: content.id})
newList.push(ad)
}else{
console.log(decodeURIComponent(`${content.start} > ${ad.start} && ${content.end} < ${ad.end}`))
}
})
})
console.log('newList',newList)
Please Help
Actually, I don't know what I can say about the code, just try this approach:
const content = [{start: 0, end: 50, id: 'C1'},{start: 50, end: 100, id: 'C2'}];
const ad = [{start:10, end: 20, id: 'A1' },{start:30, end: 60, id: 'A2' },{start:80, end: 140, id: 'A3' }];
const cPoints = content.flatMap(e => [e.start, e.end]); // [0, 50, 50, 100]
const aPoints = ad.flatMap(e => [e.start, e.end]); // [10, 20, 30, 60, 80, 140]
const rangeMin = Math.min(...cPoints); // 0
const rangeMax = Math.max(...cPoints); // 100
const rangePoints = [...new Set([...aPoints, ...cPoints])] // [10, 20, 30, 60, 80, 140, 0, 50, 100]
.filter(point => (point >= rangeMin) && (point <= rangeMax)) // [10, 20, 30, 60, 80, 0, 50, 100]
.sort((a, b) => a - b); // [0, 10, 20, 30, 50, 60, 80, 100]
const getObjByPoint = (point, arr) =>
arr.find((e) => (e.start <= point) && (point <= e.end));
const getFirstId = (point) =>
(getObjByPoint(point, ad) || getObjByPoint(point, content)).id;
const result = rangePoints.reduce((acc, end, index, arr) => {
if (index === 0) return acc;
let start = arr[index - 1];
const middle = (start + end) / 2;
const id = getFirstId(middle);
if (acc.at(-1)?.id === id) {
start = acc.pop().start;
}
acc.push({ start, end, id });
return acc;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
This may be a "not so elegant" solution to achieve the desired objective.
Code Snippet
// manipulate timeline to find "gaps" and place "ads"
// recursive method controlled by "idx"
const splitTimeline = (arr, advArr, idx) => {
const res = [...arr]; // shallow-copy intermediate result array
const ad = advArr[idx]; // direct access to current iteration of "ad"
arr.forEach(
({ start, end, id }, rIdx) => { // de-structure and res-array-index
if ( // place "ad" in existing "gap"
start < ad.start &&
end >= ad.end &&
id === 'gap'
) {
res.splice(rIdx, 1, { start, end: ad.start, id: 'gap'});
res.splice(rIdx + 1, 0, {
start: ad.start, end: Math.min(end, ad.end), id: ad.id
});
if (end > ad.end) res.splice(rIdx + 2, 0, {
start: ad.end, end, id: 'gap'
});
} else if ( // handle edge-case (last "ad" exceeds timeline
idx === advArr.length - 1 && id === 'gap' &&
ad.start > start && ad.start < end
) {
res.splice(rIdx, 1, {
start: ad.start, end: end, id: ad.id
});
res.splice(rIdx, 0, {
start: start, end: ad.start, id: 'gap'
});
}
}
);
// recurse if all "ads" not yet processed
if (idx < advArr.length - 1) return splitTimeline(res, advArr, idx + 1);
else return res;
};
// method to fill "gaps" with "content" (c-array - content-array)
const addContent = (tl, carr) => ( // "tl" is current timeline
tl.map(({ start, end, id }) => { // iterate over "tl"
// if "ad", simply return it as-is
if (id !== 'gap') return {start, end, id};
// otherwise, find a matching "content" id for existing "gap"
return {start, end, id: carr.find(
ob => start >= ob.start && end <= ob.end
)?.id ?? "no content"} // optional chain "id" or return "no content"
})
);
// simple method to construct, update a timeline
// and place contents and ads within the timeline
const placeAds = (cn, ad) => {
const cBgn = Math.min(...cn.map(({ start }) => start));
const cEnd = Math.max(...cn.map(({ end }) => end));
const initialTimeline = [{
start: cBgn, end: cEnd, id: 'gap'
}];
return (
addContent( // method to add "content"
splitTimeline( // method to split timelines and place "ads" and "gaps"
initialTimeline,
ad, // the ad array
0 // initial ad array index set to 0 (for recursion)
),
cn // the content array
)
);
};
const content = [
{start: 0, end: 50, id: 'C1'},
{start: 50, end: 100, id: 'C2'},
];
const ad = [
{start:10, end: 20, id: 'A1' },
{start:30, end: 60, id: 'A2' },
{start:80, end: 140, id: 'A3' },
];
console.log(placeAds(content, ad));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Explanation
Inline comments describe the significant aspects of the solution

Why is my Steinhaus-Johnson-Trotter Algorithm implementation producing duplicate permutations?

I have implemented the Steinhaus-Johnson-Trotter Algorithm using JavaScript, this implementation only calculates all permutations for arrays of numbers.
When the size of the array is >= 4 the algorithm is producing duplicate results. I see why it produces the results, but I am not sure how to avoid this, as creating these duplicates satisfies the algorithms principles.
class Direction {
constructor(dir) {
if(dir === 'LEFT' || dir === 'RIGHT') {
this.dir = dir
}
}
setDir(dir) {
if(dir === 'LEFT' || dir === 'RIGHT') {
this.dir = dir
}
}
switchDir() {
switch(this.dir) {
case 'LEFT':
this.dir = 'RIGHT'
break
case 'RIGHT':
this.dir = 'LEFT'
break
}
}
}
var permute = function(nums) {
if(nums.length === 1) return [nums]
if(nums.length === 2) return [nums, [nums[1], nums[0]]]
// I'm only worried about arrays up to length 6
const facts = [1, 2, 6, 24, 120, 720]
const dirs = {}
const max = Math.max(...nums)
nums.forEach(v => {
dirs[v] = new Direction('LEFT')
})
const res = []
const move = (n) => {
const i = nums.indexOf(n)
const ele = dirs[n]
switch(ele.dir) {
case 'LEFT':
[nums[i], nums[i - 1]] = [nums[i - 1], nums[i]]
break
case 'RIGHT':
[nums[i], nums[i + 1]] = [nums[i + 1], nums[i]]
break
}
if(n === max) {
return
}
nums.forEach(v => {
if(v > n) dirs[v].switchDir()
})
}
// Number is said to mobile if it can move to its direction
const isMobile = (n) => {
const d = dirs[n].dir
if(d === 'LEFT' && nums.indexOf(n) !== 0) {
return true
}
if(d === 'RIGHT' && nums.indexOf(n) !== nums.length - 1) {
return true
}
return false
}
// Finding mobiles means finding the largest number and checking if it is mobile
const findMobile = () => {
// If not max then lets find the next largest mobile
var num = Number.MIN_VALUE
nums.forEach(v => {
if(isMobile(v) && v > num) {
num = v
}
})
return num
}
// Loop through the max length factorial, included up to only 6 as req
while(res.length < facts[nums.length - 1]) {
const next = findMobile()
move(next)
res.push([...nums])
console.log(res)
}
return res
};
Test Cases:
Test 1:
Input: [1,2,3]
Result: [[1,3,2],[3,1,2],[3,2,1],[2,3,1],[2,1,3],[1,2,3]], Passed
Test 2:
Input: [5,4,6,2]
Result: [
[ 5, 6, 4, 2 ], [ 6, 5, 4, 2 ],
[ 5, 6, 4, 2 ], [ 5, 4, 6, 2 ],
[ 5, 4, 2, 6 ], [ 4, 5, 2, 6 ],
[ 4, 5, 6, 2 ], [ 4, 6, 5, 2 ],
[ 6, 4, 5, 2 ], [ 6, 4, 2, 5 ],
[ 4, 6, 2, 5 ], [ 4, 2, 6, 5 ],
[ 4, 2, 5, 6 ], [ 4, 2, 6, 5 ],
[ 4, 6, 2, 5 ], [ 6, 4, 2, 5 ],
[ 4, 6, 2, 5 ], [ 4, 2, 6, 5 ],
[ 4, 2, 5, 6 ], [ 4, 5, 2, 6 ],
[ 4, 5, 6, 2 ], [ 4, 6, 5, 2 ],
[ 6, 4, 5, 2 ], [ 6, 5, 4, 2 ]
], Failed
As shown in the results, the algorithm is producing duplicates, however as mentioned earlier, the steps between the duplicates satisfy the algorithm.
My Understanding of the Algorithm:
All elements start out facing right to left:
ie. <1<2<3<4
We find the next largest "mobile" number, in this case 4. Then we shift it towards its direction.
ie. <1<2<4<3
Repeat the process.
If a mobile number is moved that is less than another number, the larger number has its direction swapped.
EDIT
I have solved the problem, it involved in not checking the size of the mobile number and number to be swapped.
Compare steps with this simple Python implementation (ideone link to look at results, order is similar to wiki example ).
I don't see direction items swapping together with elements in your code
def SJTperms(a, dirs):
n = len(a)
id = -1
for i in range(n):
# can check mobility mobile largest mobile
if (0<=i+dirs[i]<n) and (a[i] > a[i+dirs[i]]) and ((id == -1) or (a[i] > a[id])):
id = i
if (id == -1): #last permutation
return False
for i in range(n):
if a[i] > a[id]:
dirs[i] = - dirs[i]
#swap elements AND their directions
a[id], a[id + dirs[id]] = a[id + dirs[id]], a[id]
t = dirs[id]
dirs[id], dirs[id + t] = dirs[id + t], dirs[id]
return True
a = [1,2,3,4]
d = [-1]*len(a)
cont = True
while cont:
print(a)
#print(d)
cont = SJTperms(a, d)

Algorithm: Generate path for a Knight move to all Chess Board Squares

Problem description
I am trying to get an algorithm that will find the path of a possible sequence of moves that a Knight can move in a chessboard and visit all squares without repeating any of the squares. This is possible as illustrated by the diagram below
My Approach
To try and achieve this I have followed the below steps
Created an array with allSquares ['a1', 'a2', 'a3', ..., 'h7', 'h8']
Created another array of visitedSquares. initialy this is empty []
Created a function an array of paths for each square. This represents squares to which a Knight can move from other squares
{
"a8": ["c7", "b6"],
"a7": ["c6", "b5","c8"],
"a6": ["c5","b4","c7","b8"],
...
"h3": ["f2","g1","f4","g5"],
"h2": ["f1","f3","g4"],
"h1": ["f2","g3"]
}
Created a getNextNode() function to return the maximum of the cost of nodes visited
Finally I try to solve for the longest path with the below steps
while (this.squaresNotVisited.length > 0) {
const nextTerm = this.getNextNode();
const currentCost = this.pathCosts[nextTerm[0]];
const nextPaths: string[] = this.paths[nextTerm[0]];
nextPaths.forEach(square => {
if (this.pathCosts[square] < currentCost + 1) {
this.pathCosts[square] = currentCost + 1;
}
});
this.squaresVisited = [...this.squaresVisited, nextTerm[0]];
this.squaresNotVisited = this.allSquares.filter(
x => !this.squaresVisited.includes(x)
);
}
Below is the complete Javascript code
class AppComponent {
board = {
columns: ["a", "b", "c", "d", "e", "f", "g", "h"],
rows: [8, 7, 6, 5, 4, 3, 2, 1]
};
allSquares = this.board.columns.reduce(
(prev, next) => [...prev, ...this.board.rows.map(x => next + x)],
[]
);
currentKnightPosition = "h5";
squaresVisited = [];
squaresNotVisited = [...this.allSquares];
nextPossibleKnightPosition = currentKnightPosition => {
const row = this.board.columns.indexOf(currentKnightPosition[0]);
const column = Number(currentKnightPosition[1]) - 1;
return [
[column - 1, row - 2],
[column - 1, row + 2],
[column - 2, row - 1],
[column - 2, row + 1],
[column + 1, row - 2],
[column + 1, row + 2],
[column + 2, row - 1],
[column + 2, row + 1]
]
.filter(
([row, column]) => column >= 0 && column < 8 && row >= 0 && row < 8
)
.map(
([row, column]) =>
this.board.columns[column] + this.board.rows[8 - row - 1]
);
};
paths = this.allSquares.reduce(
(prev, next) => ({
...prev,
[next]: this.nextPossibleKnightPosition(next)
}),
{}
);
isNextSquare = square =>
this.nextPossibleKnightPosition(this.currentKnightPosition).includes(
square
);
costs = { [this.currentKnightPosition]: 0 };
pathCosts = {
...this.allSquares.reduce(
(prev, next) => ({ ...prev, [next]: -Infinity }),
{}
),
[this.currentKnightPosition]: 0
};
getNextTerm = () => {
let nonVisted = Object.entries(this.pathCosts).filter(
([x, y]) => !this.squaresVisited.includes(x)
);
const maxPath = Math.max(...Object.values(nonVisted.map(([, x]) => x)));
return nonVisted.find(([, x]) => x === maxPath);
};
costsCalc = () => {
while (this.squaresNotVisited.length > 0) {
const nextTerm = this.getNextTerm();
const currentCost = this.pathCosts[nextTerm[0]];
const nextPaths = this.paths[nextTerm[0]];
nextPaths.forEach(square => {
if (this.pathCosts[square] < currentCost + 1) {
this.pathCosts[square] = currentCost + 1;
}
});
this.squaresVisited = [...this.squaresVisited, nextTerm[0]];
this.squaresNotVisited = this.allSquares.filter(
x => !this.squaresVisited.includes(x)
);
}
};
ngOnInit() {
this.costsCalc();
console.log(Math.max(...Object.values(this.pathCosts)))
}
}
const app = new AppComponent();
app.ngOnInit()
The Problem
The Approach returns that the longest path is 51... which is incorrect as the number of squares are 64. I am stuck at whether the error is in my code or the error is in the approach I am using. Below is also a demo on stackblitz
You're function gets stuck
In each step your method just takes the longest path and updates all its neighbors. It's not undoing decisions, that's why it gets stuck at a path length of 52.
It is essential that you go back, when you find out your current solution does not work, i.e. Backtracking.
Possible implementation
...using Warnsdorff's rule.
const findPath = (knightPosition) => {
if (squaresVisited.size === allSquares.length - 1) return [knightPosition]
squaresVisited.add(knightPosition)
const neighbors = paths[knightPosition]
.filter(neighbor => !squaresVisited.has(neighbor))
.map(neighbor => {
const neighborCount = paths[neighbor]
.filter(square => !squaresVisited.has(square))
.length
return {
position: neighbor,
count: neighborCount
}
})
const minNeighborsCount = Math.min(...neighbors.map(({ count }) => count))
const minNeighbors = neighbors.filter(neighbor => neighbor.count === minNeighborsCount)
for (const minNeighbor of minNeighbors) {
const { position, count } = minNeighbor
const path = findPath(position)
if (path) return [knightPosition, ...path]
}
squaresVisited.delete(knightPosition)
}
Full working example
const board = {
columns: ["a", "b", "c", "d", "e", "f", "g", "h"],
rows: [8, 7, 6, 5, 4, 3, 2, 1]
};
const allSquares = board.columns.reduce(
(prev, next) => [...prev, ...board.rows.map(x => next + x)],
[]
);
const nextPossibleKnightPositions = currentKnightPosition => {
const row = board.columns.indexOf(currentKnightPosition[0]);
const column = Number(currentKnightPosition[1]) - 1;
return [
[column - 1, row - 2],
[column - 1, row + 2],
[column - 2, row - 1],
[column - 2, row + 1],
[column + 1, row - 2],
[column + 1, row + 2],
[column + 2, row - 1],
[column + 2, row + 1]
]
.filter(
([row, column]) => column >= 0 && column < 8 && row >= 0 && row < 8
)
.map(
([row, column]) =>
board.columns[column] + board.rows[8 - row - 1]
);
};
const paths = allSquares.reduce(
(prev, next) => ({
...prev,
[next]: nextPossibleKnightPositions(next)
}),
{}
);
const squaresVisited = new Set();
const findPath = (knightPosition) => {
if (squaresVisited.size === allSquares.length - 1) return [knightPosition]
squaresVisited.add(knightPosition)
const neighbors = paths[knightPosition]
.filter(neighbor => !squaresVisited.has(neighbor))
.map(neighbor => {
const neighborCount = paths[neighbor]
.filter(square => !squaresVisited.has(square))
.length
return {
position: neighbor,
count: neighborCount
}
})
const minNeighborsCount = Math.min(...neighbors.map(({ count }) => count))
const minNeighbors = neighbors.filter(neighbor => neighbor.count === minNeighborsCount)
for (const minNeighbor of minNeighbors) {
const { position, count } = minNeighbor
const path = findPath(position)
if (path) return [knightPosition, ...path]
}
squaresVisited.delete(knightPosition)
}
const path = findPath("h5");
console.log(path)
allSquares.forEach(square => {
squaresVisited.clear()
const path = findPath(square)
if(path.length !== 64) throw new Error(sqaure)
})
console.log("Works for all squares")

Canvas not rendering In reactjs

I want to add canvas on the website that i am developing but i can seem to understand why the canvas in not showing up. what could be the issue?
Below is what i have tried. When i hover the mouse on the header it shows that the canvas is updating but not showing anything on the screen
Canvas.jsx
export class Canvas extends Component {
state = {
container: document.getElementById('test'),
canvas: document.createElement('canvas'),
ctx: document.createElement('canvas').getContext("2d"),
mouseCoords: null,
particles: [],
width: 0,
height: 0,
};
componentDidMount() {
window.scrollTo(0, 0);
document.getElementById('test').appendChild(document.createElement('canvas'));
this.setState({
container: document.getElementById('test'),
canvas: document.createElement('canvas'),
ctx: document.createElement('canvas').getContext("2d")
}, () => this.handleResize());
window.addEventListener("resize", this.handleResize)
}
r = (e, t) => {
return Math.hypot(t[0] - e[0], t[1] - e[1])
};
i = (e, t, o, s) => {
var n = e / s - 1;
return o * (n * n * (2.2 * n + 1.2) + 1) + t
};
componentDidUpdate(prevProps, prevState, snapshot) {
return null;
}
componentWillUnmount() {
this.setState({
canvas: document.getElementById('test').remove(),
});
}
handleAnimate = () => {
var e = this.state;
var that = this;
if (!(e.width < 800 * window.devicePixelRatio)) {
var t = e.particles[e.particles.length - 1]
, o = (e.width - t.coords.ref[0]) / 2
, s = t.coords.ref[0]
, n = (e.height - t.coords.ref[1]) / 2
, a = t.coords.ref[1];
e.ctx.clearRect(o, n, s, a);
e.particles.forEach((t) => {
t.timer += 1;
const o = Math.max(that.r(t.coords.ref, e.mouseCoords), 150);
s = t.coords.ref[0] + (e.mouseCoords[0] - t.coords.ref[0]) / (o / e.width * 150);
n = t.coords.ref[1] + (e.mouseCoords[1] - t.coords.ref[1]) / (o / e.height * 150);
a = 150 * t.r.ref / o + .5;
/* eslint-disable */
s === t.coords.new[0] && n === t.coords.new[1] || (t.coords.old = t.coords.current.slice(), t.coords.new = [s, n], t.r.old = t.r.current, t.r.new = a, t.timer = 1);
t.timer < 75 && (t.coords.current[0] = that.i(t.timer, t.coords.old[0], t.coords.new[0] - t.coords.old[0], 75),
t.coords.current[1] = that.i(t.timer, t.coords.old[1], t.coords.new[1] - t.coords.old[1], 75),
t.r.current = Math.max(that.i(t.timer, t.r.old, t.r.new - t.r.old, 75), 0));
e.ctx.fillStyle = t.fill;
e.ctx.beginPath();
e.ctx.arc(t.coords.current[0], t.coords.current[1], t.r.current, 0, 2 * Math.PI);
e.ctx.fill()
});
this.setState({
loop: requestAnimationFrame(this.handleAnimate)
})
}
};
handleHover = (e) => {
this.state.mouseCoords = [e.clientX * window.devicePixelRatio, e.clientY * window.devicePixelRatio]
};
handleResize = () => {
const {canvas} = this.state;
var particle = [];
let newWidth = window.innerWidth * window.devicePixelRatio,
newHeight = window.innerHeight * window.devicePixelRatio;
canvas.height = newHeight;
canvas.width = newWidth;
this.setState({
width: window.innerWidth * window.devicePixelRatio,
height: window.innerHeight * window.devicePixelRatio,
canvas,
mouseCoords: [0, newHeight]
});
var e = Math.max(newHeight / 21, 40),
t = Math.floor(newWidth / (e + 5)),
o = Math.floor(newHeight / (e + 10)) || 90,
V = [2, 2, 6, 6, 5, 5, 3, 3, 0, 0, 2, 2, 0, 0],
j = [[2, 0, 0, 2, 1, 0, 0, 3], [1, 0, 2, 2, 0, 0, 2], [2, 2, 2, 2, 3, 0, 1, 0, 0], [1, 0, 2, 2, 0, 0, 2, 2, 0], [2, 0, 1, 2, 2, 0, 2, 0, 1, 2, 2, 1, 0, 0], [0, 2, 2, 0, 3, 1, 2, 1, 2, 0, 1, 2, 2, 0], [1, 2, 1, 1, 0, 2, 2, 0, 0, 1, 2, 1, 0, 1], [2, 1, 1, 0, 0, 0, 2, 2, 1, 1, 1, 1], [2, 0, 2, 0, 0, 0], [0, 0, 0, 2, 0, 0], [0, 2, 0, 0, 0, 0, 0], [0, 0, 0, 2, 0, 0], [0, 0, 0, 0, 2, 0], [0, 0, 0, 2, 0, 0]];
console.log(t);
for (let s = 0; s < o; s += 1) {
for (var n = 0; n < t; n += 1) {
var a = Math.round(this.state.width / 2 - e / 2 * (t - 1) + n * e),
d = Math.round(this.state.height / 2 - e / 2 * (o - 1) + s * e),
l = "#555555",
r = e / 20;
if (s > 0 && s < j.length + 1)
switch (j[s - 1][t - n - V[s - 1] - 1]) {
case 0:
l = "#1DCA7F";
r = e / 2.5;
break;
case 1:
l = "#047870";
r = e / 4;
break;
case 2:
l = "#FFFFFF";
break;
case 3:
l = "#6898ae";
r = e / 2.5
}
var i = {
coords: {
ref: [a, d],
current: [a, d],
new: [a, d],
old: [a, d]
},
r: {
ref: r,
current: 0,
new: r,
old: 0
},
fill: l,
timer: 1
};
particle.push(i);
}
}
this.setState({
particles: particle
})
};
render() {
// className="-content-wrapper header"
return (
<div className="home">
<header id="test" onMouseEnter={() => this.handleAnimate()}
onMouseMove={e => this.handleHover(e)}>
</header>
</div>
)}
}
what I want to achieve is a canvas with particles.on hover the particles should move towards where the cursor is headed and zoom the greener particles
You could use refs (note that facebook discourages the uses of refs on most situations, see the documentation.
I would do something like this:
export class Canvas extends React.Component {
constructor(props) {
super(props);
this.canvas = React.createRef();
this.context = null // this will be initializaed in componentDidMount()
}
componentDidMount(){
this.context = this.canvas.getContext("2d")
}
...
render() {
return (
<div className="home">
<header id="test" onMouseEnter={() => this.handleAnimate()}
onMouseMove={e => this.handleHover(e)}>
</header>
<canvas ref={this.canvas} className={style.canvas}/>
<!-- Make sure to size the canvas correctly using CSS -->
</div>
)}
}

How to swap object value by set of index in javascript

I have array like this
arrayValue=[
{ value: 1},
{ value: 2},
{ value: "line break"},
{ value: 3},
{ value: 4},
{ value: "line break"},
{ value: 1},
{ value: 1}
]
I have to swap forward or backward value by 2 set of index, each 3 index of value having up & down arrow when i am click up/down arrow have to swap based on that two index forward or backward.for example 0th, 3rd, 6th having arrow. any one help this?
If I understand you correctly, it'll be something like the below.
function _move(arr, idx, dir) {
var res = arr.slice();
var thrown = res.splice(idx, 1)[0];
if (dir === 'up') {
res.splice(idx-1, 0, thrown);
} else {
res.splice(idx+1, 0, thrown);
}
return res;
}
Array.prototype.up = function (idx) {
return _move(this, idx, 'up');
};
Array.prototype.down = function (idx) {
return _move(this, idx, 'down');
};
var a = [1, 2, 3, 4, 5];
console.log(
a.up(2), // 1 3 2 4 5
a.down(2) // 1 2 4 3 5
);
UPDATE
If you want to swap n items, left ones starting at L and right ones starting at R - call swapItems(arr, L, R, n). Here's implementation I've written:
function swapItems(arr, leftIdx, rightIdx, itemsNum) {
var leftOnes = arr.splice(leftIdx, itemsNum);
var rightOnes = arr.splice(rightIdx - itemsNum, itemsNum);
arr.splice(leftIdx, 0, ...rightOnes);
arr.splice(rightIdx, 0, ...leftOnes);
}
var arr = [1, 2, 'br', 3, 4, 'br', 1, 1];
// first pair starts at 0, another pair start at 3, number of items to affect = 2
swapItems(arr, 0, 3, 2);
// arr = [3, 4, 'br', 1, 2, 'br', 1, 1]

Categories