This is a follow-up of my question: Make the cursor a self-drawn image.
I have a paint a picture application. The latest working version can be found here: https://knowledgeablekangaroo.github.io/paint-a-picture-backup/, where the code can be found in F12 > Sources > paint-a-picture.js.
The user can choose a color, set the background, set the thickness, shape, and opacity. There is also an eraser functionality. I want there to be a better user experience, so I am trying to draw the eraser below as the cursor. If the cursor doesn't work, I need something that doesn't smear.
The way I have programmed it, anywhere inside the "paint area" (above control center and below pallete) will smear - the background() is outside the draw.
var pg = createGraphics(pgDimensions.w, pgDimensions.h, JAVA2D);
pg.beginDraw();
pg.fill(255, 200, 255);
pg.strokeWeight(2);
pg.rect(0, 0, pgDimensions.w, pgDimensions.h);
pg.fill(0);
pg.textAlign(CENTER, CENTER);
pg.text("ERASER", pgDimensions.w / 2, pgDimensions.h / 2);
pg.endDraw();
I used the createGraphics() function to create a PGraphics Object. The point is to show the eraser while This shows the eraser I have drawn in the pGraphic above.
In the drawBrush() function, I make this an image.
var drawBrush = function() {
fill(currentColor);
noStroke();
shapes.forEach(function (element, index) {
if (pshape == index) {
element.brush();
}
});
if (C === bgColor) {
image(pg, mouseX - pgDimensions.w / 2, mouseY - pgDimensions.h / 2);
}
};
Research
This best describes my problem
After you have a graphics stored in your pg variable, you can draw that using the image() function:
image(pg, mouseX, mouseY);
Here's a small example that demonstrates what I'm talking about:
var pg;
function setup() {
createCanvas(400, 400);
pg = createGraphics(100, 100);
pg.ellipse(50, 50, 100, 100);
}
function draw() {
background(220);
image(pg, mouseX, mouseY);
}
Related
I have Graphics^ g created on a PictureBox. I can draw on it inside events like MyForm_Load, Button_Click, but not in Timer_Tick. It doesn't draw anything:
System::Void timer1_Tick(...) {
g->Clear(Color::White);
Pen^ pen = gcnew Pen(Color::Black, 1);
g->DrawLine(pen, 10, 10, 30, 50); // of course values may change
}
How to solve the problem?
To show the drawing immediately, refresh an object which drawing is created on. For example, if drawing was created like g = Graphics::FromImage(pictureBox1->Image); use pictureBox1->Refresh();
I am using Jfreechart API 1.0.8 to generate the TimeSeriesChart(line chart).
when I am generating the chart, i am facing the problem of overlapping.
Here I am trying to display the rendered points(graph rendered points), by using XYLineAndShapeRenderer with StandardXYItemLabelGenerator.
When the points are displayed, the data-point is overlapping with the generated line chart (graph).
I am taking X-Axis as time, and y-Axis as revenue of organization, and i am using line chart here.
I'm displaying the points as discussed below.
By using "renderer.setBasePositiveItemLabelPosition" method, globally i am setting the position of graph points(data points) inside the xyplot rendered chart while considering the rendered "ItemLabelAnchor".
I am sending my sample code here:
chart = ChartFactory.createTimeSeriesChart("", "", "", newxyseries, false, true, false);
renderer = new XYLineAndShapeRenderer();
renderer = (XYLineAndShapeRenderer) chart.getXYPlot().getRenderer();
renderer.setBaseItemLabelGenerator(new StandardXYItemLabelGenerator("{2}", monthDate, formatSymbol));
renderer.setBaseItemLabelsVisible(true);
renderer.setBasePositiveItemLabelPosition(new ItemLabelPosition(ItemLabelAnchor.OUTSIDE3, TextAnchor.TOP_RIGHT));
chart.getXYPlot().setRenderer(renderer);
But when I am generating the graph chart using Ms-office of Excel tools, there is no problem of overlapping of labels, the points are displayed in an effective manner without any overlapping.
JFreeChart doesn't do any overlap detection for item labels. It would be a great feature to have, but nobody has written the code to do it.
you have to refrain the labels to get overlap by define your own algo or logic because as the graph keep growing sooner the labels will start to get overlap.
the key is to make some or alternative labels transparent so that no overlapping occur
For example in the following P.O.C, only 35 labels will be drawn but the tick of graphs will remai same just the labels will reduce
CategoryAxis domainAxis = plot.getDomainAxis();
CategoryLabelPositions pos = domainAxis.getCategoryLabelPositions();
double size = plot.getCategories().size();
double occurence = Math.ceil(plot.getCategories().size() / 20);
double interval = Math.ceil(plot.getCategories().size() / 20);
for (int i = 1; i <= plot.getCategories().size(); i++) {
if (plot.getCategories().size() > 35) {
if(plot.getCategories().size()>35 && plot.getCategories().size()<250) {
if(i%8==0){
String cat_Name = (String) plot.getCategories().get(i-1);
} else{
String cat_Names = (String) plot.getCategories().get(i-1);
domainAxis.setTickLabelPaint(cat_Names, new Color(0,0,0,0));
}
}else if(plot.getCategories().size()>250){
[![enter image description here][1]][1]
if (i == occurence) {
String cat_Name = (String) plot.getCategories().get(i - 1);
if (occurence + interval >= size) {
// occurence=size;
} else {
occurence = occurence + interval;
}
} else {
String cat_Names = (String) plot.getCategories().get(i - 1);
domainAxis.setTickLabelPaint(cat_Names, new Color(0, 0, 0, 0));
}
}
}
Below line will make label transparent
domainAxis.setTickLabelPaint(cat_Names, new Color(0,0,0,0));
I have a stage that resizes to the container width based on browser width (trying to make my project responsive but struggling). I only have one layer and want the layer to resize based on the size of the stage. As of now the stage width changes with browser width but the layer width doesn't change, just gets cut off
I've tried layer.setScale(x,y) in a window.onresize function but don't have enough math sense to use this to scale the layer as the stage width changes.
I've also tried layer.setWidth(x) and used the stage width as a variable for x in the same function but no luck.
Shouldn't the layer automatically scale with the stage? If I adjust the canvas size in firebug the layer auto scales, but that's the only time I get the correct response...
By the way all the elements are polygons whose coordinates/points/etc are imported via svg/illustrator. Not sure if that has anything to do with the prob...
Totally stuck...
Here's my project: http://cityunite.org/new
There are many ways to approach this problem. I'll just give my suggestion.
You should not set the width of the stage when the browser window size changes, but you should scale instead. When you first load the page, your scale is set at 1, which is (100%). When your window size changes, you should listen for that change and set the scale accordingly.
Something like this:
//save initial scale
var initialScale = stage.scale(); //returns {x: 1, y: 1}
var initialWidth = $("#container").innerWidth(); // initial width
var initialHeight = $("#container").innerHeight(); // initial height
window.onresize = function(event) { // listen for change
var width = $("#container").innerWidth(); // new width of page
var height = $("#container").innerHeight(); // new height of page
console.log(width);
console.log(height);
var xScale = (width / initialWidth) * initialScale.x; // percent change in width (Ex: 1000 - 400/1000 means the page scaled down 60%, you should play with this to get wanted results)
var yScale = (height / initialHeight) * initialScale.y;
var newScale = {x: xScale, y: yScale};
console.log(newScale);
stage.setAttr('width', width);
stage.setAttr('height', height);
stage.setAttr('scale', newScale );
stage.draw();
}
I suppose it's some king of gradient used, but I can't tell.
I'd like to use the same in my WinForms application.
Easiest way to do something like this is to use a program like Paint.Net to get the RGB values of the colors used in the drawing.
Using a panel as an example:
void panel1_Paint(object sender, PaintEventArgs e) {
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
using (LinearGradientBrush br = new LinearGradientBrush(
panel1.ClientRectangle,
Color.FromArgb(52, 151, 254),
Color.FromArgb(61, 129, 243),
LinearGradientMode.Vertical)) {
e.Graphics.FillRectangle(br, panel1.ClientRectangle);
}
using (Pen p = new Pen(Color.FromArgb(37, 110, 184), 2)) {
e.Graphics.DrawRectangle(p, 0, 0,
panel1.ClientSize.Width - 1,
panel1.ClientSize.Height - 1);
}
}
Results in:
Pretty close to the original. You can make adjustments by lightening or darkening the colors used.
Are there any working piemenu controls for WPF?
I've found this in my favorite , you can take a look at :
This
have a nice day.
This question is probably long dead, but just a note that the control Thomas M posted, while awesome, has a major issue: You need to mouse over and click on the actual item instead of the pie slice. This means that the pie slices are not completely adjacent and IMO defeats a lot of the clickability (Frits's law) advantages of the control. So while it looks like a pie menu, it really just positions everything radially.
I ended up doing this:
private static Path makeDeliciousKeyLimePieSlice(double innerRadius, double outerRadius,
double startAngle, double endAngle, Vector ofs)
{
Point p1 = new Point(Math.Cos(endAngle) * innerRadius, Math.Sin(endAngle) * innerRadius) + ofs;
Point p2 = new Point(Math.Cos(startAngle) * innerRadius, Math.Sin(startAngle) * innerRadius) + ofs;
Point p3 = new Point(Math.Cos(startAngle) * outerRadius, Math.Sin(startAngle) * outerRadius) + ofs;
Point p4 = new Point(Math.Cos(endAngle) * outerRadius, Math.Sin(endAngle) * outerRadius) + ofs;
PathFigure fig = new PathFigure(p1, new PathSegment[] {
new ArcSegment(p2, new Size(innerRadius, innerRadius), endAngle - startAngle, false, SweepDirection.Counterclockwise, true),
new LineSegment(p3, true),
new ArcSegment(p4, new Size(outerRadius, outerRadius), startAngle - endAngle, false, SweepDirection.Clockwise, true),
}, true).GetAsFrozen();
return new Path { Data = new PathGeometry(new[] { fig }).GetAsFrozen() };
}
This will create a "slice" of the pie. You can style this how you want if you want a true pie menu. Another option is to make it transparent (set the fill to Brushes.Transparent; it must have a fill to be hit-test visible), which looks good for radial context menus. Here's my WIP after about half an hour's work (I know the spacing sucks):
alt text http://public.blu.livefilestore.com/y1pdW5ibqWquKGosMSch9C5KmOTKkiZ35mAI7iFKKUKf3cm7TGSquXhO8hkkL9Ln6Z3tKn74u67C27Qb_AIWQxzhg/radial.png?psid=1
EDIT: ah; the cursor doesn't appear in the shot -- basically, if you use the path overlay, you can have the mouse outside the actual control but still have it highlighted.
This control needs a bit of work still but it's a great starting point and supports multiple levels of items. (ie: a hierarchy) Check it out here