Improve website

website
Mattia Iavarone 5 years ago
parent 9c984f0c21
commit b6947c6267
  1. 79
      docs/_config.yml
  2. 5
      docs/_includes/footer.html
  3. 11
      docs/_includes/google_analytics.html
  4. 21
      docs/_includes/head.html
  5. 24
      docs/_includes/header.html
  6. 41
      docs/_includes/navigation.html
  7. 117
      docs/_layouts/default.html
  8. 49
      docs/_layouts/landing.html
  9. 37
      docs/_layouts/main.html
  10. 14
      docs/_layouts/page.html
  11. 3
      docs/_posts/2018-12-20-camera-events.md
  12. 1
      docs/_posts/2018-12-20-capture-size.md
  13. 10
      docs/_posts/2018-12-20-capturing-media.md
  14. 28
      docs/_posts/2018-12-20-changelog.md
  15. 6
      docs/_posts/2018-12-20-contributing.md
  16. 11
      docs/_posts/2018-12-20-controls.md
  17. 1
      docs/_posts/2018-12-20-frame-processing.md
  18. 1
      docs/_posts/2018-12-20-gestures.md
  19. 9
      docs/_posts/2018-12-20-getting-started.md
  20. 3
      docs/_posts/2018-12-20-install.md
  21. 1
      docs/_posts/2018-12-20-more-features.md
  22. 9
      docs/_posts/2018-12-20-preview-size.md
  23. 1
      docs/_posts/2018-12-20-previews.md
  24. 3
      docs/_posts/2018-12-20-runtime-permissions.md
  25. 7
      docs/_posts/2018-12-20-v1-migration-guide.md
  26. 4
      docs/_posts/2018-12-21-donate.md
  27. 1
      docs/_posts/2019-02-24-snapshot-size.md
  28. 1
      docs/_posts/2019-07-14-watermarks-and-overlays.md
  29. 9
      docs/_posts/2019-08-06-filters.md
  30. 7
      docs/_posts/2019-09-04-metering.md
  31. 2
      docs/_posts/2019-12-04-home.md
  32. 65
      docs/css/colors.css
  33. 33
      docs/css/fonts.css
  34. 34
      docs/css/fonts_responsive.css
  35. 38
      docs/css/landing.css
  36. 336
      docs/css/main.css
  37. 137
      docs/css/syntax.css
  38. 10
      docs/icons/github.svg
  39. 7
      docs/icons/menu.svg
  40. 2
      docs/index.md
  41. 107
      docs/script/new-page

@ -3,69 +3,38 @@
# Source site: http://bruth.github.io/jekyll-docs-template/ # Source site: http://bruth.github.io/jekyll-docs-template/
# Ref guide: https://visualstudiomagazine.com/Articles/2015/03/01/GitHub-Pages.aspx?Page=2 # Ref guide: https://visualstudiomagazine.com/Articles/2015/03/01/GitHub-Pages.aspx?Page=2
# Used by us
title: CameraView title: CameraView
color: '#f76c16'
# subtitle is used by ourselves, description is used by seo tag. description: A well documented, high-level Android interface that makes capturing pictures and videos easy, addressing all of the common issues and needs. # used by ourselves and by seo tag.
subtitle: A well documented, high-level Android interface that makes capturing pictures and videos easy, addressing all of the common issues and needs.
description: A well documented, high-level Android interface that makes capturing pictures and videos easy, addressing all of the common issues and needs.
# Can't remember what this does.
github: [metadata]
# Should be used by some plugins but we're not using any,
author:
name: Mattia Iavarone
email: mat.iavarone@gmail.com
github: natario1
# Add head tags.
plugins:
- jekyll-seo-tag
# if you wish to integrate disqus on pages set your shortname here
disqus_shortname: 'cameraview' disqus_shortname: 'cameraview'
# if you use google analytics, add your tracking id here
google_analytics_id: 'UA-155077779-1' google_analytics_id: 'UA-155077779-1'
google_site_verification: '4x49i17ABIrSvUl52SeL0-t0341aTnWWaC62-FYCRT4'
# Enable/show navigation. There are there options: github: [metadata] # TODO What's this?
# 0 - always hide github_repo: CameraView
# 1 - always show github_version: 2.6.0
# 2 - show only if posts are present donateurl: '/extra/donate' # relative URL for donations, used in footer.html
navigation: 2 baseurl: '/CameraView' # Keep as an empty string if served up at the root
# URL to source code, used in _includes/footer.html
codeurl: 'https://github.com/natario1/CameraView'
# relative URL for donations, used in footer.html
donateurl: '/extra/donate.html'
# Default categories (in order) to appear in the navigation
# (Missing: DOCS and DONATE info)
sections: [ sections: [
['about', 'Overview'], ['about', 'Overview'],
['docs', 'Documentation'], ['docs', 'Documentation'],
['extra', 'More'] ['extra', 'More']
] ]
# Keep as an empty string if served up at the root. If served up at a specific # Jekyll specific stuff
# path (e.g. on GitHub pages) leave off the trailing slash, e.g. /my-project author:
baseurl: '/CameraView' name: Mattia Iavarone # Should appear in <head>.
email: mat.iavarone@gmail.com
# Ensure permalinks have no date nor extension github: natario1
permalink: /:categories/:title website: https://natario.dev
plugins:
# Syntax highlighting - jekyll-seo-tag # Add SEO tags
highlighter: rouge permalink: /:categories/:title # Ensure permalinks have no date nor extension
exclude: ['script', 'README.md'] # Exclude non-site files
# Since these are pages, it doesn't really matter
future: true
# Exclude non-site files
exclude: ['script', 'README.md']
# Use the kramdown Markdown renderer highlighter: rouge # Syntax highlighting
markdown: kramdown future: true # What's this?
markdown: kramdown # Use the kramdown Markdown renderer
redcarpet: redcarpet:
extensions: [ extensions: [
'no_intra_emphasis', 'no_intra_emphasis',
@ -77,7 +46,5 @@ redcarpet:
'tables', 'tables',
'hardwrap' 'hardwrap'
] ]
# Use Github Flavored Markdown
kramdown: kramdown:
input: GFM input: GFM # Use Github Flavored Markdown

@ -1 +1,4 @@
View on GitHub: <a href="{% if site.codeurl %}{{ site.codeurl }}{% else %}{{ site.baseurl }}{% endif %}">{{ site.title }}</a> or <a href="{{ site.baseurl }}{{ site.donateurl }}">donate</a> <footer class="text-center py-3 border-top has-divider">
<span>View on <a href="https://github.com/{{ site.author.github }}/{{ site.github_repo }}">GitHub</a> or become <a href="{{ site.baseurl }}{{ site.donateurl }}">a sponsor</a>!</span>
<span class="d-block">Made by <a href="{{ site.author.website }}">{{ site.author.name }}</a></span>
</footer>

@ -1,8 +1,7 @@
<script async src="https://www.googletagmanager.com/gtag/js?id={{ site.google_analytics_id }}"></script>
<script> <script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ window.dataLayer = window.dataLayer || [];
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), function gtag(){dataLayer.push(arguments);}
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) gtag('js', new Date());
})(window,document,'script','//www.google-analytics.com/analytics.js','ga'); gtag('config', '{{ site.google_analytics_id }}');
ga('create', '{{ site.google_analytics_id }}', 'auto');
ga('send', 'pageview');
</script> </script>

@ -0,0 +1,21 @@
<meta charset="utf-8">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="{{ site.color }}">
<meta name="msapplication-navbutton-color" content="{{ site.color }}">
<meta name="msapplication-TileColor" content="{{ site.color }}">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="description" content="{{ site.description }}">
<meta name="google-site-verification" content="{{ site.google_site_verification }}" />
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
{% seo %}
{% if site.google_analytics_id != "" %}
{% include google_analytics.html %}
{% endif %}

@ -1,3 +1,21 @@
<h4><a class="brand" href="{{ site.baseurl }}/home">{{ site.title }}</a> <header class="text-center py-3 border-bottom has-divider">
{% if site.subtitle %}<small>{{ site.subtitle }}</small>{% endif %} <!-- center -->
</h4> <img class="logo align-middle" alt="Logo" src="{{ site.baseurl }}/static/icon_foreground.png"/>
<a class="h3 mx-2 align-middle text-decoration-none" href="{{ site.baseurl }}/home">{{ site.title }}</a>
<!-- left -->
<div class="left align-middle">
<img class="drawer-toggle p-2 mx-2 d-md-none"
alt="Menu toggle"
src="{{ site.baseurl }}/icons/menu.svg"
onclick="document.getElementById('drawer').classList.toggle('drawer-closed');"/>
</div>
<!-- right -->
<div class="right align-middle">
<span class="version d-none d-sm-inline-block">latest: v{{ site.github_version }}</span>
<a class="p-2 mx-2" href="https://github.com/{{ site.author.github }}/{{ site.github_repo }}">
<img alt="GitHub" src="{{ site.baseurl }}/icons/github.svg">
</a>
</div>
</header>

