The problem what I have is that React TS throws an error for my window.webkitRequestAnimationFrame and window.mozRequestAnimationFrame thinking that I mean 'requestAnimationFrame' instead. Should I replace it with something else?
App.tsx
import React from "react";
export interface Props {
canvas: HTMLElement;
particles: number;
}
function App(props: Props) {
props.canvas = document.getElementById("canvas");
var ctx = props.canvas.getContext("2d");
props.particles = [];
props.canvas.onmousedown = function (e: any) {
for (var i = 0; i < 36 * 2; i++) {
props.particles.push({
x: e.clientX,
y: e.clientY,
angle: i * 5,
size: 5 + Math.random() * 3,
life: 200 + Math.random() * 50,
});
}
};
props.canvas.onmouseup = function () {
//ctx.clearRect(0, 0, 600, 600);
};
var delta = 0;
var last = Date.now();
function animate() {
delta = Date.now() - last;
last = Date.now();
for (var i = 0; i < props.particles.length; i++) {
var p = props.particles[i];
p.x += Math.cos(p.angle) * 4 + Math.random() * 2 - Math.random() * 2;
p.y += Math.sin(p.angle) * 4 + Math.random() * 2 - Math.random() * 2;
p.life -= delta;
p.size -= delta / 50;
if (p.size <= 0) {
p.life = 0;
}
if (p.life <= 0) {
props.particles.splice(i--, 1);
continue;
}
}
}
function render() {
ctx.fillStyle = "#00FF00";
for (var i = 0; i < props.particles.length; i++) {
if (Math.random() < 0.1) {
continue;
}
var p = props.particles[i];
ctx.beginPath();
ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2, false);
ctx.fill();
}
}
window.requestAnimFrame = (function () {
return (
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
}
);
})();
(function animloop() {
requestAnimFrame(animloop);
animate();
render();
})();
return <canvas id="canvas" width="100vw" height="100vh"></canvas>;
}
export default App;
Edit:
Edited to only ask one question instead of many in this thread.
requestAnimationFrame() has been available in all major browsers for years by now. According to that link, it looks like the last browser releases that included the prefixed version were release 2012-2014.
So it's probably safe to use requestAnimationFrame directly, and then you can remove the polyfill altogether.
Related
At the moment I'm using the following boilerplate to create my p5 sketches as outlined in react-p5 (https://www.npmjs.com/package/react-p5). I
import React from "react";
import Sketch from "react-p5";
function App() {
let setup = (p5, canvasParentRef) => {
};
let draw = (p5) => {
};
return (
<div className="App">
<Sketch setup={setup} draw={draw} className="App" />
</div>
);
}
export default App;
I've tried rewriting the libraries to match the format above then exporting them and importing as 'import Clickable from './clickable.js'' with no luck.
How would I go about adding these libraries to my React app? I'm still finding my way through React but this issue has been a bit of a roadblock for me.
Most p5.js add-ons are, unfortunately, not well designed JavaScript libraries. Modern JavaScript libraries are published as modules that export specific functions/classes/variables that you can then import. There are ways to structure JavaScript modules such that they support different ways of including them (including the classic <script /> tag import, ES6 import statements, or the require() function), but many add-ons, such as p5.clickable do not do this. Additionally p5.clickable suffers from the unfortunate design decision of depending on p5.js library functions (rect/fill/stroke/etc.) being exposed globally. However, with some modest changes I was able to get it working in a React App:
Modified version of p5.clickable.js
//Determines if the mouse was pressed on the previous frame
var cl_mouseWasPressed = false;
//Last hovered button
var cl_lastHovered = null;
//Last pressed button
var cl_lastClicked = null;
//All created buttons
var cl_clickables = [];
//This function is what makes the magic happen and should be ran after
//each draw cycle.
// EDIT: Anywhere p5 was referenced, now using global.p5
global.p5.prototype.runGUI = function () {
for (let i = 0; i < cl_clickables.length; ++i) {
if (cl_lastHovered !== cl_clickables[i])
cl_clickables[i].onOutside();
}
if (cl_lastHovered != null) {
if (cl_lastClicked !== cl_lastHovered) {
cl_lastHovered.onHover();
}
}
if (!cl_mouseWasPressed && cl_lastClicked !== null) {
cl_lastClicked.onPress();
}
// EDIT: Use this.mouseIsPressed instead of the global mouseIsPressed.
// hopefully this works but I haven't investigated the this binding when
// runGUI is invoked by 'post'
if (cl_mouseWasPressed && !this.mouseIsPressed && cl_lastClicked != null) {
if (cl_lastClicked === cl_lastHovered) {
cl_lastClicked.onRelease();
}
cl_lastClicked = null;
}
cl_lastHovered = null;
cl_mouseWasPressed = this.mouseIsPressed;
}
global.p5.prototype.registerMethod('post', global.p5.prototype.runGUI);
//This function is used to get the bounding size of a
//string of text for use in the 'textScaled' property
function getTextBounds(m, font, size) {
let txt = document.createElement("span");
document.body.appendChild(txt);
txt.style.font = font;
txt.style.fontSize = size + "px";
txt.style.height = 'auto';
txt.style.width = 'auto';
txt.style.position = 'absolute';
txt.style.whiteSpace = 'no-wrap';
txt.innerHTML = m;
let width = Math.ceil(txt.clientWidth);
let height = Math.ceil(txt.clientHeight);
document.body.removeChild(txt);
return [width, height];
}
//Button Class
// EDIT: Clickable now takes a p5 instance
function Clickable(p) {
if (!p) {
// EDIT: If a p5 instance is not passed to the Clickable constructor,
// fallback on global mode
p = global;
}
this.x = 0; //X position of the clickable
this.y = 0; //Y position of the clickable
this.width = 100; //Width of the clickable
this.height = 50; //Height of the clickable
this.color = "#FFFFFF"; //Background color of the clickable
this.cornerRadius = 10; //Corner radius of the clickable
this.strokeWeight = 2; //Stroke width of the clickable
this.stroke = "#000000"; //Border color of the clickable
this.text = "Press Me"; //Text of the clickable
this.textColor = "#000000"; //Color for the text shown
this.textSize = 12; //Size for the text shown
this.textFont = "sans-serif"; //Font for the text shown
this.textScaled = false; //Scale the text with the size of the clickable
// image options
this.image = null; // image object from p5loadimage()
this.tint = null; // tint image using color
this.noTint = true; // default to disable tinting
this.filter = null; // filter effect
this.updateTextSize = function () {
if (this.textScaled) {
for (let i = this.height; i > 0; i--) {
if (getTextBounds(this.text, this.textFont, i)[0] <= this.width && getTextBounds(this.text, this.textFont, i)[1] <= this.height) {
console.log("textbounds: " + getTextBounds(this.text, this.font, i));
console.log("boxsize: " + this.width + ", " + this.height);
this.textSize = i / 2;
break;
}
}
}
}
this.updateTextSize();
this.onHover = function () {
//This function is ran when the clickable is hovered but not
//pressed.
}
this.onOutside = function () {
//This function is ran when the clickable is NOT hovered.
}
this.onPress = function () {
//This function is ran when the clickable is pressed.
}
this.onRelease = function () {
//This funcion is ran when the cursor was pressed and then
//released inside the clickable. If it was pressed inside and
//then released outside this won't work.
}
this.locate = function (x, y) {
this.x = x;
this.y = y;
}
this.resize = function (w, h) {
this.width = w;
this.height = h;
this.updateTextSize();
}
this.drawImage = function(){
// EDIT: All references to p5 library functions now use the instance p
p.image(this.image, this.x, this.y, this.width, this.height);
if(this.tint && !this.noTint){
p.tint(this.tint)
} else {
p.noTint();
}
if(this.filter){
p.filter(this.filter);
}
}
this.draw = function () {
p.push();
p.fill(this.color);
p.stroke(this.stroke);
p.strokeWeight(this.strokeWeight);
p.rect(this.x, this.y, this.width, this.height, this.cornerRadius);
p.fill(this.textColor);
p.noStroke();
if(this.image){
this.drawImage();
}
p.textAlign(p.CENTER, p.CENTER);
p.textSize(this.textSize);
p.textFont(this.textFont);
p.text(this.text, this.x + this.width / 2, this.y + this.height / 2);
if (p.mouseX >= this.x && p.mouseY >= this.y &&
p.mouseX < this.x + this.width && p.mouseY < this.y + this.height) {
cl_lastHovered = this;
if (p.mouseIsPressed && !cl_mouseWasPressed) {
cl_lastClicked = this;
}
}
p.pop();
}
cl_clickables.push(this);
}
// Export Clickable globally.
// In this case it would also be trivial to change this into a legitimate
// module by simply exporting Clickable. But I wanted to demonstrate how
// this could be done with globals
global.Clickable = Clickable;
Example Usage
import React from 'react';
import Sketch from 'react-p5';
import '../lib/p5.clickable-1.2.js';
const Clickable = global.Clickable;
let x = 50;
let y = 50;
let click1;
export default (props) => {
const setup = (p, canvasParentRef) => {
p.createCanvas(500, 500).parent(canvasParentRef);
// Example Clickable
click1 = new Clickable(p);
click1.locate(x, y);
click1.onHover = function () {
this.color = props.color;
this.textColor = "#FFFFFF";
this.text = "Yay!";
};
click1.onOutside = function() {
this.color = "#FFFFFF";
this.textColor= "#000000";
this.text = "Press Me";
};
};
const draw = (p) => {
p.background(0);
p.fill(props.color || 'blue');
click1.locate(x % p.width, y);
click1.draw();
x++;
};
return <Sketch setup={setup} draw={draw} />;
};
I believe my react code is trying to access a server directory after its compiled and sent to the client. This means when it looks for the gameLogic.js and style.css files it cant locate them. I'm wondering how I would go about getting the react component im working on to get a copy of them and send them off to the remote client. I get the following errors.
pages/game.js
import * as React from "react";
import Layout from "../components/Layout";
import Separator from "../components/Separator";
import CanvasCanvas from "../components/CanvasCanvas";
export default class extends React.Component {
render() {
return (
<Layout>
<main>
<div className="loginBox5">
<Separator height={50}/>
<div className="center">
<h1>Game Play:</h1>
<Separator height={50}/>
<div id="PlayAreaImg" className="gameContainer">
<CanvasCanvas id={"Memes"}/>
</div>
</div>
<Separator height={350}/>
</div>
</main>
</Layout>
)
}
}
src/gameLogic.js
var keyState = {};
window.addEventListener('keydown',function(e){
keyState[e.keyCode || e.which] = true;
},true);
window.addEventListener('keyup',function(e){
keyState[e.keyCode || e.which] = false;
},true);
x = 100;
function drawObj(ctx, object){
var x = object[0];
var y = object[1];
var wid = object[2];
var hei = object[3];
var r = object[4];
var g = object[5];
var b = object[6];
var t = object[7];
// Renderer usage: Canvas context, x position, y position, object height, object width, red, green, blue, transparency
ctx.fillStyle = "rgba("+String(r)+","+String(g)+","+String(b)+","+String(t)+")"; // colour ball
ctx.fillRect (x, y, wid, hei); // render ball
return ctx;
}
function renderAll(objects){
console.log("### - Render: Starting - ###");
for (var i = 0; i < objects.length; i++) {
// Iterate over numeric indexes from 0 to 5, as everyone expects.
}
console.log("### - Render: Complete - ###");
}
//Define generic move function
function transformR(object, moveAmount, canvasHeight, canvasWidth){
if (keyState[37]){
object[0] -= moveAmount
// console.log("left");
}
if (keyState[38]){
object[1] -= moveAmount
if (object[1] < 0){
// console.log("Top Edge")
object[1] = 0;
}
// console.log("up");
}
if (keyState[39]){
object[0] += moveAmount
// console.log("right");
}
if (keyState[40]){
object[1] += moveAmount
if (object[1] > (canvasHeight-object[3])){
// console.log("Bottom Edge")
object[1] = canvasHeight-object[3];
}
// console.log("down");
}
return object;
}
function transformL(object, moveAmount, canvasHeight, canvasWidth){
if (keyState[65]){
object[0] -= moveAmount
// console.log("left");
}
if (keyState[87]){
object[1] -= moveAmount
if (object[1] < 0){
// console.log("Top Edge")
object[1] = 0;
}
// console.log("up");
}
if (keyState[68]){
object[0] += moveAmount
// console.log("right");
}
if (keyState[83]){
object[1] += moveAmount
if (object[1] > (canvasHeight-object[3])){
// console.log("Bottom Edge")
object[1] = canvasHeight-object[3];
}
// console.log("down");
}
return object;
}
function collisonDetect(ball, paddle){
if (ball[0] < paddle[0] + paddle[2] &&
ball[0] + ball[2] > paddle[0] &&
ball[1] < paddle[1] + paddle[3] &&
ball[3] + ball[1] > paddle[1]) {
ball[8] = -ball[8];
ball[9] = -ball[9];
console.log("inside");
} else {
// console.log("not touching/inside");
}
return ball;
}
function ballMotion(height, width, ball, rightPaddle, leftPaddle){
var x = ball[0];
var y = ball[1];
// collision detection
ball = collisonDetect(ball, leftPaddle);
ball = collisonDetect(ball, rightPaddle);
var xSpeed = ball[8];
var ySpeed = ball[9];
x += xSpeed;
y += ySpeed;
// sides collison detection
if (y <= 0){
y = 0;
ySpeed = -ySpeed;
}
if (y >= height-ball[2]) {
y = height-ball[2];
ySpeed = -ySpeed;
}
if (x <= 0) {
x = 0;
xSpeed = -xSpeed;
leftPoints +=1
}
if (x >= width-ball[3]) {
x = width-ball[3];
xSpeed = -xSpeed;
rightPoints +=1
}
// assign new values
ball[0] = x;
ball[1] = y;
ball[8] = xSpeed;
ball[9] = ySpeed;
return ball;
}
function onPositionUpdate(position){
var lat = position.coords.latitude;
var lng = position.coords.longitude;
console.log("Current position: " + lat + " " + lng);
}
function onDown(event){
cx = event.pageX;
cy = event.pageY;
console.log(cx, cy)
}
// Define objects as follows
// Renderer usage: Canvas context, x position, y position, object height, object width, red, green, blue, transparency
// Cut down usage: X, Y, height, width, red, green, blue, transparency
if (window.innerWidth < window.innerHeight) {
ballDim = [window.innerWidth*.02, window.innerWidth*.02]
} else {
ballDim = [window.innerHeight*.02, window.innerHeight*.02]
}
var ball = [window.innerWidth/2-((window.innerWidth*.02)/2), window.innerHeight*.8*.5-((window.innerHeight*.08)/2), ballDim[0], ballDim[1],200 ,200 ,200 ,3 , 3, 2];
var leftPaddle = [window.innerWidth*.01, window.innerHeight*.8*.5-((window.innerHeight*.08)/2), window.innerWidth*.01, window.innerHeight*.08, 0, 0, 200, 3];
var rightPaddle = [window.innerWidth*.8-(window.innerWidth*.01)-(window.innerWidth*.01), window.innerHeight*.8*.5-((window.innerHeight*.08)/2), window.innerWidth*.01, window.innerHeight*.08, 255, 100, 0, 3];
var leftPoints = 0;
var rightPoints = 0;
// Define gameLoop
function gameLoop(x,y) {
if(navigator.geolocation){
navigator.geolocation.getCurrentPosition(onPositionUpdate);
} else {
console.log("navigator.geolocation is not available");
}
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
canvas.addEventListener("mousedown",onDown,false);
var width = window.innerWidth*.8;
var height = window.innerHeight*.8
ctx.canvas.width = width;
ctx.canvas.height = height;
var moveAmount = 3;
var motionTicker = + new Date()
// console.log(motionTicker)
// move checking function
leftPaddle[0] = window.innerWidth*.01;
rightPaddle[0] = window.innerWidth*.8-(window.innerWidth*.01)-(window.innerWidth*.01);
leftPaddle = transformL(leftPaddle, moveAmount, height, width);
rightPaddle = transformR(rightPaddle, moveAmount, height, width);
ball = ballMotion(height, width, ball, rightPaddle, leftPaddle);
ctx.save();
ctx.clearRect(0,0,width,height);
// Render objects in frame
drawObj(ctx, ball);
drawObj(ctx, leftPaddle);
drawObj(ctx, rightPaddle);
ctx.font = String(window.innerWidth*.05)+"px Arial";
ctx.fillStyle = "white";
ctx.fillText(String(rightPoints)+" - "+String(leftPoints), window.innerWidth*.333, window.innerHeight*.1);
ctx.restore();
setTimeout(gameLoop, 1);
await this.forceUpdate();
this.state = {motionTicker}
}
/components/CanvasCanvas.js
import * as React from "react";
export default class extends React.Component {
render() {
return (
<canvas ref={"canvas"} id = {"canvas"} width={640} height={425}/>
)
}
async componentDidMount() {
const script = document.createElement("script");
console.log("ln14")
script.src = "../src/gameLogic.js";
script.async = true;
// console.log(script);
document.head.appendChild(script);
console.log(script);
await this.setState(
{
text: this.props.text,
...this.state
}
);
await this.forceUpdate();
const canvas = this.refs.canvas;
const ctx = canvas.getContext("2d");
ctx.fillText((this.state && this.state.text) ? this.state.text : "Not initialised (nullcheck)", 210, 75);
}
}
Expected result is the gameLogic js file will render its output inside the canvas element and forceUpdate it at the end of each 'frame'.
And the actual result is a string of 404's as follows:
http://localhost:3000/css/style.css net::ERR_ABORTED 404 (Not Found)
index.js:1 Warning: Extra attributes from the server: deluminate_imagetype
GET http://localhost:3000/src/gameLogic.js net::ERR_ABORTED 404 (Not Found)
Thanks for any help you can give in advance.
If you want to access these files after compilation put them inside the static folder for example script.src = "/static/gameLogic.js"
Or use dynamic import
import dynamic from 'next/dynamic'
const gameLogic = dynamic(() => import(`../src/gameLogic.js`))
dynamic-import doc
okay so i am a beginner in web coding
so the thing is i want my website to look like this in the background of my website whenever i move the mouse over the background the wallpaper must appear for example exactly like the one in this site but i just don't know how to do that if someone will help me out with a code or some sort please
the link to the example is here
should i do it with the mouse over or javascript and how
https://www.canva.com/
I tried like this, it works for me
var image = document.querySelector('img');
var imageCanvas = document.createElement('canvas');
var imageCanvasContext = imageCanvas.getContext('2d');
var lineCanvas = document.createElement('canvas');
var lineCanvasContext = lineCanvas.getContext('2d');
var pointLifetime = 1000;
var points = [];
if (image.complete) {
start();
} else {
image.onload = start;
}
/**
* Attaches event listeners and starts the effect.
*/
function start() {
document.addEventListener('mousemove', onMouseMove);
window.addEventListener('resize', resizeCanvases);
document.body.appendChild(imageCanvas);
resizeCanvases();
tick();
}
/**
* Records the user's cursor position.
*
* #param {!MouseEvent} event
*/
function onMouseMove(event) {
points.push({
time: Date.now(),
x: event.clientX,
y: event.clientY
});
}
/**
* Resizes both canvases to fill the window.
*/
function resizeCanvases() {
imageCanvas.width = lineCanvas.width = window.innerWidth;
imageCanvas.height = lineCanvas.height = window.innerHeight;
}
/**
* The main loop, called at ~60hz.
*/
function tick() {
// Remove old points
points = points.filter(function(point) {
var age = Date.now() - point.time;
return age < pointLifetime;
});
drawLineCanvas();
drawImageCanvas();
requestAnimationFrame(tick);
}
/**
* Draws a line using the recorded cursor positions.
*
* This line is used to mask the original image.
*/
function drawLineCanvas() {
var minimumLineWidth = 25;
var maximumLineWidth = 100;
var lineWidthRange = maximumLineWidth - minimumLineWidth;
var maximumSpeed = 50;
lineCanvasContext.clearRect(0, 0, lineCanvas.width, lineCanvas.height);
lineCanvasContext.lineCap = 'round';
lineCanvasContext.shadowBlur = 30;
lineCanvasContext.shadowColor = '#000';
for (var i = 1; i < points.length; i++) {
var point = points[i];
var previousPoint = points[i - 1];
// Change line width based on speed
var distance = getDistanceBetween(point, previousPoint);
var speed = Math.max(0, Math.min(maximumSpeed, distance));
var percentageLineWidth = (maximumSpeed - speed) / maximumSpeed;
lineCanvasContext.lineWidth = minimumLineWidth + percentageLineWidth * lineWidthRange;
// Fade points as they age
var age = Date.now() - point.time;
var opacity = (pointLifetime - age) / pointLifetime;
lineCanvasContext.strokeStyle = 'rgba(0, 0, 0, ' + opacity + ')';
lineCanvasContext.beginPath();
lineCanvasContext.moveTo(previousPoint.x, previousPoint.y);
lineCanvasContext.lineTo(point.x, point.y);
lineCanvasContext.stroke();
}
}
/**
* #param {{x: number, y: number}} a
* #param {{x: number, y: number}} b
* #return {number} The distance between points a and b
*/
function getDistanceBetween(a, b) {
return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2));
}
/**
* Draws the original image, masked by the line drawn in drawLineToCanvas.
*/
function drawImageCanvas() {
// Emulate background-size: cover
var width = imageCanvas.width;
var height = imageCanvas.width / image.naturalWidth * image.naturalHeight;
if (height < imageCanvas.height) {
width = imageCanvas.height / image.naturalHeight * image.naturalWidth;
height = imageCanvas.height;
}
imageCanvasContext.clearRect(0, 0, imageCanvas.width, imageCanvas.height);
imageCanvasContext.globalCompositeOperation = 'source-over';
imageCanvasContext.drawImage(image, 0, 0, width, height);
imageCanvasContext.globalCompositeOperation = 'destination-in';
imageCanvasContext.drawImage(lineCanvas, 0, 0);
}
html,
body {
font-size: 0;
height: 100%;
margin: 0;
padding: 0;
width: 100%;
}
body {
background: url(https://wallpaperbrowse.com/media/images/pexels-photo-248797.jpeg) 0 0 / cover;
}
img {
display: none;
}
<img src="https://wallpaperbrowse.com/media/images/sunflowers-mr.jpg"/>
I have created WordCloud from angularjs using wordCloud directive,
So whenever I change the input to the cloud after generating word cloud for the first time, I am unable form word cloud.
This issue is being, I am not able to refresh the directive.
Say my html and js is ,
var app = angular.module("myApp", ["tangcloud"]);
app.controller("myCtrl", function($scope) {
$scope.words = [
{id: 1, word: "oke", size: 1},
{id: 2, word: "blabla", size: 6},
{id: 3, word: "test", size: 7},
{id: 4, word: "schaap", size: 2},
{id: 5, word: "deployment", size: 10},
{id: 6, word: "woord3", size: 3},
{id: 7, word: "wogamalord4", size: 4}];
});
<tang-cloud words="words" on-click="test(word)"></tang-cloud>
Say my directive going to be
angular.module('tangcloud', [])
.directive('tangCloud', ['$interpolate', '$compile', '$timeout', function ($interpolate, $compile, $timeout) {
var directive = {
restrict: 'E',
scope: {
words: '=',
onClick: '&',
spin: '='
},
template: function (tElement, tAttrs) {
var isClickable = angular.isDefined(tAttrs.onClick);
var clickAttr = isClickable ? 'ng-click="onClick({word : entry.word, id : entry.id})"' : '';
return "<div class='tangcloud'>" +
"<span ng-repeat='entry in words'" + clickAttr + ">{{entry.word}}</span>" +
"</div>";
},
compile: function (elem) {
elem.children().children()
.addClass('tangcloud-item-' + $interpolate.startSymbol() + 'entry.size' + $interpolate.endSymbol())
.addClass('tangcloud-item-hidden');
return function (scope, elem) {
var div = elem.children().eq(0)[0];
scope.width = div.offsetWidth;
scope.height = div.offsetHeight;
var centerX = scope.width / 2;
var centerY = scope.height / 2;
var outOfBoundsCount = 0;
var takenSpots = [];
if (scope.words) {
scope.words = shuffleWords(scope.words);
determineWordPositions();
}
function shuffleWords(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
function determineWordPositions() {
$timeout(function () {
var trendSpans = elem.children().eq(0).children();
var length = trendSpans.length;
for (var i = 0; i < length; i++) {
setWordSpanPosition(trendSpans.eq(i));
}
});
}
function setWordSpanPosition(span) {
var height = parseInt(window.getComputedStyle(span[0]).lineHeight, 10);
var width = span[0].offsetWidth;
var spot = setupDefaultSpot(width, height);
var angleMultiplier = 0;
while (spotNotUsable(spot) && outOfBoundsCount < 50) {
spot = moveSpotOnSpiral(spot, angleMultiplier);
angleMultiplier += 1;
}
if (outOfBoundsCount < 50) {
takenSpots.push(spot);
addSpanPositionStyling(span, spot.startX, spot.startY);
}
outOfBoundsCount = 0;
}
function setupDefaultSpot(width, height) {
return {
width: width,
height: height,
startX: centerX - width / 2,
startY: centerY - height / 2,
endX: centerX + width / 2,
endY: centerY + height / 2
};
}
function moveSpotOnSpiral(spot, angleMultiplier) {
var angle = angleMultiplier * 0.1;
spot.startX = centerX + (1.5 * angle) * Math.cos(angle) - (spot.width / 2);
spot.startY = centerY + angle * Math.sin(angle) - (spot.height / 2);
spot.endX = spot.startX + spot.width;
spot.endY = spot.startY + spot.height;
return spot;
}
function spotNotUsable(spot) {
var borders = {
left: centerX - scope.width / 2,
right: centerX + scope.width / 2,
bottom: centerY - scope.height / 2,
top: centerY + scope.height / 2
};
for (var i = 0; i < takenSpots.length; i++) {
if (spotOutOfBounds(spot, borders) || collisionDetected(spot, takenSpots[i])) return true;
}
return false;
}
function spotOutOfBounds(spot, borders) {
if (spot.startX < borders.left ||
spot.endX > borders.right ||
spot.startY < borders.bottom ||
spot.endY > borders.top) {
outOfBoundsCount++;
return true;
} else {
return false;
}
}
function collisionDetected(spot, takenSpot) {
if (spot.startX > takenSpot.endX || spot.endX < takenSpot.startX) {
return false;
}
return !(spot.startY > takenSpot.endY || spot.endY < takenSpot.startY);
}
function addSpanPositionStyling(span, startX, startY) {
var style = "position: absolute; left:" + startX + "px; top: " + startY + "px;";
span.attr("style", style);
span.removeClass("tangcloud-item-hidden");
}
};
}
};
return directive;
}]);
How can I refresh my directive on change the input for my word-cloud
I am trying to make a game involving a dragon burning little knights, fairly simple but I am new to AS3 and can't seem to solve this problem, sometimes when I kill a knight it returns an output error saying:
TypeError: Error #1010: A term is undefined and has no properties.
at drogtor/onTick()
I can't find any relevant solutions elsewhere on this website so I am submitting a question myself.
Here is (what I think to be) the relevant code.
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.KeyboardEvent;
import global;
import flash.display.DisplayObject;
public class drogtor extends MovieClip
{
private var updown:Boolean=true;
private var fArray:Array;
private var eArray:Array;
var wpressed:Boolean = false;
var apressed:Boolean = false;
var dpressed:Boolean = false;
var spressed:Boolean = false;
var kspawn:Number = 5;
public function drogtor()
{
addEventListener(Event.ENTER_FRAME, onTick);
stage.addEventListener(KeyboardEvent.KEY_DOWN, fliy);
stage.addEventListener(KeyboardEvent.KEY_UP, fliy);
fArray = new Array();
eArray = new Array();
}
public function onTick(e:Event):void
{
var fcount:int=0;
var sdargon:int=10;
var rdargon:int=6;
var Angle:Number = (2 * Math.PI * (dargon.rotation/360));
var dy:Number = sdargon * Math.cos(Angle);
var dx:Number = sdargon * Math.sin(Angle);
HitBox.x = dargon.x;
HitBox.y = dargon.y;
HitBox.rotation = dargon.rotation;
//Flame Spewer
if (global.count==9)
{
var fAngle:Number = (2 * Math.PI * (dargon.rotation/360));
var fdy:Number = 10 * Math.cos(fAngle);
var fdx:Number = 10 * Math.sin(fAngle);
var ftemp:Flame=new Flame;
ftemp.x=dargon.x + (10 * fdx);
ftemp.y=dargon.y - (10 * fdy);
ftemp.rotation=dargon.rotation + Math.random() * (15-(-15)) + (-15);
fArray.push(ftemp);
addChildAt(ftemp, 0);
}
var kgen:int = Math.floor((Math.random() * 3)+1);
var stageside:int = Math.floor((Math.random() * 4)+1)
if (kgen == 1)
{
if (Math.floor((Math.random() * 100) + 1) <= kspawn)
{
var ktemp:keniget = new keniget;
if (stageside == 1)
{
ktemp.x = Math.random() * stage.stageWidth;
ktemp.y = 0
}
else if (stageside == 2)
{
ktemp.x = Math.random() * stage.stageWidth;
ktemp.y = stage.stageHeight;
}
else if (stageside == 3)
{
ktemp.x = 0;
ktemp.y = Math.random() * stage.stageHeight;
}
else if (stageside == 4)
{
ktemp.x = stage.stageWidth;
ktemp.y = Math.random() * stage.stageHeight;
}
eArray.push(ktemp);
addChildAt(ktemp, 0);
}
}
for (var iKl:int = eArray.length-1; iKl >= 0; iKl --)
{
var krotation:Number = (Math.atan2(eArray[iKl].y-dargon.y, eArray[iKl].x-dargon.x) * 180/Math.PI) - 90;
eArray[iKl].rotation = krotation
var kangle:Number = (2 * Math.PI * (eArray[iKl].rotation/360));
var edx:Number = 3 * Math.sin(kangle);
var edy:Number = 3 * Math.cos(kangle);
eArray[iKl].x += edx;
eArray[iKl].y -= edy;
if (eArray[iKl].hitTestObject(HitBox))
{
removeChild(eArray[iKl]);
eArray.splice(iKl, 1);
}
for (var iF:int=fArray.length-1; iF>=0; iF--)
{
if (eArray[iKl].hitTestObject(fArray[iF]))
{
removeChild(eArray[iKl]);
eArray.splice(iKl, 1);
kspawn += 0.5
}
}
}
for(var iFl:int=fArray.length-1; iFl>=0; iFl--)
{
if(fArray[iFl].currentFrame==fArray[iFl].totalFrames)
{
removeChild(fArray[iFl]);
fArray[iFl]=null;
fArray.splice(iFl, 1);
}
}
if(updown)
{
dargon.rotationX-=1;
if(dargon.rotationX == -10)
{
updown = false;
}
}
if(!updown)
{
dargon.rotationX+=1;
if(dargon.rotationX == 10)
{
updown = true;
}
}
//Movement
if(wpressed)
{
dargon.x += dx;
dargon.y -= dy;
}
if(apressed)
{
dargon.rotation -= rdargon;
}
if(dpressed)
{
dargon.rotation += rdargon;
}
if(spressed)
{
dargon.x -= ((1/4) * dx);
dargon.y += ((1/4) * dy)
}
}
public function fliy(ke:KeyboardEvent):void
{
if(ke.type == "keyDown")
{
//key=A
if(ke.keyCode==87)
{
wpressed=true;
}
//Key=A
if(ke.keyCode==65)
{
apressed=true;
}
//Key=D
if(ke.keyCode==68)
{
dpressed=true;
}
if(ke.keyCode==83)
{
spressed=true;
}
}
if(ke.type == "keyUp")
{
//key=A
if(ke.keyCode==87)
{
wpressed=false;
}
//Key=A
if(ke.keyCode==65)
{
apressed=false;
}
//Key=D
if(ke.keyCode==68)
{
dpressed=false;
}
if(ke.keyCode==83)
{
spressed=false;
}
}
}
}
}
The problem is, that even though you removed the knight from the display list, the code is still running in the onTick function, and you are trying to access something that is not existing, I suggest you to check whether your knight's reference is null or not, if not, then run the code, else skip it.
EDIT:
Whenever you null an instance (myInstance = null), you can no longer access to it's properties, functions etc.. and if you try, then you get that error above. To avoid it, check whether your object is null or not.
if(myInstance != null) {
//do your stuff with your instance
}