Skip to main content
PESDK/Web/Features

Frames

The PhotoEditor SDK for Web provides a quick and easy way for adding frames to any creative. Learn how to add custom frame assets to the library.

Frames tool

Good frames might not save bad paintings, however they may very well complete and enhance good photography. The PhotoEditor SDK includes a versatile frame tool that works with any given photo size or ratio. For the flexible frames tool that works perfectly for creatives with repeatable or stretchable areas, we abandoned the 9-patch standard and replaced it with a novel and even more flexible 12-patch layout.

Specifying the available frames#

In order to enable or disable specific frames, simply pass the items option to the frame tool configuration. The items will be displayed in the order mentioned by the configuration. Here is the list of default frame items.

const editor = await PhotoEditorSDKUI.init({
frame: {
items: [
{ identifier: 'imgly_frame_dia' },
{ identifier: 'imgly_frame_art_decor' },
{ identifier: 'imgly_frame_black_passepartout' },
{ identifier: 'imgly_frame_wood_passepartout' },
{ identifier: 'imgly_frame_lowpoly_shadow' },
],
},
});

Adding custom frames#

Frames consist of four groups. Each group has a start, middle and an end image. The start and end images are optional and for the middle image there are two modes, repeat and stretch, the latter being the default. These modes determine whether the asset should be stretched over the area, or if it should be repeated to fill up space. Please note that in repeat mode, assets are never cut off, but rather squeezed or stretched a bit, to fit in only complete copies of the asset. The four groups can be laid out in two layouts: horizontal-inside or vertical-inside. See the following images for clarification:

frame inside

The idea behind the naming is, that if you imagine a box that covers the right and left groups and the top and bottom groups surrounding it, the horizontal box is inside the groups, as illustrated by the following image,

frame horizontal

Let's have a look at a real world example.

dia sample

The layout mode is horizontal inside. The top and bottom group just have a middle image, containing the film strip pattern. The left and right group consist of a stretched border texture, and a start and end image to create a nice transition between the two sides of the film strip.

The code to create such a frame and pass it to the editor looks like this:

const editor = await PhotoEditorSDKUI.init({
frame: {
items: [
...,
{
identifier: 'my-new-generic-frame',
name: 'Generic',
thumbnailURI: 'frames/generic.png' // path to the thumbail, relative to the frame asset directory
layoutMode: 'horizontal-inside', // 'horizontal-inside' or 'vertical-inside'
tintable: false,
/**
* Images for the 12-patch layout of a dynamic frame that automatically adapts to
* any output image resolution
*/
imageGroups: {
top: {
mid: {
image: '..', // path to the image, relative to the frame asset directory
mode: 'repeat',
},
},
left: {
start: '..', // path to the image, relative to the frame asset directory
mid: '..', // path to the image, relative to the frame asset directory
end: '..', // path to the image, relative to the frame asset directory
},
right: {
start: '..', // path to the image, relative to the frame asset directory
mid: '..', // path to the image, relative to the frame asset directory
end: '..', // path to the image, relative to the frame asset directory
},
bottom: {
mid: {
image: '..', // path to the image, relative to the frame asset directory
mode: 'repeat',
},
},
}
}
]
}
})

Custom Default Color#

You can override the defalt color used in frame tool using the defaultColor option

await PhotoEditorSDKUI.init({
...,
frame: {
// color is represented as a number array which encodes
// as a RGBA tuple of floating point values where
// each channel is defined in the range of `[0, 1]
defaultColor: [1.00, 1.00, 1.00, 1],
},
...,
})

Custom Colors#

You can override all the colors used in frame tool using the colors array

await PhotoEditorSDKUI.init({
...,
frame: {
colors: [
{
// color is represented as a number array which encodes
// as a RGBA tuple of floating point values where
// each channel is defined in the range of `[0, 1]
color: [1.00, 1.00, 1.00, 1],
// name must be unique
name: "white",
},
{ color: [0.49, 0.49, 0.49, 1], name: "gray" },
{ color: [0.00, 0.00, 0.00, 1], name: "black" },
{ color: [0.40, 0.80, 1.00, 1], name: "light blue" },
{ color: [0.40, 0.53, 1.00, 1], name: "blue" },
{ color: [0.53, 0.40, 1.00, 1], name: "purple" },
{ color: [0.87, 0.40, 1.00, 1], name: "orchid" },
{ color: [1.00, 0.40, 0.80, 1], name: "pink" },
{ color: [0.90, 0.31, 0.31, 1], name: "red" },
{ color: [0.95, 0.53, 0.33, 1], name: "orange" },
{ color: [1.00, 0.80, 0.40, 1], name: "gold" },
{ color: [1.00, 0.97, 0.39, 1], name: "yellow" },
{ color: [0.80, 1.00, 0.40, 1], name: "olive" },
{ color: [0.33, 1.00, 0.53, 1], name: "green" },
{ color: [0.33, 1.00, 0.92, 1], name: "aquamarin" },
]
},
...,
})

Toolbar Customization#

This option allows you to reorder or remove items from the ToolControlBar in the AdvancedUI or the tabs in the BasicUI.

You can find more information on this option in our Toolbar Customization section.

const editor = await PhotoEditorSDKUI.init({
frame: {
advancedUIToolControlBarOrder: [
{
type: AdvancedFrameControlBarItem.Expandable,
children: [
AdvancedFrameControlBarItem.RemoveFrameButton,
AdvancedFrameControlBarItem.FrameOpacitySlider,
AdvancedFrameControlBarItem.FrameSizeSlider,
AdvancedFrameControlBarItem.FrameColorList,
AdvancedFrameControlBarItem.Separator,
],
},
AdvancedFrameControlBarItem.Items,
],
basicUIToolControlBarTabsOrder: [
BasicFrameControlBarTabs.FrameOpacity,
BasicFrameControlBarTabs.FrameSize,
BasicFrameControlBarTabs.FrameColor,
],
},
});

Localization#

You can override all the labels used in frames tool using the custom.languages object in configuration, below are the default frames localization lables

await PhotoEditorSDKUI.init({
// ...,
custom: {
languages: {
en: {
// ...,
frame: {
title: 'Frames',
controls: {
buttonReset: 'Reset Frame',
// Relevant for AdvancedUI
sliderOpacity: 'Frame Opacity',
sliderSize: 'Frame Size',
selectColor: 'Frame Color',
// Relevant for BasicUI
tabColor: 'Color',
tabOpacity: 'Opacity',
tabSize: 'Size',
},
items: {
imgly_frame_dia: 'Dia',
imgly_frame_art_decor: 'Art Decor',
imgly_frame_black_passepartout: 'Black',
imgly_frame_lowpoly_shadow: 'Low Poly',
imgly_frame_wood_passepartout: 'Wood',
},
},
},
},
},
});