当前位置: 首页 > news >正文

电商网站建设标准网站的商业授权

电商网站建设标准,网站的商业授权,上海房产网最新二手房,建设工程查询网站引言 视频截取在社交类 APP 中十分常见。有了上传视频的功能#xff0c;就不可避免地需要提供截取和编辑的选项。如果我们过度依赖第三方库#xff0c;项目的代码可能会变得异常臃肿#xff0c;因为这些库往往包含许多我们用不到的功能#xff0c;而且它们的 UI 样式和功能… 引言 视频截取在社交类 APP 中十分常见。有了上传视频的功能就不可避免地需要提供截取和编辑的选项。如果我们过度依赖第三方库项目的代码可能会变得异常臃肿因为这些库往往包含许多我们用不到的功能而且它们的 UI 样式和功能通常比较固定不支持定制。因此有条件的话尽可能自行实现这些功能。 原本我打算直接介绍视频截取的实现方式但发现相关的 UI 设计也非常有趣。如果不把 UI 和视频截取功能结合起来即使掌握了截取技术也可能难以打造出一个好用的视频编辑工具。因此在本篇博客中我们先来介绍视频截取中最常见的 UI 样式和小组件。 组件结构 我们创建一个继承自UIView的SVVideoEditBar类整个编辑的操作小组件可以分为播放控制和截取控制两部分 播放控制 第一部分是播放和暂停按钮控制截取后视频的播放和暂停功能这里比较简单只需要一个按钮就可以实现。 /// 播放按钮private var playButton UIButton()/// 添加播放按钮private func addPlayerButton() {playButton.setImage(UIImage(named: icon_play_light_fill_24), for: .normal)playButton.setImage(UIImage(named: icon_pause_light_fill_24), for: .selected)self.addSubview(playButton)playButton.snp.makeConstraints { make inmake.leading.equalToSuperview().offset(16.0)make.centerY.equalToSuperview()make.width.height.equalTo(24.0)}}截取控制 第二部分为截取控制部分可以再详细划分为展示部分和操作部分。 展示 对于展示部分我们采用UICollectionView来显示视频获取到的缩略图。 /// 列表private var collectionView:UICollectionView!/// 添加列表private func addCollectionView() {let layout UICollectionViewFlowLayout()layout.minimumLineSpacing 0.0layout.scrollDirection .horizontalcollectionView UICollectionView(frame: .zero, collectionViewLayout: layout)collectionView.contentInset UIEdgeInsets(top: 0.0, left: 10.0, bottom: 0.0, right: 10.0)collectionView.backgroundColor UIColor.clearcollectionView.showsHorizontalScrollIndicator falsecollectionView.delegate selfcollectionView.dataSource selfcollectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: cell)self.addSubview(collectionView)collectionView.snp.makeConstraints { make inmake.leading.equalTo(lineView.snp.trailing).offset(20.0)make.trailing.equalToSuperview().offset(-20.0)make.top.equalToSuperview().offset(8.0)make.bottom.equalToSuperview().offset(-8.0)}collectionView.backgroundColor .red}关于列表中图片的尺寸会根据视频的尺寸来确定所以我们将大小在代理方法中进行设置 extension SVVideoEditBar: UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout {func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) - Int {return 10}func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) - UICollectionViewCell {let cell collectionView.dequeueReusableCell(withReuseIdentifier: cell, for: indexPath)return cell}func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) - CGSize {return CGSize(width: 40.0, height: collectionView.bounds.height)} } 滑动遮罩 遮罩也分为两部分一部分为黄色的边框边框内的内容表示的是视频截取后保留的部分而黄色边框以外的黑色半透明的遮罩则表示视频截取后舍弃的部分。 黄色的部分由我们自定义的视图SVEditorSliderView来实现。 /// 可拖拽滑动视图private var sliderView SVEditorSliderView()/// 添加滑动视图private func addSliderView() {self.addSubview(sliderView)sliderView.layer.cornerRadius 8.0sliderView.backgroundColor UIColor.yellowupdateLeftRightOffset()// 右侧拖拽回调sliderView.rightDragBlock { [weak self] x in...}// 左侧拖拽回调sliderView.leftDragBlock { [weak self] x in....}} /// 更新左右侧偏移private func updateLeftRightOffset() {sliderView.snp.remakeConstraints { make inmake.leading.equalTo(lineView.snp.trailing).offset(leftOffset)make.top.bottom.equalToSuperview()make.trailing.equalToSuperview().offset(rightOffset)}}两侧的黑色半透明遮罩直接通过UIView设置背景颜色的方式来实现 /// 左侧蒙层private var leftMaskView UIView()/// 右侧蒙层private var rightMaskView UIView()/// 添加左侧蒙层private func addLeftMaskView() {leftMaskView.backgroundColor UIColor.black.withAlphaComponent(0.3)self.addSubview(leftMaskView)leftMaskView.snp.makeConstraints { make inmake.top.bottom.equalToSuperview()make.leading.equalTo(self.lineView.snp.trailing)make.trailing.equalTo(sliderView.snp.leading)}}/// 添加右侧蒙层private func addRightMaskView() {rightMaskView.backgroundColor UIColor.black.withAlphaComponent(0.3)self.addSubview(rightMaskView)rightMaskView.snp.makeConstraints { make inmake.top.bottom.equalToSuperview()make.leading.equalTo(sliderView.snp.trailing)make.trailing.equalToSuperview()}} 进度条 另外还有一个在播放时会跟随播放进度而移动的进度条直接使用UIView加阴影的方式来实现。 class SVProgressLineView: UIView {override init(frame: CGRect) {super.init(frame: frame)self.backgroundColor .whiteself.layer.cornerRadius 1.0// 阴影self.layer.shadowColor UIColor.black.cgColorself.layer.shadowOffset CGSize(width: -1, height: 0)self.layer.shadowOpacity 0.5self.layer.shadowRadius 2.0}required init?(coder: NSCoder) {fatalError(init(coder:) has not been implemented)}}/// 进度线private var progressLineView SVProgressLineView()/// 添加进度线private func addProgressLineView() {self.addSubview(progressLineView)progressLineView.snp.makeConstraints { make inmake.leading.equalTo(sliderView).offset(20.0 10.0)make.centerY.equalToSuperview()make.width.equalTo(2.0)make.height.equalTo(self.snp.height).inset(8.0)}}实现操作视图 - SVEditorSliderView 接下来我们把重点集中到SVEditorSliderView上面首先它需要一个镂空效果来显示底部的缩图列表另外它的两侧还需要可拖拽来修改视频的截取区域。 镂空效果 那我们先来实现它的镂空效果采用图层的mask属性和贝塞尔曲线结合来实现镂空。 /// maskLayerprivate let maskLayer CAShapeLayer()/// pathprivate var path UIBezierPath()/// fullPathprivate var fullPath UIBezierPath() override init(frame: CGRect) {super.init(frame: frame)maskLayer.backgroundColor UIColor.black.cgColorself.layer.mask maskLayermaskLayer.fillRule .evenOdd...} override func layoutSubviews() {let width self.bounds.widthlet height self.bounds.heightfullPath UIBezierPath(rect: self.bounds)path UIBezierPath(rect: CGRect(x: 20.0, y: 8.0, width: width - 40.0, height: height - 16.0))fullPath.append(path)fullPath.usesEvenOddFillRule truemaskLayer.path fullPath.cgPath....} 拖拽事件 在视图的最左侧和最右侧添加可拖拽的UIView视图并处理拖拽事件由于该视图的布局在父视图上所以我们选择将退拽事件回调出去来处理。 /// 右侧可拖拽视图private let rightDragView UIView()/// 左侧可拖拽视图private let leftDragView UIView()/// 右侧退拽回调var rightDragBlock:((CGFloat)-Void)?/// 左侧拖拽回调var leftDragBlock:((CGFloat)-Void)?/// 添加右侧可拖拽视图private func addRightDragView() { // rightDragView.backgroundColor .whiteself.addSubview(rightDragView)let pan UIPanGestureRecognizer(target: self, action: #selector(panAction(_:)))rightDragView.addGestureRecognizer(pan)rightDragView.isUserInteractionEnabled true}/// 添加左侧可拖拽视图private func addLeftDragView() { // leftDragView.backgroundColor .whiteself.addSubview(leftDragView)let pan UIPanGestureRecognizer(target: self, action: #selector(panAction(_:)))leftDragView.addGestureRecognizer(pan)leftDragView.isUserInteractionEnabled true} objc private func panAction(_ pan:UIPanGestureRecognizer) {// 获取视图let view pan.viewif view rightDragView {let translation pan.translation(in: self)let x translation.xrightDragBlock?(x)} else if view leftDragView {let translation pan.translation(in: self)let x translation.xleftDragBlock?(x)}pan.setTranslation(.zero, in: self)}override func layoutSubviews() {let width self.bounds.widthlet height self.bounds.height...rightDragView.frame CGRect(x: width - 20.0, y: 0.0, width: 20.0, height: height)leftDragView.frame CGRect(x: 0.0, y: 0.0, width: 20.0, height: height)} 拖拽处理 处理拖拽事件是个细活在拖拽过程中我们需要更新sliderView的布局约束我们把它分成两个部分来讨论。 右侧拖拽事件 在SVVideoEditBar类中我们还定义另外两个CGFloat类型属性 /// 左侧偏移     private var leftOffset:CGFloat 0.0     /// 右侧偏移     private var rightOffset:CGFloat 0.0 分别表示sliderView的左侧约束的偏移量和右侧约束的偏移量默认都为0.0。 在进行右侧退拽时我们首先需要注意的是往右拖拽时不能超过SVVideoEditBar的最右端而往左退拽时不能超过sliderView自己的最左端的拖拽视图。 // 右侧拖拽回调sliderView.rightDragBlock { [weak self] x inguard let self self else { return }// 限制右侧往右的拖拽范围if self.sliderView.frame.maxX self.bounds.width x 0 {print(右侧往右拖拽到最大范围)self.rightOffset 0.0self.updateLeftRightOffset()return}// 限制右侧往左的拖拽范围if self.sliderView.frame.maxX (self.sliderView.frame.minX40.0) x 0 {print(右侧往左拖拽到最小范围)self.rightOffset -(self.bounds.width - self.sliderView.frame.minX - 40.0)self.updateLeftRightOffset()return}self.rightOffset self.rightOffset xself.updateLeftRightOffset()}左侧拖拽事件 当我们拖拽左侧是视图时需要注意当往左侧拖拽时不能超过左侧的起始位置也就是竖线的最最右侧。而往右拖拽时同样也不能超过右侧的拖拽视图。 // 左侧拖拽回调sliderView.leftDragBlock { [weak self] x inguard let self self else { return }// 限制左侧往左的拖拽范围if self.sliderView.frame.minX self.lineView.frame.maxX x 0 {print(左侧往左拖拽到最小范围)self.leftOffset 0.0self.updateLeftRightOffset()return}// 限制左侧往右的拖拽范围if self.sliderView.frame.minX (self.sliderView.frame.maxX-40.0) x 0 {print(左侧往右拖拽到最大范围)self.leftOffset self.sliderView.frame.maxX - 40.0 - self.lineView.frame.maxXself.updateLeftRightOffset()return}self.leftOffset self.leftOffset xself.updateLeftRightOffset()}这样像GIF图片一样的视频剪裁小组件的UI部分就实现了。 结语 本篇博客主要介绍了视频截取中的UI小组件介绍了如何实现镂空效果以及拖拽事件尤其是拖拽时临界值的处理。 获取到了裁剪区域之后我们就可以根据视频的长度来进行视频截取了那么下一篇博客我们将开始进入视频截取的数据处理部分。
http://www.w-s-a.com/news/765668/

