# camera

Camera
**Notice**：Related api: [`tt.createCameraContext`](https://open.feishu.cn/document/uYjL24iN/ukDOukDOukDO/camera/createcameracontext).

Before the component is called, the access to `scope.camera` must be authorized by the user. For more information, see [API scopes](https://open.feishu.cn/document/uYjL24iN/uITMuITMuITM).
## Supported capabilities

App capability | Android | iOS | PC | Preview
---|---|---|---|---
Gadget | V5.21.0+ | V5.21.0+ | **X** | Preview

## Properties

Name | Type | Default value | Required | Allow dynamic modification | Description | Minimum version
---|---|---|---|---|---|---
id | string | &nbsp; | Yes | No | The id global attribute defines an identifier (ID) which must be unique in the whole document. | 5.21.0
resolution | Enum&lt;string&gt; | medium | No | No | Resolution | 5.21.0
device-position | Enum&lt;string&gt; | back | No | Yes | The camera angle. | 5.21.0
flash | Enum&lt;string&gt; | auto | No | Yes | The flashlight. | 5.21.0
mode | Enum&lt;string&gt; | normal | No | No | Application mode. | 5.27.0
scan-code-type | Enum&lt;string&gt; | continuous | No | No | ScanCode type. | 5.27.0
bindstop | EventHandler | &nbsp; | No | Yes | Triggered when the camera is stopped abnormally, such as exiting the background. | 5.21.0
binderror | EventHandler | &nbsp; | No | Yes | Triggered when a user does not allow the use of camera or camera creation fails. | 5.21.0
bindinitdone | EventHandler | &nbsp; | No | Yes | - Triggered when camera is initialized.`e.detail = {maxZoom, devicePosition}`<br>- The callback is triggered again when the camera status changes from stop to available.<br>- When switching between cameras, the current camera is turned off and the next camera is turned on. In this case, bindstop is called first and then bindinitdone is called. | 5.21.0
bindscancode | EventHandler | &nbsp; | No | Yes | Triggered when scan code recognition is successful, only takes effect when mode = "scanCode". | 5.27.0
bindlumadetect | EventHandler | &nbsp; | No | Yes | Dark light detection callback, only takes effect when mode = "scanCode". | 5.27.0

## Bug & Tip
1. `tip`: Only one`camera`component can be added to the same page.
2. `tip`: Pay attention to the limits on the use of native components.
3. `tip`: Due to the limitation of the self-developed browser kernel coverage, the camera component does not guarantee the same layer rendering at the level. Whether to support the same layer rendering, please refer to the bindinserted callback description. In non-same-layer rendering scenarios, developers need to adapt the interface accordingly to avoid covering other components on top of the camera component. Please refer to [Native components and same-layer rendering](https://open.feishu.cn/document/uYjL24iN/uUTM5UjL1ETO14SNxkTN/native-component).

## ScanCode Tip
When mode is scanCode: 
1. Tip: `flash`=`auto`/`off` to turn off the flashlight, `on`/`torch` to turn on the flashlight.
2. Tip: `device-position` does not support switching, only `back` is supported.
3. Tip: `takePhoto`, `startRecord`, `stopRecord` are not available.

## Parameters

### Valid values for resolution
|Value|Description|Minimum version
|--|----|--
|low|Low|5.21.0
|medium|Medium|5.21.0
|high|High|5.21.0
### Valid values for device-position

|Value|Description|Minimum version
|--|----|--
|front|Front|5.21.0
|back|Rear|5.21.0
### Valid values for flash

|Value|Description|Minimum version
|--|----|--
|auto|Auto (supported on iOS devices only)|5.21.0
|on|On|5.21.0
|off|Off|5.21.0
|torch|Always on|5.21.0
### Valid values for mode

|Value|Description|Minimum version
|--|----|--
|normal|camera mode|5.21.0
|scanCode|scan mode|5.27.0
### Valid values for scan-code-type

|Value|Description|Minimum version
|--|--------|--
|continuous|Continuous callback, as long as there is a scannable code in the screen, bindscancode will continue to callback|5.27.0
|single|Triggered callback, bindscancode will callback only when the codes scanned before and after are different|5.27.0
### bindinitdone
- Called when camera is initialized for the first time.
- Called each time when camera is restored from stop to available.
``` JavaScript
interface BindInitDoneDetail {
  maxZoom: number; // Indicates the maximum zoom range. See theCameraContext.setZoomAPI for details.
  devicePosition: string; // Corresponds to the device-position property.
}
```
### bindinserted
- Called when the camera component is inserted into the page.
- This callback is currently used to tell whether to enable the same layer rendering.
```JavaScript
interface BindInsertedDetail {
  isRenderInSameLayer: boolean; // Whether the same layer rendering is currently enabled.
}
```
### bindscancode
```JavaScript
enum ScanCodeType {
    QR_CODE = 'QR_CODE',
    VORTEX_CODE = 'VORTEX_CODE',
    UPC_A_CODE = 'UPC_A_CODE',
    UPC_E_CODE = 'UPC_E_CODE',
    EAN_8_CODE = 'EAN_8_CODE',
    EAN_13_CODE = 'EAN_13_CODE',
    CODE39_CODE = 'CODE39_CODE',
    CODE128_CODE = 'CODE128_CODE',
    DATA_MATRIX = 'DATA_MATRIX',
    PDF_417 = 'PDF_417'
}

interface BindScanCodeDetail {
    type?: ScanCodeType;
    result?: string;
}
```
### bindlumadetect
- Dark light detection callback, only takes effect when mode = "scanCode".
- Callback timing: when the camera is initialized or the scene changes.
```JavaScript
interface BindLumaDetectDetail {
    scene: number; // the night return 0, and the day return 1.
}
```

## Sample code

TTML file
```html 
<scroll-view class="page-body">
  <view class="page-body-wrapper">
    <camera
    id="myCamera"
    binderror="binderror"
    bindstop="bindstop"
    bindinitdone="bindinitdone"
    bindinserted="bindinserted"
    style="{{ style }}"/>

<view class="btn-area">
      <button type="primary" bindtap="takePhoto">{{take_photo}}</button>
    </view>

<view class="btn-area">
      <button type="primary" bindtap="startRecord">{{start_record}}</button>
    </view>
    <view class="btn-area">
      <button type="primary" bindtap="stopRecord">{{stop_record}}</button>
    </view>
    <view class="preview-tips" tt:if="{{src}}">{{preview_tips}}</view>
    <view class="btn-area" tt:if="{{src}}">
      <button type="primary" bindtap="previewImage">{{preview_image}}</button>
    </view>
    <video tt:if="{{videoSrc}}" class="video" src="{{videoSrc}}"/>

</view>
</scroll-view>
``` 
JS file
```javascript 
const camera = i18n.cameraComponent

Page({
  data: {
    ...camera,
    src: undefined,
    videoSrc: undefined,
    maxZoom: undefined,
    currentDevicePosition: undefined,
    style: undefined,
  },

onReady: function () {
    this.ctx = tt.createCameraContext('myCamera');
    this.setData({
      style: "width: 100%; height: 300px",
    })
  },
  takePhoto: function () {
    this.ctx.takePhoto({
      success: res => {
        console.log('takePhoto success', res);
        this.setData({
          src: res.tempImagePath
        });
      },
      fail: res => {
        console.log('takePhoto fail', res);
      }
    });
  },

startRecord: function () {
    this.ctx.startRecord({
      timeoutCallback: res => {
        console.log('startRecord timeout', res);
        this.setData({
          src: res.tempThumbPath,
          videoSrc: res.tempVideoPath
        });
      },
      success: res => {
        console.log('startRecord success', res);
      },
      fail: res => {
        console.log('startRecord fail', res);
      }
    });
  },

stopRecord: function () {
    this.ctx.stopRecord({
      compressed: this.data.stopRecordCompressed,
      success: res => {
        console.log('stopRecord success', res);
        this.setData({
          src: res.tempThumbPath,
          videoSrc: res.tempVideoPath
        });
      },
      fail: res => {
        console.log('stopRecord fail', res);
      }
    });
  },

binderror: function (e) {
    console.log('binderror', e);
  },

bindstop: function (e) {
    console.log('bindstop', e);
  },

bindinitdone: function (e) {
    console.log('bindinitdone', e.detail);
    this.setData({
      maxZoom: e.detail.maxZoom,
      currentDevicePosition: e.detail.devicePosition,
    })
  },

previewImage: function () {
    let image = this.data.src;
    tt.previewImage({
      urls: [image]
    })
  },
})

```
TTSS file
```css
.preview-tips {
  margin: 20rpx 0;  
}

.video {
  margin: 50px auto;
  width: 100%;
  height: 300px;
}

.picker{
  padding: 19rpx 32rpx;
  background-color: #FFFFFF;
}
.section__title{
  padding: 48rpx 32rpx 8rpx 32rpx;
  font-size: medium;
  color: #999999;
}

.view-above {
  position: absolute;
  width: 100%;
  height: 40px;
  top: 40px;
}
.preview-tips {
  margin: 20rpx 0;  
}

.video {
  margin: 50px auto;
  width: 100%;
  height: 300px;
}
```
