PaperJS Rotate function displaying item two times - javascript

when i am trying to rotate the path it is displaying same item two times. can some one help me to prevent the item to display twice.
var center1 = ball1.position;
var center2 = ball2.position;
// Create a triangle shaped path
var triangle = new Path.RegularPolygon(new Point(80, 70), 3, 12);
triangle.id = Math.random();
triangle.fillColor = '#fff';
//triangle.selected = true;
triangle.strokeColor = '#00304A';
triangle.strokeWidth = 2;
triangle.position = path.position; **
var arrowAngle = 90 + ((center2.subtract(center1)).angle); ** triangle.rotation = arrowAngle;

I'm not sure why you're getting two triangles (there isn't enough code for me to see what the reason for that is) but the main problem is that rotation is a read-only property - you cannot set it. Try using rotate().
http://paperjs.org/reference/path/#rotate-angle

Related

How to specify color properties (fill and stroke) of a path in JS

So I'm trying to optimize some designs in my process, for this task I'm experimenting with javascripts for Illustrator and Photoshop, the issue i have right now is that for drawing, filling and changing the stroke color of my paths. So how I can an array of colors in JS for Illustrator to fill a path of one color and the stroke of another color?
Right know it just take my last declared CMYK color and ignores previous ones.
Code:
var RectangleColor = new CMYKColor();
RectangleColor.black = 0;
RectangleColor.cyan = 0;
RectangleColor.magenta = 0;
RectangleColor.yellow = 0;
var RectangleColorStroke = new CMYKColor();
RectangleColor.black = 0;
RectangleColor.cyan = 80;
RectangleColor.magenta = 80;
RectangleColor.yellow = 0;
and in the drawing method
rect.filled = true;
rect.fillColor = RectangleColor;
rect.strokeColor = RectangleColorStroke;
Note: I don't really know if exist a property named strokeColor, but since it didn't show any error then was decided to use it.
Well i know is not the most clean way but already found how.
declared this variable
var col = new GrayColor();
col.gray = 100;
have this at the code
var rect = artLayer.pathItems.rectangle (monthsCubeY,monthsCubeX,180,100); //draw rectangle at the selected coordenates
monthsCubeX = monthsCubeX + 190; //move the coordenates for the next rectangle
rect.filled = true;
rect.stroked = true;
strokeWidth = 1;
rect.fillColor = RectangleColor;
strokeColor = col;
I dont know much of coding, but this seems to work for me.

Photoshop Scripting: Creating a selection, then fitting a text box inside

Using Javascript for Photoshop (ExtendScript) I am trying make a dynamic text box.
My end goal is a script that the user writes their own text into a new window pop up, then that text is positioned in the bottom 10% of the image, scaled dynamically to fit the bottom 10% of an image.
So, whatever the dimensions of the lower 10% (created by resizeCanvas argument) the text always fits within it comfortably. So when the user adds a few words it does not look too small and when they add a longer sentence it does not overspill.
Question originally asked here (with pictures) https://forums.adobe.com/message/10952562#10952562
Example Start Image:
start image
Window Pop up :
custom PopUp
Small Text Outcome:
outcome1
Long Text Outcome:
outcome 2
This is where I am currently:
#target Photoshop
app.preferences.rulerUnits = Units.PIXELS;
app.preferences.typeUnits = TypeUnits.PIXELS;
var doc = app.activeDocument;
var hgt10 = doc.height / 10;
var FillColor = new SolidColor;
FillColor.rgb.hexValue = 'ff0000';
var newHgt = doc.height + hgt10
doc.resizeCanvas(doc.width, newHgt, AnchorPosition.TOPCENTER);
var win = new Window('dialog', "Custom Text");
var grp1 = win.add('group');
grp1.alignChildren = "top";
var txt = grp1.add('edittext', [0, 0, 300, 150], "Write your message", {multiline: true, scrolling: true});
txt.active = true;
var grp2 = win.add('group');
var goBtn = grp2.add('button', undefined, "Run");
grp2.add('button', undefined, "Cancel");
var newLyr = doc.artLayers.add();
newLyr.kind = LayerKind.TEXT;
// CONTENTS
var txtLyr = newLyr.textItem
txtLyr.font = "ArialMT"
txtLyr.contents = txt.text
var uV = new UnitValue(20,'mm')
txtLyr.size = UnitValue(25,'mm')
txtLyr.color = FillColor;
txtLyr.position = [25, 2200] // x, y - Need to fix position to fit in the lower 10%
goBtn.onClick = function() {
win.close();
}
win.show();
So the areas I would like some assistance with is:
1) Getting the text to be positioned in the new area (created by the resizeCanvas argument extending by 10%)
2) Adding line breaks and automatically sizing to fit a variety of length text files into the field.
Kind Regards,
To add line breaks, replace all \ns with \rs (at least for Windows, I have a feeling that this Mac version may require something else, but I'm not sure):
txtLyr.contents = txt.text.replace(/\n/gm, '\r')
To position text you need to know the size (that'll depend on lines number) and leading.
var lines = txt.text.split('\n'); //getting the number of lines
var maxSize = hgt10 / lines.length; //calculating max size for a line (including the leading) = 10% of doc height devided by lines number
newLyr.textItem.useAutoLeading = true // making sure that text uses autoleading
var leading = newLyr.textItem.autoLeadingAmount; //autoleading value is in % of text size
maxSize = maxSize / leading * 100; // recalculating text size based on leading in pixels
txtLyr.size = maxSize;
txtLyr.position = [25, originalDocHeight + maxSize]
Result with one line and with several lines:

Images not displaying the first time in this object program in JS

I am making a battleship game with polar coordinates. After the user chooses two points, a battleship should be drawn in the middle. My Battleship constructor looks like this:
function Battleship(size, location, source){
this.size = size;
//initializing the image
this.image = new Image();
this.image.src = source;
this.getMiddlePoint = function(){
//get midpoint of ship
...
}
this.distanceBetween = function(t1, t2){
//dist between two points
}
this.display = function(){
var point = [this.radius];
point.push(this.getMiddlePoint());
point = polarToReal(point[0], point[1] * Math.PI / 12);
//now point has canvas coordinates of midpoint
var width = this.distanceBetween(this.info[0][0], this.info[this.info.length-1][0]);
var ratio = this.image.width / width;
ctx.drawImage(this.image, point[0] - width/2, point[1] - this.image.height / ratio / 2, width, this.image.height / ratio);
//draws the image
}
}
The display method of each ship gets called at a certain point (after the user has chosen the location). For some reason, the images do not show the first time I do this, but when I run this code at the very end:
for(var i = 0; i<playerMap.ships.length; i++){
playerMap.ships[i].display();
}
All ships are displayed correctly (not aligned well, but they are displayed). I think there is a problem with loading the images. I am not sure how to fix this. I tried using image.onload but I never got that to work. I also tried something like this:
var loadImage = function (url, ctx) {
var img = new Image();
img.src = url
img.onload = function () {
ctx.drawImage(img, 0, 0);
}
}
but the same problem kept happening. Please help me fix this problem. Here is the game in its current condition. If you place ships, nothing happens, but after you place 5 (or 10) ships, they suddenly all load.
EDIT:
I solved the problem by globally defining the images. This is still very bad practice, since I wanted this to be in the battleship object. This is my (temporary) solution:
var sub = [];
for(var i = 1; i<5; i++){
sub[i] = new Image();
sub[i].src = "/img/ships/battleship_"+i+".png";
}

How can make random images come out from the holes in Whack-a-Mole game instead of one image

I was wondering would someone be able to help me to show me a way to be able to bring out random images from the holes instead of one image in a Whack a mole game on Javascript.
The following is the function used for an image to come up in random holes. Currently its only one image but I'd like it to be about 10 different images coming out.
var wormImg = new Image();
var worm;
wormImg.src = 'hobby.png';
wormImg.name = 'worm';
wormImg.onload = loadGfx;
function showWorm()
{
if(currentWorms == totalWorms)
{
showAlert();
}
else
{
if(lastWorm != null)
{
lastWorm.onPress = null;
stage.removeChild(lastWorm);
stage.update();
lastWorm = null;
}
var randomPos = Math.floor(Math.random() * 8);
var worm = new Bitmap (wormImg);
worm.x = wormsX[randomPos];
worm.y = wormsY[randomPos];
stage.addChild(worm);
worm.onPress = wormHit;
lastWorm = worm;
lastWorm.scaleY = 0.3;
lastWorm.y += 42;
stage.update();
Tween.get(lastWorm).to({scaleY: 1, y: wormsY[randomPos]}, 200).wait(1000).call(function(){currentWorms++; showWorm()});
}
}
I would appreciate any help, thank you for your time.
You could create an array of possible values for worm.src, and randomly select one whenever showing a new worm

Keeping a portion of an image always visible on the canvas

I want to make sure that my instance of fabric.Image is always visible.
It doesn't need to be 100% visible, but a portion of it should always be seen. I've seen a few other questions that are similar and I've based my solution on them, but I haven't found anything that completely solves the problem.
My current solution works when no rotation (angles) have been applied to the image. If the angle is at 0 then this solution is perfect, but once the angle start changing I'm having problems.
this.canvas.on('object:moving', function (e) {
var obj = e.target;
obj.setCoords();
var boundingRect = obj.getBoundingRect();
var max_pad_left_over_width = 50;//obj.currentWidth * .08;
var max_pad_left_over_height = 50;//obj.currentHeight * .08;
var max_top_pos = -(obj.currentHeight - max_pad_left_over_height);
var max_bottom_pos = obj.canvas.height - max_pad_left_over_height;
var max_left_pos = -(obj.currentWidth - max_pad_left_over_width);
var max_right_pos = obj.canvas.width - max_pad_left_over_width;
if(boundingRect.top < max_top_pos) {
obj.setTop(max_top_pos);
}
if(boundingRect.left < max_left_pos){
obj.setLeft(max_left_pos);
}
if(boundingRect.top > max_bottom_pos) {
obj.setTop(max_bottom_pos);
}
if(boundingRect.left > max_right_pos) {
obj.setLeft(max_right_pos);
}
});
I've created an example: https://jsfiddle.net/krio/wg0aL8ef/24/
Notice how when no rotation (angle) is applied you cannot force the image to leave the visible canvas. Now, add some rotation to the image and move it around. How can I get the rotated image to also always stay within view? Thanks.
Fabric.js provides with two object properties isContainedWithinRect and intersectsWithRect which we can use to solve the problem.
An object should not be allowed to go outside the canvas boundaries. This can be achieved if we somehow manage to make sure that the object is either inside the canvas, or at least intersects with the canvas boundaries.
For this case, since you want some portion of the image inside the canvas, we will take a rect smaller than the canvas instead of canvas boundaries to be the containing rect of the image.
Using the properties mentioned to make sure that the above two conditions are satisfied after any movement. Here's how the code looks like:
var canvas = new fabric.Canvas('c');
var imgElement = document.getElementById('my-img');
var imgInstance = new fabric.Image(imgElement, {
top: 0,
left: 0
});
imgInstance.setScaleX(0.6);
imgInstance.setScaleY(0.6);
canvas.add(imgInstance);
var prevLeft = 0,
prevTop = 0;
var max_pad_left_over_width = imgInstance.currentWidth * .08;
var max_pad_left_over_height = imgInstance.currentHeight * .08;
var max_top_pos = max_pad_left_over_height;
var max_bottom_pos = imgInstance.canvas.height - max_pad_left_over_height;
var max_left_pos = max_pad_left_over_width;
var max_right_pos = imgInstance.canvas.width - max_pad_left_over_width;
var pointTL = new fabric.Point(max_left_pos, max_top_pos);
var pointBR = new fabric.Point(max_right_pos, max_bottom_pos);
canvas.on('object:moving', function(e) {
var obj = e.target;
obj.setCoords();
if (!obj.intersectsWithRect(pointTL, pointBR) && !obj.isContainedWithinRect(pointTL, pointBR)) {
obj.setTop(prevTop);
obj.setLeft(prevLeft);
}
prevLeft = obj.left;
prevTop = obj.top;
});
Here's the link to the fiddle: https://jsfiddle.net/1ghvjxbk/ and documentation where these properties are mentioned.

Categories