@ -1,16 +1,41 @@
<ul class="nav nav-pills nav-stacked"> <ul id="navigation" class="py-4">
<li><a href="{{ site.baseurl }}/home">Home</a></li> <li><a href="{{ site.baseurl }}/home">Home</a></li>
{% for section in site.sections %} {% for section in site.sections %}
{% assign attr = section[0] %} {% assign attr = section[0] %}
{% assign label = section[1] %} {% assign label = section[1] %}
<li class="mt-3"><h5 class="mt-0 mb-1">{{ label }}</h5>
<ul>
{% for page in site.categories[attr] %} {% for page in site.categories[attr] %}
{% if forloop.first %} <li class="pt-2 pb-2" data-order="{{ page.order }}">
<li class="nav-header">{{ label }}</li> <a href="{{ site.baseurl }}{{ page.url }}">{{ page.title }}</a>
{% endif %} </li>
<li data-order="{{ page.order }}"><a href="{{ site.baseurl }}{{ page.url }}">{{ page.title }}</a></li>
{% endfor %} {% endfor %}
</ul>
</li>
{% endfor %} {% endfor %}
<!-- List additional links. It is recommended to add a divider
e.g. <li class="divider"></li> first to break up the content. -->
</ul> </ul>
<script>
/* find current item and make it active */
const current = document.location.href;
const links = document.querySelectorAll('#navigation a');
links.forEach((link) => {
if (current && link && current.endsWith(link.getAttribute('href'))) {
link.parentElement.classList.add('active')
}
});
/* reorder elements */
const sections = document.querySelectorAll('#navigation ul');
sections.forEach((section) => {
const entries = section.querySelectorAll('li');
const ordered = [];
entries.forEach((entry) => {
const order = entry.getAttribute('data-order');
ordered.push([entry, order]);
});
ordered.sort((a, b) => a[1] - b[1]);
ordered.forEach((entry) => {
section.appendChild(entry[0]);
})
});
</script>

@ -1,117 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width">
<title>{{ site.title }}{% if page.title %} | {{ page.title }}{% endif %}</title>
<meta name="description" content="{{ site.subtitle }}">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="{{ site.baseurl }}/css/syntax.css">
<link rel="stylesheet" href="{{ site.baseurl }}/css/main.css">
{% seo %}
</head>
<body>
<div class="container">
<div class="row">
<div id="header" class="col-sm-12">
{% include header.html %}
</div>
</div>
<div class="row">
{% assign post_count = site.posts|size %}
{% if site.navigation != 0 and site.navigation == 1 or post_count > 0 %}
<div id="navigation" class="col-sm-2">
{% include navigation.html %}
</div>
<div id="content" class="col-sm-10">
{{ content }}
</div>
{% else %}
<div id="content" class="col-sm-12">
{{ content }}
</div>
{% endif %}
</div>
{% if page.disqus == 1 %}
<div class="row">
{% if site.navigation == 1 or post_count > 0 %}
<div id="navigation" class="col-sm-2"></div>
<div id="disqus" class="col-sm-10">
{% include disqus.html %}
</div>
{% else %}
<div id="disqus" class="col-sm-12">
{% include disqus.html %}
</div>
{% endif %}
</div>
{% endif %}
<div class="row">
<div id="footer" class="col-sm-12">
{% include footer.html %}
</div>
</div>
</div>
<script>
function orderNav() {
var list,
section,
header,
sections = [],
lists = {},
headers = {};
var locationObj = document.location.href;
var navUl = document.querySelectorAll('#navigation ul')[0],
navLis = document.querySelectorAll('#navigation ul li');
if (!navUl) return;
for (var i = 0; i < navLis.length; i++) {
var order, li = navLis[i];
if (li.classList.contains('nav-header')) {
section = li.textContent || li.innerText;
sections.push(section);
headers[section] = li;
continue;
}
var link = li.childNodes[0];
if (locationObj && link && locationObj.endsWith(link.getAttribute('href'))) {
li.classList.add('active');
}
if (!lists[section]) {
lists[section] = [];
}
order = parseFloat(li.getAttribute('data-order'))
lists[section].push([order, li]);
}
for (var i = 0; i < sections.length; i++) {
section = sections[i];
list = lists[section].sort(function(a, b) {
return a[0] - b[0];
});
if (header = headers[section]) {
navUl.appendChild(header);
}
for (var j = 0; j < list.length; j++) {
navUl.appendChild(list[j][1]);
}
}
}
if (document.querySelectorAll) orderNav();
</script>
{% if site.google_analytics_id != "" %}
{% include google_analytics.html %}
{% endif %}
</body>
</html>

@ -1,43 +1,30 @@
<!DOCTYPE html> <!DOCTYPE html>
<html style="height:100%;width:100%;margin:0px;"> <html lang="en">
<head> <head>
<meta charset="utf-8"> {% include head.html %}
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width">
<title>{{ site.title }}</title> <title>{{ site.title }}</title>
<meta name="description" content="{{ site.subtitle }}"> <link rel="stylesheet" href="{{ site.baseurl }}/css/landing.css">
<meta name="google-site-verification" content="4x49i17ABIrSvUl52SeL0-t0341aTnWWaC62-FYCRT4" /> <link rel="stylesheet" href="{{ site.baseurl }}/css/fonts_responsive.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"> <link rel="stylesheet" href="{{ site.baseurl }}/css/syntax.css">
<link rel="stylesheet" href="{{ site.baseurl }}/css/main.css">
{% seo %}
</head> </head>
<body id="landing"> <body>
<div class="container" align="center"> <div class="container p-5">
<div> <img class="d-block mx-auto" id="logo" src="{{ site.baseurl }}/static/icon_foreground.png" alt="Logo">
<img src="static/icon_foreground.png" width="45%" style="max-width:400px"> <div class="text-center">
</div> <h1 id="title" class="display-2 font-weight-bold mt-2">{{ site.title }}</h1>
<div id="content">
{{ content }} {{ content }}
</div> </div>
<div class="row justify-content-sm-center"> <div class="text-center">
<div class="col-xs-12 col-sm-auto"><a href="home">Documentation</a></div> <a class="btn rounded-pill px-3 py-2 mx-2 mt-2" href="{{ site.baseurl }}/home">Documentation</a>
<div class="col-xs-12 col-sm-auto"><a href="about/changelog">Changelog</a></div> <a class="btn rounded-pill px-3 py-2 mx-2 mt-2" href="{{ site.baseurl }}/about/changelog">Changelog</a>
<div class="col-xs-12 col-sm-auto"><a href="{{ site.codeurl }}">GitHub</a></div> <a class="btn rounded-pill px-3 py-2 mx-2 mt-2" href="https://github.com/{{ site.author.github }}/{{ site.github_repo }}">GitHub</a>
<div class="col-xs-12 col-sm-auto"><a href="extra/donate">Support</a></div> <a class="btn rounded-pill px-3 py-2 mx-2 mt-2" href="{{ site.baseurl }}{{ site.donateurl }}">Support</a>
</div> </div>
<br/> <br/>
<div class="row" id="screenshots"> <div class="row">
<div class="col-sm-4"><img src="static/screen1.png"></div> <div class="col-12 col-sm-4 mt-4"><img class="img-fluid" src="{{ site.baseurl }}/static/screen1.png" alt="Screenshot 1"></div>
<div class="col-sm-4"><img src="static/screen2.png"></div> <div class="col-12 col-sm-4 mt-4"><img class="img-fluid" src="{{ site.baseurl }}/static/screen2.png" alt="Screenshot 2"></div>
<div class="col-sm-4"><img src="static/screen3.png"></div> <div class="col-12 col-sm-4 mt-4"><img class="img-fluid" src="{{ site.baseurl }}/static/screen3.png" alt="Screenshot 3"></div>
</div> </div>
</div> </div>
{% if site.google_analytics_id != "" %}
{% include google_analytics.html %}
{% endif %}
</body> </body>
</html> </html>

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en">
<head>
{% include head.html %}
<title>{{ site.title }}{% if page.title %} | {{ page.title }}{% endif %}</title>
<link rel="stylesheet" href="{{ site.baseurl }}/css/main.css">
<link rel="stylesheet" href="{{ site.baseurl }}/css/fonts_responsive.css">
</head>
<body>
{% include header.html %}
<div class="container-fluid container-md">
<div class="row">
<div id="drawer" class="col-md-3 px-4 border-right has-divider drawer drawer-closed">
{% include navigation.html %}
</div>
<div class="col-12 col-md-9">
<div class="content py-3 px-2">
{{ content }}
</div>
{% if page.disqus == 1 %}
<div class="mt-4">
{% include disqus.html %}
</div>
{% endif %}
</div>
</div>
</div>
<div class="container-fluid">
<div class="row">
<div class="col-12 p-0">
{% include footer.html %}
</div>
</div>
</div>
</body>
</html>

