createGraphics in Instance Mode in p5js - p5.js

I'm new to p5.
My aim is to display ASCII value of the key I type and also leave a trail of vertical lines whose distance from left is 200+the ASCII value of the key,
which can be done using createGraphics() (adding an additional canvas layer on top with same dimensions as original and drawing on that additional canvas layer)
But the code doesn't seem to work and also it is not displaying any errors in the console.
const c5=function(p){
let pg;
p.setup=function(){
p.createCanvas(600,400);
pg=p.createGraphics(600,400);
};
p.draw=function(){
p.background(200);
p.textAlign(p.CENTER,p.TOP);
p.textSize(20);
p.text('ASCII Value : '+p.keyCode,300,100);
pg.line(200+p.keyCode,200,200+p.keyCode,300);//shift right by 200
};
};

The first issue is that you have to tell the engine that the thing you name p is actually a p5 instance. You can construct a p5 object using new p5(...) as follows:
const c5 = new p5(function(p) {
p.setup = function(){
...
};
p.draw = function(){
...
};
});
You then correctly fill up your pg graphic object with vertical lines. However, you do not "draw" it on your original canvas. You can do so using the p5.js image() function (see also the example shown in the createGraphics() documentation).
I've made a working example in the p5.js editor here.

Your code is very close. You are creating the graphic object and drawing to it but you also need to display it as an image to your canvas. In your code snippet you are also missing the call to create the new p5js object but that may be just a copy paste error.
Here is a working snippet of your code with the call to draw the image. I also moved the key detection logic to keyPressed so the logic only runs when a key is pressed.
Also notice that running the logic inside of keyPressed allows the sketch to handle keys such as f5 by returning false and preventing default behavior. In a real application we would need to be very careful about overriding default behavior. Here we assume that the user wants to know the key code of the f5 key and will be ok with the page not reloading. In a real application that might not be the case.
const c5=function(p){
let pg;
p.setup=function(){
p.createCanvas(600,400);
pg=p.createGraphics(600,400);
};
p.draw=function(){
};
p.keyPressed = function() {
p.background(200);
p.textAlign(p.CENTER,p.TOP);
p.textSize(20);
p.text('ASCII Value : '+p.key + " " +p.keyCode,300,100);
pg.line(200+p.keyCode,200,200+p.keyCode,300);//shift right by 200
p.image(pg, 0, 0);
return false; // prevent default
}
};
var myp5 = new p5(c5)
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/p5.min.js"></script>

Related

Codename One - how to use onTitleScrollAnimation with BorderLayout?

as the Toolbar or Titlearea on scroll animation feature is referenced in the last section of the Toolbar API, and also in this great video tutorial (starting at about min 45), the animation works well under given circumstances.
I was not able to find any documentation about what these have to be, however I found one circumstance, in which it does not work. Here is a working example to demonstrate the problem:
Form hi = new Form("Title", new BoxLayout(BoxLayout.Y_AXIS));
EncodedImage placeholder = EncodedImage
.createFromImage(Image.createImage(hi.getWidth(), hi.getWidth() / 5, 0xffff0000), true);
URLImage background = URLImage.createToStorage(placeholder, "400px-AGameOfThrones.jpg",
"http://awoiaf.westeros.org/images/thumb/9/93/AGameOfThrones.jpg/400px-AGameOfThrones.jpg");
background.fetch();
Style stitle = hi.getToolbar().getTitleComponent().getUnselectedStyle();
stitle.setBgImage(background);
stitle.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL);
stitle.setPaddingUnit(Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS);
stitle.setPaddingTop(15);
// hi.setLayout(new BorderLayout()); // uncomment this for the animation to break
Container contentContainer = new Container(BoxLayout.y());
contentContainer.setScrollableY(true);
// add some elements so we have something to scroll
for (int i = 0; i < 50; i++)
contentContainer.add(new Label("Entry " + i));
hi.add(contentContainer);
// hi.add(BorderLayout.CENTER, contentContainer); // use this line instead of the above for the animation to break
ComponentAnimation anim = hi.getToolbar().getTitleComponent().createStyleAnimation("Title", 200);
hi.getAnimationManager().onTitleScrollAnimation(anim);
hi.show();
With my current app and the codesample from the Toolbar API (which is roughly adapted here), I found out that the onScrollAnimation event is not being called, when a scroll occurs inside a BorderLayout. Even when I have a separate container, which is not the contentpane itself, and I set setScrollableY(true); to true, the animation works properly. The animation stops working, when this very container is put into Center of the Form, via Borderlayout. in the example above, the layout is exactly the same, as there are no other components in other areas of course, but it breaks the animation.
How to solve this? In my app, I have the need for a BorderLayout but still want to use this cool feature. Also, this is a very un-intuitive feature, if it works for some, but not all layouts. It should be completely layout-agnostic and work in every case.
Thank you.
The adapter is bound to the forms content pane scrolling so it won't work if you have a border layout in here. In that case scrolling isn't detected because the code just isn't aware of the scrolling. It would need to track the scrolling of any component in the UI to detect that scrolling.
as hinted by Shai, the solution is the following:
hi.setLayout(new BorderLayout());
Container contentContainer = new Container(BoxLayout.y());
contentContainer.setScrollableY(true);
// add some elements so we have something to scroll
for (int i = 0; i < 50; i++)
contentContainer.add(new Label("Entry " + i));
hi.add(BorderLayout.CENTER, contentContainer); // use this line instead of the above for the animation to break
ComponentAnimation anim = hi.getToolbar().getTitleComponent().createStyleAnimation("Title", 200);
hi.getAnimationManager().onTitleScrollAnimation(contentContainer, anim);
instead of using the onTitleScollAnimation to just add the animation, provide your own scrollable "body" or content container as the first argument, appended by the animation(s).

