I am trying to achieve a simple thing - I need a text within a circle (or different path shape) and treat them as a single "object". I thought that the Group object is the best solution for it. However, the paperjs behaves strange once I add a PointText into the group.
Please check this sketch.
If there is the text in the group
new Group([circle, text])
The result of clicking on the circle is only
event.item = Group #83
But if you do not add the text into the group, then the result is
event.item = Group #87
hit2.item = Group #87
So for whatever reason if there is a text in the group, then the result of hitTest is null.
Do you see, please, if there is a bug in my code or in the library itself?
Indeed, this is weird and it looks like a bug in the library itself.
Could you please post it as a new issue here: https://github.com/paperjs/paper.js/issues, we'll try to fix it as soon as possible.
As a workaround, if you know that your text is contained within the other shape, you could simply do the hit testing on the other shape directly rather than on the group:
var hit2 = circle.hitTest(event.point);
Edit
Actually, I noticed that this also work if you call the hit testing on the group directly:
var hit2 = group.hitTest(event.point);
Related
This is a simple problem (I am new to JavaScript and have a limited knowledge of the syntax and using arrays etc.), so I am sure someone more knowledgeable will be able to advise the simplest solution fairly easily!
I would like to replace a number of text placeholders in an existing Google Doc template with variable text inputs, which I ultimately plan to populate from one or more external sources via APIs (such as a form).
function replaceAllPlaceholders() {
var body = DocumentApp.getActiveDocument().getBody(); //defines the range within which to replace text
body.replaceText('placeholder1', 'replacement1');
body.replaceText('placeholder2', 'replacement2');
body.replaceText('placeholder3', 'replacement3');
// ...
body.replaceText('placeholder98', 'replacement98');
body.replaceText('placeholder99', 'replacement99'); }
Rather than repeat the replaceText( function for each replacement as I have done above, how can I instead layout the information out as an array of placeholder:replacement pairs, and then loop through each?
// for example something like this (pseudo):
//
// var obj = {
// 'placeholder1': 'replacement1' // I would like to keep open the option to retrieve this array from an external source instead
// 'placeholder2': 'replacement2'
// 'placeholder3': 'replacement3' };
//
// body.replaceText(*all placeholders*,*all replacements*);
I imagine this would allow greater flexibility in editing the set of placeholders and or replacements going forward, either directly within Google Apps Script or by replacing the whole array to one retrieved from an external source (as well as reducing the code required). The problem is I have not been able to figure out the correct method to do this. Any suggestions?
Alternatively, is there a better way to achieve my goal?
I am open to all recommendations!
Try this
var placeholders = [
['placeholder1', 'replacement1'],
['placeholder2', 'replacement2'],
['placeholder3', 'replacement3']
];
placeholders.forEach(function(pair) {
body.replaceText(pair[0], pair[1]);
});
I write a small chrome extension which includes adding buttons add specific positions.
These positions are mostly random and can't be determined with normal css/jQuery selectors.
I need to scan the whole page for a certain text pattern (regex).
After I found matches I need to get the dom tag where the text is in.
I tried parsing the whole source with body.innerHtml but I cant get the tag obj afterwards.
Any ideas on how to accomplish such a task are highly appreciated!
Sounds like you could use :contains() for this.
$(":contains('Your Text')")
For finding text using a regular expression use .filter()
var regex = new RegExp("Your Text");
$("*").filter(function () {
return regex.test($(this).text());
});
Using the Office Javascript API, I want to be able to select the current sentence in Word. By current sentence, I mean identifying where the caret position is, then iterating from that position to get the full sentence.
However, looking at the available API calls (such as getSelectedData), this does not seem possible, as there doesn't seem to be a way to get the current caret position.
I know when creating a C# project, you could use 'Microsoft.Office.Interop.Word.Range' and 'Selection.Range' to get a range, which you could use as a caret position.
Am I wrong or can you not get the caret position using the Javascript API?
Late but maybe still helpful for someone:
You can achieve this by combining getSelection() and getTextRanges([separators])on a document - this expands the current selection in both directions, until any of the characters in the list of separators is found.
Documentation for getTextRanges: https://dev.office.com/reference/add-ins/word/range
Example (typescript):
Word.run(context => {
let sentences = context.document.getSelection().getTextRanges(['\n', '.', '?'], false);
context.load(sentences);
context.sync().then(() => {
console.log(sentences.items);
}
return context.sync();
}
I need to replace some images in an InDesign document with a given file. This happens using the InDesign server, but scripting is almost the same as with regular InDesign, except no user interaction is possible.
What I have is a InDesign Document, the ID of an Rectangle containing some image and the Path to a new image that should replace the image.
The image should be replaced, but the settings like FitOptions etc. should stay the same. Also, the new file shall be embedded in the InDesign Document. There is already some code that sort of works:
function changeImages(doc) {
var arrayLength = changeImage.length;
for (var i = 0; i < arrayLength; i++) {
var fr = doc.textFrames.itemByID(1 * changeImage[i].id);
if (!fr)
continue;
var file = File(imagePath + changeImage[i].file);
fr.place(file);
fr.fit (FitOptions.CONTENT_TO_FRAME);
fr.fit (FitOptions.PROPORTIONALLY);
fr.fit (FitOptions.CENTER_CONTENT);
}
}
This doesn't seem right. Why is it using doc.textFrames when the object is a rectangle? I am actually confused this even works.
Also it just sets some FitOptions, but I want to keep the existing.
I am very new to InDesign scripting, so I am lost here. I am reading the docs and other resources, but I am confused. e.g why is there doc.textFrames.itemByID but nothing like that for other Frames? Do I have to iterate doc.allPageItems and compare ids?
itemByID is a method available for all pageItems and both textFrames and rectangles are subclass of pageItem. So you have access to this method from both, and it'll give the same result. You should be able to use doc.rectangles.itemByID as well. See: http://www.indesignjs.de/extendscriptAPI/indesign11/#Rectangles.html#d1e201999__d1e202138
But you are right that the description is a bit confusing, it says:
Returns the TextFrame with the specified ID.
which is obviously not the case. If you already have the IDs you want to target, you could use doc.pageItems.itemByID, which is maybe less confusing, since basically you're looking for pageItems when using itemByID.
As for fitting options, they are a property of your rectangle object, so placing a new image shouldn't change the fitting options. If you want to keep the same, simply remove the calls to fit(). See in property list of Rectangle, frameFittingOptions: http://www.indesignjs.de/extendscriptAPI/indesign11/#Rectangle.html
Josef,
I've had the same problem with InDesign CS4 with keeping the original FitOptions. I was never able to figure out how to get the settings currently being used in InDesign CS4.
To get around the problem what I did was to set the value in the Fitting on Empty Frame in the Frame Fitting Options in the InDesign document.
Then in code I used that setting, something like this:
changeImages (app.activeDocument);
function changeImages(doc)
{
with(doc)
{
var rec = doc.rectangles.itemByID(207);
var file = new File("c:\\new_image.png");
rec.place(file);
rec.fit(rec.frameFittingOptions.fittingOnEmptyFrame);
}
}
I'm trying to create a little free-hand drawing app, and to figure out a way to add path segments (e.g. "L10,10") to a Raphael path Element. This answer suggests that isn't possible.
I've tried doing something like:
var e = paper.path("M0,0L100,100")
e.attr("path").push(["L",50,100])
...which does alter the array returned by e.attr("path") but doesn't change the graphic, so I guess this isn't supported behavior.
It looks like you have to call the setter version of .attr() to update the display. The following seems to work:
var e = paper.path("M0,0L100,100");
e.attr("path").push(["L",50,100]);
e.attr("path", e.attr("path"));
although this does look pretty clumsy. I don't really see a better way to do it using push(), though.
After looking through the Raphael 2 source I figured out a method to create an incremental path efficiently, by:
initializing the path using the Raphael API w/ elem = paper.path()
attaching the mousemove handler to alter the SVG DOM path directly, via elem.node.setAttribute("d", elem.node.getAttribute("d")+newLineSegment); Raphael uses the 'd' attribute to set path string internally so this should be cross-browser compatible AFAICT (Update: actually I'm mistaken; this only works for the SVG-compatible browsers, not VML), while bypassing a whole mess of code we don't need to have run on an inner loop
when done drawing, set the path attribute for the path element explicitly through Raphael's API, so it can do all the proper housekeeping on the Element e.g.: elem.attr( {path: elem.node.getAttribute("d") })
This performs reasonably well on Chrome, and other modern browsers I tested on.
I've finished a jQuery UI widget for a sketchpad that uses this. Please leave a comment if you would find such a thing useful as open source. If there's interest I'll see if I can make that happen.
I can conform that this works:
var arr = somePath.attrs.path;
arr.push(["L", x, y]);
somePath.attr({path: arr});