@ -1,11 +1,11 @@
--- ---
layout: default layout: main
--- ---
<div class="page-header"> <div class="page-header border-bottom has-divider pb-3">
<h2>{{ page.title }} <h1 class="d-inline-block mt-1 mb-0 mr-2">{{ page.title }}</h1>
{% if page.subtitle %}<small class="page-subtitle">{{ page.subtitle }}</small>{% endif %} {% if page.description %}<span>{{ page.description }}</span>{% endif %}
</h2> </div>
<div class="page mt-4">
{{ content }}
</div> </div>
{{ content }}

@ -1,8 +1,7 @@
--- ---
layout: page layout: page
title: "Camera Events" title: "Camera Events"
subtitle: "Events and lifecycle" description: "Dealing with the camera lifecycle and callbacks"
description: "Events and lifecycle"
category: docs category: docs
date: 2018-12-20 20:02:08 date: 2018-12-20 20:02:08
order: 1 order: 1

@ -1,7 +1,6 @@
--- ---
layout: page layout: page
title: "Capture Size" title: "Capture Size"
subtitle: "Set size of output media"
description: "Set size of output media" description: "Set size of output media"
category: docs category: docs
order: 9 order: 9

@ -1,8 +1,7 @@
--- ---
layout: page layout: page
title: "Capturing Media" title: "Capturing Media"
subtitle: "Taking pictures and videos" description: "Understanding pictures, videos and the snapshot concept"
description: "Taking pictures and videos"
category: docs category: docs
order: 3 order: 3
date: 2018-12-20 20:53:17 date: 2018-12-20 20:53:17
@ -49,10 +48,9 @@ resulting snapshots are square as well, no matter what the sensor available size
|`takePictureSnapshot()`|Pictures|Snapshot|`yes`|`yes`|`yes`|That of the preview stream, [or less](snapshot-size)| |`takePictureSnapshot()`|Pictures|Snapshot|`yes`|`yes`|`yes`|That of the preview stream, [or less](snapshot-size)|
|`takeVideoSnapshot(File)`|Videos|Snapshot|`yes`|`yes`|`yes`|That of the preview stream, [or less](snapshot-size)| |`takeVideoSnapshot(File)`|Videos|Snapshot|`yes`|`yes`|`yes`|That of the preview stream, [or less](snapshot-size)|
Please note that the video snaphot features requires: > Please note that the video snaphot features requires:
> - API 18. If called before, it throws
- API 18. If called before, it throws > - An OpenGL preview (see [previews](previews)). If not, it throws
- An OpenGL preview (see [previews](previews)). If not, it throws
### Capturing pictures while recording ### Capturing pictures while recording