Codename One Transition Form Automatically Scrolls to Top

I have an app with lots of components that use slide transitions.
The components, ScaleImageButtons and -Labels are added to the form directly via a GridLayout. There are also timer events involved, to make the scenario more dynamic and appealing
The form is, of course, scrollable.
Now, every time I call the form and scroll it down, it automatically jumps back to the first item at the top of the form, once that becomes animated.
But the form should stay at the current scroll position, independent of the position of the animated item, being this visible or not.
How can can make the form keep the current scroll position, independent of the position of the currently animated item?
formApps.setFocusScrolling(false); // does not help
Here is the code:
(THIS CODE WAS EDITED TO REFLECT THE WORKING SOLUTION)
Form formApps = new Form(new GridLayout(6, 2));
ArrayList<String> listApps = classStrings.listApps;
for (int i = 0; i < listApps.size(); i++) {
Container container = new Container();
ScaleImageButton scaleImageButton = new ScaleImageButton(image);
SpanButton spanButton = new SpanButton(stringDescrip);
container.add(scaleImageButton);
UITimer uit00 = new UITimer(() -> {
UITimer uit01 = new UITimer(() -> {
container.replace(spanButton, scaleImageButton,
CommonTransitions.createCover(CommonTransitions.SLIDE_HORIZONTAL, true, slideInterval));
});
uit01.schedule(startInterval, false, formApps);
UITimer uit02 = new UITimer(() -> {
container.replace(scaleImageButton, spanButton,
CommonTransitions.createCover(CommonTransitions.SLIDE_HORIZONTAL, true, slideInterval));
});
uit02.schedule(repeatIntervalOne, false, formApps);
});
uit00.schedule(repeatIntervalOne, true, formApps);
});
form.setFocusScrolling(false);
form.add(container);
container.setScrollableY(true);
formApps.show();
You shouldn't use Timer here directly. That violates the EDT. You should either wrap the timer callback in callSerially or better yet just use a UITimer which is designed exactly with this purpose in mind.
6x2 is a relatively small grid so it's possible that a small movement is enough to send you to the top as elements get resized. The size of the grid is determined by the preferred size of all the elements within. If the scaleImageButton is much larger than spanButton once they are replaced the layout might "jump" and you will end up with something much smaller which feels like scrolling but is just a new layout due to smaller preferred size.
A workaround for this would be:
Component.setSameSize(scaleImageButton, spanButton);

Adobe Animate gotoAndStop for Movie clip

I created HTML5-canvas and added Rectangle like Movie (Movie1)
Then I created Animate for Movie1
But I don't know how works JS, when I try to stop Animate.
AS3 Action:Frame1
trace (this.Movie1);
this.Movie1.gotoAndStop(1);
How I need to write it on JS ?
I check different way but all of them doesn't work.
this.Movie1.gotoAndStop(1);
Movie1.gotoAndStop(1);
I opened console IE and saw
SCRIPT5007: Unable to get property 'gotoAndStop' of undefined or null reference
also I wrote second Example
this.stop();
alert(this.Movie1);// output: MovieClip (name=null)
//this.Movie1.gotoAndStop(1);
this.addEventListener('click', alertpopup);
function alertpopup(){
//this.Movie1.gotoAndStop(1);
alert(this.Movie1); // output: undefined ???
}
So, I decided this task only when I inserted code in generated HTML file at the end Function Init(). Something like this
var canvas, stage, exportRoot;
function init() {
// --- write your JS code here ---
canvas = document.getElementById("canvas");
exportRoot = new lib.ExAS3_Canvas();
stage = new createjs.Stage(canvas);
stage.addChild(exportRoot);
stage.update();
createjs.Ticker.setFPS(lib.properties.fps);
createjs.Ticker.addEventListener("tick", stage);
Update(exportRoot);
}
function Update(root){
<!-- write your code here -->
root.stop();
//this.Movie1.name = 'Movie1';
console.log("m=" + root.Movie1);
root.Movie1.stop();
root.Movie1.addEventListener('click', alertpopup);
function alertpopup(){
root.Movie1.gotoAndStop(1);
console.log("r=" + root.Movie1);
}
}
Why the code is not working from the IDE ?
I try to change this on my first frame on exportRoot and it works partially
//this.Movie1.stop(); // it doesn't work
//exportRoot.Movie1.stop(); // it doesn't work
this.Movie1.addEventListener('click', alertpopup);
var i = 0;
function alertpopup(){
i++;
if(i==2) i = 0;
exportRoot.Movie1.gotoAndStop(i);
}
I found that writing your code in the first frame gives a problem getting in touch with movieclips on the Stage (this.Movie1) - but putting the code in the second frame helps. Also I found, that the use of "this" inside a function sometimes gives the usual js-error: "this" refers to the function, and not to the object you are "inside" (Stage). Solve this problem by a variable "var that=this;" and use "that" instead of "this" inside the function.

