Skip to content

Commit

Permalink
v1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
falkolab committed Nov 5, 2015
1 parent c6e4e40 commit a62cf24
Show file tree
Hide file tree
Showing 8 changed files with 321 additions and 15 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Build folder and log file
build/
build.log
dist/
17 changes: 2 additions & 15 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -172,21 +172,9 @@
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.

Copyright (c) 2015 Andrey Tkachenko

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright {yyyy} {name of copyright owner}

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -199,4 +187,3 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

61 changes: 61 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Radio group Widget
![screenshot1](screenshot.png?raw=true "Example screenshot")

## Quick Start

### Get it
[![gitTio](http://gitt.io/badge.svg)](http://gitt.io/component/com.falkolab.maskedimage)


Download the latest distribution ZIP-file and consult the
[Titanium Documentation](http://docs.appcelerator.com/titanium/latest/#!/guide/Using_a_Module) on how install it, or simply use the [gitTio CLI](http://gitt.io/cli):

`$ gittio install com.falkolab.maskedimage`

## Usage

This module provide support form masking images for both iOS and Android.

For android support you must additionaly install `miga.tintimage` module.

`$ gittio install miga.tintimage`

Also you must install `com.geraudbourdin.svgview` if you planing to use SVG masks.

For test purposes you can use demo masks from this repository.

For both platform you can use `mode` attribute as string from list:

* `clear`
* `darken`
* `dst_atop`
* `dst_in`
* `dst_out`
* `dst_over`
* `lighten`
* `multiply`
* `overlay`
* `screen`
* `src_atop`
* `src_in`
* `src_out`
* `xor`

Or `MaskedImage` titanium ui view `mode` attribute constants **(only for ios)**.

#### Example

<Alloy>
<Window class="container" backgroundColor="#45474F">
<View width="300" height="240">
<MaskedImage module="com.falkolab.maskedimage"
image="/images/freewilly.jpg"
mask="/images/mask.svg"
mode="src_in"
/>
</View>
</Window>
</Alloy>


Give me a star if the widget was useful for you or
Binary file added demo_mask.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
58 changes: 58 additions & 0 deletions demo_mask.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
166 changes: 166 additions & 0 deletions maskedImage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
if(Ti.Platform.osname === 'iphone') {
var modesMap = {
// unknown: add, dst, src, src_over
'clear': Titanium.UI.iOS.BLEND_MODE_CLEAR,
'darken': Titanium.UI.iOS.BLEND_MODE_DARKEN,
'dst_atop': Titanium.UI.iOS.BLEND_MODE_DESTINATION_ATOP,
'dst_in': Titanium.UI.iOS.BLEND_MODE_DESTINATION_IN,
'dst_out': Titanium.UI.iOS.BLEND_MODE_DESTINATION_OUT,
'dst_over': Titanium.UI.iOS.BLEND_MODE_DESTINATION_OVER,
'lighten': Titanium.UI.iOS.BLEND_MODE_LIGHTEN,
'multiply': Titanium.UI.iOS.BLEND_MODE_MULTIPLY,
'overlay': Titanium.UI.iOS.BLEND_MODE_OVERLAY,
'screen': Titanium.UI.iOS.BLEND_MODE_SCREEN,
'src_atop': Titanium.UI.iOS.BLEND_MODE_SOURCE_ATOP,
'src_in': Titanium.UI.iOS.BLEND_MODE_SOURCE_IN,
'src_out': Titanium.UI.iOS.BLEND_MODE_SOURCE_OUT,
'xor': Titanium.UI.iOS.BLEND_MODE_XOR
// has not map
//Titanium.UI.iOS.BLEND_MODE_COLOR
//Titanium.UI.iOS.BLEND_MODE_COLOR_BURN
//Titanium.UI.iOS.BLEND_MODE_COLOR_DODGE
//Titanium.UI.iOS.BLEND_MODE_COPY
//Titanium.UI.iOS.BLEND_MODE_DIFFERENCE
//Titanium.UI.iOS.BLEND_MODE_EXCLUSION
//Titanium.UI.iOS.BLEND_MODE_HARD_LIGHT
//Titanium.UI.iOS.BLEND_MODE_HUE
//Titanium.UI.iOS.BLEND_MODE_LUMINOSITY
//Titanium.UI.iOS.BLEND_MODE_NORMAL
//Titanium.UI.iOS.BLEND_MODE_PLUS_DARKER
//Titanium.UI.iOS.BLEND_MODE_PLUS_LIGHTER
//Titanium.UI.iOS.BLEND_MODE_SATURATION
//Titanium.UI.iOS.BLEND_MODE_SOFT_LIGHT
};
}

function pick(obj) {
var copy = {};
var keys = Array.prototype.concat.apply(Array.prototype, Array.prototype.slice.call(arguments, 1));
keys.forEach(function(key) {
if ( key in obj)
copy[key] = obj[key];
});
return copy;
};

function omit(obj) {
var copy = {};
var keys = Array.prototype.concat.apply(Array.prototype, Array.prototype.slice.call(arguments, 1));
for (var key in obj) {
if (keys.indexOf(key) === -1)
copy[key] = obj[key];
}
return copy;
};

function getImageFileFromSVG(mask, width, height) {
var file = Ti.Filesystem.getFile(Ti.Filesystem.applicationCacheDirectory,
Ti.Utils.md5HexDigest(mask + width + height + 'maskedImage.mask'));

if (!file.exists()) {
var blob = require('com.geraudbourdin.svgview').createView({
image : mask,
width : width,
height : height,
left : 0,
top : 0
}).toImage();

if (!file.write(blob)) {
Ti.API.error("Can't save to file:", opts.mask);
return null;
}

if (Ti.Platform.osname === 'android') {
return blob;
} else if(Ti.Platform.osname === 'iphone') {
return file.getNativePath();
}
} else {
if (Ti.Platform.osname === 'android') {
// fix for tint module
return Ti.UI.createImageView({
image: file.read(),
width: Ti.UI.SIZE,
height: Ti.UI.SIZE
}).toBlob();
} else if(Ti.Platform.osname === 'iphone') {
return file.getNativePath();
}
}
return null;
}

exports.createMaskedImage = function(opts) {
var mask = opts.mask;

mask && (isSVGMask = mask.toLocaleLowerCase().indexOf('.svg') !== -1);

if (Ti.Platform.osname === 'android') {
var imageOpts = omit(opts, 'mode', 'mask');
typeof imageOpts.width === 'undefined' && (imageOpts.width = Ti.UI.FILL);
typeof imageOpts.height === 'undefined' && (imageOpts.height = Ti.UI.FILL);

var view = Ti.UI.createImageView(imageOpts);
imageOpts = undefined;

if (opts.mask) {
var tintOpts = pick(opts, 'tint', 'mode', 'modeImage', 'mask');
tintOpts.imageOverlay = view.toBlob();

if(typeof tintOpts.mode !== 'undefined') {
tintOpts.modeColor = tintOpts.mode;
delete tintOpts.mode;
}

if(typeof tintOpts.tint !== 'undefined') {
Ti.API.warn("'tint' not supported yet!");
//tintOpts.color = tintOpts.tint;
//delete tintOpts.tint;
}

if (isSVGMask) {
var max = Math.max(tintOpts.imageOverlay.width, tintOpts.imageOverlay.height);
tintOpts.image = getImageFileFromSVG(opts.mask,
opts.maskWidth || max,
opts.maskHeight || max);
} else {
tintOpts.image = Ti.UI.createImageView({
image: opts.mask,
width: Ti.UI.SIZE,
height: Ti.UI.SIZE
}).toBlob();
}

tintOpts.image = tintOpts.image.imageAsResized(tintOpts.imageOverlay.width, tintOpts.imageOverlay.height);
view.image = require("miga.tintimage").tint(tintOpts);
}
return view;
} else if (Ti.Platform.osname === 'iphone') {
var maskedImageOpts = omit(opts); // like copy

if(typeof maskedImageOpts.mode === 'string') {
maskedImageOpts.mode = modesMap[maskedImageOpts.mode];
if(typeof maskedImageOpts.mode == 'undefined') {
throw "Unknown mode";
}
}

if (opts.mask) {
if(isSVGMask) {
var max;
if(typeof opts.maskWidth === 'undefined' || typeof opts.maskHeight === 'undefined') {
var size = pick(Ti.UI.createImageView({
image : opts.image,
width : Ti.UI.SIZE,
height : Ti.UI.SIZE
}).toBlob(), 'width', 'height');
max = Math.max(size.width, size.height);
}
maskedImageOpts.mask = getImageFileFromSVG(opts.mask, opts.maskWidth || max, opts.maskHeight || max);
}
}
return Titanium.UI.createMaskedImage(omit(maskedImageOpts, 'maskWidth', 'maskHeight'));
}
return null;
};
33 changes: 33 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "titanium-maskedimage",
"version": "1.0.0",
"description": "Cross platform implementation MaskedImage for Titanium SDK",
"main": "maskedImage.js",
"titaniumManifest": {
"name": "Ttitanium Masked Image",
"moduleid": "com.falkolab.maskedimage",
"guid": "f811b74f-a319-ee95-e6ee-c4b36d36924e"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"peerDependencies": {
"com.geraudbourdin.svgview": "~1.2.1",
"miga.tintimage": "~1.2"
},
"repository": {
"type": "git",
"url": "git+https://github.com/falkolab/com.falkolab.maskedimage.git"
},
"keywords": [
"maskedimage",
"commonjs",
"titaniumifier"
],
"author": "Andrey Tkachenko",
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/falkolab/com.falkolab.maskedimage/issues"
},
"homepage": "https://github.com/falkolab/com.falkolab.maskedimage#readme"
}
Binary file added screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit a62cf24

Please sign in to comment.