compass-blend-modes 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/LICENSE +22 -0
- data/README.md +115 -0
- data/compass-blend-modes.gemspec +23 -0
- data/example/config.rb +25 -0
- data/example/i/colorblend.png +0 -0
- data/example/i/colorburn.png +0 -0
- data/example/i/colordodge.png +0 -0
- data/example/i/darken.png +0 -0
- data/example/i/difference.png +0 -0
- data/example/i/dissolve.png +0 -0
- data/example/i/divide.png +0 -0
- data/example/i/exclusion.png +0 -0
- data/example/i/hardlight.png +0 -0
- data/example/i/hardmix.png +0 -0
- data/example/i/hue.png +0 -0
- data/example/i/lighten.png +0 -0
- data/example/i/linearburn.png +0 -0
- data/example/i/lineardodge.png +0 -0
- data/example/i/linearlight.png +0 -0
- data/example/i/luminosity.png +0 -0
- data/example/i/multiply.png +0 -0
- data/example/i/normal.png +0 -0
- data/example/i/overlay.png +0 -0
- data/example/i/pinlight.png +0 -0
- data/example/i/saturation.png +0 -0
- data/example/i/screen.png +0 -0
- data/example/i/softlight.png +0 -0
- data/example/i/subtract.png +0 -0
- data/example/i/vividlight.png +0 -0
- data/example/index.html +74 -0
- data/example/js/blend-modes.js +459 -0
- data/example/scss/styles.scss +39 -0
- data/lib/compass-blend-modes.rb +2 -0
- data/lib/compass/blend-modes.rb +7 -0
- data/lib/compass/blend-modes/version.rb +5 -0
- data/stylesheets/_blend-modes.scss +528 -0
- data/templates/project/manifest.rb +2 -0
- data/templates/project/screen.scss +11 -0
- metadata +97 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2d3c932a487f9195ac257617fc222ddde6121054
|
4
|
+
data.tar.gz: bea92af29b2bc5d8d7723c26103d919f5595a4f9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b967d38d8411e0a7d3edc2c7e2aaf247d0251e570a29c0d633076353abd12d64701d1d2ccd2264f48161406aaca5dbc09c803ed1687cb899fa0717d7581bdb16
|
7
|
+
data.tar.gz: f1e5d56987cb7f80c895d04f53a9a4ef6726eb100b675f25e6f206a34e7dcfc92fef757db5e7ef026ce99107b1491f77ea6ebe0b2ef0ac4fbb26aced244eb4e6
|
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Grady Kuhnline
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
# SCSS Blend Modes
|
2
|
+
CSS doesn't natively support color blending the way that Photoshop does. This library attempts to fake that by allowing you to blend a foreground color with a background color in order to approximate color blending. This not a dynamic blend; you can't use this to blend a color with an image. This was originally intended for use with the [Compass Photoshop Drop Shadow Plugin](https://github.com/heygrady/compass-photoshop-drop-shadow) but it proved impractical to integrate.
|
3
|
+
|
4
|
+
## A Note on Real CSS3 Blend Modes
|
5
|
+
Adobe has been working on a [W3C spec](http://www.w3.org/TR/compositing/) to [add blend modes to CSS3](http://blogs.adobe.com/webplatform/2012/04/04/bringing-blending-to-the-web/). However, this has [not been implemented in any browser](http://css3clickchart.com/#blending-modes). This library is **not** a polyfill for those blend modes. A polyfill for real, dynamic blend modes will require SVG or JavaScript + Canvas.
|
6
|
+
|
7
|
+
## A Note on Color Blending
|
8
|
+
The included functions are based on [blend.js](https://github.com/jseidelin/pixastic/blob/master/actions/blend.js) from the [Pixastic Image Processing Library](http://www.pixastic.com/lib/). I chose this library because JavaScript is easy enough to read and the blend modes seemed to match closely with what Photoshop offered. Additionally, a [detailed explaination of Photoshop blend modes](http://photoblogstop.com/photoshop/photoshop-blend-modes-explained) was used as a reference as well as the [Wikipedia article on blend modes](http://en.wikipedia.org/wiki/Blend_modes).
|
9
|
+
|
10
|
+
These blend mode functions are not magic. In Photoshop, the blend mode functions are applied dynamically between two layers in order to create a pixel-by-pixel blend. In CSS they can only be used to combine two solid colors together. Blend modes can be useful in times when a Photoshop design implements a blend mode on an element, like a drop shadow, that is over a mostly solid background. Choosing a dominant background color and a solid foreground color may allow for the apearance of a dynamically blended color.
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
#### Install the Ruby Gem.
|
14
|
+
```
|
15
|
+
gem install compass-blend-modes
|
16
|
+
```
|
17
|
+
|
18
|
+
#### Existing Compass Projects
|
19
|
+
You can include it in any existing Compass project by including the plugin in your config.rb file.
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
# Require any additional compass plugins here.
|
23
|
+
require 'compass-blend-modes'
|
24
|
+
```
|
25
|
+
|
26
|
+
#### New Compass Projects
|
27
|
+
You can install the plugin as part of a new Compass project.
|
28
|
+
|
29
|
+
```
|
30
|
+
compass create my_project -r compass-blend-modes
|
31
|
+
```
|
32
|
+
|
33
|
+
## Usage
|
34
|
+
|
35
|
+
```scss
|
36
|
+
@import 'blend-modes';
|
37
|
+
```
|
38
|
+
|
39
|
+
### Examples
|
40
|
+
|
41
|
+
```scss
|
42
|
+
// make sure the functions are imported
|
43
|
+
@import 'blend-modes';
|
44
|
+
|
45
|
+
// Solid background
|
46
|
+
.multiply {
|
47
|
+
background-color: blend-multiply(#7FFFD4, #DEB887);
|
48
|
+
}
|
49
|
+
|
50
|
+
// RGBa background
|
51
|
+
.multiply {
|
52
|
+
background-color: blend-multiply(rgba(#7FFFD4, 0.5), rgba(#DEB887, 0.5));
|
53
|
+
}
|
54
|
+
```
|
55
|
+
|
56
|
+
## Blending Functions
|
57
|
+
All functions expect a color as the `$foreground` and `$background` colors. The colors can be any hex, [rgb](http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html#rgb-instance_method), [rgba](http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html#rgba-instance_method), [hsl](http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html#hsl-instance_method), or [hsla](http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html#hsla-instance_method) color supported by Sass. Blending functions work by combining the colors from the top-most layer, the `$foreground`, with the lower layer, the `$background`.
|
58
|
+
|
59
|
+
- **blend-normal(** *$foreground*, *$background* **)** - Normal is used primarily to preserve the opacity after the blending has been applied to the RGB values.
|
60
|
+
- **blend-multiply(** *$foreground*, *$background* **)**
|
61
|
+
- **blend-lighten(** *$foreground*, *$background* **)**
|
62
|
+
- **blend-darken(** *$foreground*, *$background* **)**
|
63
|
+
- **blend-darkercolor(** *$foreground*, *$background* **)** - Not found in Photoshop.
|
64
|
+
- **blend-lightercolor(** *$foreground*, *$background* **)** - Not found in Photoshop.
|
65
|
+
- **blend-lineardodge(** *$foreground*, *$background* **)**
|
66
|
+
- **blend-linearburn(** *$foreground*, *$background* **)**
|
67
|
+
- **blend-difference(** *$foreground*, *$background* **)**
|
68
|
+
- **blend-screen(** *$foreground*, *$background* **)**
|
69
|
+
- **blend-exclusion(** *$foreground*, *$background* **)**
|
70
|
+
- **blend-overlay(** *$foreground*, *$background* **)**
|
71
|
+
- **blend-softlight(** *$foreground*, *$background* **)**
|
72
|
+
- **blend-hardlight(** *$foreground*, *$background* **)**
|
73
|
+
- **blend-colordodge(** *$foreground*, *$background* **)**
|
74
|
+
- **blend-colorburn(** *$foreground*, *$background* **)**
|
75
|
+
- **blend-linearlight(** *$foreground*, *$background* **)**
|
76
|
+
- **blend-vividlight(** *$foreground*, *$background* **)**
|
77
|
+
- **blend-pinlight(** *$foreground*, *$background* **)**
|
78
|
+
- **blend-hardmix(** *$foreground*, *$background* **)**
|
79
|
+
- **blend-colorblend(** *$foreground*, *$background* **)**
|
80
|
+
- **blend-dissolve(** *$foreground*, *$background* **)** - Not implemented. Dissolve treats transparency as a pixel pattern and applies a diffusion dither pattern.
|
81
|
+
- **blend-divide(** *$foreground*, *$background* **)**
|
82
|
+
- **blend-hue(** *$foreground*, *$background* **)**
|
83
|
+
- **blend-luminosity(** *$foreground*, *$background* **)**
|
84
|
+
- **blend-saturation(** *$foreground*, *$background* **)**
|
85
|
+
- **blend-subtract(** *$foreground*, *$background* **)**
|
86
|
+
|
87
|
+
## HSV Functions
|
88
|
+
These functions are used to convert between RGB, HSL and HSV color formats. The HSV color format is not natively supported by CSS or Sass. These functions were taken directly from this [Gist](https://gist.github.com/1069204). HSV values are used to calculate the results for the `blend-colorblend`, `blend-hue`, `blend-luminosity` and `blend-saturation` functions.
|
89
|
+
|
90
|
+
- **hsv-to-hsl(** *$h*, [ *$s: 0*, *$v: 0* ] **)** - Converts a HSV color values into HSL color values. `$h` can be a list of three values representing `$h`, `$s` and `$v`.
|
91
|
+
- **hsl-to-hsv(** *$h*, [ *$ss: 0*, *$ll: 0* ] **)** - Converts a HSL color values into HSV color values. `$h` can be a list of three values representing `$h`, `$ss` and `$ll`.
|
92
|
+
- **color-to-hsv(** *$color* )** - Converts a [Sass Color](http://sass-lang.com/docs/yardoc/Sass/Script/Color.html) into a [list](http://sass-lang.com/docs/yardoc/Sass/Script/List.html) HSV color values.
|
93
|
+
- **hsv-to-color(** *$h*, [* $s: 0*, *$v: 0* ] **)** - Converts a list of HSV color values into a Sass Color. `$h` can be a list of three values representing `$h`, `$s` and `$v`
|
94
|
+
|
95
|
+
## Internal Functions
|
96
|
+
These functions are used to save redundant code and are not meant to be used directly. These functions perform the blending operation on a single r, g or b value.
|
97
|
+
|
98
|
+
**NOTE:** These functions are not intended to be used directly.
|
99
|
+
|
100
|
+
- **blend-lighten-color(** *$foreground*, *$background* **)**
|
101
|
+
- **blend-darken-color(** *$foreground*, *$background* **)**
|
102
|
+
- **blend-lineardodge-color(** *$foreground*, *$background* **)**
|
103
|
+
- **blend-linearburn-color(** *$foreground*, *$background* **)**
|
104
|
+
- **blend-screen-color(** *$foreground*, *$background* **)**
|
105
|
+
- **blend-exclusion-color(** *$foreground*, *$background* **)**
|
106
|
+
- **blend-overlay-color(** *$foreground*, *$background* **)**
|
107
|
+
- **blend-softlight-color(** *$foreground*, *$background* **)**
|
108
|
+
- **blend-hardlight-color(** *$foreground*, *$background* **)**
|
109
|
+
- **blend-colordodge-color(** *$foreground*, *$background* **)**
|
110
|
+
- **blend-colorburn-color(** *$foreground*, *$background* **)**
|
111
|
+
- **blend-linearlight-color(** *$foreground*, *$background* **)**
|
112
|
+
- **blend-vividlight-color(** *$foreground*, *$background* **)**
|
113
|
+
- **blend-pinlight-color(** *$foreground*, *$background* **)**
|
114
|
+
- **blend-hardmix-color(** *$foreground*, *$background* **)**
|
115
|
+
- **blend-divide-color(** *$foreground*, *$background* **)**
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "compass/blend-modes/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'compass-blend-modes'
|
7
|
+
s.version = Compass::BlendModes::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.summary = "Using standard color blending functions in Sass."
|
10
|
+
s.description = "Using standard color blending functions in Sass."
|
11
|
+
s.homepage = "https://github.com/heygrady/scss-blend-modes"
|
12
|
+
s.authors = ["Grady Kuhnline"]
|
13
|
+
s.email = ["github@heygrady.net"]
|
14
|
+
s.license = 'MIT'
|
15
|
+
|
16
|
+
s.has_rdoc = false
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_dependency("compass")
|
23
|
+
end
|
data/example/config.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# Require any additional compass plugins here.
|
2
|
+
require 'compass-blend-modes'
|
3
|
+
|
4
|
+
# Set this to the root of your project when deployed:
|
5
|
+
http_path = "/"
|
6
|
+
css_dir = "css"
|
7
|
+
sass_dir = "scss"
|
8
|
+
images_dir = "i"
|
9
|
+
javascripts_dir = "js"
|
10
|
+
|
11
|
+
# You can select your preferred output style here (can be overridden via the command line):
|
12
|
+
output_style = :compact
|
13
|
+
|
14
|
+
# To enable relative paths to assets via compass helper functions. Uncomment:
|
15
|
+
relative_assets = true
|
16
|
+
|
17
|
+
# To disable debugging comments that display the original location of your selectors. Uncomment:
|
18
|
+
line_comments = false
|
19
|
+
|
20
|
+
|
21
|
+
# If you prefer the indented syntax, you might want to regenerate this
|
22
|
+
# project again passing --syntax sass, or you can uncomment this:
|
23
|
+
# preferred_syntax = :sass
|
24
|
+
# and then run:
|
25
|
+
# sass-convert -R --from scss --to sass sass scss && rm -rf sass && mv scss sass
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/example/i/hue.png
ADDED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/example/index.html
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
|
3
|
+
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
|
4
|
+
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
|
5
|
+
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
|
6
|
+
<head>
|
7
|
+
<meta charset="utf-8">
|
8
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
9
|
+
<title></title>
|
10
|
+
<meta name="description" content="">
|
11
|
+
<meta name="viewport" content="width=device-width">
|
12
|
+
|
13
|
+
<!-- Place favicon.ico and apple-touch-icon.png in the root directory -->
|
14
|
+
|
15
|
+
<link rel="stylesheet" href="css/styles.css">
|
16
|
+
<style>
|
17
|
+
h2 { clear: both; }
|
18
|
+
div { float:left; height: 100px; width: 100px; margin: 10px; }
|
19
|
+
</style>
|
20
|
+
</head>
|
21
|
+
<body>
|
22
|
+
<div class="foreground">foreground</div>
|
23
|
+
<div class="background">background</div>
|
24
|
+
<h2>SCSS Blend Modes</h2>
|
25
|
+
<div class="normal">normal</div>
|
26
|
+
<div class="multiply">multiply</div>
|
27
|
+
<div class="lighten">lighten</div>
|
28
|
+
<div class="darken">darken</div>
|
29
|
+
<div class="darkercolor">darkercolor</div>
|
30
|
+
<div class="lightercolor">lightercolor</div>
|
31
|
+
<div class="lineardodge">lineardodge</div>
|
32
|
+
<div class="linearburn">linearburn</div>
|
33
|
+
<div class="difference">difference</div>
|
34
|
+
<div class="screen">screen</div>
|
35
|
+
<div class="exclusion">exclusion</div>
|
36
|
+
<div class="overlay">overlay</div>
|
37
|
+
<div class="softlight">softlight</div>
|
38
|
+
<div class="hardlight">hardlight</div>
|
39
|
+
<div class="colordodge">colordodge</div>
|
40
|
+
<div class="colorburn">colorburn</div>
|
41
|
+
<div class="linearlight">linearlight</div>
|
42
|
+
<div class="vividlight">vividlight</div>
|
43
|
+
<div class="pinlight">pinlight</div>
|
44
|
+
<div class="hardmix">hardmix</div>
|
45
|
+
|
46
|
+
<h2>Photoshop</h2>
|
47
|
+
<div class="colorblend">colorblend</div>
|
48
|
+
<div class="dissolve">dissolve</div>
|
49
|
+
<div class="divide">divide</div>
|
50
|
+
<div class="hue">hue</div>
|
51
|
+
<div class="luminosity">luminosity</div>
|
52
|
+
<div class="saturation">saturation</div>
|
53
|
+
<div class="subtract">subtract</div>
|
54
|
+
|
55
|
+
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
|
56
|
+
<script src="js/blend-modes.js"></script>
|
57
|
+
<script>
|
58
|
+
var foreground = '#7FFFD4';
|
59
|
+
var background = '#DEB887';
|
60
|
+
|
61
|
+
$.each(['normal', 'multiply', 'lighten', 'darken', 'darkercolor', 'lightercolor', 'lineardodge', 'linearburn', 'difference', 'screen', 'exclusion', 'overlay', 'softlight', 'hardlight', 'colordodge', 'colorburn', 'linearlight', 'vividlight', 'pinlight', 'hardmix'], function(i, mode) {
|
62
|
+
var color = blend(mode, foreground, background);
|
63
|
+
$('.' + mode).after('<div style="background-color: ' + color + '">' + mode + ' JS</div>');
|
64
|
+
if (mode != 'darkercolor' && mode != 'lightercolor') {
|
65
|
+
$('.' + mode).after('<div style="background-image: url(i/' + mode + '.png)">' + mode + ' PS</div>');
|
66
|
+
}
|
67
|
+
});
|
68
|
+
|
69
|
+
$.each(['colorblend', 'dissolve', 'divide', 'hue', 'luminosity', 'saturation', 'subtract'], function(i, mode) {
|
70
|
+
$('.' + mode).after('<div style="background-image: url(i/' + mode + '.png)">' + mode + ' PS</div>');
|
71
|
+
});
|
72
|
+
</script>
|
73
|
+
</body>
|
74
|
+
</html>
|
@@ -0,0 +1,459 @@
|
|
1
|
+
/*
|
2
|
+
* Pixastic Lib - Blend - v0.1.1
|
3
|
+
* Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
|
4
|
+
* License: [http://www.pixastic.com/lib/license.txt]
|
5
|
+
*/
|
6
|
+
|
7
|
+
// NOTE: modified to blend 2 single pixels
|
8
|
+
|
9
|
+
// color conversions
|
10
|
+
function hex2rgba(h) {return [hexToR(h), hexToG(h),hexToB(h), 255]}
|
11
|
+
function hexToR(h) {return parseInt((cutHex(h)).substring(0,2),16)}
|
12
|
+
function hexToG(h) {return parseInt((cutHex(h)).substring(2,4),16)}
|
13
|
+
function hexToB(h) {return parseInt((cutHex(h)).substring(4,6),16)}
|
14
|
+
function cutHex(h) {return (h.charAt(0)=="#") ? h.substring(1,7):h}
|
15
|
+
function rgba2hex(color) {return '#' + (1 << 24 | color[0] << 16 | color[1] << 8 | color[2]).toString(16).substr(1);}
|
16
|
+
|
17
|
+
|
18
|
+
function blend(mode, foregroundColor, backgroundColor) {
|
19
|
+
var data = hex2rgba(backgroundColor);
|
20
|
+
var w = 1;
|
21
|
+
var h = 1;
|
22
|
+
|
23
|
+
|
24
|
+
var data2 = hex2rgba(foregroundColor);
|
25
|
+
|
26
|
+
var p = w*h;
|
27
|
+
var pix = p*4;
|
28
|
+
var pix1, pix2;
|
29
|
+
var r1, g1, b1;
|
30
|
+
var r2, g2, b2;
|
31
|
+
var r3, g3, b3;
|
32
|
+
var r4, g4, b4;
|
33
|
+
|
34
|
+
var dataChanged = false;
|
35
|
+
switch (mode) {
|
36
|
+
case "normal" :
|
37
|
+
//while (p--) {
|
38
|
+
// data2[pix-=4] = data2[pix];
|
39
|
+
// data2[pix1=pix+1] = data2[pix1];
|
40
|
+
// data2[pix2=pix+2] = data2[pix2];
|
41
|
+
//}
|
42
|
+
break;
|
43
|
+
|
44
|
+
case "multiply" :
|
45
|
+
while (p--) {
|
46
|
+
data2[pix-=4] = data[pix] * data2[pix] / 255;
|
47
|
+
data2[pix1=pix+1] = data[pix1] * data2[pix1] / 255;
|
48
|
+
data2[pix2=pix+2] = data[pix2] * data2[pix2] / 255;
|
49
|
+
}
|
50
|
+
dataChanged = true;
|
51
|
+
break;
|
52
|
+
|
53
|
+
case "lighten" :
|
54
|
+
while (p--) {
|
55
|
+
if ((r1 = data[pix-=4]) > data2[pix])
|
56
|
+
data2[pix] = r1;
|
57
|
+
if ((g1 = data[pix1=pix+1]) > data2[pix1])
|
58
|
+
data2[pix1] = g1;
|
59
|
+
if ((b1 = data[pix2=pix+2]) > data2[pix2])
|
60
|
+
data2[pix2] = b1;
|
61
|
+
}
|
62
|
+
dataChanged = true;
|
63
|
+
break;
|
64
|
+
|
65
|
+
case "darken" :
|
66
|
+
while (p--) {
|
67
|
+
if ((r1 = data[pix-=4]) < data2[pix])
|
68
|
+
data2[pix] = r1;
|
69
|
+
if ((g1 = data[pix1=pix+1]) < data2[pix1])
|
70
|
+
data2[pix1] = g1;
|
71
|
+
if ((b1 = data[pix2=pix+2]) < data2[pix2])
|
72
|
+
data2[pix2] = b1;
|
73
|
+
|
74
|
+
}
|
75
|
+
dataChanged = true;
|
76
|
+
break;
|
77
|
+
|
78
|
+
case "darkercolor" :
|
79
|
+
while (p--) {
|
80
|
+
if (((r1 = data[pix-=4])*0.3+(g1 = data[pix1=pix+1])*0.59+(b1 = data[pix2=pix+2])*0.11) <= (data2[pix]*0.3+data2[pix1]*0.59+data2[pix2]*0.11)) {
|
81
|
+
data2[pix] = r1;
|
82
|
+
data2[pix1] = g1;
|
83
|
+
data2[pix2] = b1;
|
84
|
+
}
|
85
|
+
}
|
86
|
+
dataChanged = true;
|
87
|
+
break;
|
88
|
+
|
89
|
+
case "lightercolor" :
|
90
|
+
while (p--) {
|
91
|
+
if (((r1 = data[pix-=4])*0.3+(g1 = data[pix1=pix+1])*0.59+(b1 = data[pix2=pix+2])*0.11) > (data2[pix]*0.3+data2[pix1]*0.59+data2[pix2]*0.11)) {
|
92
|
+
data2[pix] = r1;
|
93
|
+
data2[pix1] = g1;
|
94
|
+
data2[pix2] = b1;
|
95
|
+
}
|
96
|
+
}
|
97
|
+
dataChanged = true;
|
98
|
+
break;
|
99
|
+
|
100
|
+
case "lineardodge" :
|
101
|
+
/*
|
102
|
+
otherCtx.globalCompositeOperation = "source-over";
|
103
|
+
otherCtx.drawImage(params.canvas, 0, 0);
|
104
|
+
otherCtx.globalCompositeOperation = "lighter";
|
105
|
+
otherCtx.drawImage(image, 0, 0);
|
106
|
+
*/
|
107
|
+
|
108
|
+
while (p--) {
|
109
|
+
if ((r3 = data[pix-=4] + data2[pix]) > 255)
|
110
|
+
data2[pix] = 255;
|
111
|
+
else
|
112
|
+
data2[pix] = r3;
|
113
|
+
if ((g3 = data[pix1=pix+1] + data2[pix1]) > 255)
|
114
|
+
data2[pix1] = 255;
|
115
|
+
else
|
116
|
+
data2[pix1] = g3;
|
117
|
+
if ((b3 = data[pix2=pix+2] + data2[pix2]) > 255)
|
118
|
+
data2[pix2] = 255;
|
119
|
+
else
|
120
|
+
data2[pix2] = b3;
|
121
|
+
}
|
122
|
+
dataChanged = true;
|
123
|
+
|
124
|
+
break;
|
125
|
+
|
126
|
+
case "linearburn" :
|
127
|
+
while (p--) {
|
128
|
+
if ((r3 = data[pix-=4] + data2[pix]) < 255)
|
129
|
+
data2[pix] = 0;
|
130
|
+
else
|
131
|
+
data2[pix] = (r3 - 255);
|
132
|
+
if ((g3 = data[pix1=pix+1] + data2[pix1]) < 255)
|
133
|
+
data2[pix1] = 0;
|
134
|
+
else
|
135
|
+
data2[pix1] = (g3 - 255);
|
136
|
+
if ((b3 = data[pix2=pix+2] + data2[pix2]) < 255)
|
137
|
+
data2[pix2] = 0;
|
138
|
+
else
|
139
|
+
data2[pix2] = (b3 - 255);
|
140
|
+
}
|
141
|
+
dataChanged = true;
|
142
|
+
break;
|
143
|
+
|
144
|
+
case "difference" :
|
145
|
+
while (p--) {
|
146
|
+
if ((r3 = data[pix-=4] - data2[pix]) < 0)
|
147
|
+
data2[pix] = -r3;
|
148
|
+
else
|
149
|
+
data2[pix] = r3;
|
150
|
+
if ((g3 = data[pix1=pix+1] - data2[pix1]) < 0)
|
151
|
+
data2[pix1] = -g3;
|
152
|
+
else
|
153
|
+
data2[pix1] = g3;
|
154
|
+
if ((b3 = data[pix2=pix+2] - data2[pix2]) < 0)
|
155
|
+
data2[pix2] = -b3;
|
156
|
+
else
|
157
|
+
data2[pix2] = b3;
|
158
|
+
}
|
159
|
+
dataChanged = true;
|
160
|
+
break;
|
161
|
+
|
162
|
+
case "screen" :
|
163
|
+
while (p--) {
|
164
|
+
data2[pix-=4] = (255 - ( ((255-data2[pix])*(255-data[pix])) >> 8));
|
165
|
+
data2[pix1=pix+1] = (255 - ( ((255-data2[pix1])*(255-data[pix1])) >> 8));
|
166
|
+
data2[pix2=pix+2] = (255 - ( ((255-data2[pix2])*(255-data[pix2])) >> 8));
|
167
|
+
}
|
168
|
+
dataChanged = true;
|
169
|
+
break;
|
170
|
+
|
171
|
+
case "exclusion" :
|
172
|
+
var div_2_255 = 2 / 255;
|
173
|
+
while (p--) {
|
174
|
+
data2[pix-=4] = (r1 = data[pix]) - (r1 * div_2_255 - 1) * data2[pix];
|
175
|
+
data2[pix1=pix+1] = (g1 = data[pix1]) - (g1 * div_2_255 - 1) * data2[pix1];
|
176
|
+
data2[pix2=pix+2] = (b1 = data[pix2]) - (b1 * div_2_255 - 1) * data2[pix2];
|
177
|
+
}
|
178
|
+
dataChanged = true;
|
179
|
+
break;
|
180
|
+
|
181
|
+
case "overlay" :
|
182
|
+
var div_2_255 = 2 / 255;
|
183
|
+
while (p--) {
|
184
|
+
if ((r1 = data[pix-=4]) < 128)
|
185
|
+
data2[pix] = data2[pix]*r1*div_2_255;
|
186
|
+
else
|
187
|
+
data2[pix] = 255 - (255-data2[pix])*(255-r1)*div_2_255;
|
188
|
+
|
189
|
+
if ((g1 = data[pix1=pix+1]) < 128)
|
190
|
+
data2[pix1] = data2[pix1]*g1*div_2_255;
|
191
|
+
else
|
192
|
+
data2[pix1] = 255 - (255-data2[pix1])*(255-g1)*div_2_255;
|
193
|
+
|
194
|
+
if ((b1 = data[pix2=pix+2]) < 128)
|
195
|
+
data2[pix2] = data2[pix2]*b1*div_2_255;
|
196
|
+
else
|
197
|
+
data2[pix2] = 255 - (255-data2[pix2])*(255-b1)*div_2_255;
|
198
|
+
|
199
|
+
}
|
200
|
+
dataChanged = true;
|
201
|
+
break;
|
202
|
+
|
203
|
+
case "softlight" :
|
204
|
+
var div_2_255 = 2 / 255;
|
205
|
+
while (p--) {
|
206
|
+
if ((r1 = data[pix-=4]) < 128)
|
207
|
+
data2[pix] = ((data2[pix]>>1) + 64) * r1 * div_2_255;
|
208
|
+
else
|
209
|
+
data2[pix] = 255 - (191 - (data2[pix]>>1)) * (255-r1) * div_2_255;
|
210
|
+
|
211
|
+
if ((g1 = data[pix1=pix+1]) < 128)
|
212
|
+
data2[pix1] = ((data2[pix1]>>1)+64) * g1 * div_2_255;
|
213
|
+
else
|
214
|
+
data2[pix1] = 255 - (191 - (data2[pix1]>>1)) * (255-g1) * div_2_255;
|
215
|
+
|
216
|
+
if ((b1 = data[pix2=pix+2]) < 128)
|
217
|
+
data2[pix2] = ((data2[pix2]>>1)+64) * b1 * div_2_255;
|
218
|
+
else
|
219
|
+
data2[pix2] = 255 - (191 - (data2[pix2]>>1)) * (255-b1) * div_2_255;
|
220
|
+
|
221
|
+
}
|
222
|
+
dataChanged = true;
|
223
|
+
break;
|
224
|
+
|
225
|
+
case "hardlight" :
|
226
|
+
var div_2_255 = 2 / 255;
|
227
|
+
while (p--) {
|
228
|
+
if ((r2 = data2[pix-=4]) < 128)
|
229
|
+
data2[pix] = data[pix] * r2 * div_2_255;
|
230
|
+
else
|
231
|
+
data2[pix] = 255 - (255-data[pix]) * (255-r2) * div_2_255;
|
232
|
+
|
233
|
+
if ((g2 = data2[pix1=pix+1]) < 128)
|
234
|
+
data2[pix1] = data[pix1] * g2 * div_2_255;
|
235
|
+
else
|
236
|
+
data2[pix1] = 255 - (255-data[pix1]) * (255-g2) * div_2_255;
|
237
|
+
|
238
|
+
if ((b2 = data2[pix2=pix+2]) < 128)
|
239
|
+
data2[pix2] = data[pix2] * b2 * div_2_255;
|
240
|
+
else
|
241
|
+
data2[pix2] = 255 - (255-data[pix2]) * (255-b2) * div_2_255;
|
242
|
+
|
243
|
+
}
|
244
|
+
dataChanged = true;
|
245
|
+
break;
|
246
|
+
|
247
|
+
case "colordodge" :
|
248
|
+
while (p--) {
|
249
|
+
if ((r3 = (data[pix-=4]<<8)/(255-(r2 = data2[pix]))) > 255 || r2 == 255)
|
250
|
+
data2[pix] = 255;
|
251
|
+
else
|
252
|
+
data2[pix] = r3;
|
253
|
+
|
254
|
+
if ((g3 = (data[pix1=pix+1]<<8)/(255-(g2 = data2[pix1]))) > 255 || g2 == 255)
|
255
|
+
data2[pix1] = 255;
|
256
|
+
else
|
257
|
+
data2[pix1] = g3;
|
258
|
+
|
259
|
+
if ((b3 = (data[pix2=pix+2]<<8)/(255-(b2 = data2[pix2]))) > 255 || b2 == 255)
|
260
|
+
data2[pix2] = 255;
|
261
|
+
else
|
262
|
+
data2[pix2] = b3;
|
263
|
+
}
|
264
|
+
dataChanged = true;
|
265
|
+
break;
|
266
|
+
|
267
|
+
case "colorburn" :
|
268
|
+
while (p--) {
|
269
|
+
if ((r3 = 255-((255-data[pix-=4])<<8)/data2[pix]) < 0 || data2[pix] == 0)
|
270
|
+
data2[pix] = 0;
|
271
|
+
else
|
272
|
+
data2[pix] = r3;
|
273
|
+
|
274
|
+
if ((g3 = 255-((255-data[pix1=pix+1])<<8)/data2[pix1]) < 0 || data2[pix1] == 0)
|
275
|
+
data2[pix1] = 0;
|
276
|
+
else
|
277
|
+
data2[pix1] = g3;
|
278
|
+
|
279
|
+
if ((b3 = 255-((255-data[pix2=pix+2])<<8)/data2[pix2]) < 0 || data2[pix2] == 0)
|
280
|
+
data2[pix2] = 0;
|
281
|
+
else
|
282
|
+
data2[pix2] = b3;
|
283
|
+
}
|
284
|
+
dataChanged = true;
|
285
|
+
break;
|
286
|
+
|
287
|
+
case "linearlight" :
|
288
|
+
while (p--) {
|
289
|
+
if ( ((r3 = 2*(r2=data2[pix-=4])+data[pix]-256) < 0) || (r2 < 128 && r3 < 0)) {
|
290
|
+
data2[pix] = 0
|
291
|
+
} else {
|
292
|
+
if (r3 > 255)
|
293
|
+
data2[pix] = 255;
|
294
|
+
else
|
295
|
+
data2[pix] = r3;
|
296
|
+
}
|
297
|
+
if ( ((g3 = 2*(g2=data2[pix1=pix+1])+data[pix1]-256) < 0) || (g2 < 128 && g3 < 0)) {
|
298
|
+
data2[pix1] = 0
|
299
|
+
} else {
|
300
|
+
if (g3 > 255)
|
301
|
+
data2[pix1] = 255;
|
302
|
+
else
|
303
|
+
data2[pix1] = g3;
|
304
|
+
}
|
305
|
+
if ( ((b3 = 2*(b2=data2[pix2=pix+2])+data[pix2]-256) < 0) || (b2 < 128 && b3 < 0)) {
|
306
|
+
data2[pix2] = 0
|
307
|
+
} else {
|
308
|
+
if (b3 > 255)
|
309
|
+
data2[pix2] = 255;
|
310
|
+
else
|
311
|
+
data2[pix2] = b3;
|
312
|
+
}
|
313
|
+
}
|
314
|
+
dataChanged = true;
|
315
|
+
break;
|
316
|
+
|
317
|
+
case "vividlight" :
|
318
|
+
while (p--) {
|
319
|
+
if ((r2=data2[pix-=4]) < 128) {
|
320
|
+
if (r2) {
|
321
|
+
if ((r3 = 255 - ((255-data[pix])<<8) / (2*r2)) < 0)
|
322
|
+
data2[pix] = 0;
|
323
|
+
else
|
324
|
+
data2[pix] = r3
|
325
|
+
} else {
|
326
|
+
data2[pix] = 0;
|
327
|
+
}
|
328
|
+
} else if ((r3 = (r4=2*r2-256)) < 255) {
|
329
|
+
if ((r3 = (data[pix]<<8)/(255-r4)) > 255)
|
330
|
+
data2[pix] = 255;
|
331
|
+
else
|
332
|
+
data2[pix] = r3;
|
333
|
+
} else {
|
334
|
+
if (r3 < 0)
|
335
|
+
data2[pix] = 0;
|
336
|
+
else
|
337
|
+
data2[pix] = r3
|
338
|
+
}
|
339
|
+
|
340
|
+
if ((g2=data2[pix1=pix+1]) < 128) {
|
341
|
+
if (g2) {
|
342
|
+
if ((g3 = 255 - ((255-data[pix1])<<8) / (2*g2)) < 0)
|
343
|
+
data2[pix1] = 0;
|
344
|
+
else
|
345
|
+
data2[pix1] = g3;
|
346
|
+
} else {
|
347
|
+
data2[pix1] = 0;
|
348
|
+
}
|
349
|
+
} else if ((g3 = (g4=2*g2-256)) < 255) {
|
350
|
+
if ((g3 = (data[pix1]<<8)/(255-g4)) > 255)
|
351
|
+
data2[pix1] = 255;
|
352
|
+
else
|
353
|
+
data2[pix1] = g3;
|
354
|
+
} else {
|
355
|
+
if (g3 < 0)
|
356
|
+
data2[pix1] = 0;
|
357
|
+
else
|
358
|
+
data2[pix1] = g3;
|
359
|
+
}
|
360
|
+
|
361
|
+
if ((b2=data2[pix2=pix+2]) < 128) {
|
362
|
+
if (b2) {
|
363
|
+
if ((b3 = 255 - ((255-data[pix2])<<8) / (2*b2)) < 0)
|
364
|
+
data2[pix2] = 0;
|
365
|
+
else
|
366
|
+
data2[pix2] = b3;
|
367
|
+
} else {
|
368
|
+
data2[pix2] = 0;
|
369
|
+
}
|
370
|
+
} else if ((b3 = (b4=2*b2-256)) < 255) {
|
371
|
+
if ((b3 = (data[pix2]<<8)/(255-b4)) > 255)
|
372
|
+
data2[pix2] = 255;
|
373
|
+
else
|
374
|
+
data2[pix2] = b3;
|
375
|
+
} else {
|
376
|
+
if (b3 < 0)
|
377
|
+
data2[pix2] = 0;
|
378
|
+
else
|
379
|
+
data2[pix2] = b3;
|
380
|
+
}
|
381
|
+
}
|
382
|
+
dataChanged = true;
|
383
|
+
break;
|
384
|
+
|
385
|
+
case "pinlight" :
|
386
|
+
while (p--) {
|
387
|
+
if ((r2=data2[pix-=4]) < 128)
|
388
|
+
if ((r1=data[pix]) < (r4=2*r2))
|
389
|
+
data2[pix] = r1;
|
390
|
+
else
|
391
|
+
data2[pix] = r4;
|
392
|
+
else
|
393
|
+
if ((r1=data[pix]) > (r4=2*r2-256))
|
394
|
+
data2[pix] = r1;
|
395
|
+
else
|
396
|
+
data2[pix] = r4;
|
397
|
+
|
398
|
+
if ((g2=data2[pix1=pix+1]) < 128)
|
399
|
+
if ((g1=data[pix1]) < (g4=2*g2))
|
400
|
+
data2[pix1] = g1;
|
401
|
+
else
|
402
|
+
data2[pix1] = g4;
|
403
|
+
else
|
404
|
+
if ((g1=data[pix1]) > (g4=2*g2-256))
|
405
|
+
data2[pix1] = g1;
|
406
|
+
else
|
407
|
+
data2[pix1] = g4;
|
408
|
+
|
409
|
+
if ((r2=data2[pix2=pix+2]) < 128)
|
410
|
+
if ((r1=data[pix2]) < (r4=2*r2))
|
411
|
+
data2[pix2] = r1;
|
412
|
+
else
|
413
|
+
data2[pix2] = r4;
|
414
|
+
else
|
415
|
+
if ((r1=data[pix2]) > (r4=2*r2-256))
|
416
|
+
data2[pix2] = r1;
|
417
|
+
else
|
418
|
+
data2[pix2] = r4;
|
419
|
+
}
|
420
|
+
dataChanged = true;
|
421
|
+
break;
|
422
|
+
|
423
|
+
case "hardmix" :
|
424
|
+
while (p--) {
|
425
|
+
if ((r2 = data2[pix-=4]) < 128)
|
426
|
+
if (255 - ((255-data[pix])<<8)/(2*r2) < 128 || r2 == 0)
|
427
|
+
data2[pix] = 0;
|
428
|
+
else
|
429
|
+
data2[pix] = 255;
|
430
|
+
else if ((r4=2*r2-256) < 255 && (data[pix]<<8)/(255-r4) < 128)
|
431
|
+
data2[pix] = 0;
|
432
|
+
else
|
433
|
+
data2[pix] = 255;
|
434
|
+
|
435
|
+
if ((g2 = data2[pix1=pix+1]) < 128)
|
436
|
+
if (255 - ((255-data[pix1])<<8)/(2*g2) < 128 || g2 == 0)
|
437
|
+
data2[pix1] = 0;
|
438
|
+
else
|
439
|
+
data2[pix1] = 255;
|
440
|
+
else if ((g4=2*g2-256) < 255 && (data[pix1]<<8)/(255-g4) < 128)
|
441
|
+
data2[pix1] = 0;
|
442
|
+
else
|
443
|
+
data2[pix1] = 255;
|
444
|
+
|
445
|
+
if ((b2 = data2[pix2=pix+2]) < 128)
|
446
|
+
if (255 - ((255-data[pix2])<<8)/(2*b2) < 128 || b2 == 0)
|
447
|
+
data2[pix2] = 0;
|
448
|
+
else
|
449
|
+
data2[pix2] = 255;
|
450
|
+
else if ((b4=2*b2-256) < 255 && (data[pix2]<<8)/(255-b4) < 128)
|
451
|
+
data2[pix2] = 0;
|
452
|
+
else
|
453
|
+
data2[pix2] = 255;
|
454
|
+
}
|
455
|
+
dataChanged = true;
|
456
|
+
break;
|
457
|
+
}
|
458
|
+
return rgba2hex(data2);
|
459
|
+
}
|