Edit Control not updating with Spin Control MFC

I am trying to use an edit control along with a spin control using MFC visual studio .net 2003. I have carried out the basic settings for the spin control like setting the "AutoBuddy" property and "SetBuddyInteger" property to True so that the Spin control works in coordination with the edit control next to it. In my Spin control's event handler, I am facing a problem when I am trying to call my Invalidate() function. The float value in my edit control does not update and stays zero. If I remove the Invalidate(), then the value increments but my paint function is not updated obviously. A code of the following is given below:
void CMyDlg::OnSpinA(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
// TODO: Add your control notification handler code here
UpdateData();
m_A = m_ASpinCtrl.GetPos(); // m_A is my edit control float value variable
Invalidate(); // Invalidate is to be called to update my paint function to redraw the drawing
UpdateData(false);
*pResult = 0;
}
I have carried out the tab order correctly as well for the two controls.
Any suggestions on where I am going wrong?
Thanks in advance.
If you just want to have a spinning integer, you don't have to override anything.
The spin control has to be right next to the edit control in the tab order. With AutoBuddy that's all you have to do.
m_A when getting the position back would do something weird and would not return you the correct value. Try using the pointer to get your position and value and then carry out the invalidate().
{
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
// TODO: Add your control notification handler code here
UpdateData();
CString tempStr;
m_A += pNMUpDown->iDelta;
tempStr.Format("%f",m_A);
m_ACtrl.SetWindowText(tempStr); // Like a CEdit m_ACtrl to display your string
Invalidate();
UpdateData(false);
*pResult = 0;
}
This should work perfectly well. Let me know if you still get any problems.

Smooth transition (optical effect) between uitabpanels in Matlab

I have designed a group of three uitabpanels objects.
htab = uitabgroup('v0');
th1 = uitab('v0',htab,'title','Panel 1','ButtonDownFcn',...
#th1_ButtonDownFcn);
th2 = uitab('v0',htab,'title','Panel 2','ButtonDownFcn',...
#th2_ButtonDownFcn);
th3 = uitab('v0',htab,'title','Panel 3','ButtonDownFcn',...
#th3_ButtonDownFcn);
My intention is having a smooth transition between them when I change the selected uipanel through the mouse click. I pretend to achieve it changing the 'Visible' property of the elements contained inside them using the ButtonDownFcn function ( I got this idea based on the description section of this page).
set(handles.th2,'Visible','off');
set(handles.th3,'Visible','off');
...
function th1_ButtonDownFcn(hObject, eventdata)
handles = guidata(fh);
set(handles.th1,'Visible','on');
set(handles.th2,'Visible','off');
set(handles.th3,'Visible','off');
guidata(fh,handles);
end
function th2_ButtonDownFcn(hObject, eventdata)
handles = guidata(fh);
set(handles.th1,'Visible','off');
set(handles.th2,'Visible','on');
set(handles.th3,'Visible','off');
guidata(fh,handles);
end
function th3_ButtonDownFcn(hObject, eventdata)
handles = guidata(fh);
set(handles.th1,'Visible','off');
set(handles.th2,'Visible','off');
set(handles.th3,'Visible','on');
guidata(fh,handles);
end
where
fh: handle of the figure where they are contained the uitabpanels.
handles.th1, handles.th2, handles.th3: handles of the elements contained into each uitabpanel respectively.
However, it has not worked (I click on each one of uitabpanel's tabs and the visibility of them do not change) and I do not understand why.
In conclusion, the ButtonDownFcn and SelectionChangeFcn functions of an UITAB are already active when you click in the tabĀ“s label. So it is not possible to achieve the desired target (smooth optical transition) because the obtained result (modifying the mentioned functions) is the same that doing nothing.

Resources