相关文章:

  • 建设网站需要哪些软硬件条件wordpress文章页标题优化
  • 网站建设功能需求文档wordpress 1g1核1m
  • 学做窗帘要下载哪个网站用户反馈数据分析软件园
  • 宁晋网站建设多少钱产品宣传推广方式有哪些
  • delphi做网站阿里巴巴官网首页登录入口
  • 游戏网站怎么建设新建wordpress模板
  • 网络服务器是指兰州网站seo诊断
  • 怎样做投资理财网站godaddy上传网站
  • 网站建设深圳哪家好世界500强企业招聘网站
  • 如何减少网站建设中的错误温州网站公司哪家好
  • 宜章网站建设北京定制公交网站
  • 怎么让谷歌收录我的网站郑州网站建设更好
  • 在线视频网站开发方案phpaspnet网站开发实例视频
  • 正常做一个网站多少钱网站开发所遵循
  • 西部数码网站备份领英创建公司主页
  • 中山网站建设文化平台成都电商app开发
  • 无锡网站推广公司排名中国十大网站建设
  • 网站建设报价怎么差别那么大深圳开发公司网站建设
  • 京东商城网站建设方案书建设网站平台
  • 如何查询网站建设时间赤峰建网站的电话
  • 域名购买网站有哪些公司企业邮箱管理制度
  • 阿里云服务起做网站抖音seo推荐算法
  • 免费建站工具机械网站建设公司推荐
  • 怎么用自己主机做网站_如何做简单的网站
  • 阿里巴巴国际站跨境电商平台为什么有点网站打不开
  • 甘肃做网站哪家好网站开发 都包含什么语言
  • 合肥哪里有做网站的广告型网站怎么做的
  • 用dede做的网站国外免费空间哪个好
  • dede个人网站模板企点
  • 韩雪个人网站wordpress 怎么添加网站备案信息