@ -8,7 +8,7 @@ order: 3
New versions are released through GitHub, so the reference page is the [GitHub Releases](https://github.com/natario1/CameraView/releases) page. New versions are released through GitHub, so the reference page is the [GitHub Releases](https://github.com/natario1/CameraView/releases) page.
Starting from 2.4.0, you can now [support development](https://github.com/sponsors/natario1) through the GitHub Sponsors program. > Starting from 2.4.0, you can now [support development](https://github.com/sponsors/natario1) through the GitHub Sponsors program.
Companies can share a tiny part of their revenue and get private support hours in return. Thanks! Companies can share a tiny part of their revenue and get private support hours in return. Thanks!
## v2.6.0 ## v2.6.0
@ -54,7 +54,7 @@ This change greatly improved the FPS performance, which is what matters the most
<https://github.com/natario1/CameraView/compare/v2.3.1...v2.4.0> <https://github.com/natario1/CameraView/compare/v2.3.1...v2.4.0>
### v2.3.1 #### v2.3.1
- <small>[Video]</small> Improvement: better timing for `onVideoRecordingStart()` thanks to [@agrawalsuneet][agrawalsuneet] ([#632][632]) - <small>[Video]</small> Improvement: better timing for `onVideoRecordingStart()` thanks to [@agrawalsuneet][agrawalsuneet] ([#632][632])
- <small>[Video, Camera1]</small> Fix: fixed video errors when starting on specific devices ([#617][617]) - <small>[Video, Camera1]</small> Fix: fixed video errors when starting on specific devices ([#617][617])
@ -110,7 +110,7 @@ Please read the documentation page for usage instructions.
<https://github.com/natario1/CameraView/compare/v2.0.0-rc2...v2.0.0> <https://github.com/natario1/CameraView/compare/v2.0.0-rc2...v2.0.0>
### v2.0.0-rc2 #### v2.0.0-rc2
- Fix: crashes when stopping video snapshots ([#513][513]) - Fix: crashes when stopping video snapshots ([#513][513])
- Fix: dependencies missing, leading to runtime crashes ([#517][517]) - Fix: dependencies missing, leading to runtime crashes ([#517][517])
@ -131,7 +131,7 @@ This is likely to be the last release before v2.0.0.
<https://github.com/natario1/CameraView/compare/v2.0.0-beta06...v2.0.0-rc1> <https://github.com/natario1/CameraView/compare/v2.0.0-beta06...v2.0.0-rc1>
### v2.0.0-beta06 #### v2.0.0-beta06
- New: Full featured Camera2 integration! Use `cameraExperimental="true"` and `cameraEngine="camera2"` to test this out. ([#490][490]) - New: Full featured Camera2 integration! Use `cameraExperimental="true"` and `cameraEngine="camera2"` to test this out. ([#490][490])
- Improvement: we now choose a video recording profile that is compatible with the chosen size. Should fix some video recording issues. ([#477][477]) - Improvement: we now choose a video recording profile that is compatible with the chosen size. Should fix some video recording issues. ([#477][477])
@ -147,7 +147,7 @@ If you were using `focusWithMarker`, you can [add back the old marker](../docs/m
<https://github.com/natario1/CameraView/compare/v2.0.0-beta05...v2.0.0-beta06> <https://github.com/natario1/CameraView/compare/v2.0.0-beta05...v2.0.0-beta06>
### v2.0.0-beta05 #### v2.0.0-beta05
- Fixed `FrameProcessor` freeze and release behavior, was broken ([#431][431]) - Fixed `FrameProcessor` freeze and release behavior, was broken ([#431][431])
- New: new api `setAutoFocusResetDelay` to control the delay to reset the focus after autofocus was performed, thanks to [@cneuwirt][cneuwirt] ([#435][435]) - New: new api `setAutoFocusResetDelay` to control the delay to reset the focus after autofocus was performed, thanks to [@cneuwirt][cneuwirt] ([#435][435])
@ -156,21 +156,21 @@ If you were using `focusWithMarker`, you can [add back the old marker](../docs/m
<https://github.com/natario1/CameraView/compare/v2.0.0-beta04...v2.0.0-beta05> <https://github.com/natario1/CameraView/compare/v2.0.0-beta04...v2.0.0-beta05>
### v2.0.0-beta04 #### v2.0.0-beta04
- Renames setPreviewSize to setPreviewStreamSize (previewSize suggests it is related to the view size but it's not) ([#393][393]) - Renames setPreviewSize to setPreviewStreamSize (previewSize suggests it is related to the view size but it's not) ([#393][393])
- Added new APIs `setSnapshotMaxWidth` and `setSnapshotMaxHeight` ([#393][393]). You can now have a good looking preview but still take low-res snapshots using these snapshot constraints. Before this, the two sizes were coupled. - Added new APIs `setSnapshotMaxWidth` and `setSnapshotMaxHeight` ([#393][393]). You can now have a good looking preview but still take low-res snapshots using these snapshot constraints. Before this, the two sizes were coupled.
<https://github.com/natario1/CameraView/compare/v2.0.0-beta03...v2.0.0-beta04> <https://github.com/natario1/CameraView/compare/v2.0.0-beta03...v2.0.0-beta04>
### v2.0.0-beta03 #### v2.0.0-beta03
- Fixed a few bugs ([#392][392]) - Fixed a few bugs ([#392][392])
- Important fixes to video snapshot recording ([#374][374]) - Important fixes to video snapshot recording ([#374][374])
<https://github.com/natario1/CameraView/compare/v2.0.0-beta02...v2.0.0-beta03> <https://github.com/natario1/CameraView/compare/v2.0.0-beta02...v2.0.0-beta03>
### v2.0.0-beta02 #### v2.0.0-beta02
- Fixed important bugs ([#356][356]) - Fixed important bugs ([#356][356])
- Picture snapshots are now flipped when front camera is used ([#360][360]) - Picture snapshots are now flipped when front camera is used ([#360][360])
@ -182,7 +182,7 @@ If you were using `focusWithMarker`, you can [add back the old marker](../docs/m
This is the first beta release. For changes with respect to v1, please take a look at the [migration guide](../extra/v1-migration-guide). This is the first beta release. For changes with respect to v1, please take a look at the [migration guide](../extra/v1-migration-guide).
### v1.6.1 #### v1.6.1
This is the last release before v2. This is the last release before v2.
@ -204,7 +204,7 @@ This is the last release before v2.
<https://github.com/natario1/CameraView/compare/v1.5.1...v1.6.0> <https://github.com/natario1/CameraView/compare/v1.5.1...v1.6.0>
### v1.5.1 #### v1.5.1
- Bug: byte array length for Frames was incorrect thanks to [@ssakhavi][ssakhavi] ([#205][205]) - Bug: byte array length for Frames was incorrect thanks to [@ssakhavi][ssakhavi] ([#205][205])
- Bug: gestures were crashing in some conditions ([#222][222]) - Bug: gestures were crashing in some conditions ([#222][222])
@ -223,7 +223,7 @@ This is the last release before v2.
<https://github.com/natario1/CameraView/compare/v1.4.2...v1.5.0> <https://github.com/natario1/CameraView/compare/v1.4.2...v1.5.0>
### v1.4.2 #### v1.4.2
- Add prefix to XML resources so they don't collide, thanks to [@RocketRider][RocketRider] ([#162][162]) - Add prefix to XML resources so they don't collide, thanks to [@RocketRider][RocketRider] ([#162][162])
- Add `videoMaxSize` API and XML attribute, to set max size video in bytes, thanks to [@chaitanyaraghav][chaitanyaraghav] ([#104][104]) - Add `videoMaxSize` API and XML attribute, to set max size video in bytes, thanks to [@chaitanyaraghav][chaitanyaraghav] ([#104][104])
@ -232,7 +232,7 @@ This is the last release before v2.
<https://github.com/natario1/CameraView/compare/v1.4.1...v1.4.2> <https://github.com/natario1/CameraView/compare/v1.4.1...v1.4.2>
### v1.4.1 #### v1.4.1
- Fixed a bug that would flip the front camera preview on some devices ([#112][112]) - Fixed a bug that would flip the front camera preview on some devices ([#112][112])
- Two new `CameraOptions` APIs: `o.getSupportedPictureSizes()` and `o.getSupportedPictureAspectRatios()` ([#101][101]) - Two new `CameraOptions` APIs: `o.getSupportedPictureSizes()` and `o.getSupportedPictureAspectRatios()` ([#101][101])
@ -264,7 +264,7 @@ This is the last release before v2.
<https://github.com/natario1/CameraView/compare/v1.3.2...v1.4.0> <https://github.com/natario1/CameraView/compare/v1.3.2...v1.4.0>
### v1.3.2 #### v1.3.2
- Fixed a memory leak thanks to [@andrewmunn][andrewmunn] ([#92][92]) - Fixed a memory leak thanks to [@andrewmunn][andrewmunn] ([#92][92])
- Reduced memory usage when using cropOutput thanks to [@RobertoMorelos][RobertoMorelos] ([#93][93]) - Reduced memory usage when using cropOutput thanks to [@RobertoMorelos][RobertoMorelos] ([#93][93])
@ -272,7 +272,7 @@ This is the last release before v2.
<https://github.com/natario1/CameraView/compare/v1.3.1...v1.3.2> <https://github.com/natario1/CameraView/compare/v1.3.1...v1.3.2>
### v1.3.1 #### v1.3.1
- Fixed a bug that would make setFacing and other APIs freeze the camera ([#86][86]) - Fixed a bug that would make setFacing and other APIs freeze the camera ([#86][86])
- Fixed ConcurrentModificationExceptions during CameraListener callbacks ([#88][88]) - Fixed ConcurrentModificationExceptions during CameraListener callbacks ([#88][88])

@ -12,7 +12,7 @@ although it has reached a high level of stability.
We are grateful to anyone who has contributed with fixes, features or feature requests. If you don't We are grateful to anyone who has contributed with fixes, features or feature requests. If you don't
want to get involved but still want to support the project, please [consider donating](donate). want to get involved but still want to support the project, please [consider donating](donate).
## Bug reports ### Bug reports
Please make sure to fill the bug report issue template on GitHub. Please make sure to fill the bug report issue template on GitHub.
We highly recommend to try to reproduce the bug in the demo app, as this helps a lot in debugging We highly recommend to try to reproduce the bug in the demo app, as this helps a lot in debugging
@ -31,7 +31,7 @@ Recommended extras:
- LogCat logs (use `CameraLogger.setLogLevel(LEVEL_VERBOSE)` to print all) - LogCat logs (use `CameraLogger.setLogLevel(LEVEL_VERBOSE)` to print all)
- Link to a GitHub repo where the bug is reproducible - Link to a GitHub repo where the bug is reproducible
## Pull Requests ### Pull Requests
Please open an issue first. Please open an issue first.
@ -43,7 +43,7 @@ Please write tests.
Unless the code was already not covered by tests, updated tests are required for merging. The lib Unless the code was already not covered by tests, updated tests are required for merging. The lib
has a few unit tests and more robust tests in the `androidTest` folder, which can be run by Android Studio. has a few unit tests and more robust tests in the `androidTest` folder, which can be run by Android Studio.
## License ### License
CameraView was formally born as a fork of [CameraKit-Android](https://github.com/wonderkiln/CameraKit-Android) CameraView was formally born as a fork of [CameraKit-Android](https://github.com/wonderkiln/CameraKit-Android)
and [Google's CameraView](https://github.com/google/cameraview), but has been completely rewritten since. and [Google's CameraView](https://github.com/google/cameraview), but has been completely rewritten since.

@ -1,8 +1,7 @@
--- ---
layout: page layout: page
title: "Controls" title: "Controls"
subtitle: "Output parameters and capture options" description: "Configuring output parameters and capture options"
description: "Output parameters and capture options"
category: docs category: docs
order: 2 order: 2
date: 2018-12-20 21:08:53 date: 2018-12-20 21:08:53
@ -41,7 +40,6 @@ or `CameraOptions.supports(Control)` to see if it is supported.
Which camera to use, either back facing or front facing. Which camera to use, either back facing or front facing.
Defaults to the first available value (tries `BACK` first). Defaults to the first available value (tries `BACK` first).
The available values are exposed through the `CameraOptions` object. The available values are exposed through the `CameraOptions` object.
```java ```java
@ -52,7 +50,6 @@ cameraView.setFacing(Facing.FRONT);
##### cameraFlash ##### cameraFlash
Flash mode, either off, on, auto or torch. Defaults to `OFF`. Flash mode, either off, on, auto or torch. Defaults to `OFF`.
The available values are exposed through the `CameraOptions` object. The available values are exposed through the `CameraOptions` object.
```java ```java
@ -66,7 +63,6 @@ cameraView.setFlash(Flash.TORCH);
Sets the encoder for video recordings. Defaults to `DEVICE_DEFAULT`, Sets the encoder for video recordings. Defaults to `DEVICE_DEFAULT`,
which should typically be H_264. which should typically be H_264.
The available values are exposed through the `CameraOptions` object. The available values are exposed through the `CameraOptions` object.
```java ```java
@ -79,7 +75,6 @@ cameraView.setVideoCodec(VideoCodec.H_264);
Sets the desired white balance for the current session. Sets the desired white balance for the current session.
Defaults to `AUTO`. Defaults to `AUTO`.
The available values are exposed through the `CameraOptions` object. The available values are exposed through the `CameraOptions` object.
```java ```java
@ -93,7 +88,6 @@ cameraView.setWhiteBalance(WhiteBalance.CLOUDY);
##### cameraHdr ##### cameraHdr
Turns on or off HDR captures. Defaults to `OFF`. Turns on or off HDR captures. Defaults to `OFF`.
The available values are exposed through the `CameraOptions` object. The available values are exposed through the `CameraOptions` object.
```java ```java
@ -106,7 +100,6 @@ cameraView.setHdr(Hdr.ON);
The format for pictures taken with `takePicture()`. Does not apply to picture snapshots taken The format for pictures taken with `takePicture()`. Does not apply to picture snapshots taken
with `takePictureSnapshot()`. The `JPEG` value is always supported, while for other values with `takePictureSnapshot()`. The `JPEG` value is always supported, while for other values
support might change depending on the engine and the device sensor. support might change depending on the engine and the device sensor.
The available values are exposed through the `CameraOptions` object. The available values are exposed through the `CameraOptions` object.
```java ```java
@ -118,7 +111,6 @@ cameraView.setPictureFormat(PictureFormat.DNG);
Turns on or off audio stream while recording videos. Turns on or off audio stream while recording videos.
Defaults to `ON`. Defaults to `ON`.
The available values are exposed through the `CameraOptions` object. The available values are exposed through the `CameraOptions` object.
```java ```java
@ -183,7 +175,6 @@ cameraView.setPreviewFrameRate(0F);
The preview frame rate is an important parameter because it will also The preview frame rate is an important parameter because it will also
control (broadly) the rate at which frame processor frames are dispatched, control (broadly) the rate at which frame processor frames are dispatched,
the video snapshots frame rate, and the rate at which real-time filters are invoked. the video snapshots frame rate, and the rate at which real-time filters are invoked.
The available values are exposed through the `CameraOptions` object: The available values are exposed through the `CameraOptions` object:
```java ```java

@ -1,7 +1,6 @@
--- ---
layout: page layout: page
title: "Frame Processing" title: "Frame Processing"
subtitle: "Process each frame in real time"
description: "Process each frame in real time" description: "Process each frame in real time"
category: docs category: docs
order: 6 order: 6

@ -1,7 +1,6 @@
--- ---
layout: page layout: page
title: "Gestures" title: "Gestures"
subtitle: "Gestures control"
description: "Gestures control" description: "Gestures control"
category: docs category: docs
order: 5 order: 5

@ -1,7 +1,6 @@
--- ---
layout: page layout: page
title: "Getting Started" title: "Getting Started"
subtitle: "Simple guide to take your first picture"
description: "Simple guide to take your first picture" description: "Simple guide to take your first picture"
category: about category: about
date: 2018-12-20 17:48:58 date: 2018-12-20 17:48:58
@ -64,9 +63,9 @@ camera.addCameraListener(new CameraListener() {
}) })
``` ```
### Take a picture ### Taking a picture
We're done. To take a picture upon user input, just call `takePicture()`. To take a picture upon user input, just call `takePicture()`.
```java ```java
camera.addCameraListener(new CameraListener() { camera.addCameraListener(new CameraListener() {
@ -90,7 +89,7 @@ camera.takePicture();
Read the docs about `takePictureSnapshot()` for a super fast, lower quality alternative. Read the docs about `takePictureSnapshot()` for a super fast, lower quality alternative.
### Take a video ### Taking a video
Taking a video is just the same thing, except that you must make sure that camera is in `Mode.VIDEO` mode, Taking a video is just the same thing, except that you must make sure that camera is in `Mode.VIDEO` mode,
and that you have write permissions to write the file: and that you have write permissions to write the file:
@ -122,7 +121,7 @@ This was it, but there is a ton of other options available to customize the came
to control the sensor, the UI appearance, the quality and size of the output, or to live process to control the sensor, the UI appearance, the quality and size of the output, or to live process
frames. Keep reading the documentation! frames. Keep reading the documentation!
For runtime permissions and Manifest setup, please read the [permissions page](../docs/runtime-permissions). > For runtime permissions and Manifest setup, please read the [permissions page](../docs/runtime-permissions).
### Without support libraries ### Without support libraries

@ -1,7 +1,6 @@
--- ---
layout: page layout: page
title: "Install" title: "Install"
subtitle: "Integrate in your project"
description: "Integrate in your project" description: "Integrate in your project"
category: about category: about
order: 1 order: 1
@ -24,7 +23,7 @@ allprojects {
Then simply download the latest version: Then simply download the latest version:
```groovy ```groovy
api 'com.otaliastudios:cameraview:2.6.0' api 'com.otaliastudios:cameraview:{{ site.github_version }}'
``` ```
No other configuration steps are needed. No other configuration steps are needed.

@ -1,7 +1,6 @@
--- ---
layout: page layout: page
title: "More features" title: "More features"
subtitle: "Undocumented features & more"
description: "Undocumented features & more" description: "Undocumented features & more"
category: docs category: docs
order: 16 order: 16

@ -1,7 +1,6 @@
--- ---
layout: page layout: page
title: "Preview Size" title: "Preview Size"
subtitle: "Measuring behavior"
description: "Measuring behavior" description: "Measuring behavior"
category: docs category: docs
order: 8 order: 8
@ -22,7 +21,7 @@ This means that your visible preview can be of any size, not just the presets.
Whatever you do, the preview will never be distorted - it can only be cropped Whatever you do, the preview will never be distorted - it can only be cropped
if needed. if needed.
## Examples ### Examples
##### Center Inside ##### Center Inside
@ -55,11 +54,11 @@ This means that part of the preview might be hidden, and the output might contai
that were not visible during the capture, **unless it is taken as a snapshot, since snapshots account for cropping**. that were not visible during the capture, **unless it is taken as a snapshot, since snapshots account for cropping**.
## Advanced feature: Preview Stream Size Selection ### Advanced feature: Preview Stream Size Selection
*Only do this if you know what you are doing. This is typically not needed - prefer picture/video size selectors, > Only do this if you know what you are doing. This is typically not needed - prefer picture/video size selectors,
as they will drive the preview stream size selection and, eventually, the view size. If what you want is just as they will drive the preview stream size selection and, eventually, the view size. If what you want is just
choose an aspect ratio, do so with [Capture Size](capture-size) selection.* choose an aspect ratio, do so with [Capture Size](capture-size) selection.
As said, `WRAP_CONTENT` adapts the view boundaries to the preview stream size. The preview stream size must be determined As said, `WRAP_CONTENT` adapts the view boundaries to the preview stream size. The preview stream size must be determined
based on the sizes that the device sensor & hardware actually support. This operation is done automatically based on the sizes that the device sensor & hardware actually support. This operation is done automatically

@ -1,7 +1,6 @@
--- ---
layout: page layout: page
title: "Engine and Previews" title: "Engine and Previews"
subtitle: "Camera engine and preview implementations"
description: "Camera engine and preview implementations" description: "Camera engine and preview implementations"
category: docs category: docs
order: 7 order: 7

@ -1,7 +1,6 @@
--- ---
layout: page layout: page
title: "Runtime Permissions" title: "Runtime Permissions"
subtitle: "Permissions and Manifest setup"
description: "Permissions and Manifest setup" description: "Permissions and Manifest setup"
category: docs category: docs
order: 13 order: 13
@ -9,7 +8,7 @@ date: 2018-12-20 20:03:03
disqus: 1 disqus: 1
--- ---
`CameraView` needs two permissions: CameraView needs two permissions:
- `android.permission.CAMERA` : required for capturing pictures and videos - `android.permission.CAMERA` : required for capturing pictures and videos
- `android.permission.RECORD_AUDIO` : required for capturing videos with `Audio.ON` (the default) - `android.permission.RECORD_AUDIO` : required for capturing videos with `Audio.ON` (the default)

@ -1,7 +1,6 @@
--- ---
layout: page layout: page
title: "v1 Migration Guide" title: "v1 Migration Guide"
subtitle: "Breaking Changes & new concepts"
description: "Breaking Changes & new concepts" description: "Breaking Changes & new concepts"
category: extra category: extra
date: 2018-12-20 19:01:55 date: 2018-12-20 19:01:55
@ -77,7 +76,7 @@ The engine will use the video size selector when mode is `VIDEO`, and the pictur
### Picture and videos ### Picture and videos
#### Take, not capture ##### Take, not capture
- `capturePicture()` is now `takePicture()` - `capturePicture()` is now `takePicture()`
- `captureSnapshot()` is now `takePictureSnapshot()` - `captureSnapshot()` is now `takePictureSnapshot()`
@ -86,7 +85,7 @@ The engine will use the video size selector when mode is `VIDEO`, and the pictur
The new `isTakingPicture()` method was added for symmetry with videos. The new `isTakingPicture()` method was added for symmetry with videos.
#### Snapshots ##### Snapshots
This is the major improvement over v1. There are now 4 capture APIs, two for pictures and two for videos. This is the major improvement over v1. There are now 4 capture APIs, two for pictures and two for videos.
- Standard APIs: `takePicture()` and `takeVideo()`. These take a high quality picture or video, depending - Standard APIs: `takePicture()` and `takeVideo()`. These take a high quality picture or video, depending
@ -111,7 +110,7 @@ which makes it a powerful tool. The drawback is that it needs:
- API 18. If called before, it throws - API 18. If called before, it throws
- An OpenGL preview (see below). If not, it throws - An OpenGL preview (see below). If not, it throws
#### Video capturing ##### Video capturing
Some new APIs were introduced, which are respected by both standard videos and snapshot videos: Some new APIs were introduced, which are respected by both standard videos and snapshot videos:
- `setAudioBitRate()` and `cameraAudioBitRate`: sets the audio bit rate in bit/s - `setAudioBitRate()` and `cameraAudioBitRate`: sets the audio bit rate in bit/s

@ -17,13 +17,13 @@ according to the GitHub Sponsors tier you choose and the Open Collective rules.
Thank you for any contribution! Thank you for any contribution!
## Project Backers ### Project Backers
Thanks to all the project backers! [Become a backer.](https://opencollective.com/cameraview#backer) Thanks to all the project backers! [Become a backer.](https://opencollective.com/cameraview#backer)
<a href="https://opencollective.com/cameraview#backers" target="_blank"><img src="https://opencollective.com/cameraview/backers.svg?width=890"></a> <a href="https://opencollective.com/cameraview#backers" target="_blank"><img src="https://opencollective.com/cameraview/backers.svg?width=890"></a>
## Project Sponsors ### Project Sponsors
Thanks to all the project sponsors! [Become a sponsor](https://opencollective.com/cameraview#sponsor) and have your logo here. Thanks to all the project sponsors! [Become a sponsor](https://opencollective.com/cameraview#sponsor) and have your logo here.

@ -1,7 +1,6 @@
--- ---
layout: page layout: page
title: "Snapshot Size" title: "Snapshot Size"
subtitle: "Sizing the snapshots output"
description: "Sizing the snapshots output" description: "Sizing the snapshots output"
category: docs category: docs
order: 10 order: 10

@ -1,7 +1,6 @@
--- ---
layout: page layout: page
title: "Watermarks and Overlays" title: "Watermarks and Overlays"
subtitle: "Static and animated overlays"
description: "Static and animated overlays" description: "Static and animated overlays"
category: docs category: docs
order: 11 order: 11

@ -1,7 +1,6 @@
--- ---
layout: page layout: page
title: "Real-time Filters" title: "Real-time Filters"
subtitle: "Apply filters to preview and snapshots"
description: "Apply filters to preview and snapshots" description: "Apply filters to preview and snapshots"
category: docs category: docs
order: 12 order: 12
@ -37,8 +36,8 @@ cameraView.setFilter(Filters.SEPIA.newInstance());
``` ```
All of the filters stored in the `Filters` class have an XML string resource that you can use All of the filters stored in the `Filters` class have an XML string resource that you can use
to quickly setup the camera view. For example, `Filters.BLACK_AND_WHITE` can be set by using to quickly setup the camera view. For example, `Filters.BLACK_AND_WHITE` can be used by setting
`app:cameraFilter="@string/cameraview_filter_black_and_white`. `app:cameraFilter` to `"@string/cameraview_filter_black_and_white"`.
The default filter is called `NoFilter` (`Filters.NONE`) and can be used to clear up any other The default filter is called `NoFilter` (`Filters.NONE`) and can be used to clear up any other
filter that was previously set and return back to normal. filter that was previously set and return back to normal.
@ -115,7 +114,7 @@ There are some technical caveats when using a `MultiFilter`:
Advanced users with OpenGL experience can create their own filters by implementing the `Filter` interface Advanced users with OpenGL experience can create their own filters by implementing the `Filter` interface
and passing in a fragment shader and a vertex shader that will be used for drawing. and passing in a fragment shader and a vertex shader that will be used for drawing.
#### Simple filters ##### Simple filters
For very simple filters that have a static fragment shader, you can create a working filter For very simple filters that have a static fragment shader, you can create a working filter
implementation by simply creating an instance of `SimpleFilter`: implementation by simply creating an instance of `SimpleFilter`:
@ -124,7 +123,7 @@ implementation by simply creating an instance of `SimpleFilter`:
Filter filter = new SimpleFilter(myFragmentShader); Filter filter = new SimpleFilter(myFragmentShader);
``` ```
#### More complex filters ##### More complex filters
We recommend: We recommend:

@ -1,7 +1,6 @@
--- ---
layout: page layout: page
title: "Metering" title: "Metering"
subtitle: "Exposure and metering controls"
description: "Exposure and metering controls" description: "Exposure and metering controls"
category: docs category: docs
order: 4 order: 4
@ -28,8 +27,8 @@ as the device moves or the scene changes.
### Picture Metering ### Picture Metering
*In Camera1, picture metering is always enabled for pictures, and always disabled for picture snapshots. > In Camera1, picture metering is always enabled for pictures, and always disabled for picture snapshots.
The following applies to Camera2 only.* The following applies to Camera2 only.
The camera engine will try to trigger metering when a picture is requested, either with `takePicture()` The camera engine will try to trigger metering when a picture is requested, either with `takePicture()`
or `takePictureSnapshot()`. This has two obvious consequences: or `takePictureSnapshot()`. This has two obvious consequences:
@ -106,7 +105,7 @@ cameraView.setAutoFocusMarker(new DefaultAutoFocusMarker());
##### Touch Metering Reset Delay ##### Touch Metering Reset Delay
You control control how a touch metering operation is reset after completed. You control control how a touch metering operation is reset after completed.
Setting a value <= 0 or == Long.MAX_VALUE will not reset the metering values. Setting a negative value (or 0, or `Long.MAX_VALUE`) will not reset the metering values.
This is useful for low end devices that have slow auto-focus capabilities. This is useful for low end devices that have slow auto-focus capabilities.
Defaults to 3 seconds. Defaults to 3 seconds.

@ -1,5 +1,5 @@
--- ---
layout: default layout: main
title: "CameraView" title: "CameraView"
--- ---

@ -0,0 +1,65 @@
:root {
--color-primary: #f76c16;
--color-primary-active: #e75c16;
--color-primary-hover: #d74c16;
--color-secondary: #f7a816;
--color-accent: #0e95e3;
--color-accent-light: #f5fcff;
--color-accent-dark: #0e3375;
--color-background: #FFFFFF;
--color-code: var(--color-primary);
--color-code-background: #f8f8f8;
--color-text-muted: #6c757d;
}
body {
background-color: var(--color-background);
}
a {
color: var(--color-primary);
}
code, pre {
background-color: var(--color-code-background);
}
:not(pre) > code {
color: var(--color-code);
}
a:hover {
color: var(--color-primary-hover) !important;
}
.btn-primary {
background-color: var(--color-primary) !important;
border-color: var(--color-primary) !important;
color: white !important;
}
.btn-primary.active, .btn-primary:active {
background-color: var(--color-primary-active) !important;
border-color: var(--color-primary-active) !important;
}
.btn-primary:hover {
background-color: var(--color-primary-hover) !important;
border-color: var(--color-primary-hover) !important;
color: white !important;
}
.btn-outline-primary {
border-color: var(--color-primary) !important;
}
.btn-outline-primary.active, .btn-outline-primary:active {
background-color: var(--color-primary-active) !important;
border-color: var(--color-primary-active) !important;
}
.btn-outline-primary:hover {
border-color: var(--color-primary-hover) !important;
background-color: var(--color-primary-hover) !important;
color: white !important;
}

@ -0,0 +1,33 @@
@import url('https://fonts.googleapis.com/css?family=Lobster+Two:400i,700i|Roboto+Mono|Source+Sans+Pro:400,700&display=swap');
@import "fonts_responsive.css";
:root {
--font-mono: 'Roboto Mono';
--font-sans: 'Source Sans Pro';
--font-display: 'Lobster Two';
}
* {
font-family: var(--font-sans), sans-serif;
font-weight: 400;
}
h1, .h1, h2, .h2, h3, .h3, h4, .h4, h5, .h5, h6, .h6 {
font-family: var(--font-display), cursive;
font-style: italic;
font-weight: 700 !important;
}
h4, .h4, h5, .h5, h6, .h6 {
font-weight: 400;
}
button, .btn {
font-family: var(--font-display), cursive !important;
font-style: italic !important;
font-weight: 700 !important;
}
code, code * {
font-family: var(--font-mono) !important;
}

@ -0,0 +1,34 @@
/* https://christianoliff.com/blog/bootstrap-with-rfs */
/* either apply after everything else or add !important here */
@media (max-width: 1200px) {
legend {
font-size: calc(1.275rem + 0.3vw);
}
h1, .h1 {
font-size: calc(1.375rem + 1.5vw);
}
h2, .h2 {
font-size: calc(1.325rem + 0.9vw);
}
h3, .h3 {
font-size: calc(1.3rem + 0.6vw);
}
h4, .h4 {
font-size: calc(1.275rem + 0.3vw);
}
.display-1 {
font-size: calc(1.725rem + 5.7vw);
}
.display-2 {
font-size: calc(1.675rem + 5.1vw);
}
.display-3 {
font-size: calc(1.575rem + 3.9vw);
}
.display-4 {
font-size: calc(1.475rem + 2.7vw);
}
.close {
font-size: calc(1.275rem + 0.3vw);
}
}

@ -0,0 +1,38 @@
@import "fonts.css";
@import "colors.css";
html {
width: 100%;
height: 100%;
margin: 0;
}
body {
background: radial-gradient(ellipse, var(--color-secondary), var(--color-primary)) fixed !important;
}
#logo {
width: 45%;
max-width: 340px;
}
h1 {
color: white;
}
p {
color: rgba(255, 255, 255, 0.7);
font-size: 1.2em;
line-height: 100%;
}
.btn {
color: white !important;
background-color: rgba(240, 240, 240, 0.25);
font-size: 1.3em;
}
.btn:hover {
color: white !important;
background-color: rgba(240, 240, 240, 0.4);
}

@ -1,216 +1,274 @@
@import url('https://fonts.googleapis.com/css?family=Calistoga|Roboto+Mono|Source+Sans+Pro:400,700&display=swap'); @import "fonts.css";
@import "colors.css";
@import "syntax.css";
body { :root {
font-weight: 400; --color-footer: var(--color-code-background);
font-family: 'Source Sans Pro', sans-serif; --color-table-head: var(--color-code-background);
--color-divider: rgba(230, 230, 230, 0.7);
--header-height: 65px; /* kind of */
--cards-radius: 4px;
} }
h1, h2, h3, h4, h5, h6, th { html, body {
font-family: 'Calistoga', sans-serif; height: 100%;
} }
small { /* dividers */
font-weight: 400;
font-family: 'Source Sans Pro', sans-serif;
}
pre, code, pre code { .has-divider {
border: none; border-color: var(--color-divider) !important;
border-radius: 0;
background-color: #fafafa;
font-size: 0.8em;
} }
.highlight { /* header */
background-color: #fafafa;
border-radius: 12px;
}
pre { header {
font-size: 1em; background: radial-gradient(ellipse, var(--color-secondary), var(--color-primary)) fixed;
position: fixed;
top: 0;
width: 100%;
z-index: 10;
} }
code { header .left {
color: inherit; position: absolute;
font-family: 'Roboto Mono', monospace; left: 0;
color: #dd2200; top: 50%;
transform: translateY(-50%);
} }
a { header .right {
color: #0e95e3; position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
} }
#header { header a {
border-bottom: 1px solid #eee; color: white !important;
margin-bottom: 20px;
} }
#header a:hover { header a:hover {
text-decoration: none; color: white !important;
} }
#content { header .logo {
/* bigger font */ height: 32px;
font-size: 1.1em; width: auto;
} }
#content p { header .version {
/* spacing for all paragraphs */ font-size: 0.9em;
margin-top: 16px; color: rgba(255, 255, 255, 0.8);
margin-bottom: 16px;
} }
#content ul li { body {
/* spacing for lists */ /* to offset wrt sticky header */
margin-top: 8px; padding-top: var(--header-height);
margin-bottom: 8px;
} }
#content h5 { /* footer */
font-size: 1.1em;
footer {
background-color: var(--color-footer);
color: var(--color-text-muted);
font-size: 0.9em;
} }
#footer { /* drawer */
margin: 20px 0;
font-size: 0.85em; .drawer-toggle:hover {
color: #999; background-color: rgba(240, 240, 240, 0.25);
text-align: center; border-radius: 50%;
} }
#content > .page-header:first-child { @media (max-width: 768px) {
margin-top: 0; .drawer {
position: fixed;
top: 0;
left: 0;
width: 300px;
height: 100%;
overflow-x: hidden;
overflow-y: auto;
background-color: var(--color-background);
transition: transform 0.4s cubic-bezier(0.4, 0, 0, 1);
z-index: 5;
padding-top: var(--header-height);
}
.drawer-closed {
transform: translateX(-100%);
}
} }
#content > .page-header:first-child h2 { @media (max-width: 480px) {
margin-top: 0; .drawer {
width: 100%;
}
} }
#content .page-subtitle { .drawer ul {
font-size: 0.45em; list-style: none;
margin: 0;
padding: 0;
line-height: 100%;
} }
#landing { .drawer a {
background: radial-gradient(ellipse, #f7a816, #f76c16) !important; color: inherit;
background-attachment: fixed !important;
} }
#landing h1 { .drawer a:hover {
font-size: 10vw; color: var(--color-primary-hover) !important;
color: white;
margin-top: 16px;
margin-bottom: 0px;
letter-spacing: 0.04em;
font-weight: bold;
} }
@media (min-width: 576px) { .drawer li.active a {
#landing h1 { color: var(--color-primary);
font-size: 4em; position: relative;
}
} }
#landing p { /* .drawer li.active a:hover {
font-size: 1.2em; color: var(--color-primary-active) !important;
color: rgba(255, 255, 255, 0.7); text-decoration: none;
margin: 8px; } */
max-width: 80%;
line-height: 100%; .drawer li.active {
position: relative;
} }
#landing a { .drawer li.active::after {
background-color: rgba(240, 240, 240, 0.3); content: '';
color: white;
border-radius: 24px;
padding: 10px 20px 10px 20px;
margin-top: 16px;
display: inline-block; display: inline-block;
font-family: 'Calistoga', sans-serif; position: absolute;
font-size: 1.1em; right: 0;
top: 50%;
transform: translateY(-50%);
width: 8px;
height: 8px;
background-color: var(--color-primary);
border-radius: 50%;
} }
#landing #screenshots img { /* tables */
max-width: 100%;
padding: 12px; table {
/* same margins that reboot gives to pre */
margin-top: 0;
margin-bottom: 1rem;
border-collapse: collapse;
/* make it scrollable if needed */
display: block;
overflow-x: auto;
}
thead {
background-color: var(--color-table-head);
} }
#landing #screenshots { th {
margin-top: 24px; padding: 8px;
margin-bottom: 24px; border: 1px solid var(--color-divider);
font-family: var(--font-display), sans-serif;
font-weight: 700;
} }
#navigation { td {
font-size: 1.0em; padding: 8px;
border: 1px solid var(--color-divider);
} }
#navigation li a { /* page and content */
padding-left: 16px;
padding-right: 16px; .content a, footer a {
border-radius: 32px; color: var(--color-accent);
} }
#navigation li a:hover { .content a:hover, footer a:hover {
background: #fafafa; color: var(--color-accent) !important;
} }
#navigation li.active a { .content ul {
background: #f76c16; padding-left: 24px;
color: #FFFFFF;
} }
#navigation .nav-header { .content blockquote {
padding-top: 16px; background-color: var(--color-code-background);
padding-bottom: 4px; border-radius: var(--cards-radius);
padding-left: 0; border-left: 4px;
padding-right: 0; border-left-style: solid;
border-left-color: var(--color-accent);
font-size: 0.9em;
color: var(--color-text-muted);
padding: 0.8rem;
/* text-align: justify;
position: relative;
padding: 0.5rem 32px 0.5rem 0.5rem;
text-justify: inter-word; */
} }
.nav-header { /* .content blockquote::after {
font-size: 1.1em; content: '!';
cursor: default; position: absolute;
/* text-transform: uppercase; */ top: 50%;
font-weight: bold; transform: translateY(-50%);
font-family: 'Calistoga', sans-serif; right: 16px;
font-size: 1rem !important;
font-weight: 700 !important;
color: var(--color-accent);
} */
.content blockquote p, .content blockquote ul {
margin: 0;
} }
body.rtl { .content h1, .content h2, .content h3, .content h4, .content h5, .content h6 {
direction: rtl; margin-top: 1.4rem;
margin-bottom: 0.8rem;
} }
body.rtl #header .brand { .page-header span {
float: right; font-size: 0.9em;
margin-left: 5px; color: var(--color-text-muted);
} }
body.rtl .row-fluid [class*="span"] {
float: right !important; /* code */
margin-left: 0;
margin-right: 2.564102564102564%; pre {
border-radius: var(--cards-radius);
padding: 0.8rem;
font-size: 0.8rem !important;
line-height: 1.6;
} }
body.rtl .row-fluid [class*="span"]:first-child {
margin-right: 0; :not(pre) > code {
border-radius: var(--cards-radius);
padding: 2px;
font-weight: 700 !important;
font-size: 0.8rem !important;
} }
body.rtl ul, body.rtl ol { .language-java, .language-xml, .language-groovy {
margin: 0 25px 10px 0; position: relative;
} }
table { .language-java::after, .language-xml::after, .language-groovy::after {
margin-top: 25px; position: absolute;
margin-bottom: 25px; top: 0;
border: 1px solid #e5e5e5; right: 0;
border-collapse: collapse; padding: 6px;
font-size: 0.65rem;
color: var(--color-text-muted);
} }
thead { .language-java::after {
background-color: #f9f9f9; content: 'java';
} }
td { .language-xml::after {
padding: .25rem .5rem; content: 'xml';
border: 1px solid #e5e5e5;
} }
th { .language-groovy::after {
padding: 8px 12px; content: 'groovy';
border: 1px solid #e5e5e5;
font-weight: 400;
} }

@ -1,61 +1,86 @@
/* https://github.com/richleland/pygments-css/ */
@import "colors.css";
:root {
--syntax-muted: #999999;
--syntax-annotations: #a49848;
--syntax-keyword: #007020;
--syntax-operators: #606060;
--syntax-numbers: var(--syntax-keyword);
--syntax-xml-tags: var(--syntax-keyword);
}
.highlight .c { color: var(--syntax-muted); font-style: italic } /* Comment */
.highlight .ch { color: var(--syntax-muted); font-style: italic } /* Comment.Hashbang */
.highlight .cm { color: var(--syntax-muted); font-style: italic } /* Comment.Multiline */
.highlight .cp { color: var(--syntax-muted); } /* Comment.Preproc */
.highlight .cpf { color: var(--syntax-muted); font-style: italic } /* Comment.PreprocFile */
.highlight .c1 { color: var(--syntax-muted); font-style: italic } /* Comment.Single */
.highlight .cs { color: var(--syntax-muted); background-color: #fff0f0 } /* Comment.Special */
.highlight .nt { color: var(--syntax-xml-tags); font-weight: bold } /* Name.Tag */
.highlight .na { color: inherit; /* var(--color-accent) */ } /* Name.Attribute */
.highlight .nf { color: inherit; /* var(--color-accent) */ } /* Name.Function */
.highlight .mb { color: var(--syntax-numbers) } /* Literal.Number.Bin */
.highlight .mf { color: var(--syntax-numbers) } /* Literal.Number.Float */
.highlight .mh { color: var(--syntax-numbers) } /* Literal.Number.Hex */
.highlight .mi { color: var(--syntax-numbers) } /* Literal.Number.Integer */
.highlight .mo { color: var(--syntax-numbers) } /* Literal.Number.Oct */
.highlight .nd { color: var(--syntax-annotations); } /* Name.Decorator */
.highlight .k { color: var(--syntax-keyword); font-weight: bold } /* Keyword */
.highlight .kd { color: var(--syntax-keyword); font-weight: bold } /* Keyword.Declaration */
.highlight .kt { color: var(--syntax-keyword); font-weight: bold } /* Keyword.Type */
.highlight .kc { color: var(--syntax-keyword); font-weight: bold } /* Keyword.Constant */
.highlight .kn { color: var(--syntax-keyword); font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: var(--syntax-keyword); font-weight: bold } /* Keyword.Pseudo */
.highlight .kr { color: var(--syntax-keyword); font-weight: bold } /* Keyword.Reserved */
.highlight .s { color: var(--color-accent-dark); background-color: var(--color-accent-light); } /* Literal.String */
.highlight .s1 { color: var(--color-accent-dark); background-color: var(--color-accent-light); } /* Literal.String.Single */
.highlight .sa { color: var(--color-accent-dark) } /* Literal.String.Affix */
.highlight .sb { color: var(--color-accent-dark) } /* Literal.String.Backtick */
.highlight .sc { color: var(--color-accent-dark) } /* Literal.String.Char */
.highlight .dl { color: var(--color-accent-dark) } /* Literal.String.Delimiter */
.highlight .sd { color: var(--color-accent-dark); font-style: italic } /* Literal.String.Doc */
.highlight .s2 { color: var(--color-accent-dark) } /* Literal.String.Double */
.highlight .se { color: var(--color-accent-dark); font-weight: bold } /* Literal.String.Escape */
.highlight .sh { color: var(--color-accent-dark) } /* Literal.String.Heredoc */
.highlight .si { color: var(--color-accent-dark); font-style: italic } /* Literal.String.Interpol */
.highlight .sx { color: var(--color-accent-dark) } /* Literal.String.Other */
.highlight .sr { color: var(--color-accent-dark) } /* Literal.String.Regex */
.highlight .ss { color: var(--color-accent-dark) } /* Literal.String.Symbol */
.highlight .o { color: var(--syntax-operators) } /* Operator */
.highlight .hll { background-color: #ffffcc } .highlight .hll { background-color: #ffffcc }
.highlight { background: #ffffff; } .highlight .err { border: 1px solid #FF0000 } /* Error */
.highlight .c { color: #888888 } /* Comment */ .highlight .gd { color: #A00000 } /* Generic.Deleted */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; /* background-color: #fff0f0 */ } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gr { color: #FF0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .gi { color: #00A000 } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */ .highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .gt { color: #0044DD } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .m { color: #40a070 } /* Literal.Number */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .nb { color: #007020 } /* Name.Builtin */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .no { color: #60add5 } /* Name.Constant */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .ne { color: #007020 } /* Name.Exception */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .nl { color: #002070; font-weight: bold } /* Name.Label */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
.highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nv { color: #bb60d5 } /* Name.Variable */
.highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .fm { color: #06287e } /* Name.Function.Magic */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .vc { color: #bb60d5 } /* Name.Variable.Class */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .vg { color: #bb60d5 } /* Name.Variable.Global */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .il { color: #40a070 } /* Literal.Number.Integer.Long */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */

@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 512 499.36">
<path
fill="#fff"
fill-rule="evenodd"
fill-opacity="0.8"
d="M256 0C114.64 0 0 114.61 0 256c0 113.09 73.34 209 175.08 242.9 12.8 2.35 17.47-5.56 17.47-12.34 0-6.08-.22-22.18-.35-43.54-71.2 15.49-86.2-34.34-86.2-34.34-11.64-29.57-28.42-37.45-28.42-37.45-23.27-15.84 1.73-15.55 1.73-15.55 25.69 1.81 39.21 26.38 39.21 26.38 22.84 39.12 59.92 27.82 74.5 21.27 2.33-16.54 8.94-27.82 16.25-34.22-56.84-6.43-116.6-28.43-116.6-126.49 0-27.95 10-50.8 26.35-68.69-2.63-6.48-11.42-32.5 2.51-67.75 0 0 21.49-6.88 70.4 26.24a242.65 242.65 0 0 1 128.18 0c48.87-33.13 70.33-26.24 70.33-26.24 14 35.25 5.18 61.27 2.55 67.75 16.41 17.9 26.31 40.75 26.31 68.69 0 98.35-59.85 120-116.88 126.32 9.19 7.9 17.38 23.53 17.38 47.41 0 34.22-.31 61.83-.31 70.23 0 6.85 4.61 14.81 17.6 12.31C438.72 464.97 512 369.08 512 256.02 512 114.62 397.37 0 256 0z"/>
</svg>

After

Width:  |  Height:  |  Size: 993 B

@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24">
<path fill="none" d="M0 0h24v24H0V0z"/>
<path fill="#fff" fill-opacity="0.8" d="M4 18h16c.55 0 1-.45 1-1s-.45-1-1-1H4c-.55 0-1 .45-1 1s.45 1 1 1zm0-5h16c.55 0 1-.45 1-1s-.45-1-1-1H4c-.55 0-1 .45-1 1s.45 1 1 1zM3 7c0 .55.45 1 1 1h16c.55 0 1-.45 1-1s-.45-1-1-1H4c-.55 0-1 .45-1 1z"/>
</svg>

After

Width:  |  Height:  |  Size: 395 B

@ -3,7 +3,5 @@ layout: landing
title: "CameraView" title: "CameraView"
--- ---
# CameraView
A well documented, high-level library that makes capturing pictures and videos easy, A well documented, high-level library that makes capturing pictures and videos easy,
addressing all of the common issues and needs. Supports real-time filters, gestures, watermarks, frame processing, RAW, outputs of any size and much more. addressing all of the common issues and needs. Supports real-time filters, gestures, watermarks, frame processing, RAW, outputs of any size and much more.

@ -1,107 +0,0 @@
#!/usr/bin/env ruby
require 'date'
require 'optparse'
options = {
# Expects to be in the bin/ sub-directory by default
:path => File.dirname(File.dirname(__FILE__))
}
parser = OptionParser.new do |opt|
opt.banner = 'usage: jekyll-page TITLE CATEGORY [FILENAME] [OPTIONS]'
opt.separator ''
opt.separator 'Options'
opt.on('-e', '--edit', 'Edit the page') do |edit|
options[:edit] = true
end
opt.on('-l', '--link', 'Relink pages') do |link|
options[:link] = true
end
opt.on('-p PATH', '--path PATH', String, 'Path to project root') do |path|
options[:path] = path
end
opt.separator ''
end
parser.parse!
title = ARGV[0]
category = ARGV[1]
filename = ARGV[2]
# Resolve any relative links
BASE_DIR = File.expand_path(options[:path])
POSTS_DIR = "#{BASE_DIR}/_posts"
PAGES_DIR = "#{BASE_DIR}/_pages"
# Ensure the _posts directory exists (we are in the correct directory)
if not Dir.exists?(POSTS_DIR)
puts "#{POSTS_DIR} directory does not exists"
exit
end
# Create _pages directory if it doesn't exist
if not Dir.exists?(PAGES_DIR)
Dir.mkdir(PAGES_DIR)
end
if options[:link]
Dir.foreach(POSTS_DIR) do |name|
next if name[0] == '.'
nodate = name[/\d{4}-\d{2}-\d{2}-(?<rest>.*)/, 'rest']
if File.symlink?("#{PAGES_DIR}/#{nodate}")
File.delete("#{PAGES_DIR}/#{nodate}")
end
abspath = File.absolute_path("#{POSTS_DIR}/#{name}")
File.symlink(abspath, "#{PAGES_DIR}/#{nodate}")
end
end
if not title or not category
# This flag can be used by itself, exit silently if no arguments
# are defined
if not options[:link]
puts parser
end
exit
end
if not filename
filename = title.downcase.gsub(/[^a-z0-9\s]/, '').gsub(/\s+/, '-')
end
today=Date.today().strftime('%F')
now=DateTime.now().strftime('%F %T')
filepath = "#{POSTS_DIR}/#{today}-#{filename}.md"
symlink = "#{PAGES_DIR}/#{filename}.md"
if File.exists?(filepath)
puts "File #{filepath} already exists"
exit
end
content = <<END
---
layout: page
title: \"#{title}\"
category: #{category}
date: #{now}
---
END
File.open(filepath, 'w') do |file|
file.puts content
end
File.symlink("../_posts/#{today}-#{filename}.md", symlink)
if options[:edit]
if not ENV['EDITOR']
puts 'No $EDITOR variable set'
exit
end
puts ENV['EDITOR']
exec("#{ENV['EDITOR']} #{filename}")
end
Loading…
Cancel
Save